数日前からこのサイトに、「Test Post」やら「テスト投稿」などという記事が登場していたことに気付いた方は少ないと思いますが、久々の新作、(今のところ)Movable Type 用のブログクライアント「Kaku」をリリースしました。使い方やダウンロードは、こちらの Kaku の紹介ページ からどうぞ。さて、その Kaku を開発した理由ですが、以前の記事「Journey for blog client」でも書いたように…、と書こうと思ってその記事を読み返したのですが、記事の趣旨は:
- livedoor Blog への投稿がめんどくさい。クライアントソフトが欲しい
- ecto は動作があやしいところがあるけど、便利なのでこれからも使っていきたい
…と、全く関係なし(笑)。しかもその前に出すと言っていたソフトとも全く関係なし。ecto のあやしいところが少し気になる、という理由は少しありつつも、XML-RPC(XML-RPC 仕様書)を使えば同じことができる、ということを知り、試してみたかった、という部分が大きい気がします。
とはいえ、開発途中でいろいろ気付いた点も多かったので、ここではそれを書いていきたいと思います。
- AppleScript から XML-RPC API を利用する
- 出力ファイル名を変えたい
- Category の設定で詰まる
- エントリーの公開/下書きを設定できない
AppleScript から XML-RPC API を利用する
Movable Type で使える API は、オフィシャルマニュアルや Tsurupone 氏によるこちらのページで見ることができますが、これをどうやって使ったらいいのかまったく見当がつかない。そこで検索してみたら、そのまんまのものが見つかりました。
XML-RPC and SOAP Programming Guide(Apple Developer Connection)
これによると、かなり簡単に XML-RPC のメソッドを呼び出せることが分かります。構文は:
tell "<XML-RPC サーバー名>"
call xmlrpc {method name:"<メソッド名>", parameters:{<引数のリスト等>}}
end tell
これが素晴らしいのは、引数を与えるときに、何も考えず AppleScript の形式で送ればよい、ということです。String 型の引数を与えれば XML-RPC の String 型として、List を与えれば array として、Record を与えれば struct として、勝手に変換して送ってくれます。また、返り値も AppleScript の List や Record としてかえって来、エラーは AppleScript のエラーとして通知されます。
出力ファイル名を変えたい
必要ない、という人もいるかもしれませんが、XML-RPC を使ってまずやりたかったのは、エントリーファイルの名前を変更することでした(あくまでデスクトップから。管理画面からならできます)。Movable Type では、エントリーに英語のタイトルをつければ、それが URL として利用できるように変換されて、ファイル名になります。これは URL だけで記事の内容が判別でき、便利です。しかし日本語のタイトルを付けると、当然変換は行えないので、タイトルの英語部分だけが残るか、「post_1」といった一般名になってしまいます。
そこで考えたのが(恐らくたいていの人が考えると思いますが)、「まず英語のタイトルでエントリーを送る → それをすぐ日本語のタイトルに変える」という変態な方法。…しかし、何度か Movable Type にメソッドを送って試しているうちに、もっと簡単な方法が見つかります。
確か「metaWeblog.getPost」を実行したときだと思いますが、ドキュメントにない「mt_basename」なるパラメータが返ってきていることに気付きました。これを逆に「metaWeblog.editPost」で送ってみたところ、出力ファイル名を変更することに成功しました。なぜドキュメントにないのか…(使っちゃダメ?)。
Category の設定で詰まる
Kaku を作っている最中、ふたつの致命的な不具合が起きていました:
- エントリーの公開/下書きを決定する「publish」パラメータの設定が反映されない。常に公開される…(1)
- 「mt.setPostCategories」でどうしてもエラーが発生し、エントリーのカテゴリーを設定できない…(2)
(1)は、公開したくなければ送らなければいい、ということでなんとかなります。しかし、カテゴリーを設定できないのではまったく使い物にならんぞ…と。これだけで1日ぐらい悩んでしまいました。実は非常に簡単な理由だったのですが…
悩んでいるうちに、あるツールを見つけたのですが、AppleScript の XML-RPC API 呼び出しのテストをするのに便利ですので、ここで紹介しておきます。
AEXMLTutor( Zellers 氏のサイトより)
このソフトは、普通に使えば「スクリプトエディタ」と同じですが、このソフトで AppleScript の XML-RPC API 呼び出しを実行すると、実際に送信した XML データと受信した XML データを見ることができます。
さて、どうしてもエラーが発生する、ということで、Movable Type のデータベースが壊れていることを疑ったり(エラーメッセージにもそれを連想させるようなことが書かれていました)、AppleScript の XML-RPC API 呼び出し機能の問題と考えて、もう自前で XML-RPC クライアントを作るしかないのか…と思っていたら、さきの AEXMLTutor がヒントをくれました。Record(struct)のアイテムにつけたラベル(名前)が、マニュアルに載っているものとは微妙に違う形で送信されていたのです(正しくは「categoryId」送っていたのは「categoryid」)。パラメータの値に関しては、本当は文字列が必要なところに数値形式で送ったりしても、何のエラーも起きていなかったので、ラベルの大文字小文字も気にしていないのだろうと思っていたのですが、ラベルを修正して送信してみたところ、難なく成功しました。もし AppleScript の XML-RPC API 呼び出しで、理由の分からないエラーが起きる場合は、struct につけたラベルが、API 側で要求されているものと本当に同じか確認した方がいいかもしれません。
もうひとつの落とし穴は、このラベルの修正がすんなりいかない場合もある、ということです。AppleScript のエディタは、一度つけた変数名やラベルを覚えていて、修正しても、勝手にもとに戻されてしまいます。そういうときは、名前を「|(パイプ)」で囲ってください。こうすることで、AppleScript 内では別の新しい変数名/ラベルとして定義され、エディタによって勝手に変更されることはありません。
エントリーの公開/下書きを設定できない
さて、最後までネックになっていたこの問題ですが、解決しました(この記事を書いている時点では、まだ Kaku の紹介ページも修正していません)。
昨夜「もっとサイトをチューンしたい」と思って、まずは Movable Type のマニュアルを読み返していたのですが、環境変数のところに、気になるものがありました。
Movable Type 3.3 マニュアル: 環境変数NoPublishMeansDraft
Wの値が真だと、XML-RPC API/MetaWeblog APIで投稿され、かつ、"publish"フラグがないエントリーは、下書きのステータスになります。この値が"0"である場合は、このシステムにおけるAPI経由で投稿したエントリーはどれも、提出後にすぐ公開されます。デフォルト値は"0"で、すべてエントリーが公開されます。ユーザーのほとんどは、クライアントからのエントリーを提出直後に公開するよう望んでいますが、エントリーを提出後に下書きステータスにしておきたい場合は、クライアントでその機能をサポートしていることを確認し、このオプションの値を1にします。
- 対応しているバージョン
- 3.1, 3.2, 3.3, Enterprise 1.0
- 初期値
- 0
実際には、publish フラグを付けようが付けまいが、この環境変数の値が 0 になっていると、必ず投稿されます。これを 1 にすると、下書き状態でサーバに保存することが可能になります。「ユーザーのほとんどは、クライアントからのエントリーを提出直後に公開するよう望んで…」んなこたあねーよ! 案の定、ecto の FAQ にも同じ問題が報告されていました。ecto では、下書きはローカルの下書きとして保存していたのでまったく気付きませんでした。
…という感じで Kaku ができました。AppleScript には、わけのわかんないところで裏切られるので(修行が足りないのか?)、今回もそれを何回か疑ったのですが、AppleScript に非はない、という結果になりました。XML-RPC API の呼び出しがきちんとできるということで、さらに機能を追加していくのも難しくはないかな、と思います。あと、詳しくは書きませんが、Cocoa Binding の使い方も、