Plagger使ってTwitterのFavやふぁぼったーをTumblrに流すプラグイン作ったよ
前回,わざわざログインして Fav を取るやつ を書きましたが,あんなことしなくても 普通に Fav のフィード取れることが分かったので,さくっと作り直しました. これを使えば,Twitter, Favotter→Tumblr に流すことができます.てか,実は Tumblr にはフィードを食う機能があるのですが,整形できないのと調子が悪くて すぐに死ぬので自分で API 使ってあげた方が早いです.
ちなみに,ソースはすべて github にあげているので使い方分かる人はそっちから 取った方がいいかも.
Plagger::Plugin::Plugin::Tumblr
まずはメインの Tumblr にポストするプラグイン.別にたいそうなことは していなくて,WWW::Tumblr という CPAN モジュールをラップしただけ. しかも,めんどくさいから Text と Quote と Link しか作ってない.
- module: Publish::Tumblr
config:
username: your-email
password: your-password
type: post type(text, quote, or link)
interval: 2
type の部分を変更するとこんな感じで Post してくれます.
-
text
- title
- body(added link to the url at the end)
-
quote
- quote(body)
- source(title linked to the url)
-
link
- name(title)
- url
- description(body)
lib/Plagger/Plugin/Publish/Tumblr.pm
package Plagger::Plugin::Publish::Tumblr;
use strict;
use base qw( Plagger::Plugin );
use Encode;
use Time::HiRes qw(sleep);
use WWW::Tumblr;
sub register {
my($self, $context) = @_;
$context->register_hook(
$self,
'publish.entry' => \&publish_entry,
'plugin.init' => \&initialize,
);
}
sub initialize {
my($self, $context) = @_;
$self->{tumblr} = WWW::Tumblr->new;
$self->{tumblr}->email($self->conf->{username});
$self->{tumblr}->password($self->conf->{password});
}
sub publish_entry {
my($self, $context, $args) = @_;
my $title = $args->{entry}->{title};
$title = encode_utf8($title);
my $body = $args->{entry}->{body};
$body = encode_utf8($body);
my $link = $args->{entry}->{link};
my $type = $self->conf->{type} || 'regular';
$context->log(info => "Tumblr($type) posting '$title'");
if($type eq 'text'){
my $post = $body . "<div><a href=\"" . $link . "\">" . $title . "</a></div>";
$self->{tumblr}->write(
type => 'regular',
title => $title,
body => $post,
);
}
elsif($type eq 'quote'){
my $source = "<a href=\"" . $link . "\">" . $title . "</a>";
$self->{tumblr}->write(
type => 'quote',
quote => $body,
source => $source,
);
}
elsif($type eq 'link'){
$self->{tumblr}->write(
type => 'link',
name => $title,
url => $link,
description => $body,
);
}
my $sleeping_time = $self->conf->{interval} || 5;
$context->log(info => "sleep $sleeping_time.");
sleep( $sleeping_time );
}
1;
Plagger::Plugin::Filter::TwitterQuote
続いて,Twitter のフィードを Tumblr の Quote 形式にあわせて整形する Filter プラグイン. 参考にしてるのは Tombloo のやつね.あれが気に入ってるんでそれにしてます. 他の形にしたい人はお好きに変更して下さい.Publish::Tumblr のポスト方法は 上を参考にして下さい.
使い方は以下を YAML に挟むだけ.
- module: Filter::TwitterQuote
lib/Plagger/Plugin/Filter/TwitterQuote.pm
package Plagger::Plugin::Filter::TwitterQuote;
use strict;
use base qw( Plagger::Plugin );
use Encode;
sub register {
my ($self, $context) = @_;
$context->register_hook(
$self,
'update.entry.fixup' => \&filter,
);
}
sub filter {
my ($self, $context, $args) = @_;
my $body = $args->{entry}->{body};
$body =~ /^(.+?): (.+)/o;
my $id = $1;
my $quote = encode_utf8($2);
my $title = "Twitter / " . $id;
$args->{entry}->title($title);
$args->{entry}->body($quote);
}
1;
Plagger::Plugin::Filter::FavotterQuote
ふぁぼったーから流すやつも作りました.Link 先は Favotter のままです.
lib/Plagger/Plugin/Filter/FavotterQuote.pm
package Plagger::Plugin::Filter::FavotterQuote;
use strict;
use base qw( Plagger::Plugin );
use Encode;
sub register {
my ($self, $context) = @_;
$context->register_hook(
$self,
'update.entry.fixup' => \&filter,
);
}
sub filter {
my ($self, $context, $args) = @_;
my $body = $args->{entry}->{body};
$body =~ /^.+?<\/img>(.+?)<\/a> (.+?)<br \/>/o;
my $id = $1;
my $quote = $2;
my $title = "Twitter / " . $id;
$args->{entry}->title($title);
$args->{entry}->body($quote);
}
1;
Plagger::Plugin::Filter::Reverse
それから,Twitter とかのフィードは最新の方から処理されてしまうので, そのまま Plagger で Tumblr に流すと一番古い奴が一番上にくるので,それを 逆転させておく.これは id:inirvash さんの書かれた奴をコピーしただけです. id:nirvash++
lib/Plagger/Plugin/Filter/Reverse.pm
package Plagger::Plugin::Filter::Reverse;
use strict;
use base qw( Plagger::Plugin );
sub register {
my($self, $context) = @_;
$context->register_hook(
$self,
'update.feed.fixup' => \&feed
);
}
sub feed {
my($self, $context, $args) = @_;
$context->log(debug => "reverse");
my @entries = $args->{feed}->entries;
@entries = reverse(@entries);
$args->{feed}->{entries} = \@entries;
}
1;
レシピの YAML ファイル
こいつらを自分の Plagger が入ってるマシンの適当な所に放り込みます. おすすめは自分用のプラグインフォルダを作っておいて,それを YAML で読み込むことです.僕の場合,github から Pull したものを そのまま読み込んでいます.
前回も書いた様に,僕はプラグインの場所とかを設定した base.yaml を include させています.一応そちらも載せておきます.
base.yaml
global:
plugin_path:
- /home/user/plagger/lib/Plagger/Plugin
- /home/user/github/plagger/lib/Plagger/Plugin
assets_path: /home/user/plagger/assets
timezone: Asia/Tokyo
log:
level: debug
# level: info
cache:
base: /home/user/cache
define_recipes:
で,以下がメインの YAML.Filter::Rule を使っているのは,以前に 送信したものを送信しないようにするためです.Tumblr はそういうチェックを してくれないので,テストする段階で何度もやると,同じものを大量に 送信してしまいますので,こいつを使いましょう w 指定したファイルが DB となって,同じものは送らないようにしてくれます.
twitterfav2tumblr.yaml
include:
- /home/user/yaml/base.yaml
plugins:
- module: Subscription::Config
config:
feed:
- http://twitter.com/favorites/riywo.atom
- module: Filter::Rule
rule:
module: Deduped
path: /home/user/cache/plagger-twitterfav2tumblr.db
- module: Filter::TwitterQuote
- module: Filter::Reverse
- module: Publish::Tumblr
config:
username: email address
password: *****
type: quote
interval: 3
こちらは,Favotter 用.
favotter2tumblr.yaml
include:
- /home/user/yaml/base.yaml
plugins:
- module: Subscription::Config
config:
feed:
- http://favotter.matope.com/userrss.php?user=riywo&mode=new
- module: Filter::Rule
rule:
module: Deduped
path: /home/user/cache/plagger-favotter2tumblr.db
- module: Filter::FavotterQuote
- module: Filter::Reverse
- module: Publish::Tumblr
config:
username: email address
password: ******
type: quote
interval: 3
使用方法
あとは,こいつらを指定して Plagger を起動すれば OK です.
$ plagger -c /home/user/yaml/twitterfav2tumblr.yaml
$ plagger -c /home/user/yaml/favotter2tumblr.yaml
うまくいった様でしたら,cron に設定しちゃって下さい.以下の設定なら 10 分毎に実行してくれます.
*/10 * * * * plagger -c /home/user/yaml/twitterfav2tumblr.yaml
*/10 * * * * plagger -c /home/user/yaml/favotter2tumblr.yaml
注意すべきキャッシュの存在
さて,Plagger の使用にあたって最も注意すべきこと,それは**「キャッシュ」**の 存在です.Plagger はフィードを取りに行く前にローカルのキャッシュを見ます. もしキャッシュがあれば(かつそれほど古くなければ?)フィードを見に行きません. そのため,あまり短い時間感覚で cron でまわしても新しいフィードを取りに行って くれないのです.
ですので,僕はキャッシュフォルダを削除する cron を 1 分毎にまわすという,アホなことを やっています.しかも厄介なのが,base.yaml で指定したキャッシュフォルダの 他に/home/user/.plagger 辺りに別のキャッシュを勝手に作っていました.なので, 指定したものの他にこいつも消さないといけません.これに気づかなくてしばらく キレてたのは秘密です.
というわけで,現在は base.yaml で/home/user/.plagger を指定して,ここのキャッシュを 削除する cron を回しています.
*/1 * * * * rm -rf /home/user/.plagger/cache