Yahoo Widgetの再開と文字化け問題

GW中はいろいろたまってた調べごとをやっていて何か面白いものを作ったりはできなかった。休みの間はブログもtwitterも遮断してたのでぼちぼちと連休中の出来事なども思い出して書いていこう。

まずは、Yahoo! Widgetの開発を再開したこと。

My Outlook Todayは二年間も開発を放置していたらしい。つーか、Outook使ってた会社を辞めたのがそのあたりだからしょうがない。ただ、それ以上に別のWidgetがアメリカの方で公開されず何回かサポートに連絡したのに調査するだけでその後何も返事がないというやつらのやり方に頭にきてもうYahoo! Widgetいいよ。ってなったのがでかい。

でもそろそろ頭も冷えてきたので再開したよ。

ってのはうそで。Google Calendarを使っていてiPod Touchと同期してたりしたんだけどやっぱりパソコンでも見たいよねーってことでMy Outlook TodayならぬMy Google CalendarをYahoo! Widgetでつくりました!
http://widgets.yahoo.co.jp/gallery/detail.html?wid=10509
日本は本日公開された模様。本家USのほうはまだ公開されない。もう一週間たつのに。あいつら仕事しろよ。

そうだ思い出した。

以前、Yahoo WidgetでXMLHttpRequestのレスポンスが突然文字化けしたことがあったんだけど、My Google Calendarでも同じ問題に遭遇した。

というか、XMLHttpRequestのレスポンスはxmlタグのencode=”utf-8″がないとISO-8859-1と解釈されるっぽいのよ。で、Yahoo Widgetの世界ではutf-8でwidgetを書いてるので、エンジンがISO-8859-1からutf-8に文字コードを変換してくれるのよ。この親切設計(大きなお世話)。

つまり、utf-8のレスポンスなのに、ISO-8859-1からutf-8の変換が入るから文字化けするわけさ。

で、回避方法のひとつとして、XMLHttpReuqestでリクエストヘッダにAccept-Charsetを仕込む方法がforumで紹介されてた。

req.setRequestHeader(“Accept-Charset”,”ISO-8859-1,utf-8;q=0.7,*;q=0.7″);
こんな感じでutf-8でもらえるのに、わざわざISO-8859-1を要求してISO-8859-1->utf-8の変換をいれると・・・・
ただこの回避策は当然サーバサイドがISO-8859-1を返すようになってないとutf-8で返ってくるので解決できない。Google様はそうだった。

Google CalendarはGData APIでjsonで取得することもできるんだけど化け化けなんですよ。どうみても「xmlでencode=”utf-8″がある」以外は化けるのよ。つまりjsonデータはISO-8859-1で解釈される、さすがアメリカ人やることがえぐい。

で、「デフォルトをutf-8にすればいいのかもしれないがそれだとISO-8859-1を期待しているプログラムで問題がおきるようになる。」みたいなことを言っていて。まぁ確かにデフォルトをどっちにおくかってのは難しい問題なんだけど。。。

その前にレスポンスヘッダのContent-Typeを見ろよ!
Google様はちゃんと「Content-Type:application/json; charset=UTF-8」って返してくれてるよ。なんでISO-8859-1->utf8の変換をする必要がある?これはどう考えてもバグでしょう。

発言者がYahooの人か知らないけど、Yahoo Widget Engineの開発者って本当に大丈夫か?ってすげー心配になった。

で、結局My Google Calendarではjsonをあきらめてxmlで取得してDOM呼んで頑張った。。。

Widgetのアーキテクチャーを考えてみる

ちょくちょくMy Outlook Todayの質問が外人さんからくるんだけど、開発を2年も放置している。

outook使ってた会社やめたってのがでかいけど、一応Officeのライセンスもってたけどもうoutookすらインストールしてない状態だし、Microsoft OfficeのバージョンアップせずにOpenOffice使ってる。。。

商用ならまだしも、趣味のプログラミングで自分が使ってないものをサポートするのはしんどい。

ただそれはそれはそれで使ってる人に失礼だと思うので、いま使っているGoogle CalendarでMy Google Todayってのを作ってうまくMy Outlook Todayも保守するってのが落としどころじゃなかろうか。予定とってくるところと、新規予定の作成だけ抽象化すればあとは共通化できるだろうと安易に考えてる。

しかし、久しぶりにWidgetのコードみたら自分のコードがあまりにひどくて心が折れそうになる。widgetにしてもwebアプリにしてもそうなんだけど、javascriptレイヤでUIも書いてしまうから、アプリレイヤ(ビジネスロジック)とUIレイヤ(プレゼンテーション)がごっちゃになってしまう。これじゃー再利用しづらい。

そんなわけでこんな風に作ろうと心に決めた。


widgetにはajaxでデータをとってきて表示するたぐいのものが多い。なのでなんらかのAjaxフレームワークを使いたい。実はいままでprototype.jsを使っていたのだけど、Ext JS CoreがMITライセンスになったのを受けてこれを使ってみることにした。

WALってのはもともと作ろうとしていたWidget Abstract LayerというYahoo WidgetとかSidebar Gadgetとかを抽象化するAdapter。これによってFoundationとApplicaitonレイヤのコードを再利用可能にする。

UIはwidgetによってアプローチが変わってくるのでこの部分は書き直しになるのは仕方がない。Yahoo WidgetやGoogle Desktop GadgetはUI層は独自のコントロールを持っているので独自の記述が必要になるし、Sidebar GadgetはIEなのでEXT JSとかYUIとかjqueryでwebアプリと同じように描画することもできる。このあたりの選択も自由だ。

UI層のコードを減らすためにはfuncationableなものはなるべくApplicationレイヤにねじこめばいい。一番シンプルなのはUI層にはupdateという描画更新の関数しかなくて、設定の変更やデータの変更のイベントをうけてupdateを呼ぶだけってのが良い。あとはApplication層でデータをとってきてUi層からとれるようにするだけでいい。そうすればUI層が書き直しになるといってもそれほど苦にならないはずだ。

new Text();… と書くのかdocument.createElement(“p”);…と書くだけの違いだけだというレベルにまで持って行けば移植しやすくなる。