Changeset 1088

Show
Ignore:
Timestamp:
09/12/08 00:13:23 (17 months ago)
Author:
mpaschal
Message:

Untangle this rat's nest of metadata discovery
BugzID: 81932

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/StyleCatcher-2.1-dev/plugins/StyleCatcher/lib/StyleCatcher/CMS.pm

    r1040 r1088  
    88 
    99use strict; 
    10 use File::Basename qw(basename); 
     10use File::Basename qw( basename dirname ); 
    1111 
    1212use MT::Util qw( remove_html decode_html ); 
     
    464464    if ( $type =~ m!^text/css! ) { 
    465465        $data->{auto}{url} = $url; 
    466         my $theme = fetch_theme( 
     466        my $theme = metadata_for_theme( 
    467467            url  => $url, 
    468468            tags => ['collection:auto'], 
     
    503503        my $themes = []; 
    504504        for my $repo_theme (@repo_themes) { 
    505             my $theme = fetch_theme( 
     505            my $theme = metadata_for_theme( 
    506506                url => $repo_theme, 
    507507            ); 
     
    577577        next unless -d $theme; 
    578578        $theme =~ s/.*[\\\/]//; 
    579         $themes->{$theme} = fetch_theme( 
    580             url      => $theme_dir, 
    581             tags     => ['collection:mt-designs'], 
    582             baseurl  => $theme_url, 
    583             basepath => $theme_dir, 
     579        $themes->{$theme} = metadata_for_theme( 
     580            path => $theme_dir, 
     581            url  => "$theme_url/$theme/", 
     582            tags => ['collection:mt-designs'], 
    584583        ); 
    585         $themes->{$theme}{name} = $themes->{$theme}{name}; 
    586584        $themes->{$theme}{prefix} = 'default'; 
    587585    } 
     
    597595        next unless -d $theme; 
    598596        $theme =~ s/.*[\\\/]//; 
    599         $themes->{$theme} = fetch_theme( 
    600             url  => $theme_dir, 
     597        $themes->{$theme} = metadata_for_theme( 
     598            path => $theme_dir, 
     599            url  => $app->static_path . "support/themes/$theme/", 
    601600            tags => ['collection:my-designs'], 
    602601        ); 
     
    612611} 
    613612 
    614 sub fetch_theme { 
    615     my $app = MT->app; 
     613sub theme_for_url { 
    616614    my %param = @_; 
    617     my ($url, $tags, $baseurl, $basepath, $default_metadata) 
    618         = @param{qw( url tags baseurl basepath metadata )}; 
    619     $tags ||= []; 
    620  
    621     my $theme; 
    622     my $stylesheet; 
    623     my $new_url; 
    624     my $themeroot; 
    625     my $url_is_web = $url =~ m{ \A https?: }xms ? 1 : 0; 
    626     if ($url_is_web) { 
    627         # Pick up the css file 
    628         my $user_agent  = $app->new_ua; 
    629         my $css_request = HTTP::Request->new( GET => $url ); 
    630         my $response    = $user_agent->request($css_request); 
    631         $stylesheet = $response->content if ($response->code >= 200) && ($response->code < 400); 
    632         return unless $stylesheet; 
    633  
    634 # Break up the css url in to a couple useful pieces (generalize and break me out) 
    635         $theme = $url; 
    636         # discard any generic 'screen.css' filename 
    637         $theme =~ s{ / (?:screen|style) \.css \z }{}xms; 
    638         $theme =~ s/.*[\\\/]//; 
    639         my @url = split( /\//, $url ); 
    640         for ( 0 .. ( scalar(@url) - 2 ) ) { 
    641             $new_url .= $url[$_] . '/'; 
    642         } 
    643     } 
    644     else { 
    645         $themeroot = $basepath 
    646           || File::Spec->catdir( $app->static_file_path, 'support', 'themes' ); 
    647         my $webthemeroot = $baseurl || $app->static_path . 'support/themes'; 
    648  
    649         $theme = $url; 
    650         $theme =~ s/.*[\\\/]//; 
    651         my $file = File::Spec->catfile( $url, "$theme.css" ); 
    652         $new_url = "$webthemeroot/$theme/"; 
    653         if ( -e $file ) { 
    654             $stylesheet = file_mgr()->get_data($file); 
    655             $url        = $new_url . "$theme.css"; 
    656         } 
    657         else { 
    658             $file = File::Spec->catfile( $url, $theme, "screen.css" ); 
    659             if ( -e $file ) { 
    660                 $stylesheet = file_mgr()->get_data($file); 
    661                 $url        = $new_url . "screen.css"; 
    662             } 
    663         } 
    664     } 
     615    my ($url, $path, $tags, $baseurl, $basepath) 
     616        = @param{qw( url path tags baseurl basepath )}; 
     617    my $app = MT->instance; 
     618 
     619    my %theme; 
     620    if ($path && -e $path) { 
     621        $theme{stylesheet} = file_mgr()->get_data($path); 
     622        $theme{id} = basename(dirname($path)); 
     623    } 
     624    elsif ($url) { 
     625        my $user_agent = $app->new_ua; 
     626        my $response   = $user_agent->get($url); 
     627        return if !$response->is_success(); 
     628        $theme{stylesheet} = $response->content; 
     629 
     630        my $id = $url; 
     631        $id =~ s{ / (?:screen|style) \.css \z }{}xms; 
     632        $id =~ s/.*[\\\/]//; 
     633        $theme{id} = $id; 
     634    } 
     635 
     636    return %theme; 
     637} 
     638 
     639sub metadata_for_stylesheet { 
     640    my %param = @_; 
     641    my ($stylesheet) = @param{qw( stylesheet )}; 
    665642 
    666643    # Pick up the metadata from the css 
     
    685662    } 
    686663 
    687     my $comment; 
    688664    my %metadata; 
    689665 
    690666    # Trim me white space, yarr 
    691     for (@comments) { 
    692  
    693         # TBD: strip any "risky" content; we don't want any 
    694         # XSS in this content. 
     667    for my $comment (@comments) { 
    695668        # Strip any null bytes 
    696         tr/\x00//d; 
    697         s/^\s+|\s+$//g; 
    698         my ( $key, $value ) = split( /:/, $_, 2 ) or next; 
     669        $comment =~ tr/\x00//d; 
     670        $comment =~ s/^\s+|\s+$//g; 
     671 
     672        my ( $key, $value ) = split( /:/, $comment, 2 ) or next; 
    699673        next unless defined $value; 
    700674        $value =~ s/^\s+//; 
    701675        $metadata{ lc $key } = $value; 
    702     } 
    703  
    704     my %thumbnails; 
    705     THUMB: for my $thumb (qw( thumbnail thumbnail_large )) { 
    706         $thumbnails{$thumb} = $metadata{$thumb}; 
    707         next THUMB if $thumbnails{$thumb}; 
    708  
    709         my $thumb_filename = $thumb; 
    710         $thumb_filename =~ tr/_/-/; 
    711         $thumb_filename .= '.gif'; 
    712  
    713         if ($url_is_web) { 
    714             my $thumb_url = $new_url . $thumb_filename; 
    715  
    716             my $user_agent  = $app->new_ua; 
    717             my $css_request = HTTP::Request->new( HEAD => $thumb_url ); 
    718             my $response    = $user_agent->request($css_request); 
    719             if ($response->is_success()) { 
    720                 $thumbnails{$thumb} = $thumb_url; 
    721             } 
    722         } 
    723         else { 
    724             my $thumb_path = File::Spec->catfile($themeroot, $theme, 
    725                 $thumb_filename); 
    726             if (-e $thumb_path) { 
    727                 $thumbnails{$thumb} = $new_url . $thumb_filename; 
    728             } 
    729         } 
    730  
    731         $thumbnails{$thumb} ||= $app->static_path . 'plugins/StyleCatcher/' 
    732             . 'images/' . $thumb_filename; 
    733676    } 
    734677 
     
    743686        ($metadata{$best_name}) = grep { defined } 
    744687            delete @metadata{ @$possible_names }, q{}; 
     688        # TODO: do html mashing later 
    745689        $metadata{$best_name} = decode_html(remove_html($metadata{$best_name})); 
    746690    } 
    747691 
    748     require MT::Util; 
     692    return %metadata; 
     693} 
     694 
     695sub thumbnails_for_theme { 
     696    my %param = @_; 
     697    my ($url, $path, $metadata) 
     698        = @param{qw( url path metadata )}; 
     699    my $app = MT->instance; 
     700 
     701    my %thumbnails; 
     702    THUMB: for my $thumb (qw( thumbnail thumbnail_large )) { 
     703        $thumbnails{$thumb} = $metadata->{$thumb}; 
     704        next THUMB if $thumbnails{$thumb}; 
     705 
     706        my $thumb_filename = $thumb; 
     707        $thumb_filename =~ tr/_/-/; 
     708        $thumb_filename .= '.gif'; 
     709 
     710        require URI; 
     711        if ($path) { 
     712            my ($volume, $dir, $theme_filename) = File::Spec->splitpath($path); 
     713            my $thumb_path = File::Spec->catpath($volume, $dir, $thumb_filename); 
     714            if (-e $thumb_path) { 
     715                my $url_uri = URI->new_abs($thumb_filename, $url); 
     716                $thumbnails{$thumb} = $url_uri->as_string(); 
     717            } 
     718        } 
     719        elsif ($url) { 
     720            my $url_uri = URI->new_abs($thumb_filename, $url); 
     721            my $thumb_url = $url_uri->as_string(); 
     722 
     723            my $user_agent = $app->new_ua; 
     724            my $response   = $user_agent->head($thumb_url); 
     725            if ($response->is_success()) { 
     726                $thumbnails{$thumb} = $thumb_url; 
     727            } 
     728        } 
     729 
     730        # Use plugin's default thumbnail if necessary. 
     731        $thumbnails{$thumb} ||= $app->static_path . 'plugins/StyleCatcher/' 
     732            . 'images/' . $thumb_filename; 
     733    } 
     734 
     735    return %thumbnails; 
     736} 
     737 
     738sub metadata_for_theme { 
     739    my $app = MT->app; 
     740    my %param = @_; 
     741    my ($url, $path, $tags, $default_metadata) 
     742        = @param{qw( url path tags metadata )}; 
     743 
     744    # Update a path, if present, from a theme directory to the real full 
     745    # stylesheet path. 
     746    if ($path && -d $path) { 
     747        $path =~ s{ / \z }{}xms; 
     748        FILESTEM: for my $filestem (basename($path), "screen", "style") { 
     749            my $full_path = File::Spec->catfile($path, "$filestem.css"); 
     750            if ($full_path && -f $full_path) { 
     751                $path = $param{path} = $full_path; 
     752 
     753                $url =~ s{ / \z }{}xms; 
     754                $url  = $param{url}  = "$url/$filestem.css"; 
     755 
     756                last FILESTEM; 
     757            } 
     758        } 
     759    } 
     760 
     761    my %theme      = theme_for_url(%param); 
     762    my %metadata   = metadata_for_stylesheet(%param, %theme); 
     763    my %thumbnails = thumbnails_for_theme(%param, metadata => \%metadata); 
     764 
    749765    my $data = { 
    750         name         => $theme, 
     766        name         => $theme{id}, 
    751767        description  => $metadata{description} || q{}, 
    752768        title        => $metadata{title} || '(Untitled)', 
     
    755771        imageBig     => $thumbnails{thumbnail_large}, 
    756772        layouts      => $metadata{layouts} || q{}, 
    757         sort         => $metadata{name} || $theme || q{}, 
    758         tags         => $tags, 
     773        sort         => lc($metadata{title} || $theme{id} || q{}), 
     774        tags         => $tags || [], 
    759775        blogs        => [], 
    760776        author       => $metadata{author},