|
|
||
NHK BS2 で 26 日だかにこれであなたもブログ通とかいうしょうもない番組が放映されるようですが、そのゲストというかコメンテーター(?) にしょこたんが出るようですよ全国のファンのみなさん。
Data::Serializer を使うように変更。config.yml で serializer を指定することでいろんなフォーマットで書き出せる。
- module: Publish::Serializer
config:
serializer: YAML
dir: /Users/naoya/tmp
filename: test.yml
シリアライズは Data::Serializer が面倒をみることになり、サブクラスを用意する必要はなくなった。raw_serialize してるので Data::Serializer の圧縮とか暗号化オプションとか使えないけども。
package Plagger::Plugin::Publish::Serializer;
use strict;
use warnings;
use base qw (Plagger::Plugin);
use File::Spec;
use IO::File;
use Data::Serializer;
sub serialize {
my ($self, $data) = @_;
my $option = $self->conf->{option} || {};
my $selializer = Data::Serializer->new(
serializer => $self->conf->{serializer} || 'Data::Dumper',
);
$selializer->raw_serialize($data);
}
sub register {
my ($self, $context) = @_;
$context->register_hook(
$self,
'publish.feed' => \&feed,
);
}
sub feed2data {
my ($self, $feed) = @_;
my $data = {
feed => {
title => $feed->title,
link => $feed->link,
generator => join('/', 'Plagger', $Plagger::VERSION),
}
};
for my $entry ($feed->entries) {
my $eobj = {};
$eobj->{$_} = $entry->$_ for qw(title link body author tags);
push @{$data->{feed}->{entries}}, $eobj;
}
$data;
}
sub feed {
my ($self, $context, $args) = @_;
my $dir = $self->conf->{dir};
unless (-e $dir && -d _) {
mkdir $dir, 0755 or $context->error("mkdir $dir: $!");
}
my $file = $self->gen_filename($args->{feed}) ||
$args->{feed}->id . __PACKAGE__->default_file_extention;
my $path = File::Spec->catfile($dir, $file);
my $serialized = $self->serialize(
$self->feed2data($args->{feed})
);
my $io = IO::File->new("> $path");
$io->print($serialized);
$io->close;
$context->log(
info => sprintf(
"Write to %s: %d entries",
$path,
$args->{feed}->count
)
);
}
my %formats = (
'u' => sub { my $s = $_[0]->url; $s =~ s!^https?://!!; $s },
'l' => sub { my $s = $_[0]->link; $s =~ s!^https?://!!; $s },
't' => sub { $_[0]->title },
'i' => sub { $_[0]->id },
);
my $format_re = qr/%(u|l|t|i)/;
sub gen_filename {
my($self, $feed) = @_;
my $file = $self->conf->{filename} || '';
$file =~ s{$format_re}{
$self->safe_filename($formats{$1}->($feed))
}egx;
$file;
}
sub safe_filename {
my($self, $path) = @_;
$path =~ s![^\w\s]+!_!g;
$path =~ s!\s+!_!g;
$path;
}
1;
ただ、Data::Serializer は JSON をサポートしてない。そもそもこのプラグインを作ったのはフィードを JSON に変換したかったからなのだよママン。
ということで Data::Serializer::JSON を作る。
package Data::Serializer::JSON;
BEGIN { @Data::Serializer::JSON::ISA = qw(Data::Serializer) }
use strict;
use JSON;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
require AutoLoader;
@ISA = qw(Exporter AutoLoader);
@EXPORT = qw(
);
$VERSION = '0.01';
1;
__END__
=head1 NAME
Data::Serializer::JSON - Creates bridge between Data::Serializer and Storable
=head1 SYNOPSIS
use Data::Serializer::JSON;
=head1 DESCRIPTION
Module is used internally to Data::Serializer
=head1 AUTHOR
Naoya Ito <naoya@bloghackers.net>
=head1 COPYRIGHT
This program is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.
=head1 SEE ALSO
perl(1), Data::Serializer(3), JSON(3).
=cut
sub serialize {
return JSON->new->objToJson($_[1]);
}
sub deserialize {
return JSON->new->jsonToObj($_[1]);
}
Data::Serializer の他のクラスの実装に併せて作ってるのでちょっとださいけどまあしゃあない。AutoLoader を使う必要があるので AutoSplit が走るように make を実行したりとかがめんどい。
よし、作者にパッチを送ろうとおもったがしかし、Data::Serializer のテストが超わかんない。しょうがないのでテストは放置でついでに JSON::Syck と YAML::Syck も作った。
package Data::Serializer::YAML::Syck;
BEGIN { @Data::Serializer::YAML::Syck::ISA = qw(Data::Serializer) }
use strict;
use YAML::Syck;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
require AutoLoader;
@ISA = qw(Exporter AutoLoader);
@EXPORT = qw(
);
$VERSION = '0.01';
1;
__END__
sub serialize {
return Dump($_[1]);
}
sub deserialize {
return Load($_[1]);
}
package Data::Serializer::JSON::Syck;
BEGIN { @Data::Serializer::JSON::Syck::ISA = qw(Data::Serializer) }
use strict;
use JSON::Syck;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
require AutoLoader;
@ISA = qw(Exporter AutoLoader);
@EXPORT = qw(
);
$VERSION = '0.01';
1;
__END__
sub serialize {
return Dump($_[1]);
}
sub deserialize {
return Load($_[1]);
}
Data::Serializer 使えばいいとのこと。JSON がないので作るべしと。JSON は CPAN にうpするより作者に送った方がよさそうな雰囲気。
ETech から帰る飛行機の中で Hack したやつ。まだ仕上げ切れてない感じですがとりあえず。
- module: Publish::Serialize
config:
driver: JSON
dir: /Users/naoya/tmp
filename: test.js
driver を変更すれば出力のフォーマットを変えられる。JSON / YAML / Dumper が指定可能。XML とか Storable とか色々作れそうかも。
YAML ではき出すと
---
feed:
entries:
-
author: ~
body: oh my god
link: http://localhost/1
tags: []
title: first entry
-
author: ~
body: wow! amazing!
link: http://localhost/2
tags: []
title: second entry
generator: Plagger/0.5.7
link: http://localhost/
title: config feed
という具合。なんか tags が [] とかになってるな、なんだこれ。
package Plagger::Plugin::Publish::Serialize;
use strict;
use warnings;
use base qw (Plagger::Plugin);
use Encode;
use File::Spec;
use IO::File;
use UNIVERSAL::require;
sub init {
my $self = shift;
$self->SUPER::init(@_);
my $class = join '::', __PACKAGE__, $self->conf->{driver} || 'YAML';
$class->require or Plagger->context->error(
'No Such a Driver: ' . $self->conf->{driver}
);
bless $self, $class;
}
sub serialize {
my ($self, $data) = @_;
die "I am abstract method";
}
sub register {
my ($self, $context) = @_;
$context->register_hook(
$self,
'publish.feed' => \&feed,
);
}
sub feed2data {
my ($self, $feed) = @_;
my $data = {
feed => {
title => $feed->title,
link => $feed->link,
generator => join('/', 'Plagger', $Plagger::VERSION),
}
};
for my $entry ($feed->entries) {
my $eobj = {};
$eobj->{$_} = $entry->$_ for qw(title link body author tags);
push @{$data->{feed}->{entries}}, $eobj;
}
$data;
}
sub feed {
my ($self, $context, $args) = @_;
my $dir = $self->conf->{dir};
unless (-e $dir && -d _) {
mkdir $dir, 0755 or $context->error("mkdir $dir: $!");
}
my $file = $self->gen_filename($args->{feed}) ||
$args->{feed}->id . __PACKAGE__->default_file_extention;
my $path = File::Spec->catfile($dir, $file);
my $serialized = $self->serialize(
$self->feed2data($args->{feed})
);
my $io = IO::File->new("> $path");
$io->print($serialized);
$io->close;
$context->log(
info => sprintf(
"Write to %s: %d entries",
$path,
$args->{feed}->count
)
);
}
my %formats = (
'u' => sub { my $s = $_[0]->url; $s =~ s!^https?://!!; $s },
'l' => sub { my $s = $_[0]->link; $s =~ s!^https?://!!; $s },
't' => sub { $_[0]->title },
'i' => sub { $_[0]->id },
);
my $format_re = qr/%(u|l|t|i)/;
sub gen_filename {
my($self, $feed) = @_;
my $file = $self->conf->{filename} || '';
$file =~ s{$format_re}{
$self->safe_filename($formats{$1}->($feed))
}egx;
$file;
}
sub safe_filename {
my($self, $path) = @_;
$path =~ s![^\w\s]+!_!g;
$path =~ s!\s+!_!g;
$path;
}
1;
TODO は
あたりかな。
ドライバの実装は serialize をオーバーライドして dump すると。
package Plagger::Plugin::Publish::Serialize::JSON;
use strict;
use warnings;
use base qw (Plagger::Plugin::Publish::Serialize);
use JSON::Syck;
use constant default_file_extention => 'js';
sub serialize {
my ($self, $data) = @_;
return JSON::Syck::Dump($data);
}
1;
こんなの。
Amazon.co.jpからのお知らせ
お客様からご注文いただいた商品を本日発送させていただきました。
ご注文の処理が完了しましたのでお知らせします。
Amazon.co.jpをご利用いただき、ありがとうございました。またのご利用を
お待ちしております。
今回発送する商品は以下のとおりです。
---------------------------------------------------------------------
数量 商品 価格 発送済み 小計
---------------------------------------------------------------------
1 ファイナルファンタジーXII 特典 ¥7,911 1 ¥7,911
販売元: Amazon.com Int'l Sales, Inc. -
---------------------------------------------------------------------
きたー。もしかして今日届いちゃったりする?
どこのメールサーバにメールを送っても Connection timed out。変だなー、と思って調べてみるも原因がさっぱり、でたまたま巷で話題になってたのを思い出した。
これのせいかなー。ニフティの回線使ってて自宅サーバーの人はどうしてるんだろ。smtp.nifty.com を指定すればいいのか。
relayhost = smtp.nifty.com
とした。
んで今まで溜まってたメールを
$ sudo /usr/sbin/postfix flush
で queue をフラッシュ。うまく送れてるようだ。Outbound 25 Block のことをたまたま聞いたことがあったからよかったけど、そうじゃなかったらめちゃめちゃはまってたくさいなー。怖い怖い。
hori-uchi2006/03/15 10:16僕もamazonから来てた!
Tiger2006/03/15 12:00全部が全部、2/15に実施ではないということで、ポロッポロッと話題になりますね (^^;