WiLiKi:RSSMix
複数のWiLiKiからの更新情報をまとめる
http://practical-scheme.net/wiliki/rssmix.cgi
RSSMixは複数のサイトからRDF Site Summaryを取得して、 項目をいっしょくたにしてdate属性をもとに新しい順に並べて表示する スクリプトです。RSSを使うクローラー等、似たようなものは既にありますが、 こちらは複数のWiLiKiサイトをうまくつなげることを重視するつもりです。
ただ、RSS対応したWiLiKi-0.3で運用してる ところもまだあんまりなさそうだし、自分のところだけだと 寂しいので、RSSを公開している他のサイトも入れさせてもらっています。 RDFを取るのが迷惑でしたらお知らせ下さい。 一応、取得したRDFはキャッシュしてあって、 30分以内には再アクセスにいかないようにしています。 (逆に、各サイトの更新情報は最高30分遅れて反映されます)。
また、WiLiKi-0.3を運用していて、実験に参加しても良いという 方がいらっしゃいましたらお知らせ下さい。
WiLiKiに限らず、RSSにitemの作成/更新日時が入っているサイトなら 追加できます。(YukiWiki等、RSSにdateを入れていないところだとだめですが)。
RSSには最新の10〜15項目を入れるのが普通のようなので、 リストに現われるのもその項目までとなります。
たまにrssmix.cgiがスタックする件
Shiro (2003/06/13 00:37:17 PDT): 時々rssmix.cgiが固まることがある。 今利用しているサーバはLinux 2.4.20。OS specificなのか 一般的なバグかは不明。
固まった状態でデバッガをattachすると、gc中でデッドロックしている。 どうやら、子スレッド中でgethostbyname_rを呼んで、そいつが何かの ライブラリをdlopen()していて、その中に入った時にgcがトリガされると まずい模様。
2004/05/23 17:14:15 PDT: 最近見てない。
rdfが取れない場合がある件
iriyak (2004/05/15 21:57:45 PDT): こちらの rssmix.cgi の出力にSHIMADAさんが出てこないようです。目下、切り分け中です。運営しているサイトの wget で blosxom.rdf を取得したら取れました。ですので、そこから後のシーケンスのどこか、もしくは rssmix.cgi の設定値そのものに原因があるのではないかとあたりをつけています。
ふじさわ 2004/05/16 15:56:29 PDT : たぶんblosxom.rdfのdc:date項目を読めていないのが原因です。dc:date項目は何通りかの表記が可能なのですが(cf. http://www.kanzaki.com/docs/html/dtf.html )、一般的に流通しているRDFのdc:dateは「YYYY-MM-DDThh:mm:ssTZD」形式で、SHIMADAさんちのblosxom.rdfは「YYYY-MM-DDThh:mmTZD」形式です。そして、rssmix.cgiのdc:date切り出し処理はad hocなものなので、後者の形式に対応していないのです。これが原因なら、rssmix.cgiのparse-date関数を少しいじることで直ります。
Shiro 2004/05/23 16:10:04 PDT: 0.5リリースで直しておきました。
SHIMADA (2004/05/27 20:07:21 PDT): ここのやりとりに気づいていませんでした。BlosxomのRSS10フレーバーを適当にコピペ・修正した代物なのですが、秒が抜けてたとは気づきませんでした。今度追加しときます。
Setu? 2004/08/19 15:00:15 PDT: 初めまして。rdfで、<title></title> とタイトルが空の場合、そのサイトのrdfが全く表示されないです。tDiary で作られる rdf を取り込んだ所、表示されないのでデータを切り捨てながら試してみました。空のタイトルを "<title>無題</title>" とするとRSSの一覧に並びました。tDiaryでは、本文も rdf に取り込んでいて、本文中に副見出しが付いている場合、それ以降が独立の<item>となり、タイトルが空で <item>が作られる様です。
対応の仕方ですが、tDiaryの使い方としては文章/記事の一部に過ぎませんので、この タイトルが空な <item> は、まるごと捨てちゃって良いと思います。http://mixi.jp/ で、この rdf を取り込んだ所、やはり捨てています。
なお、shell から rssmix.cgi を実行した所、エラー出力に 『pair required, but got ()』と、出力されます。
Shiro (2004/08/19 20:17:30 PDT): ちゃんと試してはいないのですが、src/wiliki/rssmix.scmの 最後の関数extract-form-rdfの本体で、タイトルを扱ってる部分をこうすると どうでしょうか。今ならGaucheRefj:util.matchあたりを使ってもっと綺麗にかけそうですが。
(and (pair? chan-title) (pair? (cdr chan-title)) (if (and (pair? (cadr chan-title)) (eq? (caadr chan-title) '@)) (caddr chan-title) (cadr chan-title)))
- Setu? (2004/08/20 03:12:53 PDT): ダメでした。上のコードは「チャンネル・タイトル」の部分で、空白になっているのは「<item>の<title>」でした。でも、おかげで何処を見たら良いか分かったので、いろいろ試してみました。上のリストのすぐ下の部分を以下の様にしたらうまく行きました。ありがとうございました。
(let ((title (and-let* ((n (find-node 'rss:title item))) ++ (if (null? (cdr n)) #f (cadr n) ))) -- (cadr n)))
- Setu? 2004/11/01 11:03:56 PST: MOVABLE TYPE 2.64 のRSSが読めないようなので、上の部分を他のノードについても修正してみたら読めるようになりました。最近 scheme で遊び始めました。オリジナルの rssmix.scm との差分は:
$ diff -Naur rssmix.scm.original rssmix.scm --- rssmix.scm.original Mon May 24 07:57:52 2004 +++ rssmix.scm Tue Nov 2 03:58:54 2004 @@ -373,16 +373,24 @@ (items (filter-node 'rss:item rdf))) (cons (and (pair? chan-title) + (pair? (cdr chan-title)) (if (and (pair? (cadr chan-title)) (eq? (caadr chan-title) '@)) (caddr chan-title) (cadr chan-title))) (filter-map (lambda (item) - (let ((title (and-let* ((n (find-node 'rss:title item))) - (cadr n))) - (link (and-let* ((n (find-node 'rss:link item))) - (cadr n))) - (date (and-let* ((n (find-node 'dc:date item))) - (parse-date (cadr n))))) - (and title link date (list title link date)))) + (and-let* + ((title-node (find-node 'rss:title item)) + ((pair? (cdr title-node))) + (title (cadr title-node)) + + (link-node (find-node 'rss:link item)) + ((pair? (cdr link-node))) + (link (cadr link-node)) + + (date-node (find-node 'dc:date item)) + ((pair? (cdr date-node))) + (date (parse-date (cadr date-node))) + ) + (list title link date))) items))) )
Setu? (2004/11/09 23:36:02 PST): rdf が取れないサイトがあったので調べたら、rss 2.0 を使っていました。rssmixは rss 2.0 をサポートしていないです。今度、気が向いた時にrss 2.0を少しサポートするようにしてみようと思ってます。
Setu? (2004/11/09 23:36:02 PST): itemの時間がないとそのitemは捨てられます。巡回の一部にいれておきたいRSSでitem に時間が入っていないサイトがあるのでどうしようかと思っています。「今」を自動的にいれるといつでも最新にならんでしまうので、「今日の午前0時」を自動的に入れてみようかなと思っています。
Shiro(2004/11/14 17:50:57 PST): しばらくこっち手をつけていませんが、 年末にかけて少しいじると思うので、その時にまとめて処理します。 気がついたことがあれば書き込んでおいて下さい。
- Setu? 2004/11/14 23:39:08 PST 『RSSの出力機能』 rssMix で集めたRSSをHTMLで出力する以外に、RSSでも出力したいなあと思いました。itemのタイトルを、「チャンネル名」+「itemのタイトル」として出力したら良いだろうと思っていましたが。
Zu 2005/07/12 01:29:43 PDT:
- うまくいかない、いくつかのパターン
- item内の dc:date の時刻が日付のみ(YYYY-MM-DD)のものが混在している。(はてなダイヤリーのRSS)
- parse-date の match 文字列を変えればいちおう動くが....
(define (parse-date date) (and-let* ((match (#/^(\d\d\d\d)-(\d\d)-(\d\d)(?:T(\d\d))?(?::(\d\d))?(?::(\d\d))?([+-]\d\d)?(\d\d)?/ date)))
- parse-date の match 文字列を変えればいちおう動くが....
- item内の dc:date に日付がない。(channelのdc:dateで代用?)
- RSSのバージョンが違う。こんなパッチを書いたけど、いきあたりばったりだ(^^;
--- /home/shin/WiLiKi-0.4/src/rssmix.cgi Wed Apr 9 16:33:28 2003 +++ rssmix2.cgi Tue Jul 12 15:45:57 2005 @@ -359,7 +366,7 @@ ;; with ':' between hours and minutes. I need to parse it manually. (define (parse-date date) (and-let* - ((match (#/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)([+-]\d\d):(\d\d)/ date))) + ((match (#/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d))?([+-]\d\d):(\d\d)/ date))) (receive (year month day hour minute second zh zm) (apply values (map (lambda (i) (x->integer (match i))) (iota 8 1))) (time-second @@ -367,23 +374,36 @@ (* (if (negative? zh) -1 1) (+ (* (abs zh) 3600) (* zm 60)))))) ))) + + (define (parse-rfc822-date date) + (receive (year month day hour minute second zh zm) (rfc822-parse-date date) + (time-second + (date->time-utc (make-date 0 second minute hour day month year (* 9 3600))))) + ) - (let* ((rdf (find-node 'rdf:RDF sxml)) - (chan (find-node 'rss:channel rdf)) - (chan-title (find-node 'rss:title chan)) - (items (filter-node 'rss:item rdf))) + (let* ((rss (find-node 'rss sxml)) + (chan (find-node 'channel rss)) + (chan-title (find-node 'title chan)) + (items (filter-node 'item chan))) (cons (and (pair? chan-title) + (pair? (cdr chan-title)) (if (and (pair? (cadr chan-title)) (eq? (caadr chan-title) '@)) (caddr chan-title) (cadr chan-title))) (filter-map (lambda (item) - (let ((title (and-let* ((n (find-node 'rss:title item))) - (cadr n))) - (link (and-let* ((n (find-node 'rss:link item))) - (cadr n))) - (date (and-let* ((n (find-node 'dc:date item))) - (parse-date (cadr n))))) + (let ((title (and-let* ((n (find-node 'title item))) + (if (null? (cdr n)) #f (cadr n) ))) + (link (and-let* ((n (find-node 'link item))) + (if (null? (cdr n)) #f (cadr n) ))) + (date (or + (and-let* ((n (find-node 'dc:date item))) + (parse-date (cadr n))) + (and-let* ((n (find-node 'pubDate item))) + (parse-rfc822-date (cadr n))) + (and-let* ((n (find-node 'description item))) + (parse-rfc822-date (cadr n)))) + )) (and title link date (list title link date)))) items))) )
- item内の dc:date の時刻が日付のみ(YYYY-MM-DD)のものが混在している。(はてなダイヤリーのRSS)
議論はこちらに
Shiro (2003/02/17 21:36:03 PST): んー、時々えらく時間がかかるのは何故だろう。 今はフェッチするrdf毎にthread作ってhttp-getさせて、thread-join!で まとめるところでタイムアウト切っているんで、もし全てのhttp-getが スタックしてるとスレッド数×タイムアウト分待たされる。 各http-getをタイムアウトさせたい場合はもう一段threadをかませるしか ないのかなあ。
あ、まてよ。thread-join!のタイムアウトを絶対時間でやればいいのか。
Shiro (2003/02/18 18:51:41 PST): cgiキック時点から30秒で全部タイムアウトするようにした。 が、やっぱり一つでもひっかかると30秒待つのはいやんな感じだ。
- 頻繁に見るならRSSの取得はcronに任せて、cgiは結果表示に徹するだけに。
- →一番簡単だが、cronが使えないサーバーの利用者は使えない。
- cgiキックされたら別プロセスで取得を開始、短時間(10秒とか)で間に合えば その結果を使うが、間に合わなかったらcgiはキャッシュの情報を使い、 別プロセスは後からdbをアップデートしておく。
各サイトの、キャッシュされたデータの取得時間と、最近のhttp-getにかかった時間は
http://practical-scheme.net/wiliki/rssmix.cgi?c=info
で見られる。
Shiro: ishinaoさんが同様にRSSを集める wikistmaniaという実験を始めました。
これ見てるとRSSに<description>も載せたくなります。
Shiro (2003/02/24 05:32:30 PST): たまーにrssmix.cgiがスタックすることがあるようだ。 サーバーにログインしてみると、スレッドをclone()で作ったあと 元プロセスが死んでるっぽい。本来ならそこでスレッドも殺されるはずなんだが… 変なところでスタックするとキャッシュDBのロックが握られたままになるから 後が全部つっかえてしまう。困ったな。
yaegashi (2003/03/04 09:44:38 PST): よろしければ うちの WiLiKi も実験に加えてください。 くだらんコンテンツしかなくて恐縮ですが…。 なお WiLiKi はすでにいろいろなところで 細かな改良を加えつつ活用させていただいています。 そのほとんどが表に出せるところにないのが残念です。
kou (2003/03/04 21:14:24 PST) : RWikiにも同じような機能をつけてみたのですが、WiLiKiの提供するRSS(1.0ですよね?)には/rdf:RDF/item要素にrdf:about属性がないのはどうしてですか?http://web.resource.org/rss/1.0/spec#s5.5 には
Required Attribute(s): rdf:about
と書いてあるので必須属性だと思ったのですが。
- Shiro: 見落としです。追加しときます。 2003/03/05 12:06:13 PST: 追加しました。
kou (2003/06/16 06:08:24 PDT): /rdf:RDF/channel/items/rdf:Seq/rdf:li要素のresource属性のrdf接頭辞は http://www2.xml.gr.jp/log.html?MLID=xmlusers&N=8353&FORMAT=MIN ということだそうです.
makoto (2004/12/17 00:04:34 PST): http://www.mozilla-japan.org/products/firefox/live-bookmarks.html の右下に あるように、RSSをフィードしていることをFireFoxに知らせるためのlinkタグを WiLiKi 0.5のwiliki.scmのwiliki:default-head-elementsにベタで追加したら、 ちゃんとFireFoxのウィンドウの右下にRSSマークが出て、ライブブックマークとして 機能しています。linkタグのhref属性には、うんたら/wiliki.cgi?c=rssと 書きました。wiliki.cgiに、:rss-feed?とかあるといいのではないでしょうか?
g000001? (2022/07/20 14:52:31 UTC): RSSMixにReddit r/lisp_ja をご登録頂いていましたが、r/lisp_jaが謎のbanを喰らってしまったので、代替としてはてブ(&RSS)を利用することにしました。 https://b.hatena.ne.jp/search/tag?q=lisp_ja&users=1&mode=rss 収集される記事の傾向はこれまで通りです(正確には、はてブの性質上[lisp_ja]タグの集積であり、Redditのsubredditという感じではないですが……)
- Shiro: 取得元変更しました。redditのbanは謎ですね。
g000001?2022/09/06 13:22:01 UTC 度々すいません。Redditのr/lisp_jaの件ですが、mod(管理者)に新規立候補して受理されたため復活しました。 (ちなみに管理者を0人にしたことはなかった筈ですが……)
お手数ですが、はてなブックマークのまとめRSSだとマイナーなサイトが表示されなかったりするよう(スパム対策?)なので、Redditに復帰頂ければ幸いです。
以前は、
https://www.reddit.com/r/lisp_ja/.rss
の単発RSSだったと思いますが、multiredditsとして複数subredditを纏められるので下記だと日本語のLisp系Redditが集約可能だと思います。
https://www.reddit.com/r/lisp_ja+scheme_ja+common_lisp_ja+clojure_ja+sicp_ja/.rss
どうぞよろしくお願い致します。
- Shiro(2022/09/07 05:37:42 UTC): multireddits にしましたー。