Index: /branches/StyleCatcher-2.1-dev/plugins/StyleCatcher/lib/StyleCatcher/CMS.pm
===================================================================
--- /branches/StyleCatcher-2.1-dev/plugins/StyleCatcher/lib/StyleCatcher/CMS.pm (revision 1040)
+++ /branches/StyleCatcher-2.1-dev/plugins/StyleCatcher/lib/StyleCatcher/CMS.pm (revision 1088)
@@ -8,5 +8,5 @@
 
 use strict;
-use File::Basename qw(basename);
+use File::Basename qw( basename dirname );
 
 use MT::Util qw( remove_html decode_html );
@@ -464,5 +464,5 @@
     if ( $type =~ m!^text/css! ) {
         $data->{auto}{url} = $url;
-        my $theme = fetch_theme(
+        my $theme = metadata_for_theme(
             url  => $url,
             tags => ['collection:auto'],
@@ -503,5 +503,5 @@
         my $themes = [];
         for my $repo_theme (@repo_themes) {
-            my $theme = fetch_theme(
+            my $theme = metadata_for_theme(
                 url => $repo_theme,
             );
@@ -577,11 +577,9 @@
         next unless -d $theme;
         $theme =~ s/.*[\\\/]//;
-        $themes->{$theme} = fetch_theme(
-            url      => $theme_dir,
-            tags     => ['collection:mt-designs'],
-            baseurl  => $theme_url,
-            basepath => $theme_dir,
+        $themes->{$theme} = metadata_for_theme(
+            path => $theme_dir,
+            url  => "$theme_url/$theme/",
+            tags => ['collection:mt-designs'],
         );
-        $themes->{$theme}{name} = $themes->{$theme}{name};
         $themes->{$theme}{prefix} = 'default';
     }
@@ -597,6 +595,7 @@
         next unless -d $theme;
         $theme =~ s/.*[\\\/]//;
-        $themes->{$theme} = fetch_theme(
-            url  => $theme_dir,
+        $themes->{$theme} = metadata_for_theme(
+            path => $theme_dir,
+            url  => $app->static_path . "support/themes/$theme/",
             tags => ['collection:my-designs'],
         );
@@ -612,55 +611,33 @@
 }
 
-sub fetch_theme {
-    my $app = MT->app;
+sub theme_for_url {
     my %param = @_;
-    my ($url, $tags, $baseurl, $basepath, $default_metadata)
-        = @param{qw( url tags baseurl basepath metadata )};
-    $tags ||= [];
-
-    my $theme;
-    my $stylesheet;
-    my $new_url;
-    my $themeroot;
-    my $url_is_web = $url =~ m{ \A https?: }xms ? 1 : 0;
-    if ($url_is_web) {
-        # Pick up the css file
-        my $user_agent  = $app->new_ua;
-        my $css_request = HTTP::Request->new( GET => $url );
-        my $response    = $user_agent->request($css_request);
-        $stylesheet = $response->content if ($response->code >= 200) && ($response->code < 400);
-        return unless $stylesheet;
-
-# Break up the css url in to a couple useful pieces (generalize and break me out)
-        $theme = $url;
-        # discard any generic 'screen.css' filename
-        $theme =~ s{ / (?:screen|style) \.css \z }{}xms;
-        $theme =~ s/.*[\\\/]//;
-        my @url = split( /\//, $url );
-        for ( 0 .. ( scalar(@url) - 2 ) ) {
-            $new_url .= $url[$_] . '/';
-        }
-    }
-    else {
-        $themeroot = $basepath
-          || File::Spec->catdir( $app->static_file_path, 'support', 'themes' );
-        my $webthemeroot = $baseurl || $app->static_path . 'support/themes';
-
-        $theme = $url;
-        $theme =~ s/.*[\\\/]//;
-        my $file = File::Spec->catfile( $url, "$theme.css" );
-        $new_url = "$webthemeroot/$theme/";
-        if ( -e $file ) {
-            $stylesheet = file_mgr()->get_data($file);
-            $url        = $new_url . "$theme.css";
-        }
-        else {
-            $file = File::Spec->catfile( $url, $theme, "screen.css" );
-            if ( -e $file ) {
-                $stylesheet = file_mgr()->get_data($file);
-                $url        = $new_url . "screen.css";
-            }
-        }
-    }
+    my ($url, $path, $tags, $baseurl, $basepath)
+        = @param{qw( url path tags baseurl basepath )};
+    my $app = MT->instance;
+
+    my %theme;
+    if ($path && -e $path) {
+        $theme{stylesheet} = file_mgr()->get_data($path);
+        $theme{id} = basename(dirname($path));
+    }
+    elsif ($url) {
+        my $user_agent = $app->new_ua;
+        my $response   = $user_agent->get($url);
+        return if !$response->is_success();
+        $theme{stylesheet} = $response->content;
+
+        my $id = $url;
+        $id =~ s{ / (?:screen|style) \.css \z }{}xms;
+        $id =~ s/.*[\\\/]//;
+        $theme{id} = $id;
+    }
+
+    return %theme;
+}
+
+sub metadata_for_stylesheet {
+    my %param = @_;
+    my ($stylesheet) = @param{qw( stylesheet )};
 
     # Pick up the metadata from the css
@@ -685,50 +662,16 @@
     }
 
-    my $comment;
     my %metadata;
 
     # Trim me white space, yarr
-    for (@comments) {
-
-        # TBD: strip any "risky" content; we don't want any
-        # XSS in this content.
+    for my $comment (@comments) {
         # Strip any null bytes
-        tr/\x00//d;
-        s/^\s+|\s+$//g;
-        my ( $key, $value ) = split( /:/, $_, 2 ) or next;
+        $comment =~ tr/\x00//d;
+        $comment =~ s/^\s+|\s+$//g;
+
+        my ( $key, $value ) = split( /:/, $comment, 2 ) or next;
         next unless defined $value;
         $value =~ s/^\s+//;
         $metadata{ lc $key } = $value;
-    }
-
-    my %thumbnails;
-    THUMB: for my $thumb (qw( thumbnail thumbnail_large )) {
-        $thumbnails{$thumb} = $metadata{$thumb};
-        next THUMB if $thumbnails{$thumb};
-
-        my $thumb_filename = $thumb;
-        $thumb_filename =~ tr/_/-/;
-        $thumb_filename .= '.gif';
-
-        if ($url_is_web) {
-            my $thumb_url = $new_url . $thumb_filename;
-
-            my $user_agent  = $app->new_ua;
-            my $css_request = HTTP::Request->new( HEAD => $thumb_url );
-            my $response    = $user_agent->request($css_request);
-            if ($response->is_success()) {
-                $thumbnails{$thumb} = $thumb_url;
-            }
-        }
-        else {
-            my $thumb_path = File::Spec->catfile($themeroot, $theme,
-                $thumb_filename);
-            if (-e $thumb_path) {
-                $thumbnails{$thumb} = $new_url . $thumb_filename;
-            }
-        }
-
-        $thumbnails{$thumb} ||= $app->static_path . 'plugins/StyleCatcher/'
-            . 'images/' . $thumb_filename;
     }
 
@@ -743,10 +686,83 @@
         ($metadata{$best_name}) = grep { defined }
             delete @metadata{ @$possible_names }, q{};
+        # TODO: do html mashing later
         $metadata{$best_name} = decode_html(remove_html($metadata{$best_name}));
     }
 
-    require MT::Util;
+    return %metadata;
+}
+
+sub thumbnails_for_theme {
+    my %param = @_;
+    my ($url, $path, $metadata)
+        = @param{qw( url path metadata )};
+    my $app = MT->instance;
+
+    my %thumbnails;
+    THUMB: for my $thumb (qw( thumbnail thumbnail_large )) {
+        $thumbnails{$thumb} = $metadata->{$thumb};
+        next THUMB if $thumbnails{$thumb};
+
+        my $thumb_filename = $thumb;
+        $thumb_filename =~ tr/_/-/;
+        $thumb_filename .= '.gif';
+
+        require URI;
+        if ($path) {
+            my ($volume, $dir, $theme_filename) = File::Spec->splitpath($path);
+            my $thumb_path = File::Spec->catpath($volume, $dir, $thumb_filename);
+            if (-e $thumb_path) {
+                my $url_uri = URI->new_abs($thumb_filename, $url);
+                $thumbnails{$thumb} = $url_uri->as_string();
+            }
+        }
+        elsif ($url) {
+            my $url_uri = URI->new_abs($thumb_filename, $url);
+            my $thumb_url = $url_uri->as_string();
+
+            my $user_agent = $app->new_ua;
+            my $response   = $user_agent->head($thumb_url);
+            if ($response->is_success()) {
+                $thumbnails{$thumb} = $thumb_url;
+            }
+        }
+
+        # Use plugin's default thumbnail if necessary.
+        $thumbnails{$thumb} ||= $app->static_path . 'plugins/StyleCatcher/'
+            . 'images/' . $thumb_filename;
+    }
+
+    return %thumbnails;
+}
+
+sub metadata_for_theme {
+    my $app = MT->app;
+    my %param = @_;
+    my ($url, $path, $tags, $default_metadata)
+        = @param{qw( url path tags metadata )};
+
+    # Update a path, if present, from a theme directory to the real full
+    # stylesheet path.
+    if ($path && -d $path) {
+        $path =~ s{ / \z }{}xms;
+        FILESTEM: for my $filestem (basename($path), "screen", "style") {
+            my $full_path = File::Spec->catfile($path, "$filestem.css");
+            if ($full_path && -f $full_path) {
+                $path = $param{path} = $full_path;
+
+                $url =~ s{ / \z }{}xms;
+                $url  = $param{url}  = "$url/$filestem.css";
+
+                last FILESTEM;
+            }
+        }
+    }
+
+    my %theme      = theme_for_url(%param);
+    my %metadata   = metadata_for_stylesheet(%param, %theme);
+    my %thumbnails = thumbnails_for_theme(%param, metadata => \%metadata);
+
     my $data = {
-        name         => $theme,
+        name         => $theme{id},
         description  => $metadata{description} || q{},
         title        => $metadata{title} || '(Untitled)',
@@ -755,6 +771,6 @@
         imageBig     => $thumbnails{thumbnail_large},
         layouts      => $metadata{layouts} || q{},
-        sort         => $metadata{name} || $theme || q{},
-        tags         => $tags,
+        sort         => lc($metadata{title} || $theme{id} || q{}),
+        tags         => $tags || [],
         blogs        => [],
         author       => $metadata{author},
