cross domain webmashups with jquery and google app engine
DESCRIPTION
An example of how to do a mashup of Google App Engine applications using jQuery and JSONPTRANSCRIPT
Cross Domain Web Mashups with JQuery and Google App Engine
Andy McKay. Clearwind Consultinghttp://clearwind.ca
Also known as
A bunch of cool buzz words to try and describesome of the stuff I’m doing these days
and get me in to talk at cool conferences
Cross Domain JQuery
App Engine
Cross Domain JQuery
App Engine
mashup
“a web page or application that combines data from two or more external online sources”
reusable web applications
that aren't SOAP and WSDL
"The three chief virtues of a programmer are: Laziness, Impatience and Hubris”. Larry Wall
back in time...
Zope 2PloneRails
Django
rewriting things constantly is good for billable hours
small web applicationsreturning xml
browser: rails.site.ca
browser: django.site.ca
server: another.ca
Ajax
there's a problem
Single origin policy
browser: clearwind.ca server: some.other.ca
The same origin policy prevents document or script loaded from one origin from getting or setting properties of a document from a different origin.-- From http://www.mozilla.org/projects/security/components/same-origin.html
1. proxy
browser: clearwind.ca server: clearwind.ca server: some.other.ca
2. hacks
flashiframe
documentscript
3. JSONP
JavaScript Object Notation with Padding
Example: json-time
By Simon Willisonhttp://json-time.appspot.com/
http://github.com/simonw/json-time/tree/master
JSON{ "tz": "America\/Chicago", "hour": 3, "datetime": "Tue, 19 May 2009 03:06:50 -0500", "second": 50, "error": false, "minute": 6}
JSONP
process_time({ "tz": "America\/Chicago", "hour": 3, "datetime": "Tue, 19 May 2009 03:09:09 -0500", "second": 9, "error": false, "minute": 9})
Cross Domain JQuery
App Engine
JQuery for json-time
var url = "http://json-time.appspot.com/timezones.json?"
$.getJSON(url + "callback=?", function (json) { ... });
JSON time demo
$(document).ready(function() { var url = "http://json-time.appspot.com";
function showTime(data) { $.getJSON(url + "/time.json?tz=" + $("#zones").val() + '&callback=?', function (json){ $("#zones-msg").text('The time is now ' + json["datetime"] + '.'); }); }; $.getJSON(url + "/timezones.json?callback=?", function (json) { var zones = $("#zones"); for (var k = 0; k < json.length; k++) { zones.append("<option>" + json[k] + "</option>"); }; zones.bind("change", showTime) });});
Complete JSON time demo
Cross Domain JQuery
App Engine
Easiest deploymentBest scalabilityMinimal effort
Not straight PythonHas it's limitations and quirks
And it's free
Example Mashup
The coolest technology of 2006Google Maps
The most hyped technology of 2009Twitter
Twitter messages with a mapby hash tag eg: #owv2009
Step 1: Assign hash tag to location
geohashtag.appspot.com
browser: geohashtag.appspot.com server: geohashtag.appspot.com
from google.appengine.ext import db
class Tag(db.Model): name = db.StringProperty(required=True) geostring = db.StringProperty(required=True)
Model
You cannot do an inequality test on two fields in one query. Or use GeoPt.
GeoHash solves this problem:http://en.wikipedia.org/wiki/Geohash
Issue
tag.json (returns location for a tag)bounds.json (returns all the tags in a rectangle)
JSON
Geohashtag demo
Step 2: Parse RSS into JSONP
atomtojsonp.appspot.com
browser: atomtojsonp.appspot.com server: search.twitter.com
server: atomtojsonp.appspot.com
Because twitter doesn't have JSON exportOther services like Google RSS or Yahoo YQL have
problems
But checkout: http://developer.yahoo.com/yql/ and http://code.google.com/apis/ajaxfeeds/
Proxy?
No Model
Quite common for App Engine
class JSONHandler(webapp.RequestHandler): def get(self): url = self.request.get("url") data = feedparser.parse(url) if self.request.get("callback"): data = "%s(%s)" % (self.request.get("callback"), data) self.response.out.write(data)
Just feedparserhttp://www.feedparser.org/
twitter.json (smaller twitter version for a search term)atom.json (a whole atom file for a url)
JSON
Atomtwojsonp demo
Step 3: Mash it up
geojsontweet.appspot.com
browser: geojsontweet.appspot.com server: maps.google.com
browser: geojsontweet.appspot.com
browser: geojsontweet.appspot.com server: geohashtag.appspot.com
browser: geojsontweet.appspot.com server: maps.google.com
browser: geojsontweet.appspot.com
geojsontweet.appspot.com
browser: geojsontweet.appspot.com server: geohashtag.appspot.com
server: search.twitter.com
server: atomtojsonp.appspot.com
browser: geojsontweet.appspot.com server: maps.google.com
browser: geojsontweet.appspot.com
geojsontweet.appspot.com
No ModelIn fact, completely static HTML
(with JS, no server side code)
function move() { var bounds = map.getBounds(); var sw = bounds.getSouthWest(); var ne = bounds.getNorthEast(); var url = map_details.tags_domain + '/bounds.json?nelat='; url += ne.lat() + '&nelon=' + ne.lng(); url += '&swlon=' + sw.lng() + '&swlat=' + sw.lat() + '&callback=?' if (map_details.last_url != url) { map_details.last_url = url $.getJSON(url, function(json) { if (json) { for (var k = 0; k < json.length; k++) { ...
Some Javascript
function twitter() { var tag = null; for (var obj in tags) { var url = map_details.atom_domain + '/twitter.json?tag=' + obj + '&callback=?' $.getJSON(url, function(json) { var tweet = null; for (var k = 0; k < json.length; k++) { ....
Some more Javascript
$("#tweets-" + tweet["tag"]).parent().scrollable({ interval: 4000, loop: true, speed: 600, onBeforeSeek: function() { this.getItems().fadeTo(300, 0.2); }, onSeek: function() { this.getItems().fadeTo(300, 1); }});
Slideshowhttp://flowplayer.org/tools/scrollable.html
Geojsontweet demo
Serious issues
TrustYou are executing someone else's JavaScript
in your site. Better be trustworthy.
Single points of failure?
Single points of failure?
EnterpriseInternal servers?
Questions?
Code: http://svn.clearwind.ca/public/projects/presentationsEmail: [email protected]