Plagger+Mplayer+Lameな計画進んでる?

はこべにっき# - 音ネタでがりがりFilter::Convert::LameFilter::Convert::Lame書く等と言ってみたものの,実際やってみると多方面で結構つまってしまった.

Filter::RewriteEnclosureURLとFilter::FetchEnclosure::Wgetうまく組み合わない

そもそもFetchEnclosureなPluginはFilter::RewriteEnclosureURLと組み合わせることが多いと思う.Filter::RewriteEnclosureURLは$enclosure->local_pathに入っている値を,URLとして使えるように調整して$enclosure->urlに設定するプラグインね.で,そのFilter::RewriteEnclosureURLと,昨日書いてみたFilter::FetchEnclosure::Mplayerや,そのもとになったFilter::FetchEnclosure::Wgetあたりを組み合わせるとあんまり良くないことが起こる.うまくRewriteEnclosureURLできない.

Filter::FetchEnclosure::Wgetのコード見ると,update.entry.fixupとupdate.fixupにフックが設定されている.Plaggerでは,各エントリーに対してupdate.entry.fixupに関連づけられたメソッドが実行されたあと,フィード全体に対してupdate.fixupに関連づけられたメソッドが実行される.

Filter::RewriteEnclosureURLは$enclosure->load_pathが設定されていることを期待している.そして,字面上Filter::FetchEnclosure::Wgetは取得したファイルのデータのパスを$enclosure->local_pathに設定しているので,Filter::FetchEnclosure::Wget -> Filter::RewriteEnclosureURLの順で呼んでやれば良いということになる.しかし,わざわざ字面上とかいたからには実際は違ってるわけだ.Filter::FetchEnclosure::Wgetにおける$enclosre->local_pathへの値の設定はPOE::Session->createの中で行われている.つまりはPOE::Kernel->runが実行されるまで$enclosre->local_pathへの設定は行われない.そして,さらにPOE::Kernel->runはupdate.fixupに関連づけられたメソッドの中でよばれているのだー!って自分で書いてて良くわかんなくなってきた.つまり次のような処理が行われてるのでだめってこと.

  • update.entry.fixupフェイズ
    • Filter::FetchEnclosure::Wgetによってwgetの実行がPOE::Session->createで予約される.予約だけなので$enclosure->local_pathは設定されない
    • Filter::RewriteEnclosureURLによって$enclosure->local_pathを用いた$enclosure->urlの書き換え.まだ,$enclosure->local_pathはundefなのでエラー.
  • update.fixupフェイズ
    • Filter::FetchEnclosure::Wgetのfetchメソッドが実行されてwgetが実際に実行される.$enclosure->local_pathの設定も行われる.

とまぁこんな感じになるので,Filter::FetchEnclosure::Wgetはupdate.entry.fixup中に暫定的に$enclosure->local_pathに値設定しとく必要あるんじゃね?ってことだ.それが汚くてやな感じだったらもうちょっとウマい仕組みがいるかもなー,とそこまでは頭がまわりませんが.

ていうかそもそも

で,そこで思たのは,そもそもうちが書こうとしているFilter::FetchEnclosure::MplayerはわざわざPOE::Sessionとか使わなくてもいいんじゃないか,ということ.これまでの問題は根本的に解決しないけどね.まぁ,むしろストリームのダンプとかは逐次実行したほうが安心そうだし.それに,wavファイルをMP3にConvertするようなプラグインと組み合わせるときに,Fetch -> Convertの順番が保証されないじゃん.

というわけで普通にsystem関数使った感じ書き換えようかな.POE::Wheel::Runのようにイベントをハンドルできて,なおかつ子プロセスを立ち上げないような仕組みがあるとらくちんそうだけど.