svv/wsgi.py
changeset 0 b28a1681e79b
child 1 06451697083a
equal deleted inserted replaced
-1:000000000000 0:b28a1681e79b
       
     1 import werkzeug
       
     2 from werkzeug import exceptions
       
     3 from werkzeug import Request, Response
       
     4 from werkzeug.routing import Map, Rule
       
     5 
       
     6 import logging
       
     7 
       
     8 # logging
       
     9 log = logging.getLogger('svv.wsgi')
       
    10 
       
    11 class AppHandler (object):
       
    12     """
       
    13         Per-request handler context
       
    14     """
       
    15 
       
    16     # default content type for response
       
    17     CONTENT_TYPE = 'text/html'
       
    18 
       
    19     def __init__ (self, request) :
       
    20         """
       
    21             Initialize for processing the given Request, to prepare for action-method later on
       
    22         """
       
    23 
       
    24         self.request = request
       
    25 
       
    26     def respond (self, url_values) :
       
    27         """
       
    28             Handle request that was mapped to ourselves via the URL routing, using given dict of values from URL.
       
    29         """
       
    30 
       
    31         # render
       
    32         html = unicode(self.render(**url_values))
       
    33 
       
    34         # XXX: unicode
       
    35         return Response(html, mimetype='text/html')
       
    36 
       
    37     def render (self, **args) :
       
    38         """
       
    39             Handling a GET request, returning the proper response HTML.
       
    40         """
       
    41 
       
    42         raise NotImplementedError()
       
    43 
       
    44 import html
       
    45 from html import tags
       
    46 
       
    47 class Index (AppHandler) :
       
    48     def render (self) :
       
    49         title = "Index"
       
    50         css = ["/static/layout.css", "/static/style.css"]
       
    51 
       
    52         head = (
       
    53             tags.title(title),
       
    54             (tags.link(rel='Stylesheet', type="text/css", href=src) for src in css),
       
    55         )
       
    56 
       
    57         header = ("Foo List")
       
    58         nav = [tags.ul(tags.li(tags.a(href='#')(name)) for name in ['Nav A', 'Nav B', 'Nav C'])]
       
    59         menu = [tags.ul(tags.li(tags.a(href='#')(name)) for name in ['Menu A', 'Menu B', 'Menu C'])]
       
    60         footer = ("Copyright?")
       
    61 
       
    62         content = (
       
    63             tags.ul(tags.li("Item #%d" % i) for i in xrange(10))
       
    64         )
       
    65 
       
    66         layout = (
       
    67             tags.div(id='header')(header),
       
    68             tags.div(id='container')(
       
    69                 tags.div(id='menu')(menu),
       
    70                 tags.div(id='nav')(nav),
       
    71                 tags.div(id='content')(content),
       
    72             ),
       
    73             tags.div(id='footer')(footer),
       
    74         )
       
    75         
       
    76         return html.document(head, layout)
       
    77 
       
    78 class WSGIApp (object) :
       
    79     """
       
    80         Top-level WSGI handler impl
       
    81     """
       
    82 
       
    83     # URL paths
       
    84     # map to AppHandler-endpoint
       
    85     URLS = Map((
       
    86         Rule('/', endpoint=Index),
       
    87     ))
       
    88 
       
    89     def __init__ (self) :
       
    90         pass
       
    91 
       
    92     # wrap to use werkzeug's Request/Response
       
    93     @Request.application
       
    94     def __call__ (self, req) :
       
    95         """
       
    96             Main WSGI entry point, error handling
       
    97         """
       
    98 
       
    99         try :
       
   100             # wrapped handler
       
   101             response = self.request(req)
       
   102 
       
   103         except exceptions.HTTPException, e :
       
   104             # format properly as response, also includes redirects
       
   105             return e.get_response(req.environ)
       
   106         
       
   107         # XXX: except Exception, e :
       
   108         # XXX: we want to trap errors in prod, but not in dev?
       
   109 
       
   110         else :
       
   111             # a-ok
       
   112             return response
       
   113 
       
   114     def request (self, req) :
       
   115         """
       
   116             Wrapped request handler, URL mapping
       
   117         """
       
   118 
       
   119         # map URLs against this request
       
   120         urls = self.URLS.bind_to_environ(req)
       
   121 
       
   122         # lookup matching URL for handler type and matched values from URL
       
   123         url_handler, url_values = urls.match()
       
   124 
       
   125         # the per-request handler (from endpoint)
       
   126         req_handler = url_handler(req)
       
   127 
       
   128         # XXX: per-method thing?
       
   129         response = req_handler.respond(url_values)
       
   130 
       
   131         # ok
       
   132         return response
       
   133 
       
   134