Showing posts with label mashup. Show all posts
Showing posts with label mashup. Show all posts

Thursday, July 17, 2008

Google Calendar Demo Gadgets

I have implemented some calendar gadgets based on existing legacy gadgets.

(1) Google calendar viewer gadget
This app does not use Google Calendar Javascript API. Google Calendar generates automatically feeds for public events owned by a user. Address of the feed is http://www.google.com/calendar/feeds/username@gmail.com/public/full. This gadget retrieves public events of a specific calendar user and display them accordingly. Not all events are retrieved and displayed.
Assume today is A, then events that fall into period (A-30days) to (A + 60days) are handled.
Note: this gadget can just get public events.
I deployed it in both Orkut sandbox and Ringside.  Following screenshots are taken from Orkut.

Main page:
image

Description of various parts of the page:
image

When a user clicks the brief information of an event, detailed information will be displayed in place.
 image

(2) Standalone Google calendar client application.
This app does not rely on Gadget API or Open Social API. It just relies on Google Calendar Javascript library. So it can be run independently without gadget container. I deployed it on Ringside using IFrame.
It can be accessed by visiting http://gf1.ucs.indiana.edu:8080/gcalendar/calendar2.htm or you can use it in Ringside.

If a user has not logged in Google account, he/she will see a "Login" button.
image

After user clicks the "Login" button, he/she will be redirected to Google login page. After he/she logs in Google, he/she will be redirected to a "Access Request Authorization" page. Then the user can choose to grant or deny the access. It is shown below:
image

After the user grants access, following initial page will be displayed:
image

Description of every part in the page:
image 

When a user clicks the time range selection text box, a data picker will be displayed so that the user can easily select time period. It is shown below:
image

When a user selects his/her time range and clicks "Go" button, information of events within the specific time perios will be retrieved. And when the user clicks the drop-down box with label "Select...", a list of events will be displayed. See below screenshot:
 image

When the user selects an event, detailed information will be displayed in corresponding fields.
image

The user can modify information of an event and save it back in Google Calendar by clicking button "Save to Google Calendar".
image

(3) Google calendar gadget which allowes users to log in
This gadget is different from the first gadget mentioned above because this gadget allowes users to log in so that all events(public and private) can be retrieved and displayed. This gadget is based on the app(2) which is described above. The user interface is the same as that of app(2).
I deployed it on Ringside and Orkut sandbox successfully.

Wednesday, July 09, 2008

Demo Apps

I have written several demo apps.
(1) A regular gadget with gadgets.* API
This is based on official youtube gadget presented here. Official youtube gadget uses traditional gadget API, which means it can not be run in open social containers.
I modified the source of official youtube gadget to make it compatible with open social API. Source is hosted here.
I run it on Ringside, and it works well. Screenshot is shown below:
ringside_youtube2_thumb1
Besides, I run it on iGoogle sandbox and Orkut sandbox successfully.

(2) An open social gadget
This gadget is written with Open Social API so that it can be run in all standard compatible containers. This gadget lists all friends you have in a container. If you add it to your Orkut account, it will list your friends in your Orkut account. If you add it to your hi5 account, it will list your friends in your hi5 account.
Source is hosted here.
I run it on Ringside, and screenshot is shown below:
image_thumb1
Besides, I run it on iGoogle sandbox and Orkut sandbox successfully.

(3) A Facebook application.
This application gets your friend list on Facebook and displays related information including profile picture, last name, first name and birth date. You can see its information here. Meanwhile you can add it to your Facebook account.
Screenshot is shown below:
image_thumb3 

(4) A port of application (3)(The facebook application). 
Because Ringside implements Facebook API and FBML, application (3) should be able to be run on Ringside with minor modifications. New API key and secret should be used. Besides Ringside RESTful server (instead of Facebook server) address should be used.
Finally, I got it to run successfully on Ringside.
ringside_friend_thumb1

(5) Make Facebook to use Ringside application
I used the method described in this post and this post. It should work. But unfortunately it did not work. Currently I don't know why.

To try it in Ringside
First go to http://gf1.ucs.indiana.edu:8080/ to log in.
Then click tab "Applications":
ringside_tab_thumb2
Following page should be displayed:
ringside_apps_thumb1
Main panel displays a list of all applications you have added to your account. You can click any one to use it.
Or you can click button "Find More Apps" at top right corner to browse more available apps.
Application "youtube gadget" is the application (1) described above.
Application "Friend gadget(Open social)" is the application (2) described above.
Application "Your Friends Native" is the application(4) described above.
To run application (3), you need a Facebook account and add it to your account by accessing here.

