Ruby on Rails の youRoom と Apache Shindg を連動させる

先日のブログに続きまして、youRoom Extension(Apps)の実装についてです。youRoom Extensionとは、次世代youRoom APIで、youRoom上でOpenSocialガジェットを動かして拡張できるようにするという想定です。詳しくは、前回のブログを。
http://d.hatena.ne.jp/mat_aki/20101129/1291026469

まずは、Ruby on RailsのyouRoom本体とApache Shindigを連携させるところからです。javaPHPShindigのどちらを使うか検討したのですが、Apacheだけで簡単に動かせるPHP版を利用しようと思っています。RailsがすでにApacheで動作しているので、運用も楽にできるだろうという観点からです。

まずは、Shindig本体をCheckoutします。もちろん SVN の Trank から。

svn co http://svn.apache.org/repos/asf/shindig/trunk/

と。。。構築方法よりもメインの連動方法をしっかり書きたいので、以下のブログとメモを参考にとだけ書いておきます。
http://gurimusan.blog93.fc2.com/blog-entry-75.html
http://shindig.apache.org/developers/php/build.html

MacMacportsを利用して構築メモ

sudo port -v install php5 +apache2 +pear +universal

sudo /opt/local/apache2/bin/apxs -a -e -n "php5" /opt/local/apache2/modules/libphp5.so

sudo port install php5-curl +universal
sudo port install php5-gd +universal
sudo port install php5-mcrypt +universal
sudo port install php5-mysql +universal
sudo port install php5-openssl +universal

sudo cp -p /opt/local/etc/php5/php.ini-development /opt/local/etc/php5/php.ini

Apacheの設定を行って、以下のURLにアクセスして動作確認。これが動作していればShindigのセットアップは完了です。
http://localhost/gadgets/ifr?url=http://www.labpixies.com/campaigns/todo/todo.xml

連動の1stステップはyouRoom内でガジェットを表示することを目標としてみます。

いろいろドキュメントを見てみたのですが、最初はほとんど的確なドキュメントが見つかりませんでした。はじめは、どこを探したら良いのかが本当に分からないのです。。。コンテナの情報すくない。。。

なので参考になったものをまずは紹介します。

shindigWiki https://cwiki.apache.org/confluence/display/SHINDIG/Display+a+gadget+in+a+web+page
shindigのサンプル #{svn co した shindig}/content/container/sample*.html

iFrameで表示する方法とjavascriptAPIから表示する方法の2通りがあるみたいなんですが、Shindigのサンプルはjavascriptでやっていたのでそちらで実装することにしました。

youRoom(コンテナ)側でやらないといけないことは3つ

です。上から見ていきましょう。

まずは、Shindigのコンテナ用のjavascriptをyouRoom側で表示するときに読み込まないといけません。

http://shindig-host/gadgets/js/core:rpc:pubsub:shindig-container.js?c=1&debug=1

というjsを読み込みましょう。":"で繋がっている部分で利用するライブラリを選択できるようです。Shindigで結合・圧縮してjavascriptを返してくれます。debugパラメータを付けると圧縮しないようになります。上のURLはおそらく全部のせ。

実際のyouRoom側の実装は、こんな感じ。

= javascript_include_tag gadget_server_url("/gadgets/js/core:rpc:pubsub:shindig-container.js?c=1&debug=1")

ヘルパーメソッドとして、ShindigサーバのURLをこのように返すメソッドを定義しています。

  def gadget_server_url(path)
    "http://ext.youroom.local:3333" + path
  end

次に、javascriptでガジェットをレンダリングします。変数があるのでRailsのViewで記述しています。

var gadget = shindig.container.createGadget({specUrl: "#{xml_url}"});
gadget.setServerBase('#{gadget_server_url("/gadgets/")}');
shindig.container.addGadget(gadget);
shindig.container.layoutManager.setGadgetChromeIds(['gadgets-gadget-chrome-#{gadget_mod_id}']);
shindig.container.renderGadget(gadget);

1行目でOpenSocialガジェットのURLを渡してガジェットオブジェクトを生成します。2行目でShindigサーバのURLを指定しています。3行目でガジェットを操作するコンテナオブジェクトに登録し、4行目でどの場所に配置するのかをlayoutManagerというクラスを利用して設定しています。引数はガジェットを配置するDIVのidを配列で渡します。最後に5行目でレンダリングしています。この一連の処理を行うことでjavascriptからガジェットがレンダリングできます。

最後に、metadataのAPIを定義します。このmetadataですが、実はまだちょっと分かっていません。ユーザの情報などを返すべきなのですが一旦はSampleのデータを参考にモックで実装したところ動いています。URLは "/gadgets/metadata" で、jsonでデータを返すという仕様のようです。以下、routesの定義部分とmetadataのアクションのモック部分です。

api.gadget_metadata "/gadgets/metadata", :controller => "gadgets", :action => "metadata", :conditions => { :method => :post }
  def metadata
    # FIXME: mock
    render :text => '{"gadgets":[{"iframeUrl":"http:\/\/ext.youroom.local:3333\/gadgets\/ifr?container=default&v=ba5a1d09f63dbf63ee3efa2a04bcccbf&lang=default&country=default&view=&url=http%3A%2F%2Fext.youroom.local%3A3333%2Fsamplecontainer%2Fexamples%2FSocialHelloWorld.xml","features":["globals","core.config","core.util","shindig.auth","core.json","core.io","core.log","core.prefs","core.legacy","core","core.none","rpc","locked-domain","auth-refresh","security-token","osapi","settitle","dynamic-height.util","dynamic-height"],"links":[],"icons":null,"views":{"":{"view":"","type":"HTML","href":"","preferedHeight":"","preferedWidth":"","quirks":"","authz":"","oauthServiceName":"","oauthTokenName":"","oauthRequestToken":"","oauthRequestTokenSecret":"","signOwner":"","signViewer":"","refreshInterval":"","dataPipelining":[]}},"author":"","authorEmail":"","description":"The Social Hello World Application Displays multilingual hello messages","directoryTitle":"","screenshot":"","thumbnail":"http:\/\/localhost:8080\/","title":"Social Hello World","titleUrl":"","authorAffiliation":"","authorLocation":"","authorPhoto":"","authorAboutme":"","authorQuote":"","authorLink":"","showInDirectory":"","showStats":"","width":"","height":"","categories":["",""],"singleton":"","scaling":"","scrolling":"","moduleId":1,"url":"http:\/\/ext.youroom.local:3333\/samplecontainer\/examples\/SocialHelloWorld.xml","userPrefs":[],"oauth":[]}]}'
+  end

以上、3つを行うとガジェットがyouRoom上で動作することが確認できました。以下は cacoo opensocial gadget をyouRoom内に表示したところです。

いい感じに動作しています。このGadgetはOAuthやSocial APIなどを利用していないため、現在の実装でもうまく動作するようです。ここまでで1stステップの目標としていたガジェットをyouRoom内に表示するができました!
次回は、トピックの投稿時にガジェットのデータを一緒に保存することを目標にやってみます。