The unified diff between revisions [79b896cf..] and [000645e7..] is displayed below. It can also be downloaded as a raw diff.
This diff has been restricted to the following files: 'viewmtn.py'
#
#
# patch "viewmtn.py"
# from [657d61af6a6a853bd10a1e38aaf5eb7f53588f9f]
# to [e76f6d2b58d5b7cda4c2ddbb92dfaeee73e05702]
#
============================================================
--- viewmtn.py 657d61af6a6a853bd10a1e38aaf5eb7f53588f9f
+++ viewmtn.py e76f6d2b58d5b7cda4c2ddbb92dfaeee73e05702
@@ -34,10 +34,16 @@ import binascii
hq = cgi.escape
import heapq
import binascii
+from itertools import izip, chain, repeat
import web
debug = web.debug
+# 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)
+
# /about.psp -> /about
# /branch.psp -> /branch/{branch}/
@@ -359,7 +365,31 @@ class Renderer:
terms.update(kwargs)
web.render(template, terms)
+class OperationsFactory:
+ def __init__ (self):
+ # has the user specified a dbfiles hash? if so, use it
+ self.ops_instances = {}
+ self.default = None
+ if hasattr (config, "dbfiles"):
+ for name, dbfile in config.dbfiles:
+ self.ops_instances[name] = mtn.Operations([config.monotone, dbfile])
+ if hasattr (config, "defaultdb"):
+ self.default = config.defaultdb
+ else:
+ self.ops_instances["legacy"] = mtn.Operations([config.monotone, config.dbfile])
+ self.default = "legacy"
+
+ def get_ops(self, name):
+ if not (name is None):
+ return self.ops.get (name, None)
+ else:
+ return self.ops.get (self.default, None)
+
+#
+# TODO: try and wrap these globals up in a single global object
+#
renderer = Renderer()
+op_fact = OperationsFactory()
ops = mtn.Operations([config.monotone, config.dbfile])
mimehelp = sharedmimeinfo.LookupHelper(getattr(config, "mime_map", None))
if config.icon_theme:
@@ -1266,43 +1296,44 @@ class RobotsTxt:
for access_method in ['/revision/', '/branch/head/', '/branch/anyhead/', '/branch/changes/from/', '/json/', '/mimeicon/']:
print "Disallow:", access_method + revision_page
-urls = (
- r'/', 'Index', #done
- r'/about', 'About', #done
- r'/tags', 'Tags', #done
- r'/help', 'Help', #done
- r'/json/([A-Za-z]+)/(.*)', 'Json',
+common_urls = (
+# these don't care about multiple databases specified via the URL
+ r'', 'Index',
+ r'about', 'About',
+ r'help', 'Help',
+ r'robots.txt', 'RobotsTxt', ## FIXME needs o exclude per-db paths
+ r'mimeicon/([A-Za-z0-9][a-z0-9\-\+\.]*)/([A-Za-z0-9][a-z0-9\-\+\.]*)', 'MimeIcon',
+)
- r'/revision/browse/('+mtn.revision_re+')/(.*)', 'RevisionBrowse',
- r'/revision/browse/('+mtn.revision_re+')()', 'RevisionBrowse',
- r'/revision/diff/('+mtn.revision_re+')/with/('+mtn.revision_re+')', 'RevisionDiff',
- r'/revision/rawdiff/('+mtn.revision_re+')/with/('+mtn.revision_re+')', 'RevisionRawDiff',
- r'/revision/diff/('+mtn.revision_re+')/with/('+mtn.revision_re+')'+'/(.*)', 'RevisionDiff',
- r'/revision/rawdiff/('+mtn.revision_re+')/with/('+mtn.revision_re+')'+'/(.*)', 'RevisionRawDiff',
- r'/revision/file/('+mtn.revision_re+')/(.*)', 'RevisionFile',
- r'/revision/filechanges/()()('+mtn.revision_re+')/(.*)', 'RevisionFileChanges',
- r'/revision/filechanges/from/(\d+)/to/(\d+)/('+mtn.revision_re+')/(.*)', 'RevisionFileChanges',
- r'/revision/filechanges/rss/()()('+mtn.revision_re+')/(.*)', 'RevisionFileChangesRSS',
- r'/revision/filechanges/rss/from/(\d+)/to/(\d+)/('+mtn.revision_re+')/(.*)', 'RevisionFileChangesRSS',
- r'/revision/downloadfile/('+mtn.revision_re+')/(.*)', 'RevisionDownloadFile',
- r'/revision/info/('+mtn.revision_re+')', 'RevisionInfo',
- r'/revision/tar/('+mtn.revision_re+')', 'RevisionTar',
- r'/revision/graph/('+mtn.revision_re+')', 'RevisionGraph',
+perdb_urls = (
+ r'tags', 'Tags',
+ r'json/([A-Za-z]+)/(.*)', 'Json',
- r'/branch/changes/(.*)/from/(\d+)/to/(\d+)', 'HTMLBranchChanges',
- r'/branch/changes/([^/]+)()()', 'HTMLBranchChanges',
- r'/branch/changes/(.*)/from/(\d+)/to/(\d+)/rss', 'RSSBranchChanges',
- r'/branch/changes/([^/]+)()()/rss', 'RSSBranchChanges',
- r'/branch/tags/([^/]+)', 'Tags',
+ r'([a-zA-Z]/)?revision/browse/('+mtn.revision_re+')/(.*)', 'RevisionBrowse',
+ r'revision/browse/('+mtn.revision_re+')()', 'RevisionBrowse',
+ r'revision/diff/('+mtn.revision_re+')/with/('+mtn.revision_re+')', 'RevisionDiff',
+ r'revision/diff/('+mtn.revision_re+')/with/('+mtn.revision_re+')'+'/(.*)', 'RevisionDiff',
+ r'revision/file/('+mtn.revision_re+')/(.*)', 'RevisionFile',
+ r'revision/filechanges/()()('+mtn.revision_re+')/(.*)', 'RevisionFileChanges',
+ r'revision/filechanges/from/(\d+)/to/(\d+)/('+mtn.revision_re+')/(.*)', 'RevisionFileChanges',
+ r'revision/filechanges/rss/()()('+mtn.revision_re+')/(.*)', 'RevisionFileChangesRSS',
+ r'revision/filechanges/rss/from/(\d+)/to/(\d+)/('+mtn.revision_re+')/(.*)', 'RevisionFileChangesRSS',
+ r'revision/downloadfile/('+mtn.revision_re+')/(.*)', 'RevisionDownloadFile',
+ r'revision/info/('+mtn.revision_re+')', 'RevisionInfo',
+ r'revision/tar/('+mtn.revision_re+')', 'RevisionTar',
+ r'revision/graph/('+mtn.revision_re+')', 'RevisionGraph',
+ r'branch/changes/(.*)/from/(\d+)/to/(\d+)', 'HTMLBranchChanges',
+ r'branch/changes/([^/]+)()()', 'HTMLBranchChanges',
+ r'branch/changes/(.*)/from/(\d+)/to/(\d+)/rss', 'RSSBranchChanges',
+ r'branch/changes/([^/]+)()()/rss', 'RSSBranchChanges',
+ r'branch/tags/([^/]+)', 'Tags',
+
# let's make it possible to access any function on the head revision
# through this proxy method; it'll return a redirect to the head revision
# with the specified function
- r'/branch/(head)/([A-Za-z]+)/([^/]+)(.*)', 'BranchHead',
- r'/branch/(anyhead)/([A-Za-z]+)/([^/]+)(.*)', 'BranchHead',
-
- r'/robots.txt', 'RobotsTxt',
- r'/mimeicon/([A-Za-z0-9][a-z0-9\-\+\.]*)/([A-Za-z0-9][a-z0-9\-\+\.]*)', 'MimeIcon',
+ r'branch/(head)/([A-Za-z]+)/([^/]+)(.*)', 'BranchHead',
+ r'branch/(anyhead)/([A-Za-z]+)/([^/]+)(.*)', 'BranchHead',
)
def runfcgi_apache(func):
@@ -1317,7 +1348,32 @@ if __name__ == '__main__':
web.wsgi.runwsgi = runfcgi_apache
if hasattr(config, "debug") and config.debug:
web.webapi.internalerror = web.debugerror
- func = lambda : per_request_wrapper(web.webpyfunc(urls, fvars=globals()))
+
+ def assemble_urls():
+ fvars = {}
+ urls = ()
+ for url, fn in grouper (2, common_urls):
+ url = r'^/' + url
+ urls += (url, fn)
+ fvars[fn] = globals()[fn]
+
+ def get_db_closure (fn):
+ the_cls = globals()[fn]()
+ class PerDBClosure:
+ def GET (self, *args, **kwargs):
+ db, other_args = args[0], args[1:]
+ the_cls.GET (*other_args, **kwargs)
+ return PerDBClosure
+
+ for url, fn in grouper (2, perdb_urls):
+ url = r'^/([A-Za-z]+/)?' + url
+ urls += (url, fn)
+ fvars[fn] = get_db_closure (fn)
+ print "fvars::", fvars['Index']
+ print "globals:", globals()['Index']
+ return urls, fvars
+ urls, fvars = assemble_urls()
+ func = lambda : per_request_wrapper(web.webpyfunc(urls, fvars=fvars))
web.run(func, globals(), web.reloader)
###