読者です 読者をやめる 読者になる 読者になる

CustomFeed::Mork頓挫

先週からほったらかしのネタ。
File::Mork で history.dat を読んで CustomFeed にする、というものだが。title のデコードがわからん。
例えば "YouTube - スプー、襲来 [SPOO ATTACK]" というタイトル。

Y$00o$00u$00T$00u$00b$00e$00 $00-$00 $00$B90$D70$FC0$010r$89eg $00[$00S$00P$00O$00O$00 $00A$00T$00T$00A$00C$00K$00]$00

これが histroy.dat に入っている生の文字列。これを decode してるのが File::Mork の以下の部分。

              # Approximate wchar_t -> ASCII and remove NULs
              $val =~ s/\$00//g;  # faster if we remove these first
              $val =~ s/\$([\dA-F]{2})/chr(hex($1))/ge;

最初の置換で $00 が取っ払われてこうなる。

YouTube - $B90$D70$FC0$010r$89eg [SPOO ATTACK]

ここまではいいんだが、次の置換で謎なことになる。ASCIIだけなら問題ないんだけど。
"$00$B90$D70$FC0$010r$89eg" が 「スプー、来襲」になる、んだけどどうすれば UTF-8 に持って行けるのか?

[追記] http://d.hatena.ne.jp/sfujiwara/20060605/1149488462 UTF-16-(LE|BE) なんだけど環境(マシンアーキテクチャ) 依存ぽい. orz.

ということで、頓挫。CustomFeed::Mork はせっかく書いたので、一応貼っておく。

package Plagger::Plugin::CustomFeed::Mork;
use strict;
use base qw( Plagger::Plugin );
use Plagger::Date;
use File::Mork;

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

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

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

    my $file = $self->conf->{filename};
    my $mork = File::Mork->new( $file )
        or do {
            $context->log( error => $File::Mork::ERROR );
            return;
        };

    my $feed = Plagger::Feed->new;
    $feed->title( $file );
    $feed->link( sprintf 'file://%s', $file );
    $feed->updated( Plagger::Date->from_epoch((stat($file))[9]) );

 ENTRY:
    foreach my $entry( $mork->entries ) {
        foreach my $key( keys %{$self->conf->{cond}} ){
            my $regexp = $self->conf->{cond}->{$key};
            next ENTRY unless $entry->{$key} =~ /$regexp/;
        }
        my $p_entry = Plagger::Entry->new;
        $p_entry->title( $entry->{Name} );
        $p_entry->link ( URI->new( $entry->{URL} ) );
        $p_entry->date ( Plagger::Date->from_epoch( $entry->{FirstVisitDate} ) );
        $feed->add_entry( $p_entry );
    }
    $context->update->add($feed);
    return 1;
}
1;
__END__
=head1 NAME

Plagger::Plugin::CustomFeed::Mork - Custom feed reading Mork file.

=head1 SYNOPSIS

  - module: CustomFeed::Mork
    config:
      filename: /home/fujiwara/.mozilla/firefox/xxxxxxx/history.dat
      cond:
        URL: youtube\.com/watch\?v=

=head1 AUTHOR

FUJIWARA Shunichiro <fujiwara at topicmaker.com>

=head1 SEE ALSO

L<Plagger>

=cut