Added:
/trunk/sample/ext/orkut
/trunk/sample/ext/orkut/OrkutSampleApp.xml
/trunk/sample/ext/orkut/flex
/trunk/sample/ext/orkut/flex/OrkutSampleApp.mxml
/trunk/sample/ext/orkut/flex/build.bat
/trunk/src/org/opensocial/client/base/Album.as
/trunk/src/org/opensocial/client/ext/orkut
/trunk/src/org/opensocial/client/ext/orkut/jswrapper
/trunk/src/org/opensocial/client/ext/orkut/jswrapper/OrkutJsWrapperClient.as
/trunk/src/org/opensocial/client/features/AlbumsRequestOptions.as
/trunk/src/org/opensocial/client/features/MediaItemsRequestOptions.as
Modified:
/trunk/src/org/opensocial/client/base/DataRequest.as
/trunk/src/org/opensocial/client/base/MediaItem.as
/trunk/src/org/opensocial/client/core/Feature.as
/trunk/src/org/opensocial/client/features/UIRequestOptions.as
/trunk/src/org/opensocial/client/jswrapper/default.xml
=======================================
--- /dev/null
+++ /trunk/sample/ext/orkut/OrkutSampleApp.xml Tue Mar 23 02:50:27 2010
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<Module>
+<ModulePrefs
+ title="SampleApp For Orkut"
+ description="Just a sample to demo OpenSocial AS3 Client Library."
+ height="500"
+ directory_title="Sample App for OpenSocial AS3 Client Library"
+ author_email="zakiy...@gmail.com"
+ author_affiliation="Google Inc."
+ author_location="Beijing, China"
+ scaling="true"
+ singleton="false">
+ <Require feature="opensocial-0.8"/>
+ <Require feature="dynamic-height"/>
+ <Require feature="views"/>
+ <Require feature="rpc"/>
+ <Require feature="settitle"/>
+
+</ModulePrefs>
+<Content type="html">
+<![CDATA[
+
+<h1 style="font-size:32px; font-weight:bold; font-family:verdana;
text-align: center;">
+ SampleApp For Orkut
+</h1>
+<div id="flashcontainer" style="text-align: center;"></div>
+
+
+<script type="text/javascript">
+ var DEBUG = true;
+
+ // Change nocache to version number when releasing other than random
timestamps.
+ var nocache = new Date().getTime();
+
+ var baseUrl = "http://as3testing.appspot.com/";
+
+ function loadSwf() {
+
+ embedFlash(
+ baseUrl + "OrkutSampleApp.swf?bpc=" + nocache,
+ "flashcontainer",
+ "9.0.115.0",
+ {
+ width: "730",
+ height: "500",
+ quality: "high",
+ wmode: "transparent",
+ allowScriptAccess: "always"
+ });
+ gadgets.window.adjustHeight();
+ };
+
+
+ // TODO: refine this function
+ var DEFAULT_FLASH_ID = 'flashObj';
+ function embedFlash (swfUrl, swfContainer, opt_playerVersion,
opt_params, opt_upgradeMsgHTML) {
+ opt_params = opt_params || {};
+ // Check container element
+ var container = document.getElementById(swfContainer);
+ if (!container) return false;
+
+ // Check version
+ var version = opt_playerVersion.match(/(\d+)(?=[\.,]?)/g);
+ var expectMajorVer = (version != null ? Number(version[0]) : 9);
+
+ // Generate the flash object element
+ var html = "";
+ if (navigator.plugins &&
+ navigator.mimeTypes &&
+ navigator.mimeTypes.length) {
+ // netscape plugin architecture
+ html = '<embed src="'+ swfUrl +
+ '" id="' + DEFAULT_FLASH_ID +
+ '" name="' + DEFAULT_FLASH_ID +
+ '" type="application/x-shockwave-flash"';
+ for(var key in opt_params){
+ html += key +'="'+ opt_params[key] +'" ';
+ }
+ html += '/>';
+ } else {
+ // PC IE
+ html = '<object id="' + DEFAULT_FLASH_ID +
+ '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"';
+ var params = '<param name="movie" value="'+ swfUrl +'" />';
+ for(var key in opt_params) {
+ if (key == 'width' || key == 'height') {
+ html += ' ' + key + '="' + opt_params[key] + '"';
+ } else {
+ params += '<param name="'+ key +'" value="'+ opt_params[key] +'"
/>';
+ }
+ }
+ html += '>' + params + "</object>";
+ }
+ container.innerHTML = html;
+ return true;
+ };
+
+
+ loadSwf();
+
+</script>
+
+
+]]>
+</Content>
+</Module>
=======================================
--- /dev/null
+++ /trunk/sample/ext/orkut/flex/OrkutSampleApp.mxml Tue Mar 23 02:50:27
2010
@@ -0,0 +1,730 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
+ width="730" height="500" color="#FFFFFF"
+ backgroundGradientAlphas="[1.0, 1.0]"
+ backgroundGradientColors="[#666666, #666666]"
+ initialize="init()">
+
+ <mx:Metadata>
+ <![CDATA[
+ /**
+ * Sample Application using the OpenSocial AS3 Client Library in Flex
3.
+ * Build the SampleApp.mxml with Flex SDK to swf file and it works
with the gadget spec XML
+ * (//sample/SampleApp.xml).
+ *
+ * <p>
+ * Usage:<br>
+ * 1. Create a JsWrapperClient instance.
+ * <br>
+ * 2. Add a eventhandler for READY event and call the start() method.
+ * <br>
+ * 3. When the client is ready, use the any of the
<code>AsyncRequest</code> objects and
+ * <code>SyncHelper</code> objects to interact with OpenSocial API.
All these are located in
+ * <code>org.opensocial.client.features</code> package.
+ * <br>
+ * </p>
+ *
+ * @author yiz...@google.com (Yizi Wu)
+ */
+ ]]>
+ </mx:Metadata>
+ <mx:Script>
+ <![CDATA[
+ import
org.opensocial.client.ext.orkut.jswrapper.OrkutJsWrapperClient;
+ import com.adobe.serialization.json.JSON;
+ import mx.controls.Alert;
+ import mx.collections.ArrayCollection;
+ import mx.events.ListEvent;
+
+ import org.opensocial.client.base.*;
+ import org.opensocial.client.core.*;
+ import org.opensocial.client.features.*;
+ import org.opensocial.client.jswrapper.*;
+ import org.opensocial.client.util.*;
+
+ private var client:JsWrapperClient;
+ private var helper:SyncHelper;
+
+ private static var logger:Logger = new Logger(OrkutSampleApp);
+
+ [Bindable]
+ public var dataProvider:ArrayCollection = new ArrayCollection();
+
+ private function init():void {
+
+ // Create the output box for information displaying
+ var printer:TextFieldPrinter = new TextFieldPrinter(2, 160, 450,
330);
+ this.rawChildren.addChild(printer);
+ //var printer:FirebugPrinter = new FirebugPrinter();
+ Logger.initialize(printer, 1);
+ logger.info("OpenSocial(0.8) AS3 Client Library in Flex 3");
+ logger.log(new Date());
+
+ // Initialize Client and start
+ client = new OrkutJsWrapperClient();
+ client.addEventListener(OpenSocialClientEvent.CLIENT_READY,
onReady);
+ client.start();
+
+ helper = new SyncHelper(client);
+
+ }
+
+ private function onReady(event:OpenSocialClientEvent):void {
+ logger.info("Domain: " + helper.getDomain());
+ logger.info("ContainerDomain: " + helper.getContainerDomain());
+ logger.info("CurrentView: " + helper.getCurrentView());
+ logger.info("Client Ready.");
+ }
+
+
+ // -------------------------------------------------------------
+ // Demo Actions
+ // -------------------------------------------------------------
+
+ // ----------------- Fetch Me ------------------
+ private function fetchMe():void {
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.PEOPLE_GET,
+ new PeopleRequestOptions()
+ .setUserId("@me")
+ .setGroupId("@self"));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
fetchMeEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
fetchMeEventErrorHandler);
+ req.send(client);
+ dataProvider.removeAll();
+ }
+
+ private function fetchMeEventHandler(event:ResponseItemEvent):void {
+ var p:Person = event.response.getData();
+ logger.info(p.getDisplayName());
+ dataProvider.addItem(p);
+ }
+
+ private function
fetchMeEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch me failed: " +
event.response.getErrorMessage());
+ }
+
+
+ // ----------------- Fetch Friends ------------------
+ private function fetchFriends():void {
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.PEOPLE_GET,
+ new PeopleRequestOptions()
+ .setUserId("@me")
+ .setGroupId("@friends")
+ .setCount(2)
+ .setStartIndex(0));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
fetchFriendsEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
fetchFriendsEventErrorHandler);
+ req.send(client);
+ dataProvider.removeAll();
+ }
+
+ private function
fetchFriendsEventHandler(event:ResponseItemEvent):void {
+ var c:Collection = event.response.getData();
+ logger.info(c.toDebugString());
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var p:Person = arr[i];
+ logger.info(p.getDisplayName());
+ dataProvider.addItem(p);
+ }
+
+ if (c.getRemainingSize() > 0) {
+ var req:AsyncDataRequest = event.target as AsyncDataRequest;
+ (req.getOptions() as
PeopleRequestOptions).setStartIndex(c.getNextOffset());
+ req.send(client);
+ }
+ }
+
+ private function
fetchFriendsEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch friends failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Send Message ------------------
+ private function sendMessage():void {
+ // the change for myspace. myspace is not support Message object's
type equal to null.
+ var message:Message = Message.newInstance("Hello World...",
+ "My new message.",
+ Message.Type.EMAIL);
+ logger.log(message.toRawObject());
+
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.REQUEST_SEND_MESSAGE,
+ new UIRequestOptions()
+ .setRecipientIds(["@viewer"])
+ .setMessage(message));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
sendMessageEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
sendMessageEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
sendMessageEventHandler(event:ResponseItemEvent):void {
+ logger.info("msg sent.");
+ }
+
+ private function
sendMessageEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("msg sending failed: " +
event.response.getErrorMessage()
+ + " msg error code:" + event.response.getErrorCode());
+ }
+
+
+ // ----------------- Create Activity ------------------
+ private function createActivity():void {
+ var activity:Activity = Activity.newInstance("My new
activity!", "Hello World...");
+
+ logger.log(activity.toRawObject());
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.REQUEST_CREATE_ACTIVITY,
+ new UIRequestOptions()
+ .setActivity(activity));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
createActivityEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
createActivityEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
createActivityEventHandler(event:ResponseItemEvent):void {
+ logger.info("activity created");
+ }
+
+ private function
createActivityEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("activity creation failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Fetch Activities ------------------
+ private function fetchActivities():void {
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.ACTIVITIES_GET,
+ new ActivitiesRequestOptions());
+ req.addEventListener(ResponseItemEvent.COMPLETE,
fetchActivitiesEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
fetchActivitiesEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
fetchActivitiesEventHandler(event:ResponseItemEvent):void {
+ var c:Collection = event.response.getData();
+ logger.info(c.toDebugString());
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var a:Activity = arr[i];
+ logger.info(a.toString());
+ }
+
+ if (c.getRemainingSize() > 0) {
+ var req:AsyncDataRequest = event.target as AsyncDataRequest;
+ (req.getOptions() as
ActivitiesRequestOptions).setStartIndex(c.getNextOffset());
+ req.send(client);
+ }
+ }
+
+ private function
fetchActivitiesEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch activities failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Create Album ------------------
+ private function createAlbum():void {
+ var album:Album = Album.newInstance("yan's album");
+
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.ALBUMS_CREATE,
+ new AlbumsRequestOptions()
+ .setAlbum(album));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
createAlbumEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
createAlbumEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
createAlbumEventHandler(event:ResponseItemEvent):void {
+ logger.info("album created");
+ }
+
+ private function
createAlbumEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("album create failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Fetch Albums ------------------
+ private function fetchAlbums():void {
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.ALBUMS_GET,
+ new AlbumsRequestOptions());
+ req.addEventListener(ResponseItemEvent.COMPLETE,
fetchAlbumsEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
fetchAlbumsEventErrorHandler);
+ req.send(client);
+ dataProvider.removeAll();
+ }
+
+ private function
fetchAlbumsEventHandler(event:ResponseItemEvent):void {
+ var c:Collection = event.response.getData();
+ logger.info(c.toDebugString());
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var a:Album = arr[i];
+ logger.info(a.getTitle());
+ dataProvider.addItem(a);
+ }
+
+ if (c.getRemainingSize() > 0) {
+ var req:AsyncDataRequest = event.target as AsyncDataRequest;
+ (req.getOptions() as
PeopleRequestOptions).setStartIndex(c.getNextOffset());
+ req.send(client);
+ }
+ }
+
+ private function
fetchAlbumsEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch albums failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Update Album ------------------
+ private function updateAlbum():void {
+ var album:Album = Album.newInstance("my album");
+
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.ALBUMS_UPDATE,
+ new AlbumsRequestOptions()
+ .setAlbumId("5449419248073287638")
+ .setAlbum(album));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
updateAlbumEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
updateAlbumEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
updateAlbumEventHandler(event:ResponseItemEvent):void {
+ logger.info("album updated");
+ }
+
+ private function
updateAlbumEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("album updated failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Delete Album ------------------
+ private function deleteAlbum():void {
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.ALBUMS_DELETE,
+ new AlbumsRequestOptions()
+ .setAlbumId("5449384896924854230"));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
deleteAlbumEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
deleteAlbumEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
deleteAlbumEventHandler(event:ResponseItemEvent):void {
+ logger.info("album deleted");
+ }
+
+ private function
deleteAlbumEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("album delete failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Upload Photo ------------------
+ private function uploadPhoto():void {
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.REQUEST_UPLOAD_MEDIAITEM,
+ new UIRequestOptions()
+ .setAlbumId("5449419248073287638"));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
uploadPhotoEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
uploadPhotoEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
uploadPhotoEventHandler(event:ResponseItemEvent):void {
+ logger.info("photo uploaded");
+ }
+
+ private function
uploadPhotoEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("photo upload failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Fetch Photos ------------------
+ private function fetchPhotos():void {
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.MEDIAITEMS_GET,
+ new MediaItemsRequestOptions()
+ .setAlbumId("5449419248073287638"));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
fetchPhotosEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
fetchPhotosEventErrorHandler);
+ req.send(client);
+ dataProvider.removeAll();
+ }
+
+ private function
fetchPhotosEventHandler(event:ResponseItemEvent):void {
+ var c:Collection = event.response.getData();
+ logger.info(c.toDebugString());
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var m:MediaItem = arr[i];
+ logger.info(m.getTitle());
+ dataProvider.addItem(m);
+ }
+
+ if (c.getRemainingSize() > 0) {
+ var req:AsyncDataRequest = event.target as AsyncDataRequest;
+ (req.getOptions() as
PeopleRequestOptions).setStartIndex(c.getNextOffset());
+ req.send(client);
+ }
+ }
+
+ private function
fetchPhotosEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch photos failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Update Photo ------------------
+ private function updatePhoto():void {
+ var mediaItem:MediaItem = new
MediaItem(MutableDataType.createRawObject());
+ mediaItem.setField(MediaItem.Field.TITLE, "First Photo");
+
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.MEDIAITEMS_UPDATE,
+ new MediaItemsRequestOptions()
+ .setAlbumId("5449419248073287638")
+ .setMediaItemId("1268905081365")
+ .setMediaItem(mediaItem));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
updatePhotoEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
updatePhotoEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
updatePhotoEventHandler(event:ResponseItemEvent):void {
+ logger.info("photo updated");
+ }
+
+ private function
updatePhotoEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("photo update failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Make Request ------------------
+ private function makeRequest():void {
+ var req:ProxiedRequest = new ProxiedRequest(
+ "http://www.google.com/crossdomain.xml",
+ new ProxiedRequestOptions()
+ .setContentType(GadgetsIo.ContentType.TEXT));
+ req.addEventListener(ProxiedRequestEvent.COMPLETE,
makeRequestEventHandler);
+ req.addEventListener(ProxiedRequestEvent.ERROR,
makeRequestEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
makeRequestEventHandler(event:ProxiedRequestEvent):void {
+ logger.info(event.response.getData());
+ }
+
+ private function
makeRequestEventErrorHandler(event:ProxiedRequestEvent):void {
+ logger.info("make request failed: " + event.response.getRC()
+ + "|" + event.response.getText());
+ }
+
+
+ // ----------------- Call RPC ------------------
+ private function callRpc():void {
+ // To use this, you need to first register the rpc service with
name "srv-parent" on
+ // container side. If you are using firefox+firebug and looking on
a shindig container,
+ // before clicking the "Call Rpc" button in the flash to call this
method, copy+paste the
+ // following codes to the console window:
+ //
+ // <code>
+ // gadgets.rpc.register("srv-parent", function(){
+ // console.log(arguments);
+ // return "'srv-parent' returned."
+ // });
+ // </code>
+ var req:RPCRequest = new RPCRequest(null, "srv-parent", "abc",
123, {'xyz':456});
+ req.addEventListener(RPCRequestEvent.RPC_CALLBACK,
callRpcEventHandler);
+ req.send(client);
+ }
+
+ private function callRpcEventHandler(event:RPCRequestEvent):void {
+ logger.info("--- invoked by the returning of 'srv-parent' ---");
+ logger.log(event.returnValue);
+ }
+
+
+ // ----------------- Register RPC Service ------------------
+ private function registerService():void {
+ // To use this, you need to make a rpc call to "srv-app" from
container side. If you are
+ // using firefox+firebug and shindig container, click
the "Register Srv" button in the
+ // flash to call this method, then copy+paste the following codes
to the console window
+ // to test the rpc.
+ // ("remote_iframe_0" assumes this flash app is the first app on
the page)
+ //
+ // <code>
+ // gadgets.rpc.call("remote_iframe_0","srv-app",function(r){
+ // console.log(r);
+ // },"abc", 123, {'xyz':456});
+ // </code>
+ var srv:RPCService = new RPCService("srv-app");
+ srv.register(client);
+ srv.addEventListener(RPCServiceEvent.RPC_SERVICE,
serviceEventHandler);
+ }
+
+ private function serviceEventHandler(event:RPCServiceEvent):void {
+ logger.info("--- invoked by 'srv-app' get called ---");
+ logger.log(event.params);
+ event.callback("'srv-app' returned.");
+ }
+
+ // ----------------- Batch Request------------------
+ private function batchRequest():void {
+ var batch:BatchRequest = new BatchRequest();
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.PEOPLE_GET,
+ new PeopleRequestOptions()
+ .setUserId("@me")
+ .setGroupId("@self"));
+
+// req.addEventListener(ResponseItemEvent.COMPLETE,
batchFetchMeEventHandler);
+// req.addEventListener(ResponseItemEvent.ERROR,
batchFetchMeEventErrorHandler);
+
+
+ batch.add(req, "meProfile");
+
+ req = new AsyncDataRequest(
+ Feature.PEOPLE_GET,
+ new PeopleRequestOptions()
+ .setUserId("@me")
+ .setGroupId("@friends")
+ .setCount(2)
+ .setStartIndex(0));
+//
+// req.addEventListener(ResponseItemEvent.COMPLETE,
batchFetchFriendsEventHandler);
+// req.addEventListener(ResponseItemEvent.ERROR,
batchFetchFriendsEventErrorHandler);
+//
+ batch.add(req, "friendList");
+
+ batch.addEventListener(ResponseItemEvent.COMPLETE,
batchDataRequestEventHandler);
+ batch.addEventListener(ResponseItemEvent.ERROR,
batchDataRequestErrorHandler);
+ batch.send(client);
+ }
+
+ private function
batchDataRequestEventHandler(event:ResponseItemEvent):void {
+ logger.info("=============== Batch Success ================");
+ var p:Person = event.response.getData("meProfile");
+ logger.info("meProfile =============== " + p.getDisplayName());
+
+ var c:Collection = event.response.getData("friendList");
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var person:Person = arr[i];
+ logger.info("friendList =============== " +
person.getDisplayName());
+ }
+ logger.info("=============== Batch Success ================");
+ }
+
+ private function
batchDataRequestErrorHandler(event:ResponseItemEvent):void {
+ logger.info("=============== Batch Error ================");
+ logger.info(event.response.getErrorMessage());
+ logger.info("=============== Batch Error ================");
+ }
+
+ private function
batchFetchMeEventHandler(event:ResponseItemEvent):void {
+ var p:Person = event.response.getData();
+ logger.info(p.getDisplayName());
+ dataProvider.addItem(p);
+ }
+
+ private function
batchFetchMeEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch me failed: " +
event.response.getErrorMessage());
+ }
+
+ private function
batchFetchFriendsEventHandler(event:ResponseItemEvent):void {
+ var c:Collection = event.response.getData();
+ logger.info(c.toDebugString());
+ var arr:Array = c.getArray();
+ for (var i:int = 0; i < arr.length; i++) {
+ var p:Person = arr[i];
+ logger.info(p.getDisplayName());
+ dataProvider.addItem(p);
+ }
+
+ if (c.getRemainingSize() > 0) {
+ var req:AsyncDataRequest = event.target as AsyncDataRequest;
+ (req.getOptions() as
PeopleRequestOptions).setStartIndex(c.getNextOffset());
+ req.send(client);
+ }
+ }
+
+ private function
batchFetchFriendsEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("fetch friends failed: " +
event.response.getErrorMessage());
+ }
+
+ // ----------------- Update Appdata ------------------
+ private function updateAppdata():void {
+ var player:Object = {name:"Zakiyy",age:22,gender:"male"};
+
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.APP_DATA_UPDATE,
+ new AppDataRequestOptions()
+ .setDatum("player", JSON.encode(player)));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
updateAppdataEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
updateAppdataEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
updateAppdataEventHandler(event:ResponseItemEvent):void {
+ logger.info("update success!");
+ }
+
+ private function
updateAppdataEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("update failed: " + event.response.getErrorMessage());
+ }
+
+ // ----------------- Get Appdata ------------------
+ private function getAppdata():void {
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.APP_DATA_GET,
+ new AppDataRequestOptions()
+ .setKeys(["player"]));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
getAppdataEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
getAppdataEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
getAppdataEventHandler(event:ResponseItemEvent):void {
+ logger.info("get success!");
+ }
+
+ private function
getAppdataEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("get failed: " + event.response.getErrorMessage());
+ }
+
+
+ // ----------------- Delete Appdata ------------------
+ private function deleteAppdata():void {
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.APP_DATA_DELETE,
+ new AppDataRequestOptions()
+ .setKeys(["player"]));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
deleteAppdataEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
deleteAppdataEventErrorHandler);
+ req.send(client);
+ }
+
+ private function
deleteAppdataEventHandler(event:ResponseItemEvent):void {
+ logger.info("delete success!");
+ }
+
+ private function
deleteAppdataEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("delete failed: " + event.response.getErrorMessage());
+ }
+
+ // ----------------- Share App ------------------
+ private function shareApp(event:ListEvent):void {
+ // To use this, you need First run "Fetch Friends" or "Fetch Me"
and then click People.
+ var p:Person = event.itemRenderer.data as Person;
+ var message:Message = Message.newInstance("Hey [recipient]!
[sender] wants you to " +
+ "add [app]. It's way awesome!", "A fun way to view your
profile!");
+ logger.log(message.toRawObject());
+
+ var req:AsyncDataRequest = new AsyncDataRequest(
+ Feature.REQUEST_SHARE_APP,
+ new UIRequestOptions()
+ .setRecipientIds([p.getId()])
+ .setReason(message));
+ req.addEventListener(ResponseItemEvent.COMPLETE,
shareAppEventHandler);
+ req.addEventListener(ResponseItemEvent.ERROR,
shareAppEventErrorHandler);
+ req.send(client);
+ }
+
+ private function shareAppEventHandler(event:ResponseItemEvent):void {
+ logger.info("msg sent.");
+ }
+ private function
shareAppEventErrorHandler(event:ResponseItemEvent):void {
+ logger.info("msg sending failed: " +
event.response.getErrorMessage());
+ }
+
+ ]]>
+ </mx:Script>
+ <mx:Button x="468" y="45" label="Fetch Me" height="22" width="123"
+ id="fetchMeBtn" click="fetchMe()"/>
+ <mx:Button x="468" y="75" label="Fetch Friends" height="22" width="123"
+ id="fetchFriendsBtn" click="fetchFriends()"/>
+ <mx:Button x="468" y="105" label="Send Message" height="22" width="123"
+ id="sendMessageBtn" click="sendMessage()"/>
+ <mx:Button x="468" y="135" label="Create Activity" height="22"
width="123"
+ id="createActivityBtn" click="createActivity()"/>
+ <mx:Button x="468" y="165" label="Fetch Activities" height="22"
width="123"
+ id="fetchActivitiesBtn" click="fetchActivities()"/>
+ <mx:Button x="468" y="195" label="Update Appdata" height="22" width="123"
+ id="updateAppdataBtn" click="updateAppdata()"/>
+ <mx:Button x="468" y="225" label="Get Appdata" height="22" width="123"
+ id="getAppdataBtn" click="getAppdata()"/>
+ <mx:Button x="468" y="255" label="Delete Appdata" height="22" width="123"
+ id="deleteAppdataBtn" click="deleteAppdata()"/>
+ <mx:Button x="468" y="285" label="Create Album" height="22" width="123"
+ id="createAlbumBtn" click="createAlbum()"/>
+ <mx:Button x="468" y="315" label="Fetch Albums" height="22" width="123"
+ id="fetchAlbumsBtn" click="fetchAlbums()"/>
+ <mx:Button x="468" y="345" label="Update Album" height="22" width="123"
+ id="updateAlbumBtn" click="updateAlbum()"/>
+ <mx:Button x="468" y="375" label="Delete Album" height="22" width="123"
+ id="deleteAlbumBtn" click="deleteAlbum()"/>
+ <mx:Button x="468" y="405" label="Upload Photo" height="22" width="123"
+ id="uploadPhotosBtn" click="uploadPhoto()"/>
+ <mx:Button x="468" y="435" label="Fetch Photos" height="22" width="123"
+ id="fetchPhotosBtn" click="fetchPhotos()"/>
+ <mx:Button x="468" y="465" label="Update Photo" height="22" width="123"
+ id="updatePhotoBtn" click="updatePhoto()"/>
+ <mx:Button x="599" y="45" label="Make Request" height="22" width="123"
+ id="makeRequestBtn" click="makeRequest()"/>
+ <mx:Button x="599" y="75" label="Call Rpc" height="22" width="123"
+ id="rpcCallBtn" click="callRpc()"/>
+ <mx:Button x="599" y="105" label="Register Srv" height="22" width="123"
+ id="rpcRegisterBtn" click="registerService()"/>
+ <mx:Button x="599" y="135" label="Batch Request" height="22" width="123"
+ id="batchRequestBtn" click="batchRequest()"/>
+ <mx:TileList width="450" height="120" id="titleList"
dataProvider="{dataProvider}"
+ itemClick="shareApp(event)" x="10" y="26" backgroundColor="#666666"
mouseFocusEnabled="true">
+ <mx:itemRenderer>
+ <mx:Component>
+ <mx:Box width="96" height="120" focusEnabled="false"
+ horizontalScrollPolicy="off" verticalScrollPolicy="off">
+ <mx:Script>
+ <![CDATA[
+ import org.opensocial.client.base.Album;
+ import org.opensocial.client.base.Person;
+ import org.opensocial.client.base.MediaItem;
+
+ [Bindable]
+ public var text:String;
+
+ [Bindable]
+ public var image:Object;
+
+ override public function set data(value:Object):void {
+ super.data = value;
+ image = data.getThumbnailUrl();
+ if (data is Person) {
+ text = data.getDisplayName();
+ } else if (data is Album){
+ text = data.getTitle();
+ } else if (data is MediaItem) {
+ text = data.getTitle();
+ }
+ }
+ ]]>
+ </mx:Script>
+ <mx:Image source="{image}" width="96" height="96"/>
+ <mx:Label text="{text}"/>
+ </mx:Box>
+ </mx:Component>
+ </mx:itemRenderer>
+ </mx:TileList>
+ <mx:Text x="356" y="3"
+ text="OpenSocial (0.8) AS3 Client Library (JS Wrapper
Client)
SampleApp For Orkut - Flex 3"
+ width="366" height="34" textAlign="right"/>
+</mx:Application>
=======================================
--- /dev/null
+++ /trunk/sample/ext/orkut/flex/build.bat Tue Mar 23 02:50:27 2010
@@ -0,0 +1,2 @@
+mxmlc "OrkutSampleApp.mxml" -sp "..\..\..\..\..\src"
-o "..\..\..\..\..\bin\OrkutSampleApp.swf"
+pause
=======================================
--- /dev/null
+++ /trunk/src/org/opensocial/client/base/Album.as Tue Mar 23 02:50:27 2010
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.opensocial.client.base {
+
+/**
+ * Wrapper of <code><j>opensocial.Album</j></code> object in javascript.
+ *
+ * @see
http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/OpenSocial-Specification.html#opensocial.Album
+ *
+ * @author zakiy...@gmail.com (Zhinan Yan)
+ */
+public class Album extends MutableDataType {
+
+ /**
+ * <code><j>opensocial.Album.Field</j></code> constants.
+ * @see
http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/OpenSocial-Specification.html#opensocial.Album.Field
+ */
+ public static const Field:ConstType = new ConstType(
+ "opensocial.Album.Field", {
+ DESCRIPTION : 'description',
+ ID : 'id',
+ LOCATION : 'location', /*
opensocial.Address */
+ MEDIA_ITEM_COUNT : 'mediaItemCount',
+ MEDIA_MIME_TYPE : 'mediaMimeType', /* Array.<String> */
+ MEDIA_TYPE : 'mediaType', /*
Array.<MediaItem> */
+ OWNER_ID : 'ownerId',
+ THUMBNAIL_URL : 'thumbnailUrl',
+ TITLE : 'title'
+ });
+
+
+ /**
+ * Creates an <code>Album</code> object. The signature only accepts
several common fields. For
+ * other fields, use the <code>setField</code> method.
+ * @param title The title text.
+ * @return The new instance.
+ */
+ public static function newInstance(title:String):Album {
+ var album:Album = new Album(MutableDataType.createRawObject());
+ album.setField(Field.TITLE, title);
+ return album;
+ }
+
+ /**
+ * Constructor.
+ * <p>
+ * NOTE: This constructor is internally used. Do not call this
constructor directly outside
+ * this package.
+ * </p>
+ * @param rawObj The wrapped object from Js-side passed by the
<code>ExternalInterface</code>.
+ * @private
+ */
+ public function Album(rawObj:Object) {
+ super(rawObj);
+ }
+
+ /**
+ * Gets the ID that can be permanently associated with this album.
+ * @return The id string.
+ */
+ public function getId():String {
+ return getRawProperty("id") as String;
+ }
+
+ /**
+ * Get the thumbnail url field of the album. Will not throw error if not
exists.
+ * @return The thumbnail url if exists.
+ */
+ public function getThumbnailUrl():String {
+ return getFieldString(Field.THUMBNAIL_URL);
+ }
+
+ /**
+ * Get the title field of the album. Will not throw error if not exists.
+ * @return The title if exists.
+ */
+ public function getTitle():String {
+ return getFieldString(Field.TITLE);
+ }
+
+ /**
+ * Returns the default album display string.
+ * @return The album field: <code>TITLE</code>
+ */
+ override public function toString():String {
+ return getFieldString(Field.TITLE);
+ }
+
+}
+}
=======================================
--- /dev/null
+++
/trunk/src/org/opensocial/client/ext/orkut/jswrapper/OrkutJsWrapperClient.as
Tue Mar 23 02:50:27 2010
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.opensocial.client.ext.orkut.jswrapper {
+
+import org.opensocial.client.core.Feature;
+import org.opensocial.client.jswrapper.JsWrapperClient;
+import org.opensocial.client.jswrapper.JsWrapperParsers;
+
+/**
+ * Extenstion of normal JsWrapperClient for orkut container. This
container doesn't support
+ * rpc and settitle feature. But it supports photos, albums and many other
extensions.
+ *
+ * @author zakiy...@gmail.com (Zhinan Yan)
+ */
+public class OrkutJsWrapperClient extends JsWrapperClient {
+
+ public function OrkutJsWrapperClient(jsNamespace:String = null,
jsAllowedDomain:String = "*") {
+ super(jsNamespace, jsAllowedDomain);
+ }
+
+ /**
+ * @inheritDoc
+ * @private
+ */
+ override protected function initFeatureBook():void {
+ super.initFeatureBook();
+
+ // Orkut does not support ACTIVITIES_GET and REQUEST_SHARE_APP features
+ removeFeature(Feature.ACTIVITIES_GET);
+
+
+ // Orkut has some more extension.
+ with (JsWrapperParsers) {
+ super.addFeature(Feature.ALBUMS_CREATE, true, parseParams,
parseEmpty);
+ super.addFeature(Feature.ALBUMS_GET, true, parseParams,
parseWrappedData);
+ super.addFeature(Feature.ALBUMS_UPDATE, true, parseParams,
parseEmpty);
+ super.addFeature(Feature.ALBUMS_DELETE, true, parseParams,
parseEmpty);
+
+ super.addFeature(Feature.REQUEST_UPLOAD_MEDIAITEM, true,
parseParams, parseEmpty);
+ super.addFeature(Feature.MEDIAITEMS_GET, true, parseParams,
parseWrappedData);
+ super.addFeature(Feature.MEDIAITEMS_UPDATE, true, parseParams,
parseEmpty);
+
+ }
+ }
+}
+}
=======================================
--- /dev/null
+++ /trunk/src/org/opensocial/client/features/AlbumsRequestOptions.as Tue
Mar 23 02:50:27 2010
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.opensocial.client.features {
+
+import org.opensocial.client.base.Album;
+
+/**
+ * Options for <code><j>osapi.albums</j></code> service. The options
format is based on the
+ * OS-Lite style. The key names of the options object is defined in the
protocol spec.
+ * <p>
+ * It's used to initialize the <code>AsyncDataRequest</code> instance.
+ * </p>
+ *
+ * @see AsyncDataRequest
+ *
+ * @see
http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/RPC-Protocol.html
+ * RPC Protocol
+ * @see
http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/RPC-Protocol.html#Albums
+ *
+ * @author zakiy...@gmail.com (Zhinan Yan)
+ */
+public class AlbumsRequestOptions extends RequestOptions {
+
+ /**
+ * Constructor of the options object for albums service.
+ * @param options Initial value for the options. If null, default values
will be applied.
+ */
+ public function AlbumsRequestOptions(options:Object = null) {
+ if (options == null) {
+ options = {
+ "userId" : "@me",
+ "groupId" : "@self",
+ "count" : 20,
+ "startIndex" : 0
+ };
+ }
+ super(options);
+ }
+
+
+ /**
+ * Sets the user id value.
+ * @param userId The user id. Can be "@me", "@viewer", "@owner" or
actual user id value.
+ * @return The options itself.
+ */
+ public function setUserId(userId:String):AlbumsRequestOptions {
+ modify("userId", [userId]);
+ return this;
+ }
+
+
+ /**
+ * Sets the user id values.
+ * @param userIds An array of user ids.
+ * @return The options itself.
+ */
+ public function setUserIds(userIds:Array):AlbumsRequestOptions {
+ modify("userId", userIds);
+ return this;
+ }
+
+
+ /**
+ * Adds the user id values.
+ * @param userIds User ids to be added.
+ * @return The options itself.
+ */
+ public function addUserIds(...userIds:Array):AlbumsRequestOptions {
+ append("userId", userIds);
+ return this;
+ }
+
+
+ /**
+ * Sets the group id value.
+ * @param groupId The group id.
+ * @return The options itself.
+ */
+ public function setGroupId(groupId:String):AlbumsRequestOptions {
+ modify("groupId", groupId);
+ return this;
+ }
+
+
+ /**
+ * Sets the number of people to be fetch. Only used in the
<code>ALBUMS_GET</code>
+ * feature.
+ * @param count The number of the counts.
+ * @return The options itself.
+ */
+ public function setCount(count:int):AlbumsRequestOptions {
+ modify("count", count);
+ return this;
+ }
+
+
+ /**
+ * Sets the start index to be fetch. Only used in the
<code>ALBUMS_GET</code> feature.
+ * @param startIndex The number of the start index.
+ * @return The options itself.
+ */
+ public function setStartIndex(startIndex:int):AlbumsRequestOptions {
+ modify("startIndex", startIndex);
+ return this;
+ }
+
+
+ /**
+ * Sets the album id. Only used in the <code>ALBUMS_UPDATE</code> and the
+ * <code>ALBUMS_DELETE</code> feature.
+ * @param albumId The album id.
+ * @return The options itself.
+ */
+ public function setAlbumId(albumId:String):AlbumsRequestOptions {
+ modify("albumId", albumId);
+ return this;
+ }
+
+
+ /**
+ * Sets the album instance. Only used in the <code>ALBUMS_CREATE</code>
and the
+ * <code>ALBUMS_UPDATE</code> feature.
+ * @param album The album instance.
+ * @return The options itself.
+ */
+ public function setAlbum(album:Album):AlbumsRequestOptions {
+ modify("album", album.toRawObject());
+ return this;
+ }
+}
+}
=======================================
--- /dev/null
+++ /trunk/src/org/opensocial/client/features/MediaItemsRequestOptions.as
Tue Mar 23 02:50:27 2010
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.opensocial.client.features {
+
+import org.opensocial.client.base.MediaItem;
+
+/**
+ * Options for <code><j>osapi.mediaItems</j></code> service. The options
format is based on the
+ * OS-Lite style. The key names of the options object is defined in the
protocol spec.
+ * <p>
+ * It's used to initialize the <code>AsyncDataRequest</code> instance.
+ * </p>
+ *
+ * @see AsyncDataRequest
+ *
+ * @see
http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/RPC-Protocol.html
+ * RPC Protocol
+ * @see
http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/RPC-Protocol.html#
+ * MediaItem
+ *
+ * @author zakiy...@gmail.com (Zhinan Yan)
+ */
+public class MediaItemsRequestOptions extends RequestOptions {
+
+ /**
+ * Constructor of the options object for mediaItems service.
+ * @param options Initial value for the options. If null, default values
will be applied.
+ */
+ public function MediaItemsRequestOptions(options:Object = null) {
+ if (options == null) {
+ options = {
+ "userId" : "@me",
+ "groupId" : "@self",
+ "count" : 20,
+ "startIndex" : 0
+ };
+ }
+ super(options);
+ }
+
+
+ /**
+ * Sets the user id value.
+ * @param userId The user id. Can be "@me", "@viewer", "@owner" or
actual user id value.
+ * @return The options itself.
+ */
+ public function setUserId(userId:String):MediaItemsRequestOptions {
+ modify("userId", [userId]);
+ return this;
+ }
+
+
+ /**
+ * Sets the user id values.
+ * @param userIds An array of user ids.
+ * @return The options itself.
+ */
+ public function setUserIds(userIds:Array):MediaItemsRequestOptions {
+ modify("userId", userIds);
+ return this;
+ }
+
+
+ /**
+ * Adds the user id values.
+ * @param userIds User ids to be added.
+ * @return The options itself.
+ */
+ public function addUserIds(...userIds:Array):MediaItemsRequestOptions {
+ append("userId", userIds);
+ return this;
+ }
+
+
+ /**
+ * Sets the group id value.
+ * @param groupId The group id.
+ * @return The options itself.
+ */
+ public function setGroupId(groupId:String):MediaItemsRequestOptions {
+ modify("groupId", groupId);
+ return this;
+ }
+
+
+ /**
+ * Sets the number of people to be fetch. Only used in the
<code>MEDIAITEMS_GET</code>
+ * feature.
+ * @param count The number of the counts.
+ * @return The options itself.
+ */
+ public function setCount(count:int):MediaItemsRequestOptions {
+ modify("count", count);
+ return this;
+ }
+
+
+ /**
+ * Sets the start index to be fetch. Only used in the
<code>MEDIAITEMS_GET</code> feature.
+ * @param startIndex The number of the start index.
+ * @return The options itself.
+ */
+ public function setStartIndex(startIndex:int):MediaItemsRequestOptions {
+ modify("startIndex", startIndex);
+ return this;
+ }
+
+
+ /**
+ * Sets the mediaitem d. Only used in the <code>MEDIAITEMS_GET</code>
feature.
+ * @param startIndex The number of the start index.
+ * @return The options itself.
+ */
+ public function
setMediaItemId(mediaItemId:String):MediaItemsRequestOptions {
+ modify("mediaItemId", mediaItemId);
+ return this;
+ }
+
+
+ /**
+ * Sets the album id.
+ * @param albumId The album id.
+ * @return The options itself.
+ */
+ public function setAlbumId(albumId:String):MediaItemsRequestOptions {
+ modify("albumId", albumId);
+ return this;
+ }
+
+
+ /**
+ * Sets the mediaitem instance. Only used in the
<code>MEDIAITEMS_UPDATE</code> feature.
+ * @param mediaitem The mediaitem instance.
+ * @return The options itself.
+ */
+ public function
setMediaItem(mediaitem:MediaItem):MediaItemsRequestOptions {
+ modify("mediaItem", mediaitem.toRawObject());
+ return this;
+ }
+}
+}
=======================================
--- /trunk/src/org/opensocial/client/base/DataRequest.as Wed Sep 30
01:09:12 2009
+++ /trunk/src/org/opensocial/client/base/DataRequest.as Tue Mar 23
02:50:27 2010
@@ -96,6 +96,17 @@
MAX : 'max' /* Number */
});
+ /**
+ * <code><j>opensocial.DataRequest.AlbumRequestFields</j></code>
constants.
+ * @see
http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/
+ *
OpenSocial-Specification.html#opensocial.DataRequest.AlbumRequestFields
+ * opensocial.DataRequest.AlbumRequestFields
+ */
+ public static const AlbumRequestFields:ConstType = new ConstType(
+ "opensocial.DataRequest.AlbumRequestFields", {
+ FIRST : 'first', /* Number */
+ MAX : 'max' /* Number */
+ });
/**
* Prepare a people request parameter object. Keys are defined in
=======================================
--- /trunk/src/org/opensocial/client/base/MediaItem.as Wed Sep 30 01:09:12
2009
+++ /trunk/src/org/opensocial/client/base/MediaItem.as Tue Mar 23 02:50:27
2010
@@ -35,9 +35,27 @@
*/
public static const Field:ConstType = new ConstType(
"opensocial.MediaItem.Field", {
- TYPE : 'type', /* MediaItem.Type */
- MIME_TYPE : 'mimeType',
- URL : 'url'
+ ALBUM_ID : 'albumId',
+ CREATED : 'created',
+ DESCRIPTION : 'description',
+ DURATION : 'duration',
+ FILE_SIZE : 'fileSize',
+ ID : 'id',
+ LANGUAGE : 'language',
+ LAST_UPDATED : 'lastUpdated',
+ LOCATION : 'location',
+ MIME_TYPE : 'mimeType',
+ NUM_COMMENTS : 'numComments',
+ NUM_VIEWS : 'numViews',
+ NUM_VOTES : 'numVotes',
+ RATING : 'rating',
+ START_TIME : 'startTime',
+ TAGGED_PEOPLE : 'taggedPeople', /* Array.<String> */
+ TAGS : 'tags', /* Array.<String> */
+ THUMBNAIL_URL : 'thumbnailUrl',
+ TITLE : 'title',
+ TYPE : 'type', /* MediaItem.Type */
+ URL : 'url'
});
/**
@@ -84,6 +102,30 @@
public function MediaItem(rawObj:Object) {
super(rawObj);
}
+
+ /**
+ * Gets the ID that can be permanently associated with this media item.
+ * @return The id string.
+ */
+ public function getId():String {
+ return getRawProperty("id") as String;
+ }
+
+ /**
+ * Get the thumbnail url field of the media item. Will not throw error
if not exists.
+ * @return The thumbnail url if exists.
+ */
+ public function getThumbnailUrl():String {
+ return getFieldString(Field.THUMBNAIL_URL);
+ }
+
+ /**
+ * Get the title field of the media item. Will not throw error if not
exists.
+ * @return The title if exists.
+ */
+ public function getTitle():String {
+ return getFieldString(Field.TITLE);
+ }
/**
* Returns the default media item display string.
=======================================
--- /trunk/src/org/opensocial/client/core/Feature.as Wed Sep 30 01:09:12
2009
+++ /trunk/src/org/opensocial/client/core/Feature.as Tue Mar 23 02:50:27
2010
@@ -51,6 +51,16 @@
/** The feature of fetching activities. */
public static const ACTIVITIES_GET:String = "activities.get";
+ // -- osapi.albums --
+ public static const ALBUMS_GET:String = "albums.get";
+ public static const ALBUMS_CREATE:String = "albums.create";
+ public static const ALBUMS_UPDATE:String = "albums.update";
+ public static const ALBUMS_DELETE:String
= "albums.deleteData";
+
+ // -- osapi.mediaItems --
+ public static const MEDIAITEMS_GET:String = "mediaItems.get";
+ public static const MEDIAITEMS_UPDATE:String
= "mediaItems.update";
+
// -- osapi.ui --
/** The feature of creating an activity */
public static const REQUEST_CREATE_ACTIVITY:String
= "ui.requestCreateActivity";
@@ -60,7 +70,9 @@
public static const REQUEST_SHARE_APP:String
= "ui.requestShareApp";
/** The feature of requesting permission. */
public static const REQUEST_PERMISSION:String
= "ui.requestPermission";
-
+ /** The feature of upload an mediaitem */
+ public static const REQUEST_UPLOAD_MEDIAITEM:String
= "ui.requestUploadMediaItem";
+
// -- opensocial.Environment --
/** The feature of checking supported fields. */
public static const SUPPORTS_FIELD:String
= "env.supportsField";
=======================================
--- /trunk/src/org/opensocial/client/features/UIRequestOptions.as Wed Sep
30 01:09:12 2009
+++ /trunk/src/org/opensocial/client/features/UIRequestOptions.as Tue Mar
23 02:50:27 2010
@@ -44,6 +44,8 @@
* opensocial.requestCreateActivity
* @see
http://code.google.com/apis/opensocial/docs/0.8/reference/#opensocial.requestPermission
* opensocial.requestPermission
+ * @see http://www.opensocial.org/Technical-Resources/opensocial-spec-v09/
+ * OpenSocial-Specification.html#opensocial.requestUploadMediaItem
*
* @author yiz...@google.com (Yizi Wu)
*/
@@ -120,5 +122,15 @@
modify("permission", permission);
return this;
}
+
+ /**
+ * Sets the album id. Only used in the
<code>REQUEST_UPLOAD_MEDIAITEM</code> feature.
+ * @param albumId the album id.
+ * @return The options itself.
+ */
+ public function setAlbumId(albumId:String):UIRequestOptions {
+ modify("albumId", albumId);
+ return this;
+ }
}
}
=======================================
--- /trunk/src/org/opensocial/client/jswrapper/default.xml Sun Feb 28
20:07:20 2010
+++ /trunk/src/org/opensocial/client/jswrapper/default.xml Tue Mar 23
02:50:27 2010
@@ -351,7 +351,14 @@
*/
me.getDataItem = function(responseItem) {
if (!responseItem) return null;
- if (responseItem.hadError()) {
+
+ /**
+ * NOTE:
+ * For orkut. When delete not exist photo, The
responseItem.hadError() is false,
+ * But the responseItem.getErrorMessage() has error
message.
+ */
+
+ if (responseItem.hadError() ||
responseItem.getErrorMessage()) {
var e = new Error(responseItem.getErrorMessage());
e['name'] = "OpenSocialError";
e['code'] = responseItem.getErrorCode();
@@ -382,7 +389,8 @@
'org.opensocial.client.base.MediaItem' :
opensocial.MediaItem,
'org.opensocial.client.base.Message' :
opensocial.Message,
'org.opensocial.client.base.NavigationParameters' :
opensocial.NavigationParameters,
- 'org.opensocial.client.base.Collection' :
opensocial.Collection
+ 'org.opensocial.client.base.Collection' :
opensocial.Collection,
+ 'org.opensocial.client.base.Album' :
opensocial.Album
};
]]></script>
</dataTypes>
@@ -527,6 +535,8 @@
fields[opensocial.Activity.Field.MEDIA_ITEMS] =
richItems;
}
return opensocial.newActivity(fields);
+ } else if (type == opensocial.Album) {
+ return new opensocial.Album(fields);
}
}
@@ -1414,6 +1424,227 @@
</deleteData>
</appdata>
+
+ <!-- ========================== OSAPI.ALBUMS
=========================== -->
+ <albums>
+ <script><![CDATA[
+ api.albums = {};
+ ]]></script>
+
+ <getRequest>
+ <script><![CDATA[
+ /**
+ * According to operation mode, get request object.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * PeopleRequestOptions.
+ * @param {string} mode The operation mode.
+ * @param {DataRequest} req An exist DataRequest.
+ * @member opensocial.flash.albums
+ */
+ api.albums.getRequest = function(options, mode, req) {
+ switch (mode){
+ case 'create':
+ var idSpec = me.translateIdSpec(options);
+ var album = me.unwrapObject(options['album'],
opensocial.Album);
+ return req.newCreateAlbumRequest(idSpec, album);
+ case 'get':
+ var params = me.translatePaginationParams(options);
+ var idSpec = me.translateIdSpec(options);
+ return req.newFetchAlbumsRequest(idSpec, params);
+ case 'update':
+ var album = options['album']['fields'];
+ var idSpec = me.translateIdSpec(options);
+ var albumId = options['albumId'];
+ return req.newUpdateAlbumRequest(idSpec, albumId,
album);
+ case 'delete':
+ var idSpec = me.translateIdSpec(options);
+ var albumId = options['albumId'];
+ return req.newDeleteAlbumRequest(idSpec, albumId);
+ }
+ };
+ ]]></script>
+ </getRequest>
+ <create>
+ <script><![CDATA[
+ /**
+ * Sends request to remote site to create album.
+ * @param {string} reqID The request id.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * AlbumsRequestOptions.
+ * @member opensocial.flash.albums
+ */
+ api.albums.create = function(reqID, options, req, resKey) {
+ var req = opensocial.newDataRequest();
+ var request = me.api.albums.getRequest(options, 'create',
req);
+ req.add(request, 'a');
+ req.send(function(dataResponse) {
+ try {
+ me.getData(dataResponse, 'a');
+ me.handleAsync(reqID);
+ } catch (e) {
+ me.handleError(reqID, e);
+ }
+ });
+ };
+ ]]></script>
+ </create>
+ <get>
+ <script><![CDATA[
+ /**
+ * Sends request to remote site to get albums.
+ * @param {string} reqID The request id.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * AlbumsRequestOptions.
+ * @member opensocial.flash.albums
+ */
+ api.albums.get = function(reqID, options, req, resKey) {
+ var req = opensocial.newDataRequest();
+ var request = me.api.albums.getRequest(options, 'get',
req);
+ req.add(request, 'a');
+ req.send(function(dataResponse) {
+ try {
+ var response =
me.wrapObject(me.getData(dataResponse, 'a'));
+ me.handleAsync(reqID, response);
+ } catch (e) {
+ me.handleError(reqID, e);
+ }
+ });
+ };
+ ]]></script>
+ </get>
+ <update>
+ <script><![CDATA[
+ /**
+ * Sends request to remote site to update album.
+ * @param {string} reqID The request id.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * AlbumsRequestOptions.
+ * @member opensocial.flash.albums
+ */
+ api.albums.update = function(reqID, options, req, resKey) {
+ var req = opensocial.newDataRequest();
+ var request = me.api.albums.getRequest(options, 'update',
req);
+ req.add(request, 'a');
+ req.send(function(dataResponse) {
+ try {
+ me.getData(dataResponse, 'a');
+ me.handleAsync(reqID);
+ } catch (e) {
+ me.handleError(reqID, e);
+ }
+ });
+ };
+ ]]></script>
+ </update>
+ <deleteData>
+ <script><![CDATA[
+ /**
+ * Sends request to remote site to update album.
+ * @param {string} reqID The request id.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * AlbumsRequestOptions.
+ * @member opensocial.flash.albums
+ */
+ api.albums.deleteData = function(reqID, options, req,
resKey) {
+ var req = opensocial.newDataRequest();
+ var request = me.api.albums.getRequest(options, 'delete',
req);
+ req.add(request, 'a');
+ req.send(function(dataResponse) {
+ try {
+ me.getData(dataResponse, 'a');
+ me.handleAsync(reqID);
+ } catch (e) {
+ me.handleError(reqID, e);
+ }
+ });
+ };
+ ]]></script>
+ </deleteData>
+ </albums>
+
+
+ <!-- ========================== OSAPI.MEDIAITEMS
=========================== -->
+ <mediaItems>
+ <script><![CDATA[
+ api.mediaItems = {};
+ ]]></script>
+
+ <getRequest>
+ <script><![CDATA[
+ /**
+ * According to operation mode, get request object.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * PeopleRequestOptions.
+ * @param {string} mode The operation mode.
+ * @param {DataRequest} req An exist DataRequest.
+ * @member opensocial.flash.mediaItems
+ */
+ api.mediaItems.getRequest = function(options, mode, req) {
+ switch (mode){
+ case 'get':
+ var params = me.translatePaginationParams(options);
+ var idSpec = me.translateIdSpec(options);
+ var albumId = options['albumId'];
+ return req.newFetchMediaItemsRequest(idSpec, albumId,
params);
+ case 'update':
+ var mediaItem = options['mediaItem']['fields'];
+ var idSpec = me.translateIdSpec(options);
+ var albumId = options['albumId'];
+ var mediaItemId = options['mediaItemId'];
+ return req.newUpdateMediaItemRequest (idSpec, albumId,
mediaItemId, mediaItem);
+ }
+ };
+ ]]></script>
+ </getRequest>
+ <get>
+ <script><![CDATA[
+ /**
+ * Sends request to remote site to get mediaitems.
+ * @param {string} reqID The request id.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * AlbumsRequestOptions.
+ * @member opensocial.flash.mediaItems
+ */
+ api.mediaItems.get = function(reqID, options, req, resKey) {
+ var req = opensocial.newDataRequest();
+ var request = me.api.mediaItem.getRequest(options, 'get',
req);
+ req.add(request, 'm');
+ req.send(function(dataResponse) {
+ try {
+ var response =
me.wrapObject(me.getData(dataResponse, 'm'));
+ me.handleAsync(reqID, response);
+ } catch (e) {
+ me.handleError(reqID, e);
+ }
+ });
+ };
+ ]]></script>
+ </get>
+ <update>
+ <script><![CDATA[
+ /**
+ * Sends request to remote site to update mediaItem.
+ * @param {string} reqID The request id.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * AlbumsRequestOptions.
+ * @member opensocial.flash.mediaItems
+ */
+ api.mediaItems.update = function(reqID, options, req,
resKey) {
+ var req = opensocial.newDataRequest();
+ var request =
me.api.mediaItem.getRequest(options, 'update', req);
+ req.add(request, 'm');
+ req.send(function(dataResponse) {
+ try {
+ me.getData(dataResponse, 'm');
+ me.handleAsync(reqID);
+ } catch (e) {
+ me.handleError(reqID, e);
+ }
+ });
+ };
+ ]]></script>
+ </update>
+ </mediaItems>
<!-- ========================== OSAPI.UI
=========================== -->
<ui>
@@ -1513,6 +1744,28 @@
};
]]></script>
</requestPermission>
+ <requestUploadMediaItem>
+ <script><![CDATA[
+ /**
+ * Sends request to remote site to request an mediaitem
upload.
+ * @param {string} reqID The request id.
+ * @param {Object.<string, Object>?} options An object
unwrapped from
+ * UIRequestOptions.
+ * @member opensocial.flash.ui
+ */
+ api.ui.requestUploadMediaItem = function(reqID, options) {
+ var albumId = options['albumId'];
+ opensocial.requestUploadMediaItem(albumId,
function(responseItem) {
+ try {
+ me.getDataItem(responseItem);
+ me.handleAsync(reqID);
+ } catch (e) {
+ me.handleError(reqID, e);
+ }
+ });
+ };
+ ]]></script>
+ </requestUploadMediaItem>
</ui>
</api>