Below is the file 'viewmtn.py' from this revision. You can also download the file.
#!/usr/bin/env python # Copyright (C) 2005 Grahame Bowland <grahame@angrygoats.net> # # This program is made available under the GNU GPL version 2.0 or # greater. See the accompanying file COPYING for details. # # This program is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. import os, sys, urllib from itertools import izip, chain, repeat from urlparse import urljoin import web import mtn, handlers, links from urls import common_urls, perdb_urls from render import Renderer import config # purloined from: http://docs.python.org/lib/itertools-recipes.html def grouper(n, iterable, padvalue=None): "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')" return izip(*[chain(iterable, repeat(padvalue, n-1))]*n) class RequestContext(object): def __init__ (self, dbname, ops, renderer): self.dbname, self.ops, self.renderer = dbname, ops, renderer # make sure that any unread automate output is flushed away if not ops is None: ops.per_request() self.nodb_join = lambda path: urljoin(config.dynamic_uri_path, path) if self.dbname is None: self.perdb_join = self.nodb_join else: self.perdb_join = lambda path: urljoin(config.dynamic_uri_path, urllib.quote(self.dbname) + '/' + path) self.static_join = lambda path: urljoin(config.static_uri_path, path) def link (self, *args, **kwargs): kwargs['ctxt'] = self return links.link (*args, **kwargs) def render(self, *args, **kwargs): self.renderer.render (self, *args, **kwargs) class RequestContextFactory(object): def __init__ (self): # has the user specified a dbfiles hash? if so, use it self.ops_instances = {} self.default = None self.renderer = Renderer() if hasattr (config, "dbfiles"): for name in config.dbfiles: self.ops_instances[name] = mtn.Operations([config.monotone, config.dbfiles[name]]) if hasattr (config, "defaultdb"): self.default = config.defaultdb else: self.ops_instances[None] = mtn.Operations([config.monotone, config.dbfile]) self.default = None def __getitem__(self, name): if name is None: ops = self.ops_instances.get (self.default, None) else: ops = self.ops_instances.get (name, None) if ops is None: return None else: return RequestContext(name, ops, self.renderer) def runfcgi_apache(func): web.wsgi.runfcgi(func, None) def per_request_wrapper(func, *args, **kwargs): return func(*args, **kwargs) if __name__ == '__main__': if hasattr(config, "running_under_apache2") and config.running_under_apache2: web.wsgi.runwsgi = runfcgi_apache if hasattr(config, "debug") and config.debug: web.webapi.internalerror = web.debugerror def assemble_urls(): fvars = {} urls = () factory = RequestContextFactory() def per_db_closure (handler): class PerDBClosure(object): def GET (self, *args, **kwargs): db, other_args = args[0], args[1:] # due to regexp we use, db passed in will always have a trailing slash if not db is None: db = db[:-1] ctxt = factory[db] if ctxt is None: return web.notfound() return handler.GET (ctxt, *other_args, **kwargs) return PerDBClosure for url, fn in grouper (2, common_urls): url = r'^/' + url if hasattr(handlers, fn): fvars[fn] = getattr(handlers, fn) urls += (url, fn) else: print >>sys.stderr, "*** URL defined for non-existant handler %s: %s" % (fn, url) for url, fn in grouper (2, perdb_urls): if hasattr(handlers, fn): url = r'^/([A-Za-z]+/)?' + url urls += (url, fn) fvars[fn] = per_db_closure (getattr(handlers, fn)()) else: print >>sys.stderr, "*** URL defined for non-existant handler %s: %s" % (fn, url) return urls, fvars urls, fvars = assemble_urls() func = lambda : per_request_wrapper(web.webpyfunc(urls, fvars=fvars)) web.run(func, globals()) ### ### vi:expandtab:sw=4:ts=4 ###