2008-12-31

Postal Search Ajax API の Test Suite を公開します

おはようございます。なかじまんです。Postal Search Ajax API Test Suite を公開します。

Postal Search Ajax API Test Suite は、Postal Search Ajax API をリリースするためのテスト環境とテストケース群です。それぞれ aquilegia さんが開発してくれました。ありがとうございます。

Postal Search Ajax API も改良を進めてきた結果、それなりの規模になってきました。そのため、ソースコードの根本的なところに手を入れると、どんな影響があるか手軽に確認しにくくなってきました。また、現在は、次世代ブラウザの多様化や端境期ということもあり、各ブラウザ上でのテストのバリエーションが増大してきました。という背景から、Postal Search Ajax API Test Suite という形で、テストを自動化するに至った次第です。

Postal Search Ajax API Test Suite を開くと、すぐにテストがはじまります。そして、次のように、テストの内容と結果をリスト表示していきます。グリーンはテストが成功したことを表しています。



レッドはテストが失敗したことを表します。合わせて、テストが失敗した条件や事由を表示します。↓スクリーンショットのエラーは Opera 固有の振る舞いにより、期待する結果にならなかったことを示しています。



Postal Search Ajax API は、script 要素を使って動的に JavaScript をロードする仕組みを使っていますが、ローカルファイル(file プロトコル)からのロードは、ブラウザのセキュリティモデルに依存するため、テストケースから除外しています。input 要素の type="file" の value なども同様です。

Postal Search Ajax API は、非同期の API で、背後でタイマを使っていることもあり、低スペックの PC だとタイマの誤差により、テストが失敗することがあります。また、ネットワークの帯域などその状況にも左右されて、テストが失敗することがあります。

安定したテスト環境を用意したり、Mock 的なアプローチを導入して、インタフェースのみをテストするという方法もありうるのですが、やはり、リリース後と同じ状況でテストするべきという目的は譲れないため、不安定な部分も残しつつも公開しました。ですので、個別の事象や不都合は、少しずつよくなるよう改善を進めていきます。

Postal Search Ajax API Test Suite は、aquilegia さん作の Ael という JavaScript ライブラリ で構築されています。Ael がどういうものか、その概要は把握しているのですが、どのようにして、テスト環境を構築して、テストケースを動作させているのかは、わたしも未知です。これから覗いてみます。そのうち aquilegia さんが説明してくれると、勝手に期待しています。

2008-12-30

opensocial-jquery 0.2.0 view の操作をサポートしました

こんばんは。なかじまんです。opensocial-jquery 0.2.0 をリリースしました。

opensocial-jquery 0.2.0 では、次のとおり、view の操作を追加しました。

現在の view 名を取得できます。view 名は "profile", "home", "canvas", "preview" などの文字列です。

var name = jQuery.view();
// console.log(name) => "home"

現在のコンテナで使用できる view 名を配列として取得できます。

var names = jQuery.views();
// console.log(names) => ["home", "canvas"]

view 名を指定して、view を切り替えることができます。

jQuery.view("canvas");

view を切り替えるとき、パラメータを引き渡すことができます。

jQuery.view("canvas", { name: "nakajiman" } );

そのパラメータは ready イベントの引数として取得できます。

