年が明けて数日が立ちました。暦上は皆さん今日から仕事はじめでしょうか?本年もよろしくお願いします。
さて、年末年始関係なくData APIのプラグインやスクリプトを書きまくっている上野ですが、年始に実家に寄ろうと移動中、実家近所の駅近のタリーズでMT開発チームの元同僚と偶然会うなど、年明け早々Movable Type漬けになりそうな雰囲気でございます(笑)
さて、今日のエントリーもData APIネタ。Movable TypeのData APIで本当に作る必要があったのか微妙ですが、うちのブログメディアは基本flickrに上がっている画像を引っ張ってHTMLに貼付けています。その中のこれという画像を個別にアセットとしてアップロードし、メイン画像としてカスタムフィールドに放り込むとMTMLで色々と画像が処理される仕組みになっています。
この仕組み、今からアップするエントリーは個別にその作業をすれば良いのですが、今まで書いて来た数百件にのぼるエントリーに改めてこの作業をするのは骨が折れます。そこでData APIの出番。スクリプトでがりっとやってしまおうというのが今回のお題です。
まず作ったのは今までのスクリプトの派生としてData APIを使って全エントリーを取得するだけのスクリプト。さすがに数百件のエントリーをいっぺんに取得するのはメモリーの無駄遣いなので、offsetとlimitを使って適当な数で区切って読み込むようにしました。読み込む内容は、'id,permalink,body,more,assets,customFields'をfieldsにセットしてやります。これで、エントリーID、エントリーURL(permalink)、エントリーtext、エントリーmore、アセット情報、カスタムフィールド情報、が取得出来ます。
最初、エントリーtextを取得するのに fields => 'text' なんてやっていたものだから取得出来ず、悩んだ挙げ句リファレンスを読んだら fields => 'body' なんだとか。ちょっとビックリ。
これで数十件まとめて読んだところ、MT::Util::from_jsonがエラーを吐いた。取得したjsonを見てみると途中で切れてる。取得するjsonに容量制限ってあったのかしら?仕方がないので、エラーを出さない範囲(余分を見て5件)毎にしました。
bodyとmoreを連結して、HTML::TagParserで<img>タグを取得。そのsrcを見て、flickr.comが含まれていたら外部サイトにある画像だと認識。
画像ファイルを一旦 /tmp/ 配下に保存してData APIのアセットアップロード機能を使ってアップロード。ここで HTTP::Request のPOSTでファイルをアップロードするのにちょっとしたテクニックが必要でした(詳細は別の詳しいサイトにまかせます)。戻り値としてアセット情報が返ってくるので、このアセットIDを保存しておきます。
今度はアセットをエントリーに紐づける必要があるのですが、Data APIにはその機能がありません。そこで、アセットのREST APIにentry_idを放り込むと紐づけてくれるエンドポイントをプラグインとして追加しました。具体的には内部で MT::ObjectAsset->get_by_key() を呼んでやり、エントリーにアセットを紐づけます。
通常であればここまでで良いのですが今回はその情報をカスタムフィールドに設定しなければなりません。そこでData APIのエントリーアップデート機能を使ってカスタムフィールドを更新します。画像カスタムフィールドは内部で画像以外の値(<form>タグなど)を持っているので、それにあわせて整形しアセットのURLとIDをセットしました。
このエントリーのアップデートで困ったのが Can't call method "errtrans" without a package or object reference at lib/MT/CMS/Entry.pm line 2266. というエラーが頻発した事。処理自体は最後まで行っているのでリビルドの際に何か問題が起きているのかもしれませんが、深くは追いませんでした。時間があれば調べてみます。今回はスクリプトの再実行で済ませました。
こんな風にした事で、過去のエントリーで使った画像もサムネールとして表示されるようになりました。ここまでやるのであれば別にData APIではなくてMT::Appから派生させれば良いのですがまあ良しとします。おかげでData APIの内部構造もかなり分かってきましたし、MT::Appから作成するよりも画像のアップロードなどは簡単にできますし、他にも色々な面で深く考える必要がないので短時間で実装が可能でした。
あとはスクリプトの内部にID, PASSWORDをもたないといけない点だけをクリアしたいです。accessTokenを生成するための内部コードを書けばよさそうですね。また今度考えてみます。
Movable Type 6 本格活用ガイドブック (Web Designing BOOKS) | |
藤本 壱 柳谷 真志 奥脇 知宏 シックス・アパート株式会社 マイナビ 2013-11-30 売り上げランキング : 80852 Amazonで詳しく見る by G-Tools |