As Sloth As Possible

可能な限りナマケモノでありたい

タグ:Fastladder

LDR&Fastladderの中の人から「これ面白そうだから、OpenFLで使ってみようよ。ていうか作ってよ」と大変無茶振りをされたのでYet Another PraggerでFastladderのクローラを書いてみた。

YapraかわいいよYapra

使ってみた感想としては良い感じ。Class-basedなプラグインなところが本家PRaggerより好みだし、でもlegacyなプラグインも読み込める互換性が使い勝手がいい。あと「実行時に使うプラグインだけ読み込む」ってことをしてくれるのも素敵。

肝心のFastladderのクローラは

iDiskに置いといたので興味のある方は持ってってください。展開したら中身をlib-plugin/yapra/plugin以下あたりに配置すると使えると思います。YapraはYuanyingさんのところから。ちなみにconfig.yamlのサンプルはこんな感じ。

- module: Fastladder::Config
  config:
    root: /path/to/fastladder/root
    environment: development
- module: Fastladder::CrawlTarget
- module: Fastladder::Fetch
- module: Fastladder::Store

最初のConfigでfastladderのパスとRAILS_ENVを指定して初期化して、CrawlTargetでDBからFetch対象のフィードを選んで、Fetchでフィードを取得、StoreでDB内のデータを更新、という流れでございます。んで、なんでわざわざPragger(Yapra)で作ってみたかというと、プラグイン形式のものにクローラを置き換えることを検討しているので。

例えば今のクローラは単順に古いのから順にフィードの取得をしに行くんだけど、もっと賢く(更新頻度が高いフィードや購読者が多いフィードを優先してフェッチする、とか)したければCrawlTargetだけ別なプラグインと置き替えてやればいい。例えばフィードを全文表示に展開するとか広告を除去するとか特定の記事だけを抽出するとかそういうフィルタをかけたければ、FetchとStoreの間にフィルタプラグインを挟んでやればいい。とか、そういうことがやりやすくなるかなと。

まぁPlaggerで既にやってる人は多々いると思うんだけど、正直Plaggerはインストールの敷居が高いし、同じRubyで書ける方がとっつきやすい人もいるだろうなと思うので、もしプラグイン風のクローラを採用するとしたらPraggerかYapraかなーという感じかなぁと話してるところです。Praggerくらいのサイズなら同梱できちゃいそうだし、なんならそれっぽい機構のものを再発明するのもありかも。

まあ一応念の為

これはあくまで「試しに作ってみた」だけのものなので。「添付のクローラより格段にすごい!」とか「PlaggerのStore::Fastladderなんか目じゃないぜ」みたいなものではありません。正直中でやってることは添付のクローラをほぼそのまま移植しただけなので、あちこちアレなところも直してないですし、fastladder本体にいろいろ依存してるので大変気持ちの悪い箇所が多々あります。今のところ既存のPraggerプラグインとの連携もできてないし、便利プラグインも作ってないです。あくまで試作品ですのでご了承下さい。

てか誰か作ってくれないかな。よさげなもの。上の試作品を完成させてくれちゃっても良いよ!(他力本願)

追記

流石にiDiskに置いとくのはアレなので、とりあえずgithubに上げときました。ついでにまた少しいじった。

朝出社したら社内ブログが出来たとのお知らせが届いてた。livedoorBlogと(ほぼ)同等の機能を持つものがイントラで動いている。

こりゃいいや、と早速記事を書いたりしてたのだけど、あちこちから「新着確認できない」「reader欲しい」との声が聞こえて来た。こういうときこそオープンソース版Fastladderの出番ですぜ。とはいえ、社員の人数分Fastladderが動いてると言うのもなんなので、社内の実験用サーバを借りてインストールしてみることにした。

まっさらなサーバに入れるので、まずは必要な環境を整える。何はともあれruby。1.8.6p-111をインストール。勢いで1.9.0を入れてやろうかとも思ったけど、今回の趣旨は実験じゃなくて「まともに使う」なので流石に自重した。gemは最新版の1.0.1を普通に入れる。Fastladder本体はパッケージ版ではなくtrunkを使う。こっちではクローラがメモリリークするとかフォームのバグでインポートが出来ないとかの不具合に対応してあって、若干安定性が増している(多分)。

若干ハマったのはFreeImage。Mac/Win版はバイナリがあるんだけど、それ以外のプラットホームでは自分で入れなければならない。今回はXen上のCentOSに入れたんだけど、パッケージが見当たらなかったのでソースからビルドしてみた。ここで容量が足りなくてコンパイル中に止まったので確認したら、ディスクが2GBしか設定されてなくて噴いた。容量設定し直してもらって再挑戦。