Saturday, July 05, 2008

Google Gadget and OpenSocial

Opensocial API is an open set of APIs which can be used to access various social network applications. Currently, social network apps which support OpenSocial API are listed here.

Google Gadget:
Official specification of Gadget server/container is here(http://code.google.com/apis/gadgets/docs/spec.html). It includes abundant information about how gadget container handles gadget requests from clients. The basic idea is gadget container processes gadget .xml definition file and generates corresponding HTML+CSS+Javascript and then transferres the result to end users. Variety of functionalities gadget deveoper can utilize depends on gadget container. Different gadget containers may provide different set of features. However, some APIs are mandatory and must be supported by all compliant implementations. Javascript gadget specification is here(http://code.google.com/apis/gadgets/docs/reference/). Gadget XML reference is here(http://code.google.com/apis/gadgets/docs/reference.html). This site contains many useful hints about how to develop and test Google Gadgets.

There are two set of Gadget APIs:Legacy API and gadgets.* api(used by Open Social spec).

Gadget Host:
If you don't have a web server to host the gadget XML file, Google Gadgets Editor is a tool provided by Google which can be used to edit and host gadgets. You can test your gadgets in GGE withoug logging in Google. But you cannot save your gadgets without logging in. You can add Google Gadget Editor gadget to your iGoogle homepage by accessing this site. It seems that only legacy gadget APIs are supported in preview mode by GGE. GGE just provides very simple functionalities. You can use it just as a hosting service which stores your gadget spec files. If you want more functionalities like version control, you can use Google Code Hosting(http://code.google.com/hosting/) or other full-fledged hosting services.  This site contains detailed information about how to use Google hosting services.

Legacy Gadget Container:
Besides spec files, gadget container is necessary to run your gadgets. To test legacy Google Gadgets, you can GGE or iGoogle content directory. Here contains instructions about how to publish your gadgets to iGoogle content directory. You can update your submitted gadgets using this site. NOTE: iGoogle content directory only applies to legacy gadgets.

Open Social Gadget container:
To test new google gadgets(using gadgets.* API), you should use a certain container listed here. Note: two services from Google are in the list. However, to use them, you must sign up for sandbox access besides regular logging in. To sign up sandbox access of iGoogle, visit this site(http://www.google.com/ig/sandbox). To sign up sandbox access of Orkut, visit this site. These two services are still in beta phase and thus provide limited functionalities.

Resources:
iGoogle Dev: http://code.google.com/apis/igoogle/docs/igoogledevguide.html
Orkut Dev: http://code.google.com/apis/orkut/docs/orkutdevguide.html

Wednesday, July 02, 2008

Ringside application development

Table of Content

Ringside Social Application Server seems a promising project. However, because it is still in beta development, online documents are not well organized. A better directory layout may help a lot. After reading the documents and trying Ringside server myself, I got some experience which is shared in this post.

What Ringside server can do?

(1) Open Social container.
It means all open social applications can be run on Ringside server. Of course, the open social applications should not use extensions provided a specific container( e.g. iGoogle, Orkut ) if you want these apps to run on Ringside server.
Note: Gadgets in Google content directory(repository of traditional gadgets) can not be used on Ringside server because traditional Gadget API is different from new Gadget spec used by Open Social API.
(2) Facebook platform mock
It supports FBML and Facebook API and adds some extensions, which means you can use the same function names and markups of Facebook to write your Ringside apps.
(3) Extensibility
Because Ringside server is open source, users can customize and extend Ringside server in the way they wish. For example, users can add their new APIs and extend XML tags to provide customized tags.

How to add and set up a new app?

Add a new app:
First click "Developer" tab, and in the main panel click "Create a New Application", following picture should be displayed:
image
When you create a new application in Ringside, the procedure is well similar to that of Facebook. The configuration options are almost the same as well. Look at below picture:
image 
One big difference is highlighted in the picture. In Facebook, you can just choose your app type between "Use FBML" and "Use IFrame". However, in Ringside server, one more option("Use Open Social") is supported. The key thing you should configure is "Callback URL" which points to the location of your application. For option "Canvas URL", you just need to specify a unique name and you must not specify the full-path URL. Prefix is implicit which is http://ringside_server_domain:port/canvas.php/. So if you specify "myapp" as your "Canvas URL", the URL to access your app becomes http://ringside_server_domain:port/canvas.php/myapp.
Note!!! When you set "Callback URL", you had better not use loopback domain or ip(e.g. localhost, 127.0.0.1) as host. If type of your app is "Use FBML", it may work well. In this mode, the output content is fully contained in the response. However, if type of your app is "Use IFrame", your app may not work. In this mode, a frame element is embedded in returned html and src attribute is set to point to the "Callback URL". As a result, the browser will send requests to its local host (the host a user is using to try your app) instead of the server which hosts your app. After you deploy and publish the app, using loopback address will definitely cause problems. To make your app work both in FBML mode and IFrame mode, loopback address should not be used!!!

Develop your own Ringside applications in PHP

See instructions here. After you get PHP library, generally you need to modify your php.ini and append path of the library to variable include_path so that PHP interpreter knows where to look for Ringside PHP library.
You applications do not need to be hosted on the same host as Ringside server. Ringside provides a PHP client library which can be used to ease PHP development. Ringside PHP client library is based on Facebook PHP client library. But Ringside wraps the code in original Facebook PHP client library. In original Facebook PHP client library, the rest server which you send requests to is hard-coded in the source code as "http://www.facebook.com". There is a class in Ringside library called "RingsideApiClients" which is a subclass of class "Facebook" and overwrites most of the inherited functions. Besides, Ringside adds some extra APIs which are mainly contained in class "RingsideApiClientsRest"(It is a subclass of class "FacebookRestClient").
So, you should use class "RingsideApiClients" to send requests to backend Ringside server. One thing your must do is configure the Ringside server URL so that your app knows where requests should be sent. There are two ways that I know:
(1) When you create an instance of RingsideApiClients, you can send weburl, serverurl and socialurl as parameters of contructor.
Prototype of the constructor is :
public function __construct($api_key, $secret, $webUrl = null, $serverUrl = null, $socialUrl = null, $client = null ).
(2) Change static variable in class RingsideApiClientsConfig.
Sample usage:
RingsideApiClientsConfig::$webUrl= ringside_web_url;
RingsideApiClientsConfig::$serverUrl = ringside_server_url;
RingsideApiClientsConfig::$socialUrl = ringside_social_url;

Extend API provided by Ringside Server

Good resource (1), (2).

Add your own tags to Ringside server

Good resources (1), (2).

Tuesday, July 01, 2008

Ringside Networks Social Application Server on Linux


This post is based on official documents from Ringside, and describes steps to set up Ringside Networks Social Application Server.
(1) Download
First, download the app server from here. In the distributed package, all dependent packages/libraries are included. Main additional components include: Apache2, PHP5 (core package and some extensions), Mysql and some unix/linux tools(e.g. curl, tidy and their libraries). So size of the whole package is sort of big. But it is an all-in-one package so that you can easily make it work without much configuration. Installation directory structure is explained here.
If you don't want the all-in-one package, check instructions here to individually set up your environment.

(2) Install
A GUI installation wizard is provided. You can get instructions here. The process is easy.

(3) Config
You can change various apache setting by modifying following files:
(*)%RNAS_ROOT%/apps/phpmyadmin/conf/phpmyadmin.conf
//This conf file is related to using of phpmyadmin. By default, users can only access phpmyadmin from IP 127.0.0.1. You can modify it
//if you want to use phpmyadmin from remote client.
(*)%RNAS_ROOT%/apps/ringside/conf/ringside.conf
//
ringside related conf. It sets where the document root is... Generally, this file should not be modified.
(*)%RNAS_ROOT%/apache2/conf/httpd.conf
//General apache http server configuration is in this file. If you want to change the port, set it here.

(4) Run
Let me assume you installed Ringside Networks Application Server into directory %RNAS_ROOT%. Under directory %RNAS_ROOT%, you should see a script called "ctlscript.sh" which can be used to start/stop/restart server components. Sample commands are shown below:
./ctlscript.sh start                    //start both apache and mysql
./ctlscript.sh stop mysql           //stop mysql
./ctlscript.sh status apache       //get status of apache server.
Official document is here which has more information.

(5) Setup/Initialization
First, you need to access http://your_ip_or_domain:port/setup.php. Default port is 8080. Then the server will carry out some setup work. For example, a database called ringside is created...
You should see following page:
image

(6) Test/Using
Main page: http://your_ip_or_domain:port
Phpmyadmin access: http://your_ip_or_domain:port/phpmyadmin.
Login: http://your_ip_or_domain:port/login.php. When you run initial setup in step (5), a user is automatically generated for you. See content in the green box in last picture.

(7) upgrades
[*] Upgrade via PEAR:
You can update Ringside source via PEAR. Instructions are described here.
[*] Check out latest code:
You can checkout latest Ringside code and build your own development/deployment environment. You should install the all-in-one package first. By following instructures here, you substitute new version of Ringside for the original one which is included in the all-in-one package.

(8) Remove
Use executable uninstall. Check instructions here.

Thursday, June 19, 2008

Client side techniques

Namespace mimic in Javascript (similar to technique used by YUI):
namespace:   function(   sNameSpace, obj   )   {  
    if   (!sNameSpace   ||   !sNameSpace.length)   {  
        return   null;  
    }  
    var   levels   =   sNameSpace.split(".");  
    var   currentNS   =   CGL;  
    //   CGL   is   implied,   so   it   is   ignored   if   it   is   included  
    for   (var   i=(levels[0]   ==   "CGL")   ?   1   :   0;   i<levels.length;   ++i)   { 
        if( arguments.length == 2 && i == levels.length - 1)
	    currentNS[levels[i]]   =   obj;
	else
	    currentNS[levels[i]]   =   currentNS[levels[i]]   ||   {};  
	currentNS   =   currentNS[levels[i]];  
    }
    return   currentNS;  
}
By default, following namespaces are supported:
CGL.mashup.resourcetype:
This object maintains resource types we support. Currently, text, image and video are supported.
CGL.mashup.addr:
This object maintains base path for our applications.
CGL.mashup.sites:
This object maintains all backend sites we support. Currently, Youtube and Flickr are supported.
CGL.mashup.log:
This object maintains request history so that in the future we can reinvoke a certain old request.
CGL.mashup.init:
All initialization work is done here.
CGL.mashup.urlbuilder:
This object provides functions which can ease construction of request URL to access various resources.
CGL.mashup.service:
This object provides functions which send various requests (e.g. get user information) to server side.
CGL.mashup.helper:
This object includes some utility functions.
GL.mashup.htmlformatter:
This object contains functions that can be used to display response in a specific format .
CGL.mashup.jsonresponse:
This object handls JSON responses from server and parses the content.
CGL.mashup.opmapper:
This object maps operation names to concrete function implementations. Callback can be specified as well.

Web2.0 Integration Summary

The server-side architecture is described here:
http://zhenhua-guo.blogspot.com/2008/05/mashup-architecture.html.

Authentication: OpenID which is described here (http://zhenhua-guo.blogspot.com/2008/05/openid.html).
Authorization: Although OAuth seems promising, it has not been supported by large web 2.0 applications. So, I make use of various authorization mechanisms of different applications.

RESTful web services are used instead of SOAP-based web services. URL pattern used to access various resources is described here(http://zhenhua-guo.blogspot.com/2008/05/url-pattern-in-mashup.html).

At client side, Ajax is used to enhance user experience. Client side functionality is described here(http://zhenhua-guo.blogspot.com/2008/06/client-side-techniques.html).

Sunday, May 25, 2008

OAuth

In my mashup framework, OpenID is used to do authentication which provides a way to make sure the users are really who they claim to be. The mechanism is that the users prove that they own/control the OpenID they provides. Here is what I wrote about OpenID.

However, OpenID just solves authentication. After users are authenticated, OpenID does not specify how the third-party apps access the protected data on service providers. And the requirement that third-party apps can access protected data stored on service providers on behalf of users is not imaginary, but real. In my mashup framework, I need to manipulate data on behalf of users which needs authorization besides authentication. Youtube and Flickr both provide ways for third-party integration. They provide similar authorization procedures (I am using this mechanism right now) which fundamentally match principles of OAuth specification.

OAuth provides a way for users to grant access to third-party apps. The procedure is pretty much the same as OpenID. What is different are parameters in requests and responses. OAuth is an independent specification which means it is not an extension of OpenID. But, in my opinion, it may be better to combine these two together because they are similar to each other. In this way, user experience can be improved because authentication and authorization can be done in the same pass instead of two. However, some sites may just support authentication service or authorization service (in terms of support of open standards like OpenID, OAuth). So how to combine them together without losing flexibility is an issue.

One problem that OAuth does not address is fine-grained access control. I think this issue must be addressed in the long run. However, nowadays, the goal is too far to reach. Actually, current version of OAuth is not supported widely.

DataPortability is a new organization which aims to promote data portability. Of course, it includes OpenID and OAuth with respect to authentication and authorization data portability. I am not sure which ones will survive and stand out  eventually, but this is a good signal that data portability is being considered as a critical issue and I hope it will be addressed in the near future.

Saturday, May 24, 2008

Authentication and Authorization in Mashup

Authentication
Currently, I don't build my own independent user authentication system. I make use of OpenID to utilize existing authentication systems, such as Yahoo Flickr, Google Blogspot, LiveJournal... You can check whether you have already had an OpenID here. I wrote a simple introduction. In essence, we delegate the task to existing authentication systems.
After a user is authenticated successfully, OpenID is used to track the user. Servlet session technique is used to associate session id and user information.

Authorization
Currently, I don't ask end users for their usernames and passwords in existing services (e.g. youtube, flickr) because it requires deep trust of end users. The user id redirected to an authorization web page hosted by the destination service(e.g. youtube). If the user accepts the request, then the user browser will be redirected to my mashup application. Generally, an auth token is appended to the URL which will be used in following requests.
Currently, for every backend service, I request the user to authorize the most powerful privilege level. For example, if the service supports READ and WRITE permission control, my application will request WRITE permission. If the service supports READ, WRITE and DELETE permission control, my application will request DELETE permission. This is not always a good strategy. But because of diversity of permission control systems, I must choose the mechanism which can be used in every possible service.
Maybe in the future, I can come up with a better framework with fine-grained access control.

URL Pattern In Mashup

URL Pattern

Note: All variables enclosed in ‘{’ and ‘}’ must be substituted with real values.
GET means HTTP GET request type and POST means HTTP POST type.

/cgl/feeds/api/{category}/{service}/users/{userid}
GET:
    Get information of a user.

/cgl/feeds/api/{category}/{service}/login
GET:
     Login the service.

/cgl/feeds/api/{category}/{service}/users/{userid}/resources
GET:
    Get all resources of the user.
POST:
    Add a new resource.

/cgl/feeds/api/{category}/{service}/users/{userid}/resources/resourceid
/cgl/feeds/api/{category}/{service}/resources/resourceid
GET:
    Get information of a specific resource.
DELETE:
    Delete the corresponding resource.
PUT:
    Update the corresponding resource.

/cgl/feeds/api/{category}/{service}/resources/resourceid/comments
GET:
    Get all comments of the resource.
POST:
    Add a new comment.

/cgl/feeds/api/{category}/{service}/resources/resourceid/rating
GET:
Get rating of the resource.

/cgl/feeds/api/{category}/{service}/tag/{tag}?perpage={perpage}&page={page}
GET:
    Get records by tag. Parameter perpage indicates how many resources you want to retrieve.Parameter page indicates which page you want to retrieve.

/cgl/feeds/api/{category}/{service}/statistics/{standard}? perpage={perpage}&page={page}
GET:
    Get records by standards.
    E.g. most viewed, most recent…

Example:

/cgl/feeds/api/videos/youtube/tag/soccer
get resources tagged as soccer.
/cgl/feeds/api/videos/youtube/statistics/most_viewed
get resources that are most viewed.
/cgl/feeds/api/pictures/flickr/users/testuser/resources
get resources belonging to user testuser.

Saturday, May 10, 2008

Youtube API usage

Authentication

       http://code.google.com/apis/youtube/developers_guide_protocol.html
       It is recommended that you include the proper authentication headers in all of your requests even if those requests do not explicitly require authentication.
       A request must include the X-GData-Key and Authorization headers.
       The X-GData-Key header specifies your developer key, a value that uniquely identifies your application(s). The Authorization header specifies a token that you obtain for each user using one of two authentication schemes, AuthSub or ClientLogin. Headers are like this:

AuthSub

ClientLogin

Authorization:AuthSub token=<authentication_token>

X-GData-Key: key=<developer_key>

Authorization:GoogleLogin auth=<authentication_token>

X-GData-Key: key=<developer_key>

(1)    Functions supported in AuthSub
http://code.google.com/apis/accounts/docs/AuthForWebApps.html

(1.1)           AuthSubRequest

       A call to this method sends the user to a Google Accounts web page, where the user is given the opportunity to log in and grant Google account access to the web application. If successful, Google provides a single-use authentication token, which the web application can use to access the user's Google service data. This is done by using GET to a specific formatted URL.

Sample URL

https://www.google.com/accounts/AuthSubRequest?scope=http%3A%2F%2Fgdata.youtube.com&next=http%3A%2F%2Fzhguo.blogspot.com

(1.2)           AuthSubSessionToken

       A call to this method allows the web application to exchange a single-use token for a session token.

Sample request
       curl https://www.google.com/accounts/AuthSubSessionToken --header ‘Authorization: AuthSub token="token"’

Response

Token=DQAA...7DCTN

Expiration=20061004T123456Z

(1.3)          AuthSubRevokeToken

       A call to this method revokes a session token. Once a token is revoked it is no longer valid.

Sample Request
       curl https://www.google.com/accounts/AuthSubRevokeToken --header ‘Authorization: AuthSub token="token"’ 

(1.4)           AuthSubTokenInfo.

       A call to this method verifies whether a specified session token is valid and returns data associated with the token. This operation applies to both one-time-use and session keys.

Sample request

         curl https://www.google.com/accounts/AuthSubTokenInfo --header 'Authorization: AuthSub token="CO7xhO-6GhDT5f2tAwd"'

Sample response

Target=http://www.yourwebapp.com

Scope=http://www.google.com/calendar/feeds/

Secure=true

(2)    ClientLogin

       http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html

       Before using ClientLogin, you must have an existing Google account. The POST request should be structured as a form post with the default encoding application/x-www-form-urlencoded. Parameters should be included in the body of the post.

Action URL parameter: https://www.google.com/accounts/ClientLogin

Sample request format:

POST /accounts/ClientLogin HTTP/1.0

Content-type: application/x-www-form-urlencoded

 

accountType=HOSTED_OR_GOOGLE&Email=jondoe@gmail.com&Passwd=north23AZ&service=cl&source=Gulp-CalGulp-1.05

CURL command
       curl    --location https://www.google.com/youtube/accounts/ClientLogin 
                   --data 'Email=username&Passwd=password&service=youtube&source=Test'
                   --header 'Content-Type:application/x-www-form-urlencoded' -i

Sample Response:

SID=DQAAAGgA...7Zg8CTN

LSID=DQAAAGsA...lk8BBbG

Auth=DQAAAGgA...dk3fA5N

 (3)    Difference of two mechanisms

       To use ClientLogin, a third-party application must own Youtube’s username and password of every user. Then the third-party application can do anything the end user can do. This mechanism is convenient for third-party apps to use because it does not require much intervening from users. However, it requires trust of users who may be afraid that their person information is not stored appropriately.

       To use AuthSub, a third-party does not need to own Youtube’s username and password of user. Instead, the user will be redirected to a web site from google to authorize third-party app’s access to user’s account. At first, third-party app is given a one-time access key which can be used to exchange a session key that can be used longer. This method is more secure for users at the cost of manually authorizing access requests.

Some development detail

(1)    Some videos are not allowed to be embedded in third-party applications.

       In the feed of these videos, mediagroup::content element does not exist!!! I manually construct URL by concatenating http://gdata.youtube.com/feeds/api/videos/ and video id and try to embed it into my app. As I expect, it does not work. However, I figured out a method which can work around this problem. I concatenate http://www.youtube.com/swf/l.swf?video_id= and video id and it works.

(2)    Some videos are not allowed to be commented by some users. These videos should be handled carefully.

       http://gdata.youtube.com/feeds/api/videos/gmNbl5ZTBZE

(3)    Duplicate elimination

       If you upload the same video clip more then once using different metadata, Youtube can figure it out and all uploads but the first one will be rejected. I am not sure how they compare two different video clips, maybe using MD5 to calculate a signature. The duplicate uploads are still displayed in your account. And all metadata is preserved except the video clip itself. The only difference between original upload and following duplicate uploads is that you can not play duplicate video clips.

clip_image002

As shown in above picture, metadata (e.g. description, tags, views, published time…) are still there. But the video clip itself is rejected

(4)    OpenSearch support

       If you search videos on Youtube, in returned feed openSearch extension is supported:

<openSearch:totalResults>274842</openSearch:totalResults>

<openSearch:startIndex>1</openSearch:startIndex>

<openSearch:itemsPerPage>25</openSearch:itemsPerPage> 

(5)    Navigation of many returned results.

       In returned feeds, if not all results are returned, there should be a link element in the feed. It is like this:

<link rel="next" type="application/atom+xml" href="http://... "/>

<link rel="previous" type="application/atom+xml" href="http://... "/>

 

Mashup Architecture

Architecture:
image

Adapter:

image

TODO:
Integrate authentication architecture.