jQuery(function($, data) {
// console.log(data) => { name: "nakajiman" }
}

jQuery(document).ready(function($, data) {
// console.log(data) => { name: "nakajiman" }
}

view の切り替えとパラメータの引渡しの実例を用意しました。

http://opensocial-jquery.googlecode.com/svn/tags/0.2.0/samples/picasa.xml

jQuery.getJSON を使って Picasa Web Albums から新着の写真を取得し、リスト表示しています。このときの view は "profile" です。



写真をクリックすると、jQuery.view を使って "canvas" view に切り替えます。そして、クリックした写真を拡大して表示します。このとき、切り替えた view でどの写真をクリックしたか判別できるように、jQuery.view のパラメータとして、写真の URL を引き渡しています。



上のスクリーンショットは Orkut sandbox のものですが、iGoogle sandbox でも動作します。 以前は動作していたと思うのですが、Orkut sandbox で jQuery(window).title (gadgets.window.setTitle) を呼び出すとエラーが発生するようになっています。あれれ。

2008-12-25

opensocial-jquery OpenSocial ガジェット向けにカスタマイズした jQuery とそのプラグインです

おはようございます。なかじまんです。opensocial-jquery 0.1.0 をリリースしました。

opensocial-jquery は、OpenSocial ガジェット (アプリケーション) 向けにカスタマイズした jQuery とそのプラグインです。opensocial-jquery を使うと、OpenSocial APIGadgets API をほとんど意識することなく、jQuery を使ってウェブサイトを開発するノリで OpenSocial ガジェットを開発できます。

実例

まずは、サンプルのソースコードを紹介します。ガジェットのソースコードですが、jQuery を使ってウェブサイトを開発するのと変わらないでしょ?



<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="jQuery.getJSON - samples - opensocial-jquery">
<Require feature="dynamic-height" />
<Require feature="settitle" />
</ModulePrefs>
<UserPref name="tag" default_value="dog" required="true" />
<Content type="html"><![CDATA[
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.gadgets.js"></script>
<script type="text/javascript">
jQuery(function($) {

// Retrieves a preference as a string.
var tag = $.pref('tag');

// Sets the gadget title.
$(window).title(tag + ' - YouTube');

// Fetches content from the YouTube that content into the callback function.
var url = 'http://gdata.youtube.com/feeds/videos';
var data = { vq: tag, 'max-results': 21, alt: 'json' };

$.getJSON(url, data, function(json) {

$.each(json.feed.entry, function() {

var img = $('<img width="80" heieht="60" />')
.attr('src', this.media$group.media$thumbnail[0].url);

$('<a target="_blank" />')
.attr('href', this.media$group.media$player[0].url)
.append(img)
.appendTo('#videos');
});

// Adjusts the gadget height.
$(window).adjustHeight();
});

});
</script>
<style type="text/css">
<!--
#videos img {
border: 0;
margin: 2px;
width: 80px;
height: 60px;
}
-->
</style>
<div id="videos"></div>
]]></Content>
</Module>

opensocial-jquery は jQuery 本体の改良とプラグインから構成しています。

jQuery 本体

(1) jQuery.ajax

jQuery.ajax を介したリクエストは、すべて gadgets.io.makeRequest に橋渡しします。すべてのリクエストがガジェットサーバのプロキシで中継されます。そのため、クロスドメインリクエストの制約がありません。

text, html, xml, json, jsonp, script すべての dataType が使えます。jsonp や script であっても Gadgets サーバのプロキシで中継します。もちろん jQuery.ajax のショートカットである jQuery.fn.load, jQuery.get, jQuery.post, jQuery.getJSON, jQuery.getScript も使えます。

(2) dataType="feed" と jQuery.getFeed

jQuery.ajax の dateType として feed を追加しました。gadgets.io.makeRequest でgadgets.io.ContentType.FEED を指定したのと同じです。ショートカットとして jQuery.getFeed が使えます。

(3) jQuery(function() {}) と jQuery.ready

ガジェットコンテナのライフサイクルを尊重し、gadgets.util.registerOnLoadHandler のタイミングで ready イベントが起こるようにしています。

jQuery プラグイン

(4) jQuery(window).title

ガジェットのタイトルを変更できます。gadgets.window.setTitle に橋渡ししています。

(5) jQuery(window).adjustHeight

ガジェットの高さを自動調整します。高さを指定することもできます。gadgets.window.adjustHeight に橋渡ししています。

(6) jQuery.pref

ガジェットのユーザ設定を取得します。gadgets.Prefs.getString に橋渡ししています。

Shindig feature

opensocial-jquery は Shindig feature 形式でアーカイブしています。Shindig の feature として追加すると、次のように Require要素で opensocial-jquery の JavaScript 群をインポートできます。そのため script タグは不要です。

<ModulePrefs title="jQuery.getJSON - samples - opensocial-jquery">
<Require feature="opensocial-jquery" />
</ModulePrefs>

今後の予定

(a) jQuery.ajax を OAuth に対応することを検討しています。OAuth やその手続きをなるべく意識せずに使えればベストです。OAuth の深い知識が必要かな。やっぱり。

(b) gadgets.* を jQuery ライクに取り込んでいきます。よく使うと思われるものから優先的に取り組みます。はじめは gadgets.views が候補です。canvas ビューなど、複数のビューを使うことをサポートします。

(c) 各 opensocial.DataRequest を jQuery ライクに取り込みます。jQuery.getData を追加して "/people/@me/@friends" のように OpenSocial RESTful Protocol や RPC Protocol 的に条件指定できることを検討しています。各 opensocial.request* は jQuery.postData として追加することを検討しています。

opensocial-jquery を通じて、OpenSocial ガジェットの開発に貢献できればと願っています。以上、リリースのお知らせでした。

2008-12-14

gooラボの BLOGRANGER TG が API も含めてサービスを終了しちゃいます

BLOGRANGER TG 実験終了のお知らせ
今回のサービス終了の対象は、BLOGRANGER TGのタグマップを使ったブログ検索サービスだけではなく、タグマップAPIや、BLOGRANGER 2.0から2年間提供してきましたブログマイニングAPI、パーツを含めて、BLOGRANGERのすべてのサービスとなります。
↑とのことです。今まで BLOGRANGER API を使って、ちょっとした遊びアプリを作ってきましたが、もう動かなくなるってことですね。なので、作ったものの中から代表的なものを振り返ってみます。

Twitter.statuses.join(BLOGRANGER::TG)
今回は Twitter API を使いました。Twitter API で public_timeline を拾い続けて、そのユーザのアイコンを並べて表示していきます。このとき同時に、オートタギング API を使って、"つぶやき" のテキストからタグを自動推定します。そして、同じタグが推定された "つぶやき" 同士をくっつけて、アイコンをグループ化します。


オートタギングAPI を使ってブログのエントリを勝手に分類してみる
少し過去の話題にさかのぼります。上記のとおり、BLOGRANGER TG のブログパーツで、このブログのミニ地図が表示できなかったので、手始めに BLOGRANGER API の オートタギング API というのを使って、指定したブログのエントリからタグを自動推定して、そのタグごとにエントリを分類して表示するアプリケーションを作ってみました。


再び BLOGRANGER TG tube サムネイルがぐるぐる回転します
BLOGRANGER TG API を使って仮想地図を表示します。そして、その仮想地図の中央付近の話題と繋がりのある動画を YouTube Data API を使って検索し、その動画のサムネイルをグルっと一周する円として表示します。さらに、その動画のサムネイルをクリックすると、その動画を Flash Player を使って再生します。


マッシュアップレシピ BLOGRANGER TG tube 地図とタグと動画のビミョーな関係
タグに関連する動画のサムネイルを、タグの周囲に表示するようにしました。動画のサムネイルは、タグをキーワードとして YouTube Data API を使って検索しています。仮想地図に表示されたタグに対して、その検索を3秒ごとに繰り返して、次々とサムネイルを表示していきます。仮想地図をスクロールすると、そのスクロール先で表示されたタグのサムネイルを繰り返し表示します。


マッシュアップレシピ BLOGRANGER TG touch の Google ニュース和え
BLOGRANGER TG の地図をタップすると、そのタップした位置が画面中央になるように移動します。画面端をタップしながら地図の上を歩いていくような感じです。タグをタップすると、そのタグで最近のニュースを検索するようにしました。ニュースの検索は Google ニュースを使っています。BLOGRANGER TG の地図とタグは、ブログ界の様相を表している?ので、ブログ界とニュースの関係とそこから何かの発見があるかもしれない・・・。


マッシュアップカフェのプレゼン資料で Postal Search Ajax API のサンプルが引用されました
マッシュアップカフェの BLOGRANGER API のプレゼン資料の中で Postal Search Ajax API のサンプルが引用されました。マッシュアップカフェの様子は、こちらにレポートがあります。
もっとあった気がするのですが、どこに何があるのか分からなくなってしまっています。旧ブログ でもいろいろ紹介していましたので、こっちにあるかもしれません。

BLOGRANGER といろいろマッシュアップしてきたその足跡を振り返ってみました。

MA4 応募者限定の忘年会に参加してきたよ!

12月10日(水)ですが、MA4 応募者限定の忘年会という集まりに参加してきました。会場は銀座メディアテクノロジーラボ のオフィスです。
Mashup Awards 4 (MA4) での受賞からその後、いかがでしょうか?直前のご案内となってしまい恐縮ですが、明日10日(水)19時半~よりリクルート メディアテクノロジーラボのオフィス(東京都中央区銀座)にて、MA4 応募者限定の交流会(忘年会)を開催いたします!
アジェンダは、次のとおりです。
  • 自己紹介 & 作品 PR タイム
  • MA4 振り返り
    • KEEP(続けるべき点)
    • PROBLEM(問題だった点)
    • TRY(次回に向けて+α)
  • 懇親会
参加者みんなで1つのテーブルを囲み、自己紹介 & 作品 PR タイムから。作品 PR タイム(例)のお題は、次のとおり。
  • お名前
  • 作品・サービス概要紹介
  • 開発裏話
    • 開発と応募の動機
    • 知られざる機能・ウラ技
    • 泣なくして語れない秘話
    • 笑える話
  • 応募後の評判・反響
  • 今後の展望
続けて、懇親会兼 MA4 振り返りへ。次のとおり、事前アンケートを分類して、参加者みんなの MA4 に思うところをシェアしたり。
  • KEEP
  • PROBLEM
  • TRY
  • TOPICS
んで、お開きしたときは 23:00 をとっくに過ぎてました。

MA4 振り返りでは、クレームに近いような要望に対して、事務局や関係者の方々は、真剣に耳を傾けていました。MA5 があるかどうかは明言していませんでしたが、何らかの形で次回もあり、よりよいものへという意気込を感じました。

私からは、個人の参加者がモチベーションを高められる企画や体制とか、私のような SIer 的な立場の人でも参加しやすいような状況作りとかを、伝えることができました(というつもりです)。なんらかの形で実現されることを願っています。

もし MA5 があれば、よい意味で期待を裏切るためにも、SIer 的な作品を応募して、新しい参加の形を開拓してみようかなと、ひそかに計画するのでありました。見せ付けてやらんといけんですよ。みなさん。そのときになりましたら、また声をかけあって作品を開発しましょう。

iGoogle サンドボックスは、ガジェットのソースコードによって環境を切り替えることで互換性を保っている!?



iGoogle サンドボックスは、ガジェットのソースコードの内容から、旧仕様のガジェットか、新仕様のガジェットかを判別して、それぞれ異なる環境で動作させるようです。

次のガジェットを iGoogle サンドボックスに追加しても、gadgets.util.* といった Gadgets API が取り込まれません。ガジェットをレンダリングする iframe の中身を確認すると、旧仕様のガジェット(現在の iGoogle)と同じ環境に見えます。

<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="gadgets.util.registerOnLoadHandler">
</ModulePrefs>
<Content type="html"><![CDATA[
<script type="text/javascript">
_IG_RegisterOnloadHandler(function() {});
</script>
]]></Content>
</Module>

しかし、次のガジェットを iGoogle サンドボックスに追加すると、状況が一変し、gadgets.util.* といった Gadgets API が取り込まれます。ガジェットをレンダリングする iframe の中身を確認すると、新仕様のガジェット(Opensocial 系コンテナ)に近い環境になっているように見えます。

<?xml version="1.0" encoding="UTF-8"?>
<Module>
<ModulePrefs title="gadgets.util.registerOnLoadHandler">
</ModulePrefs>
<Content type="html"><![CDATA[
<script type="text/javascript">
gadgets.util.registerOnLoadHandler(function() {});
</script>
]]></Content>
</Module>

旧仕様と新仕様の切り替わる接点を調べてみましたが、Content 要素の内容が影響していました。次のとおり、Gadgets API を部分的 "gadgets.ut" に含めると、新仕様の環境に切り替わります。

<Content type="html"><![CDATA[
<script type="text/javascript">
//gadgets.ut
</script>

しかし、次のとおり、"gadgets.u" とすると、旧仕様の環境に切り替わります。

<Content type="html"><![CDATA[
<script type="text/javascript">
//gadgets.u
</script>

開発上の都合から、ガジェットのソースコードをすべて外部ファイルに追い出そうと試みたのですが、なぜか iGoogle サンドボックスだけ動作しなかったため、この事象に気がつきました。

iGoogle サンドボックスで Gadgets API を使うときは、Content 要素に Gadgets API を使ってるぞと判別できるような断片を含めておく必要があるみたいです。iGoogle は1つの環境で、新旧の互換性を確保するに至っていないということでしょうかね!?