So-net blog の AtomAPI を使う (ルートエンドポイント篇) [Tcl]
この So-net blog には AtomAPI (最近ではAtomPP: Atom Publishing Protocol) を使って記事を投稿する機能があるらしい。
http://www.so-net.ne.jp/blog/sitetour/atom_api_spec.html
ちょっと使ってみたいと思ってまずは Perl の XML::Atom をインストールしようとしたけどめんどくさくて放り投げる。せっかくだから Tcl で自分でごりごり書いてみようと思います。
Atom API ではまずはルートエンドポイントという URL にアクセスしてブログの情報を取得するところからはじめるようだ。
ネットでみつけたコードとかを参考にして Tcl で実装したのがこれ。
sha1 や base64 は tcllib パッケージを使用。
package require http
package require sha1
package require base64
set Username [lindex $argv 0]
set password [lindex $argv 1]
set nonce [expr rand()]
set Created [clock format [clock seconds] -format %Y-%m-%dT%H:%M:%SZ -gmt 1]
set PasswordDigest [base64::encode [sha1::sha1 -bin "$nonce$Created$password"]]
set Nonce [base64::encode $nonce]
set wssefmt {UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"}
set wsse [format $wssefmt $Username $PasswordDigest $Nonce $Created]
set token [::http::geturl {http://blog.so-net.ne.jp/_atom/blog} \
-headers [list X-WSSE $wsse]]
upvar #0 $token state
puts $state(body)
さて実行してみると、、
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <title>So-net blog : システムエラーが発生いたしました。</title>
…。念のため BlogWrite という Atom API 対応ソフトウェアで接続してみても同じなのでサーバが原因のようだ。
[2006-06-20追記] 念のため Livedoor Blog でやってみたらちゃんと動く。おかしいなと思ったら勘違いをしていたことに気づいた。このブログの場合Atom API のユーザIDは ether ではなくて rainyday になるのが正しい!
それにしても 40x ではなくて 505 になってしまってるのはどうかと思うが。
[2006-06-20追記]
というわけで取得ができたので結果の XML を処理する。
このリクエストで得られる情報というのは PostURI, FeedURI, UploadURI という3つの URI で、これらが今後の処理の次の足がかりになる。
<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://purl.org/atom/ns#"> <link rel="service.post" href="http://blog.so-net.ne.jp/_atom/blog/1" type="application/x.atom+xml" title="user_nameのブログ" /> <link rel="service.feed" href="http://blog.so-net.ne.jp/_atom/blog/1" type="application/x.atom+xml" title="user_nameのブログ" /> <link rel="service.upload" href="http://blog.so-net.ne.jp/_atom/image/1" type="application/x.atom+xml" title="user_nameのブログ" /> </feed>こういうデータは基本的にハッシュの構造なので Tcl のハッシュにしてしまおう。 XML 処理のコードを追加して以下のようにした。
package require http
package require sha1
package require base64
package require dom
set Username [lindex $argv 0]
set password [lindex $argv 1]
set url [lindex $argv 2]
set nonce [expr rand()]
set Created [clock format [clock seconds] -format %Y-%m-%dT%H:%M:%SZ -gmt 1]
set PasswordDigest [base64::encode [sha1::sha1 -bin "$nonce$Created$password"]]
set Nonce [base64::encode $nonce]
set wssefmt {UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"}
set wsse [format $wssefmt $Username $PasswordDigest $Nonce $Created]
set token [::http::geturl $url -headers [list X-WSSE $wsse]]
upvar #0 $token state
set xml $state(body)
set domdoc [::dom::DOMImplementation parse $xml]
set linkelems [::dom::selectNode $domdoc {/atom:feed/atom:link} \
-namespaces {atom http://purl.org/atom/ns#}]
set rels [list]
foreach linkelem $linkelems {
lappend rels [::dom::element getAttribute $linkelem rel]
lappend rels [::dom::element getAttribute $linkelem href]
}
array set linkh $rels
puts "service.upload: $linkh(service.upload)"
puts "service.post: $linkh(service.post)"
puts "service.feed: $linkh(service.feed)"
というわけでルートエンドポイントへの処理は完了。
コメント 0