P::P::F::TrackEndTimeFromTitleを書いた

先週の続き

だいぶ前にhackしたEvent.pmを使うの前提にPlagger::Plugin::Filter::TrackEndTimeFromTitleってのを書いてみました。書いたというかyusukebeさんのP::P::Filter::YouTubeFromTitleをほぼそのままパクリ。ありがとうございます。
package Plagger::Plugin::Filter::TrackEndTimeFromTitle;

use strict;
use base qw( Plagger::Plugin );
use Encode;
use HTML::Entities;
use Plagger::Event;

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

sub filter {
    my($self, $context, $args) = @_;
    my $e = $args->{entry};
    my ($title, $artist,$duration);
    my $starttime = $e -> date;
    my $event = $e -> event;

    $title = $e->title;
    $title = encode('UTF-8',$title);

    #Last.FM/audioscrobbler
    if($title =~ /(.*?)\s\342\200\223\s(.*?)\Z/){
        $artist = decode('UTF-8',$1);
        $title = decode('UTF-8',$2);
    }

    $duration = get_duration($self, $context, $artist, $title);

    unless($duration eq '') {
        my $event = Plagger::Event -> new;
        $event -> dtstart($e -> date);
        $event -> dtend($e -> date + DateTime::Duration->new(seconds => ($duration/1000)));
        $e -> add_event($event);
    }
}

sub get_duration {
    my ($self,$context,$artist, $title) = @_;
    my $url  = URI->new('http://ws.audioscrobbler.com/2.0/');
    my $file = $self->cache->path_to('track.getInfo_result.html');

    $artist = encode('UTF-8', $artist) unless $context->conf->{no_decode_utf8};
    $title = encode('UTF-8', $title) unless $context->conf->{no_decode_utf8};
    $context->log( info => 'Getting song duration from ' . $artist . " / " . $title );

    my $ua = Plagger::UserAgent->new;
    $url->query_form(method => 'track.getinfo',
                     artist => $artist,
                     track => $title,
                     api_key => $self->conf->{api_key} || 'b25b959554ed76058ac220b7b2e0a026',);

    my $res = $ua->mirror( $url->as_string => $file );
    if($res->is_error) {
        $context->log( error => $res->status );
        return;
    }

    open my $fh, "<:encoding(utf-8)", $file
        or return $context->log(error => "$file: $!");

    my $duration;
    while (<$fh>) {
        if(m!(.*?)!){
            $duration = $1;
            $context->log(info => "duration: $duration");
            last;
        }
    }
    return $duration;
}

yamlはこんな感じ。
plugins:
  - module: Subscription::Config
    config:
      feed:
        - url: http://ws.audioscrobbler.com/1.0/user/yoozoosato/recenttracks.rss

  - module: Filter::Rule
    rule:
      module: Fresh
      mtime:
        path: ./lastfm.tmp
        autoupdate: 1

  - module: Filter::TrackEndTimeFromTitle
    config:
      api_key: YOUR_API_KEY

しょこたんTVと同じようにGoogle Calendarに放るとこんな感じで自分がiTunesで再生した曲が可視化できる。

20081112.png

明日くらいからもうちょっと突っ込んだことに挑戦する予定。