Fastladderの必須gemパッケージはrails2.0.2、rfeedfinder、feed-normalizer、opml、あとDBのドライバとしてsqlite3-ruby。だけど、今回は加えてMySQLのドライバとthinを入れた。多人数で共有しようと思ったらsqliteは流石にキツい。thinはrails用のサーバで、mongrelより軽量で速いと聞いたので試しにこっちにしてみた。これはただの趣味で、mongrel+mongrel_clusterでも別に良かった。上手く行ったら今後何かで使うかもしれない。

これで一応動かせる環境が出来たのだけど、さらにフロントにApache2を立てて、mod_proxy_balancerで3つ位立ち上げたthinサーバに分散させてやることにした。社内とはいえ流石に単体で動かすと遅いだろうし、クラスタリングするとまだ見ぬバグが炙り出される可能性もあったので。

ここまでやって、さぁ!みんな使え!ってところで、みんなに発表する直前でCTOから「イントラにLDR立てました」ってアナウンスがあった。…そうだよね。自社だもんね。LDR使えばいいよね。…うん。

というわけで、LDBlog+LDRの快適社内ブログ環境が整い、Fastladderは寂しくユーザ数1人(俺)のまま稼働しているというお話でした。どうしよう。1人で使うか。Faulladder。

feedが登録出来ない。addをクリックして、URLを入力するのだが

"You need to sign in to Fastladder

Please reload the browser and sign in again"

といったエラーが出る。

Fastladderを使って、5分でアンインストールした

すいません、これはaddフォームのバグです。ちなみに、OPMLのインポートフォームでもこの現象が起きているはずです。

どういうことかというと、Rails 2.0からのセキュリティ周りの拡張に起因します。Rails2.0ではprotected_from_forgenyとすると、POSTリクエストを送るときにセッションのトークンが含まれていない場合リクエストを拒否するようになって、これがFastladderでも有効にしてありました。で、Rails 2.0系でform_tagとかを使うとその辺よしなにやってくれるんですが、インターフェース部は大部分が本家Fastladderからの流用なのでその記述がなかった。そのため、addフォームからのリクエストが送られてきたときに不正なリクエストと判断してしまい、ログインしてくださいという、ユーザからしてみれば「??」なエラーメッセージになってしまっていました。

これはtrunk版では既に対応済みで、パッケージ版の0.0.3リリースに含めますが、差しあたっての対策としては、app/controllers/application.rbの以下の部分で

# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.

class ApplicationController < ActionController::Base
  include AuthenticatedSystem
  #protect_from_forgery こいつをコメントアウト
  helper :all # include all helpers, all the time

と、この機能を無効にしてやると、addやimportが出来るようになります*1

もともとmod_perlとSledgeで書いてるものをRailsで書き直したものなんで、多分この手のインターフェースとバックエンドの齟齬とか、Railsのお作法にのっとってないとかのバグはまだちらほらあるんだろうなぁ。早急にリファクタ作業に入りたいところです。

追記

と思ったけどOPMLのインポート出来なかった。formで送ってるパラメータとcontrollerが受けとってるパラメータが違うし。そういえば直した記憶あるなこれ*2

=== app/views/reader/index.rhtml
==================================================================
--- app/views/reader/index.rhtml        (revision 4072)
+++ app/views/reader/index.rhtml        (local)
@@ -392,7 +392,7 @@
                                <b>file</b> : <input type="file" name="opml" style="width:230px"> <input type="submit" value=" Upload " style="width:90px">
                        </form>
                        <form target="_blank" action="/import/fetch" method="post" enctype="multipart/form-data">
-                               <b>OPML URL</b> : <input type="text" name="opml_url" value="http://" style="width:280px"> <input type="submit" value=" Import from URL " style="width:90px">
+                               <b>OPML URL</b> : <input type="text" name="url" value="http://" style="width:280px"> <input type="submit" value=" Import from URL " style="width:90px">
                        </form>
                        <div style="float:left" class="discover_help">
                                <a href="/import/"><img src="/img/icon/new_window.gif" border="none"></a>

こんな感じです。あわわわ。テスト書こうテスト。はやくリリースしよう。

*1:社内でCSRFとかやられる心配がなければね!

*2http://code.google.com/p/fastladder/source/detail?r=23

いわずと知れたlivedoor Readerの英語版*1であり、malaさんの卒論としても有名なオープンソース版のFastladderのコミット権をもらいました。

やりたいこと、やってくれと言われてることは色々あるので、これからちょこちょこといじって行きます。

*1:まぁ、「サービスとしてのFastladder」と「アプリケーションとしてのFastladder」は別モノなんですが

↑このページのトップヘ