Changeset 786

Show
Ignore:
Timestamp:
05/19/06 18:01:10
Author:
miyagawa
Message:

FindEnclosures? is now extensible using plugins. Thanks to mizzy
Fixes #236

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/plagger/lib/Plagger/Plugin/Filter/FindEnclosures.pm

    r750 r786  
    44 
    55use HTML::TokeParser; 
    6 use Plagger::Util
     6use Plagger::Util qw( decode_content )
    77use URI; 
     8use DirHandle; 
     9use Plagger::Enclosure; 
     10use Plagger::UserAgent; 
    811 
    912sub register { 
     
    1619    ); 
    1720} 
     21 
     22sub init { 
     23    my $self = shift; 
     24    $self->SUPER::init(@_); 
     25    $self->load_plugins(); 
     26 
     27    $self->{ua} = Plagger::UserAgent->new; 
     28} 
     29 
     30sub load_plugins { 
     31    my $self = shift; 
     32    my $context = Plagger->context; 
     33 
     34    my $dir = $self->assets_dir; 
     35    my $dh = DirHandle->new($dir) or $context->error("$dir: $!"); 
     36    for my $file (grep -f $_->[0] && $_->[0] =~ /\.(?:pl|yaml)$/, 
     37                  map [ File::Spec->catfile($dir, $_), $_ ], sort $dh->read) { 
     38        $self->load_plugin(@$file); 
     39    } 
     40} 
     41 
     42sub load_plugin { 
     43    my($self, $file, $base) = @_; 
     44 
     45    Plagger->context->log(debug => "loading $file"); 
     46 
     47    my $load_method = $file =~ /\.pl$/ ? 'load_plugin_perl' : 'load_plugin_yaml'; 
     48    push @{ $self->{plugins} }, $self->$load_method($file, $base); 
     49} 
     50 
     51sub load_plugin_perl { 
     52    my($self, $file, $base) = @_; 
     53 
     54    open my $fh, $file or Plagger->context->error("$file: $!"); 
     55    (my $pkg = $base) =~ s/\.pl$//; 
     56    my $plugin_class = "Plagger::Plugin::Filter::FindEnclosures::Site::$pkg"; 
     57 
     58    my $code = join '', <$fh>; 
     59    unless ($code =~ /^\s*package/s) { 
     60        $code = join "\n", 
     61            ( "package $plugin_class;", 
     62              "use strict;", 
     63              "use base qw( Plagger::Plugin::Filter::FindEnclosures::Site );", 
     64              "sub site_name { '$pkg' }", 
     65              $code, 
     66              "1;" ); 
     67    } 
     68 
     69    eval $code; 
     70    Plagger->context->error($@) if $@; 
     71 
     72    return $plugin_class->new; 
     73} 
     74 
     75sub load_plugin_yaml { Plagger->context->error("NOT IMPLEMENTED YET") } 
    1876 
    1977sub filter { 
     
    45103        $enclosure->is_inline($inline); 
    46104        $entry->add_enclosure($enclosure); 
    47     } 
     105        return; 
     106    } 
     107 
     108    my $url = $tag->[1]{$attr}; 
     109    my $content; 
     110    for my $plugin (@{$self->{plugins}}) { 
     111        if ( $plugin->handle($url) ) { 
     112            Plagger->context->log(debug => "Try $url with " . $plugin->site_name); 
     113            $content ||= $self->fetch_content($url) or return; 
     114 
     115            if (my $enclosure = $plugin->find($content)) { 
     116                Plagger->context->log(info => "Found enclosure " . $enclosure->url ." with " . $plugin->site_name); 
     117                $entry->add_enclosure($enclosure); 
     118                return; 
     119            } 
     120        } 
     121    } 
     122
     123 
     124sub fetch_content { 
     125    my($self, $url) = @_; 
     126 
     127    my $ua  = Plagger::UserAgent->new; 
     128    my $res = $ua->fetch($url, $self); 
     129    return if $res->is_error; 
     130 
     131    return decode_content($res); 
     132
     133 
     134sub find_enclosure_plugin { 
     135    my($self, $plugin, $url) = @_; 
     136 
     137    my $content; 
     138    $content ||= do { 
     139        my $res = $self->{ua}->fetch( $url, $self ); 
     140        my $content = decode_content($res); 
     141    }; 
     142 
     143    return $plugin->handle($url) && $plugin->find($content); 
    48144} 
    49145 
     
    63159    $mime && $mime->mediaType =~ m!^(?:audio|video|image)$!; 
    64160} 
     161 
     162package Plagger::Plugin::Filter::FindEnclosures::Site; 
     163sub new { bless {}, shift } 
     164sub handle { 0 } 
     165sub find { } 
    65166 
    661671;