1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Building OpenSocial Apps- P5 pdf

50 327 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Building OpenSocial Apps
Trường học Unknown
Chuyên ngành Computer Science
Thể loại Tài liệu
Định dạng
Số trang 50
Dung lượng 317,78 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Table 9.1 Overview of Endpoints Supported by the MySpace SDKFunction name get_albums Description Fetches a list of albums Parameters user_id—the ID of the user Sample response { "count":

Trang 1

Summary

Being able to communicate securely with an external server has some huge advantages.

You can write custom Web services and host large databases.The possibilities are nearly limitless.

There are many options out there for hosting providers.We chose Google App Engine mainly because it is free for sites with small amounts of traffic, and free is nice Amazon Web Service (AWS) is a competing “cloud-computing” service that behaves differently from GAE.With GAE you’re forced to use their Web servers and database back end, write your code in Python or Java, and upload it all to their servers.With AWS you can pick and choose which of their services to use and in what language you write your code.

There’s also Microsoft’s Azure, not to mention traditional Web hosting companies from which you can rent physical servers sitting in physical racks.There’s also that spare

Figure 8.3 Example of Canvas surface link on a user’s Profile

Trang 2

computer you have sitting in your closet, but that probably can’t handle too many concurrent users (see Chapter 13, Performance, Scaling, and Security, to learn how to scale your app).

Before deciding on a service, it’s best to shop around and do some research See what’s easiest, and possibly cheapest, for your new app.Whatever you choose, use the basic principles outlined in this chapter to safely communicate between MySpace and your hosting service.

NoteCode listings and/or code examples for this chapter can be found on our Google Codepage under http://opensocialtictactoe.googlecode.com

Trang 3

ptg

Trang 4

External Iframe Apps

T his chapter is essentially an extension of the preceding one In Chapter 8 we discussed several elements of OAuth that are relevant to this chapter and to writing external iframe apps on the MySpace platform We recommend that if you skipped Chapter 8,

go back now and read the sections that describe OAuth.

Moving forward in this chapter, we’ll assume you’re familiar with OAuth and with setting up and publishing Web services using Python on Google App Engine (GAE).

In this chapter we’ll take our existing on-site app and port it over to an external iframe, or off-site, app Be prepared, because there’s a pretty large paradigm shift from an on-site JavaScript app to an off-site app.

With on-site apps, you supply some markup and possibly a few Web services, and the MySpace platform takes care of the rest.Your markup is wrapped in some headers and footers (mostly script tags that pull in the OpenSocial container) so it can be correctly rendered When a user accesses the page, the MySpace infrastructure takes care of the actual rendering of the page.

When the app starts running, it has very little knowledge of the user; it really knows only the IDs of both the Viewer and the Owner.That means that the app has to send out requests for data when it loads—maybe it requires a friend list, or some details from your servers.These asynchronous requests are sent out while the app idles, perhaps with

a loading message and one of those “spinner” graphics twirling away to give the illusion

of activity.When the requests come back, the app leaps into action, as it should now have all the data it needs to fully load.

That’s the typical flow of an on-site app, but off-site apps have a very different pattern For an off-site app, MySpace simply renders an iframe onto the page with the

srcattribute set to the URL of your choice Since you control the contents of the URL, you have full control over the app But this control comes at a cost; you are now responsible for the rendering of the app.

Off-site apps behave much more like traditional Web pages A request comes in, then it’s picked up by your Web server and passed off for processing to your scripting language of choice, such as PHP, ASP.NET, or Python The request is then processed.

Trang 5

Let’s say we send off a REST request to the MySpace API for a friend list and also pull some data out of our local database The friend list and the data are then pushed down onto the page used as the iframe app In this case, the app has all the data it needs

to fully load at render time The trade-off here is that on-site apps render immediately, then idle while waiting for data Off-site apps, by contrast, do their waiting for data up front and then completely load.

The other big difference is that with on on-site apps you really have only one page.

In our Tic-Tac-Toe app we hide and show various HTML elements to give the illusion

of multiple pages Off-site apps can have multiple actual pages, so markup and JavaScript code can be separated a little more cleanly.Well-known techniques like clicking a button that posts back a form can be used.

As you can see, there are some pros and cons to using an off-site app.The biggest reason for using one would be that you have an existing app somewhere on the Web that you could wrap an iframe around and there you go—you now have an instant MySpace app So, let’s dig a little deeper into what it would take to accomplish that.

REST APIs

What exactly is a “REST API”? Well, REST stands for REpresentational State Transfer, which isn’t overly helpful as an actual definition It essentially comes down to how resources are accessed The underlying assumption with REST is that objects and records exist in one place, their universal resource identifier (URI), on the Internet and stay there.The address is used to state the “who” of the object we wish to work with.

This is coupled with an action verb (for example, GET or POST) in the request to state the “what” of what we wish to do.

How a REST Web Service Is Addressed

A REST Web service is addressed via URIs Say we have a REST Web service that returns data on fruit.To get a list of all the fruit available, we might access a URI like this with a GET request:

And even more specifically, there’s an orchard down the street that we want data on.

Each producer would have a unique identifier; this one’s is 12345 We might access the price list for that producer’s Granny Smiths via the following URI:

Trang 6

This is an example of a REST API; we access the actual data we want by addressing the URI in a specific way and use a globally unique identifier (GUID) to drill down to specific entities MySpace’s APIs follow a similar pattern but replace fruit with MySpace users, GUIDs with MySpace IDs, and price lists with friend lists.

If you are not used to using REST, this may seem a little strange and low-level, but MySpace provides several SDKs to help you out.The beauty of having an SDK is that just about all of this is abstracted away You’ll see shortly how easy it is to make requests

to the MySpace APIs using an SDK.

Setting Up an External Iframe App

Now that we understand what the REST APIs are, let’s take a look at how to set up an app on MySpace that will make use of them Up until now, our Tic-Tac-Toe app has used MySpace’s OpenSocial container to make requests to the API, has lived on MySpace servers, and has been written entirely in JavaScript.

What if we had an app already written and running on a Web site and wanted to make it a MySpace app? Would we have to completely rewrite the app in JavaScript?

And convert all of our server communication to makeRequest? That’s one possibility, but another is to simply “iframe your app.”

What that means is that MySpace provides the ability to load in an external iframe

on the Canvas surface instead of loading in the usual MySpace-hosted iframe Let’s walk through what it might take to convert parts of our Tic-Tac-Toe app to an iframe app.

First we’ll need to create a new app by following the instructions found in Chapter 1, Your First MySpace App Once it’s created, navigate to Edit App Source and click on the Canvas Surface tab (it’s the default tab) Instead of selecting HTML/Javascript Source from the radio buttons at the top, we’ll select External Iframe.

Then, inside the External IFrame URL field, enter the starting point for your app In our case, and as shown in Figure 9.1, it’s http://opensocial—tic-tac-toe.appspot.com/play.

When the Canvas surface for this app loads, it will load the page you entered into the External Iframe URL field instead of loading a MySpace-hosted page In addition, it will append several parameters to the source of the iframe in order to pass values to your app.

An example of this would be the following:

Trang 7

parameters later in the chapter when we discuss cross-domain communication and sending messages.

When our initial page loads, we’ll be able to determine the user’s ID, use the MySpace SDK to fetch any data we might need from the MySpace APIs, and push the data onto the page when it renders Let’s implement the Play and Invite tabs of our current Tic-Tac-Toe app.The Play tab requires the user’s Profile data, and the Invite tab requires the user’s friend list.

Figure 9.1 Screen shot of the external iframe URL setup process

Trang 8

The Server Code

Let’s go back to our code from Chapter 8 and update our app.yaml again For reference, you can find the Chapter 8 code in this folder:

http://opensocialtictactoe.googlecode.com/svn/trunk/chapter8/opensocial—tic-tac-toe/.

application: opensocial—tic-tac-toeversion: 1

runtime: pythonapi_version: 1

handlers:

- url: /wsscript: ws/ws.py

- url: /playscript: play/play.py

- url: /invitescript: invite/invite.py

As you can see, we’re going to use two separate pages for the two tabs The handlers for each (play.py and invite.py) are very similar Let’s take a look at invite.py in detail and then take a quick look at play.py.

import osimport ckeynsecret

from django.utils import simplejson

from google.appengine.ext import webappfrom google.appengine.ext.webapp.util import run_wsgi_appfrom google.appengine.ext.webapp import template

from myspace.myspaceapi import MySpace, MySpaceErrorfrom oauthlib import oauth

from entities import WinLoss

class Invite(webapp.RequestHandler):

def get(self):

id = self.request.get(‘opensocial_viewer_id’)appid = self.request.get(‘appid’)

opensocial_token = self.request.get(‘opensocial_token’)

error = False

Trang 9

try:

int(id)int(appid)except:

error = True

ms = MySpace(ckeynsecret.CONSUMER_KEY, ckeynsecret.CONSUMER_SECRET)ms.token = oauth.OAuthToken(‘’, ‘’)

try:

friends = ms.get_friends(id)except MySpaceError, mse:

error = True

if error:

msg = ‘Oops, there was an error, try refreshing the page!’

self.response.out.write(msg)return

path = os.path.join(os.path.dirname( file ), ‘invite.html’)self.response.out.write(template.render(path, template_values))

application = webapp.WSGIApplication(

[(‘/invite’, Invite)],debug=True)

def main():

run_wsgi_app(application)

if name == “ main ”:

main()import ckeynsecretincludes our consumer key and secret from an external file, and we import the official MySpace SDK using from myspace.myspaceapi importMySpace, MySpaceError For the request handler itself, we define only a GET handler Just as in our Chapter 8 code, it starts by checking the incoming user ID and

Trang 10

To make use of the MySpace SDK (you can download it at http://code.google.com/p/myspaceid-sdk/ and pick the language of your choice), we need to instantiate a MySpaceobject All of the API functionality will be done through this object To initialize the MySpaceobject, you need to always do the following two things:

ms = MySpace(ckeynsecret.CONSUMER_KEY, ckeynsecret.CONSUMER_SECRET)ms.token = oauth.OAuthToken('', '')

The first line creates the MySpaceobject given the consumer key and secret.The second creates an OAuth token; the two parameters are always empty strings when accessing the MySpace API with an OpenSocial app.

Fetching a friend list is as simple as this:

friends = ms.get_friends(id)

That’s all there is to it; the SDK should take care of the rest Assuming no exception was thrown, we now have the user’s friend list.The circumstances for throwing an exception are mostly permission-related—the user might not have the app installed, might be blocking the app, and so on.

We then get the friend list ready to be pushed down onto the page by using

simplejson.dumps(friends) We pass a total of four items down to the page: the friend list, the app ID, the owner ID, and the OpenSocial token.

REST API List

Now that we’ve seen one of the APIs in action, let’s take a look at what other functionality the SDKs support Table 9.1 describes all of the endpoints supported

by the MySpace SDK as of this writing Some of the data has been truncated for readability, but these are mostly just long URLs The most important part, the schema

of the data, is intact MySpace also maintains documentation for the APIs (not the SDKs themselves, just the bare endpoints) at http://wiki.developer.myspace.com/index.

php?title=MySpace_REST_Resources.

Table 9.1 Overview of Endpoints Supported by the MySpace SDKFunction name get_albums

Description Fetches a list of albums

Parameters <integer>user_id—the ID of the user

Sample response {

"count": 1,

"albums":

Trang 11

Function name get_album

Description Fetches data for a particular album

Parameters <integer>user_id—the ID of the user

<integer>album_id—the ID of the album

Trang 12

Function name get_friends

Description Fetches a list of friends

Parameters <integer>user_id—the ID of the user

<integer>page—the page number

<integer>page_size—the number of records to fetch

<string>list—defines how to filter the friend list; one of thefollowing values can be provided:

top—only the top friendsonline—only friends who are currently onlineapp—only friends who have the app installed

<string>show—what extra data to provide for each friend; anycombination of the following values is allowed:

mood—each friend’s mood

Trang 13

Notes The "next" URI is to aid in paging; it returns the URI to use to

retrieve the next page of friends But since we’re using the SDK andnot manually sending out these requests, we’ll have to maintain the

Trang 14

Function name get_friendship

Description Given a user ID and a list of friend IDs, returns true for each ID in

the list that is a friend of the user, false otherwise

Parameters <integer>user_id—the ID of the user

<string>friend_ids—a semicolon-delimited list of integer IDs

Notes Either the MySpace SDK or the API has a bug with this endpoint

A semicolon-delimited list of friend IDs is required for thefriend_idsparameter The endpoint correctly returns data if youuse just one ID, such as 6221 However, if you supply more thanone ID, such as 6221;123456;876543, the API returns a 401 error

The error provided is “Invalid digital signature for base string.”

Luckily, this endpoint isn’t the most useful

Function name get_mood

Description Fetches the user’s mood data

Parameters <integer>user_id—the ID of the user

Sample response {

"moodLastUpdated": "4\/12\/2009 8:32:10 PM",

Trang 15

Function name get_moods

Description Fetches the entire list of moods currently supported by MySpace for

the particular user

Parameters <integer>user_id—the ID of the user

Sample response {

"moods":

[{

Function name get_photos

Description Fetches a list of photos

Trang 16

Table 9.1 Continued

Parameters <integer>user_id—the ID of the user

<integer>page—the page number

<integer>page_size—the number of records to fetch

Sample response {

"count": 2,

"photos":

[{"photoUri": "http:\/\/uri_to_photo",

Trang 17

Function name get_photo

Description Fetches data on a particular photo

Parameters <integer>user_id—the ID of the user

<integer>photo_id—the ID of the photo

Function name get_profile

Description Fetches Profile data

Trang 18

Table 9.1 Continued

Parameters <integer>user_id—the ID of the user

<string>type—the level of detail to fetch for the Profile data;

valid values are basic, full,and extended

Notes Later in the chapter we’ll discuss the differences among the three

levels of detail The sample response here is for a basic Profile;

we’ll make use of an extended Profile a little later

Function name get_status

Description Fetches the user’s status and mood

Parameters <integer>user_id—the ID of the user

Trang 19

Table 9.1 Continued

Function name get_videos

Description Fetches a list of videos

Parameters <integer>user_id—the ID of the user

Trang 20

Function name get_video

Description Fetches data for a particular video

Parameters <integer>user_id—the ID of the user

<integer>video_id—the ID of the video

Trang 21

Table 9.1 Continued

"videoUri": "http:\/\/uri_to_video"

}

Function name get_activities_atom

Description Fetches the list of app activities that the user has raised

Parameters <integer>user_id—the ID of the user

Sample response "<feed xml:lang=\"en-US\" >

<title type=\"text\">

Recent activities from Chad Russell at MySpace

<\/title>

<subtitle type=\"text\">

This feed contains all of the activities for a

➥single MySpace user

Trang 22

Function name get_friends_activities_atom

Description Fetches the list of app activities that the user’s friends have raised

Parameters <integer>user_id—the ID of the user

Sample response Very similar to the schema outlined for the response of the

get_activities_atom endpoint

Function name set_status

Description Sets the status for the particular user ID

Parameters <integer>user_id—the ID of the user

<string>status—the new status, as an arbitrary string

Sample response ""

Function name set_mood

Description Sets the mood for the particular user ID

Parameters <integer>user_id—the ID of the user

<integer>mood—the new mood; must correspond to one of thevalid mood IDs, which can be fetched using the get_moods API

Sample response ""

Function name create_album

Description Creates a new media album

Trang 23

Table 9.1 Continued

Parameters <integer>user_id—the ID of the user

<string>title—the new title for the album, as an arbitrary string

<string>location—the geographic location where the albummedia takes place, as an arbitrary string

<string>privacy—the album’s privacy setting; valid values are Me(a private album), FriendsOnly (just the user’s friends can see it),and Everyone (a public album)

Sample response {"id": 2098891, "title": "family photos"}

Function name get_indicators

Description Fetches the indicators that are currently raised; can indicate a new

friend request, message, app invite, or comment approval

Parameters <integer>user_id—the ID of the user

Notes In the sample response, the user has one new mail message

pending and one IM message that has yet to be read

Function name send_notification

Description Sends a notification from the app to the specified user; see

Chapter 5, Communication and Viral Features, for details

Parameters <integer>app_id—the app ID that will raise the notification

<string>recipients—a comma-delimited list of integer recipientIDs, such as "6221,12345"

<string>content—the main body of the message

<string>btn0_label—optional; the label for the first button

<string>btn0_surface—optional; which surface the first buttonwill navigate to; can be canvas or appProfile

Trang 24

Note

In the course of researching all of the available endpoints, we created a test page If you’rehaving trouble accessing any of the APIs, this test page might come in handy The testpage comes in two parts The first is a client-side HTML page, which can be downloaded athttp://opensocialtictactoe.googlecode.com/svn/trunk/chapter8/opensocial—tic-tac-toe/index.html

This page has a series of buttons on it, each corresponding to an endpoint (there aresome additional buttons that were used in Chapter 8) Clicking a button causes a Webservice request to some Python code, which can be downloaded at

We hope you’ll find this page useful!

The Client Code

To create the markup and JavaScript for our off-site app, we modified the Canvas surface code from our on-site app Because it’s mostly the same, we won’t repeat it here.The main difference is that instead of Ajax requests being sent to the API when the app loads, the data is already there.The template object we push down from the Python script has four members:friends_obj, appid, ownerId, and opensocial_token In our client-side markup, we can use these four template parameters by enclosing the member names in double braces:{{ some_name }}.The space between the braces, and including the braces, will be replaced by actual data at render time.

So the typical flow becomes the following:

1 A user loads our Canvas surface.

2 MySpace creates an iframe with the srcattribute pointing to our URL.

Table 9.1 Continued

<string>btn1_label—optional; the label for the second button

<string>btn1_surface—optional; which surface the secondbutton will navigate to; can be canvas or appProfile

<string>mediaitems—optional; must be in the formathttp://api.myspace.com/v1/users/6221, where 6221 is auser ID; posts that user’s thumbnail image along with thenotification

Sample response ""

Trang 25

3 The iframe loads and the request hits our servers.

4 We interrogate the query string of the request to determine the Viewer’s ID.

5 Using that ID, we make requests against the MySpace API for data.

6 The data comes back (or it doesn’t) and we put that data into a template object.

7 When the page renders, it looks for the double braces; if any are found, and the label matches the name of one of the template members, the template is replaced

by actual data.

Ourfriends_objparameter contained a JSON object of our user’s friend list We can access this on the client by doing the following:

var friends = {{ friends_obj }};

The friend list has now made its way from the MySpace API into our server scripts and down to the client in the form of a JavaScript object It’s now ready to be used on the page.

We also want to pass along pertinent data between pages Each page in our app is expecting certain data to exist on the query string.These query string parameters are initially set by MySpace But if a user clicks a link to go to another page, those query string parameters are lost So when we construct the link that will take the user to the Play page, we add the other template values manually.The Play page has a similar link pointing back to the Invite page:

<a id="tab0" class="left tab"

href="/play?opensocial_viewer_id={{ ownerId }}&

appid={{ appid }}&

opensocial_token={{ opensocial_token }}">Play</a>

When a user clicks this link, we pass the three parameters ownerId, appid, and

opensocial_tokento the receiving page.This is just one of many ways to maintain session state in your app.

Now that we have all of our data pushed down onto the page, we need to make a few more changes in order to get everything working correctly.These modifications are necessary because the friend data isn’t in the same format as it was for an on-site app We will no longer need to use the getFieldfunction to access data; the fields are instead accessed directly from the object.Table 9.1 can be a great help with figuring out where all the data should be.Tools like Firebug and Fiddler (see the Introduction for what these tools are and where to get them) are also invaluable for understanding the data responses.

We first make the body execute a function after it has loaded:

Ngày đăng: 21/01/2014, 12:20

TỪ KHÓA LIÊN QUAN