import os, sys, re
import wsgiref.handlers
from google.appengine.ext.webapp import template
from google.appengine.ext import webapp
from google.appengine.api import urlfetch
BASE_URL = "http://a2parking.appspot.com/"
PARKING_API_URL = \
"http://www.a2dda.org/parking__transportation/available_parking_spots/"
PARKING_LOCATIONS_RE = re.compile(">[\s\w\.:]+[\r\n\s]*
[\s\w\.]+<",
re.MULTILINE)
def xml_response(handler, page, templatevalues=None):
"""
Renders an XML response using a provided template page and values
"""
path = os.path.join(os.path.dirname(__file__), page)
handler.response.headers["Content-Type"] = "text/xml"
handler.response.out.write(template.render(path, templatevalues))
def fetch_parking():
result = urlfetch.fetch(PARKING_API_URL)
if result.status_code != 200:
return None
return result.content
class ParkingSpotsPage(webapp.RequestHandler):
"""
Accepts input digits from the caller, fetches the parking info from an
external site, and reads back the number of spots to the caller
"""
def get(self):
self.post()
def _error(self, msg, redirecturl=None):
templatevalues = {
'msg': msg,
'redirecturl': redirecturl
}
xml_response(self, 'error.xml', templatevalues)
def post(self):
location = self.request.get('Digits')
try:
location = location.replace('#', '').replace('*', '')[:1]
location = int(location)
except:
self._error("Invalid parking location.", BASE_URL)
return
parkingpage = fetch_parking()
if not parkingpage:
self._error("Error fetching parking page. Good Bye.")
return
locations = PARKING_LOCATIONS_RE.findall(parkingpage)
if not locations:
self._error("Error parsing parking spots.", BASE_URL)
return
if location >= len(locations):
self._error("Invalid parking location.", BASE_URL)
return
try:
name = locations[location][1:].split(':')[0]
spots = locations[location].\
split(" | ")[1][1:].split('<')[0].strip('.')
spots = int(spots)
except:
self._error("Error parsing parking spots.", BASE_URL)
return
templatevalues = {
'name': name,
'spots': spots,
}
xml_response(self, 'spots.xml', templatevalues)
class ParkingLocationPage(webapp.RequestHandler):
"""
Initial user greeting. Fetches the parking locations and asks the user
to select a location. Setup to work with less than 10 locations.
"""
def get(self):
self.post()
def post(self):
parkingpage = fetch_parking()
if not parkingpage:
self._error("Error fetching parking page. Good Bye.")
return
l = PARKING_LOCATIONS_RE.findall(parkingpage)
if not l:
self._error("Error parsing parking locations.", BASE_URL)
return
locations = ''
for i, p in enumerate(l):
locations += 'Press %d for ' % i
locations += p[1:].split(':')[0] + '\n'
templatevalues = {
'locations': locations,
'postprefix': BASE_URL,
}
xml_response(self, 'locations.xml', templatevalues)
def main():
application = webapp.WSGIApplication([ \
('/', ParkingLocationPage),
('/spots', ParkingSpotsPage)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()
|