chokan & FOAF
実験的に Rena を使ってみたかったので、よろしそうなプログラムを考える。
IRC BOT に何か FOAF アレこれできるような機能をつけてみたかった (意味があるかは考えない) ので、とりあえず URI に反応して、それが FOAF だったら foaf:nick と foaf:name をとってくるようにしてみた。
URI (http:) が PRIV されたら HEAD でアクセスして、ステータスコードと Content-Type を確認。`text/xml', `application/xml', `application/rdf+xml', `text/ntriples' であれば Rena にロードさせる。
ロードしたら rdf:about="" なリソースを探し、それが foaf:PersonalProfileDocument であれば foaf:primaryTopic のさすリソースの foaf:nick と foaf:name をてけとーに取得して IRC に NOTICE
Rena は結構遅いので、RDF パース中は chokan が他の処理しないかもしれない。
作るにあたって Using Rena to Process RDF in Ruby が役に立った。
よく考えると open-uri に Accept ヘッダを加えるのは無理 (もしくはめんどう) なので、最初から GET して、response.body を StringIO にして Rena に投げることにする。こうしないとネゴシエーション効いてる場合ダメになる。
メイン部分のコード。
# uri は読み込んだ RDF の URI の URI クラスのインスタンス
# res は HTTP#get の値
model = Rena::MemModel.new
model.load(StringIO.new(res.body),{
:content_type => Regexp.last_match[0],
:base => uri.to_s
})
resource = model[uri.to_s] # 相対 URI は絶対 URI に変換されている。
if resource &&
resource.get_property(RDF + "type").uri == URI.parse(FOAF + "PersonalProfileDocument")
mes = "foaf:PersonalProfileDocument"
foaf = resource.get_property(FOAF + "primaryTopic")
nick = foaf.get_property_values(FOAF + "nick")
name = foaf.get_property_values(FOAF + "name")
# string_array は rdf:Alt とかも全部ひっくるめて単一の文字列の配列にする
mes += " [nick:#{string_array(nick).join(", ")}]" unless nick.empty?
mes += " [name:#{string_array(name).join(", ")}]" unless name.empty?
subject << notice(channel, mes.to_jis)
else
puts "Not FOAF"
end
関連エントリー
- 日記簡易表記 さて、また哀さんのとこをパクって簡易表記を導入してみた。<a>Syrup16g</a> と書くと lexicon.xml の Term = ...
- RDF mm:Artist MusicBrainz の語彙に Artist っつうのがあるけど、アーティストって何か漠然としてる上に個人だか団体だかが分からないので、グ...
- リソースの定義 URI の R の定義。 RFC 3986 に書いてあるみたい。 要約が Web Kanzaki にある。URIとファイルディレクトリ --...
- IRC nickserv の使用法メモ なんか nick 管理にアレゲな機能がついているので使ってみる。memo 機能とかあって面白いけど使ってない。freenode と phas...
- microdata を適当に抜き出す Perl スクリプト あんまり仕様書読みこめてないけど書くだけ書いてみた。CPAN にあるのは依存がひどいし、別に HTML::Parser 的なもの一個の依存で...