noboruhiの日記

2007-01-24

[][]Filter::WriteSource(仮) 23:24

Plaggerはてなグループ日記でよく見かけるFilter-EntryFullTextやCustomFeed-Configのassetsをエディタ開いてコピペするのがめんどくさいんでこんなモノを書いてみました。


lib/Plagger/Plugin/Filter/WriteSource.pm

package Plagger::Plugin::Filter::WriteSource;
use strict;
use base qw( Plagger::Plugin );

use File::Spec;
use File::Path;
use HTML::TokeParser;

sub register {
    my($self, $context) = @_;
    $context->register_hook(
        $self,
        'update.entry.fixup' => \&filter,
    );
}

sub init {
    my $self = shift;
    $self->SUPER::init(@_);

   #Plugin::Filter::FetchEnclosureから拝借
   defined $self->conf->{dir} or Plagger->context->error("config 'dir' is not set.");
    # XXX make it Plagger::Util function
    if ($self->conf->{dir} =~ /^[a-zA-Z]/ && $self->conf->{dir} !~ /:/) {
        $self->conf->{dir} = File::Spec->catfile( Cwd::cwd, $self->conf->{dir} );
    }
    
    unless (-e $self->conf->{dir} && -d _) {
        Plagger->context->log(warn => $self->conf->{dir} . " does not exist. Creating");
        mkpath $self->conf->{dir};
    } 
}

sub filter {
    my($self, $context, $args) = @_;  

    my $feed_dir = File::Spec->catfile($self->conf->{dir}, $args->{feed}->id_safe);
    unless (-e $feed_dir && -d _) {
      $context->log(info => "mkdir $feed_dir");
        mkdir $feed_dir, 0777;
    }

    my $body = $args->{entry}->body->data;

   #html解析
   
    my $parser = HTML::TokeParser->new(\$body);

    my $file_name = '';
    my $file_body = '';
    my $i = 1;
    while ( my $token = $parser->get_tag('h4','pre') ) {
      my($tag, $attr, $attrseq, $text) = @$token;
      if ( $tag eq 'h4') {
        $file_name = $parser->get_text('/h4');
      } elsif ($tag eq 'pre') {
        $file_body = $parser->get_text('/pre');
        unless ($file_name) {
          $file_name = 'undifined' . $i;
          $i++;
        }
        #write
        my $entry_id = $args->{entry}->id_safe;
        my ($vol,$dir,$file) = File::Spec->splitpath( $file_name );
        $dir = File::Spec->catdir( $feed_dir,$entry_id,$dir);
        unless (-e $dir) {
          mkpath($dir);
        }
        $file_name = File::Spec->catfile($dir,$file);
        my $title = $args->{entry}->{title};
        $context->log(info => "wire $file_name at $title($entry_id)");
        open my $fh, ">", $file_name or $context->error("$file_name: $i");
        print $fh Encode::encode('utf-8',$file_body);
        close $fh;
        $file_name = undef;
      }
    }
}



1;
__END__


- module: Filter::WriteSource
  config:
    dir: ./tmp

このフィルタは指定したディレクトリに<pre>タグ内のソースを直前の<h4>のパスで保存します。

以下使用例。

writesource.yaml

plugins:
  - module: Subscription::Config
    config:
      feed:
        - url: http://plagger.g.hatena.ne.jp/SweetPotato/rss2
        - url: http://plagger.g.hatena.ne.jp/acqua_alta/rss2
        - url: http://plagger.g.hatena.ne.jp/Seacolor/rss2
  - module: CustomFeed::Config

  - module: Filter::WriteSource 
    config:
      dir: ./tmp
  - module: Publish::Feed
    config:
      format: RSS
      dir: .
      filename: %t.rss

todo:

  • もっとしっくり来るPlugin名
  • 設定項目のいくつかをassetsに逃がす(サイト毎にパスルールが異なってたりする為)
  • 同時に吐かれたrssと連携して上手いことデプロイ

SweetPotatoSweetPotato 2007/01/27 03:46 使ってみたらtypoに気がつきました。
s/undifined/undefined/g

ゲスト



トラックバック - http://plagger.g.hatena.ne.jp/noboruhi/20070124