:ls
とかでどうでしょう?
.
メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。
RSSやFEEDなんかもhttp://code.google.com/intl/ja/apis/gadgets/docs/remote-content.html#Fetch_Feed
にあるとおり、gadgetsの機能で扱えるらしい。
ということで、早速やってみた。
GadgetXMLは上記リンクにあるとおりで、"http://atkonn.blogspot.com/feeds/posts/default
を取得してみた。
・・・すげー。
できてるし。
そんだけ。
.
投稿者 atkonn 時刻: 23:17:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
gadgets.io.makeRequestというメソッドを使用して、
外部リソースへリクエストを投げるらしい。
まずは、認証タイプはNONEで、textファイルを取得してみる。
ガジェットは
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="makeRequest NONE">
</ModulePrefs>
<Content type="html" view="canvas,profile,view">
<![CDATA[
<div id="content_div" style="height: 100px;"></div>
<script type="text/javascript">
function getHtml() {
var params = {};
/* テキストタイプ */
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
/* www.google.comからとってくる */
var url = "http://localhost/a.txt";
/* リクエスト */
gadgets.io.makeRequest(url, response, params);
};
/**
* コールバック
*/
function response(obj) {
/* obj.textにリクエストの応答が入っている。 */
var html = '';
if (obj.rc != 200) {
html = 'ぼよよん';
}
else {
var str = obj.text;
/* 最初の400文字取得 */
html = str.substr(0,400);
}
document.getElementById('content_div').innerHTML = html;
};
gadgets.util.registerOnLoadHandler(getHtml);
</script>
]]>
</Content>
</Module>
投稿者 atkonn 時刻: 22:44:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
外部との通信の認証には、
gadgets.io.AuthorizationType.OAUTH (コンテナは OAuth プロトコルを使用する)
gadgets.io.AuthorizationType.SIGNED (コンテナが要求に署名する)
gadgets.io.AuthorizationType.NONE
投稿者 atkonn 時刻: 21:43:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
shindigのソースを読む限り、使えそうなcontent-rewriter機能を使ってみる。
shindigのバージョンは1.1-SNAPSHOT。
まず、デフォルトでの機能をオフにする。
デフォルトでは全てのURLで有効になっている模様。
この設定を変更するには、
shindig.properties
をいじる。
デフォルトだと、
shindig.content-rewrite.include-urls=.*
shindig.content-rewrite.exclude-urls=
shindig.content-rewrite.include-tags=link,script,embed,img,style
shindig.content-rewrite.expires=86400
shindig.content-rewrite.proxy-url=/gadgets/proxy?url=
shindig.content-rewrite.concat-url=/gadgets/concat?
shindig.content-rewrite.exclude-urls=
shindig.content-rewrite.exclude-urls=.*
shindig.content-rewrite.expires=86400
shindig.content-rewrite.expires=0
shindig.cache.xml.refreshInterval=300000
shindig.cache.xml.refreshInterval=0
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="content-rewrite">
<Require feature="opensocial-0.8" />
<Optional feature="content-rewrite">
<Param name="expires">86400</Param>
<Param name="include-urls">.*</Param>
<Param name="exclude-urls"></Param>
</Optional>
</ModulePrefs>
<Content type="html" view="canvas,profile,view">
<![CDATA[
<div id="content_div" style="height: 100px;"></div>
<script type="text/javascript">
</script>
どうかな,
どうかな,
どうかな
<img src="http://www.google.co.jp/intl/ja_jp/images/logo.gif" alt="googleだよ" />
]]>
</Content>
</Module>
<Param name="include-urls">.*</Param>
<Param name="exclude-urls"></Param>
<Param name="include-url">.*</Param>
<Param name="exclude-url"></Param>
投稿者 atkonn 時刻: 19:48:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
ガジェットのユーザ毎の設定(UserPref?)をガジェットから扱える機能を追加するもの。
使えるメソッドは、
gadgets.Prefs.set(key, value)
gadgets.Prefs.setArray(key,value)
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="setprefsフィーチャー">
<Require feature="opensocial-0.8" />
<Require feature="setprefs" />
</ModulePrefs>
<UserPref name="counter" default_value="0" datatype="hidden"/>
<Content type="html" view="canvas,profile,view">
<![CDATA[
<div id="content_div" style="height: 100px;"></div>
<script type="text/javascript">
var prefs = null;
var html = "";
var div = '';
function incrementCounter() {
var count = prefs.getInt("counter");
div.innerHTML = "The count is " + count + ".";
prefs.set("counter", count + 1);
}
function resetCounter(){
prefs.set("counter", 0);
div.innerHTML = "Count reset to " + prefs.getInt("counter") + ".";
}
function init() {
prefs = new gadgets.Prefs();
html = "";
div = document.getElementById('content_div');
var count = prefs.getInt("counter");
div.innerHTML = "The count is " + count + ".";
}
gadgets.util.registerOnLoadHandler(init);
</script>
<input type=button value="Count" name="count" onClick="incrementCounter()">
<input type=button value="Reset" name="reset" onClick="resetCounter()">
]]>
</Content>
</Module>
投稿者 atkonn 時刻: 18:18:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
ガジェットのタイトルをプログラムから設定する場合に指定するもの。
使えるメソッドは、
gadgets.window.setTitle(title)
_IG_SetTitle
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="settitleフィーチャー">
<Require feature="settitle"/>
</ModulePrefs>
<Content type="html" view="canvas,profile,home">
<![CDATA[
<script type="text/javascript">
function init() {
gadgets.window.setTitle('ああああ');
}
function changeTitle(form) {
_IG_SetTitle(form.inputbox.value);
}
gadgets.util.registerOnLoadHandler(init);
</script>
<FORM NAME="myform" ACTION="" METHOD="GET"><BR>
<INPUT TYPE="text" NAME="inputbox" VALUE="">
<INPUT TYPE="button" NAME="button" Value="Add" onClick="changeTitle(this.form)">
<INPUT TYPE="button" NAME="button2" Value="Clear" onClick="clearList(this.form)">
</FORM>
<div id="content_div"></div>
]]>
</Content>
</Module>
gadgets.IfrGadgetService.prototype.setTitle = function(title) {
var element = document.getElementById(this.f + '_title');
if (element) {
element.innerHTML = title.replace(/&/g, '&').replace(/</g, '<');
}
};
ガジェットを表示するiframeの名前+'_title'
投稿者 atkonn 時刻: 18:05:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
dynamic-heightフィーチャーを使うことで、ガジェットの高さを動的に変更できる。
使えるメソッドは、
gadgets.window.adjustHeight(opt_height)
gadgets.window.getViewportDimensions()
_IG_AdjustIFrameHeight
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Dynamic Height"
height="100">
<Require feature="dynamic-height"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<script type="text/javascript">
// This example lets users add items to a grocery list and then clear the list.
// When items are added or cleared, the gadget resizes itself.
var mylist = "";
var flag = 0;
// Function that is invoked whenever user clicks the Add button to add an
// item to the list.
function addToList (form) {
var input = _trim(form.inputbox.value);
if (input == "") {
return;
}
// Make alternating lines green/white, depending on value of flag variable.
var d = gadgets.window.getViewportDimensions();
if(flag == 0){
mylist += "<div style='padding-left: 5px;background-color: #E6FFE6; font-family:Arial, Helvetica;'>" +input + " width:" + d.width + " height:" + d.height + "</div>";
flag = 1;
}
else {
mylist += "<div style='padding-left: 5px;font-family:Arial, Helvetica;'>" +input + " width:" + d.width + " height:" + d.height + "</div>";
flag = 0;
}
// Call setContent to output HTML to div and resize gadget
setContent(mylist);
}
// Clear the list
function clearList(form) {
// Call setContent to remove all items from the list and resize the gadget
setContent("");
}
// Outputs content to the div and resizes the gadget
function setContent(html) {
document.getElementById('content_div').innerHTML = html;
// Tells gadget to resize itself
gadgets.window.adjustHeight();
}
gadgets.util.registerOnLoadHandler(_IG_AdjustIFrameHeight);
</script>
<FORM NAME="myform" ACTION="" METHOD="GET"><BR>
<INPUT TYPE="text" NAME="inputbox" VALUE="">
<INPUT TYPE="button" NAME="button" Value="Add" onClick="addToList(this.form)">
<INPUT TYPE="button" NAME="button2" Value="Clear" onClick="clearList(this.form)">
</FORM>
<div id="content_div"></div>
]]>
</Content>
</Module>
投稿者 atkonn 時刻: 16:26:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
ガジェットにviewを切り替える機能を追加できるらしい。
ふーん。
ということで、やってみる。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="viewsフィーチャー" >
<Require feature="views" />
</ModulePrefs>
<Content type="html">
<![CDATA[
サポートされているビュー:<div id="supported_view"></div>
現在のビュー:<div id="current_view"></div>
<script type="text/javascript">
var views = gadgets.views.getSupportedViews();
var ul = document.createElement('ul');
for (var xx in views) {
var li = document.createElement('li');
var a = document.createElement('a');
a.href = 'javascript:void(0);';
a.innerHTML = '名前:' + xx + '<br />'
+ 'タイプ:' + views[xx].getName() + '<br /><hr />';
function setView(a, view) {
a.onclick = function(){gadgets.views.requestNavigateTo(view);};
}
setView(a, views[xx]);
li.appendChild(a);
ul.appendChild(li);
}
document.getElementById('supported_view').appendChild(ul);
var current = gadgets.views.getCurrentView();
document.getElementById('current_view').innerHTML = current.getName();
</script>
<br />
]]>
</Content>
</Module>
投稿者 atkonn 時刻: 12:07:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
flashのswfを実行できるflashフィーチャーというものがある。
面倒なので、Googleに張ってあったgadgetのサンプルをそのまま実行してみた。
あらら。
Shindigデフォルトでちゃんと動くっぽい。
すばらしいねー。
そんだけ。
投稿者 atkonn 時刻: 12:05:00 0 コメント
ラベル: Apache Shindig, OpenSocial, お勉強
gadgets APIのひとつにminimessageというフィーチャーがあるけど、
minimessageフィーチャーってなんだろね。
コメントによると、
メッセージをガジェットに表示する際に使用できるもの
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="minimessageフィーチャー">
<Require feature="minimessage" />
</ModulePrefs>
<UserPref name="selectedTab" value="0" />
<Content type="html" view="home,profile,canvas">
<![CDATA[
<script type="text/javascript">
var msgObj = null;
function getInstance() {
if (msgObj) {
return msgObj;
}
return new gadgets.MiniMessage();
}
function init() {
var msg = getInstance();
msg.createDismissibleMessage("ぼよよーん");
}
function onclick() {
var msg = getInstance();
msg.createDismissibleMessage("ぶよよーん");
}
gadgets.util.registerOnLoadHandler(init);
</script>
<input type="button" value="ボタンだよ" onclick="onclick();" />
]]>
</Content>
</Module>
投稿者 atkonn 時刻: 11:43:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
Shindigのgadgets.tabsでは、選択したタブをUserPrefsに自動保存する、
という機能が効かないみたい。
(コードにそのような記述はない。)
Google gadgets APIでは、
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="tabsフィーチャー">
<Require feature="setprefs" />
<Require feature="tabs" />
</ModulePrefs>
<UserPref name="selectedTab" value="0" />
<Content type="html" view="home,profile,canvas">
--- tabs.js.old 2009-07-30 23:48:32.000000000 +0900
+++ tabs.js 2009-07-31 09:28:01.000000000 +0900
@@ -171,6 +171,9 @@
'text-decoration: none;',
'}'
].join(''));
+ if (gadgets.util.hasFeature('setprefs')) {
+ this.prefs = new gadgets.Prefs();
+ }
};
/**
@@ -230,6 +233,12 @@
if (tabName == this.defaultTabName_ || (!this.defaultTabName_ && tabIndex === 0)) {
this.selectTab_(tab);
}
+ if (this.prefs) {
+ var selectedTab = this.prefs.getString("selectedTab");
+ if (selectedTab === tabName) {
+ this.selectTab_(tab);
+ }
+ }
this.tabsAdded_++;
this.displayTabs(true);
@@ -602,7 +611,13 @@
* @return {Function} Callback function to select the tab.
*/
gadgets.TabSet.prototype.setSelectedTabGenerator_ = function(tab) {
- return function() { tab.handle_.selectTab_(tab); };
+ var self = this;
+ return function() {
+ if (self.prefs) {
+ self.prefs.set("selectedTab", tab.getName());
+ }
+ tab.handle_.selectTab_(tab);
+ };
};
/**
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
どうも、Googleのgadgets APIとOpenSocialのgadgets APIは
とても似ているけど、別ものらしい。。
Google gadgets APIの内容とShindigのgadgets APIが微妙に違う。
おかしいなぁと思っていたら、OpenSocialのgadgets APIはgadgets APIの「拡張」と
書いてあった。
要は別もの。
なるほどねー。
.
ラベル: Apache Shindig, OpenSocial, お勉強
リファレンス見ればわかるんだけど、一応出力。
tabの削除をしてみた。
使用するのはこれ。
gadgets.TabSet.prototype.removeTab = function(tabIndex) {
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="tabsフィーチャー">
<Require feature="opensocial-0.8" />
<Require feature="tabs" />
<Require feature="setprefs" />
<Require feature="jquery" />
</ModulePrefs>
<Content type="html" view="home,profile,canvas">
<![CDATA[
<script type="text/javascript">
var tabdayon = function() {
this.tabs = null;
this.tabDivId = {};
};
tabdayon.prototype.init = function() {
this.tabs = new gadgets.TabSet(__MODULE_ID__, "タブセットだよーん");
var oneId = this.tabs.addTab("One");
this.tabDivId = {};
this.tabDivId[oneId] = oneId;
var twoId = this.tabs.addTab("Two");
this.tabDivId[twoId] = twoId;
document.getElementById(oneId).innerHTML = "最初のタブのコンテンツだよ";
document.getElementById(twoId).innerHTML = "2番目のタブのコンテンツだよ";
};
/**
* タブの追加
*/
tabdayon.prototype.addTab = function(ev) {
var tabName = $('.tabName').val();
$('.tabName').val('');
var divId = this.tabs.addTab(tabName);
this.tabDivId[divId] = divId;
document.getElementById(divId).innerHTML = tabName + 'を追加したよ';
};
tabdayon.prototype.removeTab = function() {
var tab = this.tabs.getSelectedTab();
var cont = tab.getContentContainer();
this.tabs.removeTab(tab.getIndex());
this.tabDivId[cont.id] = null;
};
var tabInstance = null;
function init() {
tabInstance = new tabdayon();
tabInstance.init();
$('.addTab').click(function(ev) {tabInstance.addTab(ev);});
$('.removeTab').click(function(ev) {tabInstance.removeTab();});
}
gadgets.util.registerOnLoadHandler(init);
</script>
<form>
<input type="text" class="tabName" value="">
</form>
<a href="#" class='addTab'>タブ追加だよ</a>
<a href="#" class='removeTab'>タブ削除だよ</a>
<div id="result"></div>
]]>
</Content>
</Module>
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
フィーチャーのtabsを見ていく。
ソースは、
features/tabs/tabs.js
ガジェットにタブ付きのユーザー インターフェースを追加できます。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="tabsフィーチャー">
<Require feature="opensocial-0.8" />
<Require feature="tabs" />
<Require feature="setprefs" />
<Require feature="jquery" />
</ModulePrefs>
<Content type="html" view="home,profile,canvas">
<![CDATA[
<script type="text/javascript">
var tabdayon = function() {
this.tabs = null;
this.tabDivId = {};
};
tabdayon.prototype.init = function() {
this.tabs = new gadgets.TabSet(__MODULE_ID__, "タブセットだよーん");
var oneId = this.tabs.addTab("One");
this.tabDivId = {};
this.tabDivId[oneId] = oneId;
var twoId = this.tabs.addTab("Two");
this.tabDivId[twoId] = twoId;
document.getElementById(oneId).innerHTML = "最初のタブのコンテンツだよ";
document.getElementById(twoId).innerHTML = "2番目のタブのコンテンツだよ";
};
/**
* タブの追加
*/
tabdayon.prototype.addTab = function(ev) {
var tabName = $('.tabName').val();
$('.tabName').val('');
var divId = this.tabs.addTab(tabName);
this.tabDivId[divId] = divId;
document.getElementById(divId).innerHTML = tabName + 'を追加したよ';
};
var tabInstance = null;
function init() {
tabInstance = new tabdayon();
tabInstance.init();
$('.addTab').click(function(ev) {tabInstance.addTab(ev);});
}
gadgets.util.registerOnLoadHandler(init);
</script>
<form>
<input type="text" class="tabName" value="">
</form>
<a href="#" class='addTab'>タブ追加だよ</a>
<div id="result"></div>
]]>
</Content>
</Module>
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
たぶんこれでサーバ側ひととおり触った、ような気がする。
次はgadgets APIを見ていく。
とにかくJavaScriptにはまった。。
.
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
opensocial.requestShareAppをサーバ側まで含めて動かしてみる。
方針は、
1) requestShareAppがコールされると、ダイアログを表示する。
2) ダイアログには友達一覧が表示され、requestShareApp先を選択できる。
3) ダイアログで「送信」ボタンを押下すると、messages.modifyがサーバ側へ発行される。
4) サーバ側はmessageサービスのmodifyメソッドにて処理する。
5) DBに保存。
といった感じ。
requestSendMessageと分けるために、msgCollIdにrequestShareAppから来たデータで
あることが分かるような値をセットする。
まずは
features/opensocial-jsonrpc/jsonrpccontainer.jsで、ガジェットと同じフレームで
実行されるrequestShareAppを定義。(前やったけどやりなおし。)
JsonRpcContainer.prototype.requestShareApp = function(recipientIds, reason,
opt_callback, opt_params) {
var callbackId = "cId_" + Math.random();
var self = this;
var callback = function(success, recip, title, body) {
var req = opensocial.newDataRequest();
var viewer = new opensocial.IdSpec({'userId' : 'VIEWER'});
var rpc = { method : "messages.modify" };
rpc.params = self.translateIdSpec(viewer);
rpc.params.appId = "@app";
FieldTranslations.translateNetworkDistance(viewer, rpc.params);
rpc.params.msgCollId = 'shareApp';
rpc.params.entity = {};
rpc.params.entity["title"] = title;
rpc.params.entity["body"] = body;
rpc.params.entity["recipients"] = recip
var shareAppRequest = new JsonRpcRequestItem(rpc);
req.add(shareAppRequest, 'key');
req.send(function(response) {
opt_callback(response.get('key'));
});
};
callbackIdStore[callbackId] = callback;
var body = gadgets.util.unescapeString(reason.getField(
opensocial.Message.Field.BODY));
if (!body || body.length === 0) {
var bodyMsgKey = gadgets.util.unescapeString(reason.getField(
opensocial.Message.Field.BODY_ID));
body = gadgets.Prefs.getMsg(bodyMsgKey);
}
/* 修正ここから */
/* 友達一覧を取得する */
var friendsArray = [];
var handleGetFriends = function(data) {
var friends = data.get("get_friends");
if (friends.hadError()) {
return;
}
var data = friends.getData();
data.each(function(friend) {
var tmp = {};
tmp.thumbnailUrl = friend.getField(opensocial.Person.Field.THUMBNAIL_URL);
tmp.nickname = friend.getField(opensocial.Person.Field.NICKNAME );
tmp.id = friend.getField(opensocial.Person.Field.ID );
friendsArray.push(tmp);
});
gadgets.rpc.call('..', 'shindig.requestShareApp',
null,
callbackId,
friendsArray,
body);
};
var getfriends = function() {
var params = {};
params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [
opensocial.Person.Field.ID,
opensocial.Person.Field.NICKNAME,
opensocial.Person.Field.THUMBNAIL_URL,
opensocial.Person.Field.PROFILE_URL
];
var req = opensocial.newDataRequest();
var idSpecParam = {};
idSpecParam[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER;
idSpecParam[opensocial.IdSpec.Field.GROUP_ID] = opensocial.IdSpec.GroupId.FRIENDS;
var idSpec = opensocial.newIdSpec(idSpecParam);
req.add(req.newFetchPeopleRequest(idSpec, params), "get_friends");
req.send(handleGetFriends);
};
getfriends();
};
gadgets.IfrGadgetService.prototype.requestShareApp = function(rpc, callbackId, friends, body) {
if (!gadgets.container.gadgetService.shareAppDialog_) {
return;
}
var title = gadgets.container.getGadget(this.getGadgetIdFromModuleId(rpc.f))
.title + 'はお勧めだよ!';
var shareAppDialog = gadgets.container.gadgetService.shareAppDialog_;
var onSubmit = function() {
var friendsIds = this.getData().shareAppDialog_friendsId;
var recipients = [];
if (typeof friendsIds === 'boolean') {
if (friendsIds) {
recipients = [friends[0].id];
}
}
else {
var len = friendsIds.length;
for (var ii=0; ii<len; ii++) {
if (friendsIds[ii]) {
recipients.push(friends[ii].id);
}
}
}
if (callbackId) {
window.setTimeout(function() {
gadgets.rpc.call(rpc.f,
'shindig.requestShareApp_callback',
null,
callbackId,
true,
recipients,
title,
body);
}, 0);
}
this.cancel();
};
var onCancel = function() {
if (callbackId) {
window.setTimeout(function() {
gadgets.rpc.call(rpc.f,
'shindig.requestShareApp_callback',
null,
callbackId,
false,
[],
title,
body);
}, 0);
}
this.cancel();
};
document.getElementById('shareAppDialog_title').innerHTML = title;
document.getElementById('shareAppDialog_body').innerHTML = body;
var ul = document.createElement('ul');
var fc = 0;
document.getElementById('shareAppDialog_friends').innerHTML = '';
for (xx in friends) {
var li = document.createElement('li');
li.innerHTML = ''
+ ''
+ '';
ul.appendChild(li);
fc++;
}
if (fc == 0) {
document.getElementById('shareAppDialog_friends').innerHTML = 'ひとりぼっちだよ';
}
else {
document.getElementById('shareAppDialog_friends').appendChild(ul);
}
shareAppDialog.setHeader('確認');
shareAppDialog.cfg.queueProperty("icon",YAHOO.widget.SimpleDialog.ICON_WARN);
shareAppDialog.cfg.queueProperty("buttons", [
{text: "送信", handler: onSubmit, isDefault: true},
{text: "キャンセル", handler: onCancel}
]);
shareAppDialog.registerForm();
shareAppDialog.render();
shareAppDialog.show();
};
JsonRpcContainer.requestShareAppCallback_ = function(callbackId,
success, recipientIds, title, body) {
callback = callbackIdStore[callbackId];
if (callback && success) {
callbackIdStore[callbackId] = null;
callback(success, recipientIds, title, body);
}
};
投稿者 atkonn 時刻: 23:38:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
なんだかshindig-1.1-SNAPSHOTだと動かないっぽいので、
動かす。
まず、jsonrpccontainer.jsを見てみる。
JsonRpcContainer.prototype.requestShareApp = function(recipientIds, reason,
opt_callback, opt_params) {
var callbackId = "cId_" + Math.random();
callbackIdStore[callbackId] = opt_callback;
var body = gadgets.util.unescapeString(reason.getField(
opensocial.Message.Field.BODY));
if (!body || body.length === 0) {
var bodyMsgKey = gadgets.util.unescapeString(reason.getField(
opensocial.Message.Field.BODY_ID));
body = gadgets.Prefs.getMsg(bodyMsgKey);
}
gadgets.rpc.call('..', 'shindig.requestShareApp',
null,
callbackId,
recipientIds,
body);
};
gadgets.IfrGadgetService = function() {
var self = this;
gadgets.GadgetService.call(this);
gadgets.rpc.register('resize_iframe', this.setHeight);
gadgets.rpc.register('set_pref', this.setUserPref);
gadgets.rpc.register('set_title', this.setTitle);
gadgets.rpc.register('requestNavigateTo', this.requestNavigateTo);
};
gadgets.rpc.call('..', 'shindig.requestShareApp',
null,
callbackId,
recipientIds,
body);
gadgets.rpc.register('shindig.requestShareApp', function(callbackId,recipientIds,body) {
self.requestShareApp.apply(self,[this, callbackId, recipientIds, body]);
});
gadgets.IfrGadgetService.prototype.shareAppDialog_ = null;
gadgets.IfrGadgetService.prototype.setShareAppDialog = function(dialog) {
gadgets.container.gadgetService.shareAppDialog_ = dialog;
};
gadgets.IfrGadgetService.prototype.requestShareApp = function(rpc, callbackId, recipients, body) {
if (gadgets.container.gadgetService.shareAppDialog_) {
/* 以下YUI前提 */
var onSubmit = function() {
if (callbackId) {
window.setTimeout(function() {
gadgets.rpc.call(rpc.f, 'shindig.requestShareApp_callback', null, callbackId, true, recipients, body);
}, 0);
}
this.cancel();
};
var onCancel = function() {
if (callbackId) {
window.setTimeout(function() {
gadgets.rpc.call(rpc.f, 'shindig.requestShareApp_callback', null, callbackId, false, recipients, body);
}, 0);
}
this.cancel();
};
gadgets.container.gadgetService.shareAppDialog_.cfg.queueProperty("buttons", [
{text: "送信", handler: onSubmit, isDefault: true},
{text: "キャンセル", handler: onCancel}
]);
document.getElementById('shareAppDialog_body').innerHTML = body;
gadgets.container.gadgetService.shareAppDialog_.render();
gadgets.container.gadgetService.shareAppDialog_.show();
}
else {
if (callbackId) {
window.setTimeout(function() {
gadgets.rpc.call(rpc.f, 'shindig.requestShareApp_callback', null, callbackId, true, recipients, body);
}, 0);
}
}
};
JsonRpcContainer.requestShareAppCallback_ = function(callbackId,
success, recipientIds, body) {
callback = callbackIdStore[callbackId];
if (callback) {
callbackIdStore[callbackId] = null;
var data = null;
if (recipientIds) {
data = {'recipientIds': recipientIds};
}
var responseItem = new opensocial.ResponseItem(null, data, opensocial.ResponseItem.Error.BAD_REQUEST);
callback(responseItem);
}
};
投稿者 atkonn 時刻: 15:11:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
opensocial.requestShareAppを使ってみる。
とりあえずガジェットXML。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="opensocial.requestShareApp">
<Require feature="opensocial-0.8" />
</ModulePrefs>
<Content type="html" view="home,profile,canvas">
<![CDATA[
<script type="text/javascript">
function shareApp() {
opensocial.requestShareApp(
"VIEWER_FRIENDS",
opensocial.newMessage("ぼよよーん"),
call_back);
}
function call_back(status) {
if (status.hadError()) {
document.getElementById('result').innerHTML = '失敗したよ:' + status.getErrorCode();
} else {
document.getElementById('result').innerHTML = '送ったよ';
}
}
</script>
<div id="result"></div>
<input type="button" value="このガジェットを友達と共有する" onclick="shareApp();" /><br />
]]>
</Content>
</Module>
Unknown RPC service: shindig.requestShareApp
投稿者 atkonn 時刻: 15:00:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
goo Developer's キッチンによると、
opensocial.requestShareAppを使うことで、ビューアーが友達にガジェットを教えることができます。
指定したユーザーとこのガジェットを共有するようにコンテナに要求します。
投稿者 atkonn 時刻: 14:12:00 0 コメント
ラベル: Apache Shindig, OpenSocial, お勉強
とりあえず、サーバ側の実装してみた。
requestSendMessage時に発行するmethodはmessages.modifyにした。
で対応するサービスは、MessageServiceのcreateMessage。
messages.modifyがクライアントから飛んでくると、必ずcreateMessageが呼ばれる、
のではなく、msgCollIdなるパラメータに何かしらの値が入っているとき、
のみらしい。
msgCollIdというのは、どうもMessageを束ねるもののIDらしい。よくわかんないけど。
とりあえず使わないので考えない。
クライアントからはダミーのmsgCollIdを送付するようにして、messages.modifyのときは
必ずcreateMessageが呼ばれるようにした。
で、以下createMessageの実装。
public Future<Void> createMessage(UserId userId, String appId, String msgCollId, Message message,
SecurityToken token) throws ProtocolException {
logic.createMessage(userId, appId, msgCollId, message, token);
return ImmediateFuture.newInstance(null);
}
public void createMessage(UserId userId, String appId, String msgCollId, Message message,
SecurityToken token) throws ProtocolException {
logger.info("メッセージ生成開始:");
String viewerId = token.getViewerId();
String ownerId = token.getOwnerId();
GmsPerson viewer = null;
try {
if (StringUtils.hasText(viewerId)) {
viewer = gmsPersonDao.selectByLoginId(viewerId);
}
}
catch (ObjectRetrievalFailureException ex) {
}
if (viewer == null) {
if (logger.isDebugEnabled()) {
logger.debug("Guestは送信できない:");
}
throw new ProtocolException(HttpServletResponse.SC_FORBIDDEN,
"Guestのため、送信できない");
}
if (! isInstalledGadget(viewer, token.getModuleId())) {
if (logger.isDebugEnabled()) {
logger.debug("ガジェット未インストール:"
+ "viewerId:[" + viewer.getLoginId() + "]:"
+ "ガジェットID:[" + token.getModuleId() + "]"
);
}
throw new ProtocolException(HttpServletResponse.SC_FORBIDDEN,
"未インストールのため、送信できない:loginid:[" + viewer.getLoginId() + "]");
}
GmsPerson owner = gmsPersonDao.selectByLoginId(ownerId);
String fromLoginId = userId.getUserId(token);
GmsPerson fromUser = gmsPersonDao.selectByLoginId(fromLoginId);
for (String recip: message.getRecipients()) {
GmsMessage gmsMessage = new GmsMessage();
gmsMessage.setId(UuidGenerator.compress(UuidGenerator.generate()));
gmsMessage.setFromPersonId(fromUser.getId());
UserId toUserId = new UserId(UserId.Type.jsonValueOf(recip), recip);
String recipLoginId = toUserId.getUserId(token);
GmsPerson recipPerson = gmsPersonDao.selectByLoginId(recipLoginId);
gmsMessage.setToPersonId(recipPerson.getId());
if (StringUtils.hasText(message.getBody())) {
gmsMessage.setBody(message.getBody());
}
else {
gmsMessage.setBody("");
}
gmsMessage.setBodyId("");
if (StringUtils.hasText(message.getTitle())) {
gmsMessage.setTitle(message.getTitle());
}
else {
gmsMessage.setTitle("");
}
gmsMessage.setTitleId("");
gmsMessage.setType(message.getType().toString());
gmsMessage.setCreatedAt(new Timestamp(System.currentTimeMillis()));
gmsMessageDao.insert(gmsMessage);
}
logger.info("メッセージ生成終了:");
}
投稿者 atkonn 時刻: 13:56:00 0 コメント
ラベル: Apache Shindig, java, OpenSocial, shindig, お勉強
requestSendMessageに対応するサービスはmessages.createかと思いきや、
そうとは限らないっぽい。
OpenSocialでは特に規定が無いので、
実装しやすそうな
messages.modify
を使用しようかと。
で、その際のjsonrpccontainer.jsのrequestSendMessageの今のところの実装。
JsonRpcContainer.prototype.requestSendMessage = function(recipientIds, message, opt_callback, opt_params) {
opt_callback = opt_callback || function(){};
opt_params = opt_params || {}; /* 使わないよ */
var body = gadgets.util.unescapeString(message.getField(
opensocial.Message.Field.BODY));
var title = gadgets.util.unescapeString(message.getField(
opensocial.Message.Field.TITLE));
var type = gadgets.util.unescapeString(message.getField(
opensocial.Message.Field.TYPE));
if (!body || body.length === 0) {
var bodyMsgKey = gadgets.util.unescapeString(message.getField(
opensocial.Message.Field.BODY_ID));
body = gadgets.Prefs.getMsg(bodyMsgKey);
}
if (!title || title.length === 0) {
var titleMsgKey = gadgets.util.unescapeString(message.getField(
opensocial.Message.Field.TITLE_ID));
title = gadgets.Prefs.getMsg(titleMsgKey);
}
var self = this;
var callback = function() {
var req = opensocial.newDataRequest();
var viewer = new opensocial.IdSpec({'userId' : 'VIEWER'});
var rpc = { method : "messages.modify" };
rpc.params = self.translateIdSpec(viewer);
rpc.params.appId = "@app";
FieldTranslations.translateNetworkDistance(viewer, rpc.params);
rpc.params.msgCollId = "dummyMsgCollId";
rpc.params.entity = {};
rpc.params.entity["title"] = title;
rpc.params.entity["body"] = body;
rpc.params.entity["type"] = type;
rpc.params.entity["recipients"] = self.translateIdSpec(self.makeIdSpec(recipientIds))["userId"];
var messageRequest = new JsonRpcRequestItem(rpc);
req.add(messageRequest, 'key');
req.send(function(response) {
opt_callback(response.get('key'));
});
};
var callbackId = "cId_" + Math.random();
callbackIdStore[callbackId] = callback;
gadgets.rpc.call(null, 'requestSendMessage',
null,
callbackId,
recipientIds,
title,
body);
};
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
JSON-RPCで使用するmessagesサービスのmethod一覧。
* messages.delete
* messages.get
* messages.modify
* messages.create
ソースから抽出。
ドキュメントは見てない。
--
messages系はOpenSocialの仕様じゃないっぽい。
.
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
opensocial.requestSendMessageの実装をしてみる。
とりあえず、JavaScript。
方針
ざっと実装方針。
GadgetXML内でrequestSendMessageがコールされると、
ダイアログが出て、送信していいか確認する。
確認後、message.postmessages.createを発行する。
ってな感じ。
ダイアログはYUIをしてみる。
ガジェットXML
ガジェットXMLはこんな感じ。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="opensocial.Message">
<Require feature="opensocial-0.8" />
</ModulePrefs>
<Content type="html" view="home,profile,canvas">
<![CDATA[
<script type="text/javascript">
function sendMessage() {
var opt_params = [];
opt_params[opensocial.Message.Field.TITLE] = 'タイトルだよーん';
opt_params[opensocial.Message.Field.TYPE] = opensocial.Message.Type.PRIVATE_MESSAGE;
var body = 'テストメッセージだよーん';
var msg = opensocial.newMessage(body, opt_params);
opensocial.requestSendMessage(opensocial.IdSpec.PersonId.OWNER, msg, call_back);
}
function call_back(status) {
if (status.hadError()) {
document.getElementById('result').innerHTML = '失敗したよ:' + status.getErrorCode();
} else {
document.getElementById('result').innerHTML = '送ったよ';
}
}
</script>
<div id="result"></div>
<input type="button" value="メッセージ送信" onclick="sendMessage();" /><br />
]]>
</Content>
</Module>
JsonRpcContainer.prototype.requestSendMessage = function(recipientIds, message, opt_callback, opt_params) {
opt_callback = opt_callback || function(){};
opt_params = opt_params || {}; /* 使わないよ */
var body = gadgets.util.unescapeString(message.getField(
opensocial.Message.Field.BODY));
var title = gadgets.util.unescapeString(message.getField(
opensocial.Message.Field.TITLE));
if (!body || body.length === 0) {
var bodyMsgKey = gadgets.util.unescapeString(message.getField(
opensocial.Message.Field.BODY_ID));
body = gadgets.Prefs.getMsg(bodyMsgKey);
}
if (!title || title.length === 0) {
var titleMsgKey = gadgets.util.unescapeString(message.getField(
opensocial.Message.Field.TITLE_ID));
title = gadgets.Prefs.getMsg(titleMsgKey);
}
var self = this;
var callback = function() {
var req = opensocial.newDataRequest();
var viewer = new opensocial.IdSpec({'userId' : 'VIEWER'});
var rpc = { method : "messages.create" };
rpc.params = self.translateIdSpec(viewer);
rpc.params.appId = "@app";
FieldTranslations.translateNetworkDistance(viewer, rpc.params);
/* ここから、とりあえず版。後でちゃんとする */
rpc.params.message = {};
rpc.params.message["title"] = title;
rpc.params.message["body"] = body;
rpc.params.message["recipients"] = self.translateIdSpec(self.makeIdSpec(recipientIds))["userId"];
/* ここまで、とりあえず版。後でちゃんとする */
var messageRequest = new JsonRpcRequestItem(rpc);
req.add(messageRequest, 'key');
req.send(function(response) {
opt_callback(response.get('key'));
});
};
var callbackId = "cId_" + Math.random();
callbackIdStore[callbackId] = callback;
gadgets.rpc.call(null, 'requestSendMessage',
null,
callbackId,
recipientIds,
title,
body);
};
(function() {
})();
gadgets.IfrGadgetService.prototype.requestSendMessage = function(rpc, callbackId, recipients, title, body) {
if (gadgets.container.gadgetService.sendMessageDialog_) {
/* 以下YUI前提 */
var onSubmit = function() {
if (callbackId) {
window.setTimeout(function() {
gadgets.rpc.call(rpc.f, 'requestSendMessage_callback', null, callbackId, recipients, title, body);
}, 0);
}
this.cancel();
};
var onCancel = function() {
this.cancel();
};
gadgets.container.gadgetService.sendMessageDialog_.cfg.queueProperty("buttons", [
{text: "OK", handler: onSubmit, isDefault: true},
{text: "キャンセル", handler: onCancel}
]);
document.getElementById('sendMessageDialog_title').innerHTML = title;
document.getElementById('sendMessageDialog_body').innerHTML = body;
gadgets.container.gadgetService.sendMessageDialog_.render();
gadgets.container.gadgetService.sendMessageDialog_.show();
}
else {
if (callbackId) {
window.setTimeout(function() {
gadgets.rpc.call(rpc.f, 'requestSendMessage_callback', null, callbackId, recipients, title, body);
}, 0);
}
}
};
gadgets.rpc.call(rpc.f, 'requestSendMessage_callback', null, callbackId, recipients, title, body);
gadgets.rpc.register('requestSendMessage', function(callbackId, recipients, title, body) {
self.requestSendMessage.apply(self, [this, callbackId, recipients, title, body]);
});
JsonRpcContainer.requestSendMessageCallback_ = function(callbackId, recipients, title, body) {
var callback = callbackIdStore[callbackId];
if (callback) {
callbackIdStore[callbackId] = null;
callback();
}
};
org.apache.shindig.protocol.ProtocolException: The method message.post is not implemented
at jp.qsdn.gms.social.protocol.SpringHandlerRegistry.getRpcHandler(SpringHandlerRegistry.java:137)
投稿者 atkonn 時刻: 23:20:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
gadgets.rpcを使って、子フレームから親フレームの関数をコールすることは簡単にできた。
で、親フレームから子フレームの関数をコールしてみたら・・・、
できない!!
でほぼ丸1日費やした・・。
goo ホームのサンドボックス見てみたり、外人さんのページみたり、
ソースのあっちゃこっちゃに
if (window['console'] && window['console']['log']) {
window['console']['log']('あへあへ');
}
投稿者 atkonn 時刻: 21:35:00 0 コメント
ラベル: Apache Shindig, OpenSocial, shindig, お勉強
gadgets.rpcを理解するにあたって、別ドメイン別フレームという環境がほしくなった。
そこで、ShindigのlockedDomain機能を有効にしてみた。
以下手順。
1) container.jsで、lockedDomainを有効にする。
container.jsのgadgets.lockedDomainRequiredとgadgets.lockedDomainSuffixを有効にすべく
設定する。以下設定後の値。
"gadgets.lockedDomainRequired" : true,
"gadgets.lockedDomainSuffix" : ".gadget.example.com"
<変な値>.gadget.example.com
//<変な値>.gadget.example.com/gadgets/ifr・・・・・
ProxyPreserveHost On
投稿者 atkonn 時刻: 14:40:00 0 コメント
ラベル: Apache Shindig, java, OpenSocial, shindig, お勉強
Apache Shindigに関して、バグが多いという記事を良く見かける。
多分、そもそもの前提が間違っている気がする。
Apache Shindigのデフォルト実装では、たいしたことしていない
というか、サンプル程度の実装しかしていない
というか、手抜きっぽい。
1.1はまだつくり中で0.9の仕様とそもそも合っていないっぽい。
中途半端に手が入っているようで、そもそも動作しない機能もあったりするみたい。
だから、Apache Shindigをダウンロードしてきて、インストールした
だけで、バグが多いというのは、ちょっと違うと思う。
Apache Shindigを使って実装してみて、はじめてバグが多いかどうか判断できるのではないかなー。
なんとなく、Shindigの中身みてて思ったよ。
--
Shindig試すなら、「OpenSocial入門」に書かれてあるpartuzaを使うか、
OpenPNEを使うか、とかじゃないのかなー。
.
投稿者 atkonn 時刻: 11:19:00 0 コメント
ラベル: Apache Shindig, java, OpenSocial, shindig, お勉強