Plagger使ってみた

遅!
Perlも久しぶり。こんな感じでいいんかな。

package Plagger::Plugin::CustomFeed::HatenaDiaryReferer;
use strict;
use base qw( Plagger::Plugin );

use DateTime;
use Encode;
use HTML::TokeParser;
use Plagger::UserAgent;
use Plagger::Util qw( decode_content );

sub register {
    my ($self, $context) = @_;
    $context->register_hook(
        $self,
        'subscription.load' => \&load,
    );
}

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

    unless ($self->conf->{id}) {
        $context->log(error => "Hatena id not specified");
        return;
    }

    my $feed = Plagger::Feed->new;
    $feed->aggregator(sub { $self->aggregate(@_) });
    $context->subscription->add($feed);
}

sub aggregate {
    my ($self, $context, $args) = @_;
    foreach my $id (@{$self->conf->{id}}) {
        $self->aggregate_diary($context, $id, $args);
    }
}

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

    my $url = 'http://d.hatena.ne.jp/' . $id . '/comment?date=' . DateTime->now->strftime('%Y%m%d');
    $context->log(info => "Get $url");
    my $agent = Plagger::UserAgent->new;
    my $res = $agent->fetch($url, $self);

    if ($res->http_response->is_error) {
        $context->log(error => "GET $url failed: " . $res->status_code);
        return;
    }

    my $content = decode_content($res);

    my $feed = Plagger::Feed->new;
    $feed->title("id:$idへのリファラ(" . DateTime->now->strftime('%F %T') . ')');
    $feed->link($url);

    my $parser = HTML::TokeParser->new(\$content);
    while (my $token = $parser->get_tag('div')) {
        next unless $token->[1]->{class} =~ /\brefererlist\b/;

        next if $parser->get_trimmed_text('/div') =~ /トラックバック/;

        $parser->get_tag;                    # discard </div>
        my $next_elem = $parser->get_tag;
        if ($next_elem->[0] ne 'ul') {
            $parser->unget_token($next_elem);
            next;
        }

        foreach (split /\n/, $parser->get_text('/ul')) {
            next unless m!^\s*(\d+)\s+(\S+)!;

            my $entry = Plagger::Entry->new;
            $entry->title("$2 ($1 visitors)");
            $entry->link($2);
            $feed->add_entry($entry);

            $context->log(debug => "Add $2 ($1 visitors)");
        }
    }

    $context->update->add($feed);
}

1;

__END__

=head1 NAME

Plagger::Plugin::CustomFeed::HatenaDiaryReferer - Fetch Hatena diary's referer list

=head1 SYNOPSIS

  - module: CustomFeed::HatenaDiaryReferer
    config:
      id:
        - sample
        - hatenacinnamon

=head1 AUTHOR

motemen

=head1 SEE ALSO

L<Plagger>

=cut

$_はちょう便利だなぁ。