From df2a92b4d98538f29bca3c2f243398d12b73be7e Mon Sep 17 00:00:00 2001 From: Erik Ostrom Date: Sat, 3 Mar 2012 20:12:23 -0600 Subject: [PATCH] Added JSONP support. --- README.markdown | 10 ++++++++++ direction.py | 3 ++- jsonp.py | 7 +++++++ main.py | 9 +++++++++ nextrip.py | 3 ++- routes.py | 3 ++- stops.py | 3 ++- 7 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 jsonp.py diff --git a/README.markdown b/README.markdown index 3a19949..b6df66d 100644 --- a/README.markdown +++ b/README.markdown @@ -10,6 +10,8 @@ Currently Supported Interfaces: * nextrip - Displays a list of times for the bus to arrive given a stop, direction, and route +JSONP is supported using a callback parameter. + ## Routes Example: *http://metrotransitapi.appspot.com/routes* @@ -58,6 +60,14 @@ Example: *http://metrotransitapi.appspot.com/nextrip?route=6&direction=1&stop=HE [{"time": "9 Min", "actual": true, "number": "6B", "name": "France Av \/Southdale \/ Via Woodale"}, {"time": "7:50", "actual": false, "number": "6E", "name": "Minn Drive \/ Xerxes Av \/ Southdale"}, {"time": "8:05", "actual": false, "number": "6D", "name": "Southdale\/France Av"}, {"time": "8:18", "actual": false, "number": "6E", "name": "Minn Drive \/ Xerxes Av \/ Southdale"}, {"time": "8:32", "actual": false, "number": "6B", "name": "France Av \/Southdale \/ Via Woodale"}, {"time": "8:47", "actual": false, "number": "6E", "name": "Minn Drive \/ Xerxes Av \/ Southdale"}] +## JSONP + +Example: *http://metrotransitapi.appspot.com/nextrip?route=6&direction=1&stop=HEUP&callback=handleNextrip* + +### Sample output: + + handleNextrip([{"time": "9 Min", "actual": true, "number": "6B", "name": "France Av \/Southdale \/ Via Woodale"}, {"time": "7:50", "actual": false, "number": "6E", "name": "Minn Drive \/ Xerxes Av \/ Southdale"}, ...]) + ## Info & License Developed by Corey Maul. Very loosely based on yourmuni by mihaysa (http://yourmuni.appspot.com) diff --git a/direction.py b/direction.py index b765082..28c06f4 100755 --- a/direction.py +++ b/direction.py @@ -31,6 +31,7 @@ from BeautifulSoup import BeautifulSoup from google.appengine.api import memcache from django.utils import simplejson as json +from jsonp import jsonp directionURL = "http://metrotransit.org/Mobile/Nextrip.aspx?route=" @@ -62,7 +63,7 @@ def get(self): if directions is None: directions = scrapeDirection(self, route) memcache.add(route, directions, 60*60*24) - self.response.out.write(directions) + self.response.out.write(jsonp(self.request, directions)) except (ValueError, TypeError): self.response.out.write("

Invalid Input

route is a required input.
Example: /direction?route=4

") diff --git a/jsonp.py b/jsonp.py new file mode 100644 index 0000000..ad94b22 --- /dev/null +++ b/jsonp.py @@ -0,0 +1,7 @@ +def jsonp(request, data): + callback = request.get('callback') + if callback: + return "%s(%s)" % (callback, data) + else: + return data + diff --git a/main.py b/main.py index bcb86d8..0049bf4 100755 --- a/main.py +++ b/main.py @@ -116,6 +116,15 @@ def get(self): [{"time": "9 Min", "actual": true, "number": "6B", "name": "France Av \/Southdale \/ Via Woodale"}, {"time": "7:50", "actual": false, "number": "6E", "name": "Minn Drive \/ Xerxes Av \/ Southdale"}, {"time": "8:05", "actual": false, "number": "6D", "name": "Southdale\/France Av"}, {"time": "8:18", "actual": false, "number": "6E", "name": "Minn Drive \/ Xerxes Av \/ Southdale"}, {"time": "8:32", "actual": false, "number": "6B", "name": "France Av \/Southdale \/ Via Woodale"}, {"time": "8:47", "actual": false, "number": "6E", "name": "Minn Drive \/ Xerxes Av \/ Southdale"}] +

JSONP

+ +

Example: http://metrotransitapi.appspot.com/nextrip?route=6&direction=1&stop=HEUP&callback=handleNextrip

+ +

Sample output:

+ +
handleNextrip([{"time": "9 Min", "actual": true, "number": "6B", "name": "France Av \/Southdale \/ Via Woodale"}, {"time": "7:50", "actual": false, "number": "6E", "name": "Minn Drive \/ Xerxes Av \/ Southdale"}, ...])
+    
+

Info & License

Developed by Corey Maul. Very loosely based on yourmuni by mihaysa (http://yourmuni.appspot.com)

diff --git a/nextrip.py b/nextrip.py index 2104779..c485a3e 100644 --- a/nextrip.py +++ b/nextrip.py @@ -29,6 +29,7 @@ from BeautifulSoup import BeautifulSoup from google.appengine.api import memcache from django.utils import simplejson as json +from jsonp import jsonp import re stopsURL = "http://metrotransit.org/Mobile/Nextriptext.aspx?route=" @@ -68,7 +69,7 @@ class MainHandler(webapp.RequestHandler): def get(self): departures = scrapeDirection(self) - self.response.out.write(departures) + self.response.out.write(jsonp(self.request, departures)) def main(): application = webapp.WSGIApplication([('/nextrip', MainHandler)], diff --git a/routes.py b/routes.py index b79fb48..e62cf5f 100755 --- a/routes.py +++ b/routes.py @@ -29,6 +29,7 @@ from BeautifulSoup import BeautifulSoup from google.appengine.api import memcache from django.utils import simplejson as json +from jsonp import jsonp routeURL = "http://metrotransit.org/Mobile/Nextrip.aspx" @@ -57,7 +58,7 @@ def get(self): if routes is None: routes = scrapeRoutes(self) memcache.add("routes", routes, 60 * 60 * 24) - self.response.out.write(routes) + self.response.out.write(jsonp(self.request, routes)) def main(): diff --git a/stops.py b/stops.py index 1fcc591..0ba34b7 100644 --- a/stops.py +++ b/stops.py @@ -29,6 +29,7 @@ from BeautifulSoup import BeautifulSoup from google.appengine.api import memcache from django.utils import simplejson as json +from jsonp import jsonp stopsURL = "http://metrotransit.org/Mobile/Nextrip.aspx?route=" @@ -66,7 +67,7 @@ def get(self): if stops is None: stops = scrapeStops(route, direction) memcache.add(memKey, stops, 60*60*24) - self.response.out.write(stops) + self.response.out.write(jsonp(self.request, stops)) except (ValueError, TypeError): self.response.out.write("

Invalid Input

route and direction are required inputs.
Example: /direction?route=6&direction=4

")