The unified diff between revisions [ace1480d..] and [e573b84f..] is displayed below. It can also be downloaded as a raw diff.
#
#
# patch "viewmtn.py"
# from [78b92d8c6980db2077c8fb48277b64f5088c74ee]
# to [c0e46420ea8ad46d0a3a4c1b80d981e4fd4970c0]
#
============================================================
--- viewmtn.py 78b92d8c6980db2077c8fb48277b64f5088c74ee
+++ viewmtn.py c0e46420ea8ad46d0a3a4c1b80d981e4fd4970c0
@@ -367,10 +367,6 @@ class Renderer(object):
self._templates_loaded = True
def render(self, template, **kwargs):
- # technically it'd be better to do this before serving the
- # request, however this is about the only per-request
- # spot that runs for every handler..
- ops.per_request()
self.load_templates()
terms = self.terms.copy()
terms.update(kwargs)
@@ -382,8 +378,8 @@ class OperationsFactory(object):
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])
+ 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:
@@ -391,17 +387,25 @@ class OperationsFactory(object):
self.default = "legacy"
def get_ops(self, name):
- if not (name is None):
- return self.ops.get (name, None)
+ ops = None
+ if name is None:
+ ops = self.ops_instances.get (self.default, None)
else:
- return self.ops.get (self.default, None)
+ name = name.rstrip('/')
+ ops = self.ops_instances.get (name, None)
+ # technically it'd be better to do this before serving the
+ # request, however this is about the only per-request
+ # spot that runs for every handler..
+ if not ops is None:
+ ops.per_request()
+ return ops
#
# TODO: try and wrap these globals up in a single global object
#
renderer = Renderer()
op_fact = OperationsFactory()
-ops = mtn.Operations([config.monotone, config.dbfile])
+##ops = mtn.Operations([config.monotone, config.dbfile])
mimehelp = sharedmimeinfo.LookupHelper(getattr(config, "mime_map", None))
if config.icon_theme:
try:
@@ -437,7 +441,7 @@ class Index(object):
divisions = BranchDivisions ()
class Index(object):
- def GET(self, *args):
+ def GET(self, ops):
branches = list(ops.branches ())
divisions.calculate_divisions (branches)
def division_iter():
@@ -476,7 +480,7 @@ class Tags(object):
renderer.render('about.html', page_title="About")
class Tags(object):
- def GET(self, restrict_branch=None):
+ def GET(self, ops, restrict_branch=None):
# otherwise we couldn't use automate again..
tags = list(ops.tags())
if restrict_branch != None:
@@ -505,7 +509,7 @@ class Changes(object):
renderer.render('help.html', page_title="Help")
class Changes(object):
- def __get_last_changes(self, start_from, parent_func, selection_func, n):
+ def __get_last_changes(self, ops, start_from, parent_func, selection_func, n):
"""returns at least n revisions that are parents of the revisions in start_from,
ordered by time (descending). selection_func is called for each revision, and
that revision is only included in the result if the function returns True."""
@@ -550,7 +554,7 @@ class Changes(object):
rv = map (lambda x: (x.revision, x.certs), result), revq
return rv
- def on_our_branch(self, branch, revision):
+ def on_our_branch(self, ops, branch, revision):
rv = False
for cert in ops.certs(revision):
if cert[4] == 'name' and cert[5] == 'branch':
@@ -558,7 +562,7 @@ class Changes(object):
rv = True
return rv
- def for_template(self, revs, pathinfo=None, constrain_diff_to=None):
+ def for_template(self, ops, revs, pathinfo=None, constrain_diff_to=None):
rv = []
for rev, certs in revs:
rev_branch = ""
@@ -611,20 +615,21 @@ class Changes(object):
previous_to = previous_from + per_page
return (from_change, to_change, next_from, next_to, previous_from, previous_to)
- def branch_get_last_changes(self, branch, from_change, to_change):
+ def branch_get_last_changes(self, ops, branch, from_change, to_change):
heads = [t for t in ops.heads(branch.name)]
if not heads:
return web.notfound()
- changed, new_starting_point = self.__get_last_changes(heads,
+ changed, new_starting_point = self.__get_last_changes(ops,
+ heads,
lambda r: ops.parents(r),
- lambda r: self.on_our_branch(branch, r),
+ lambda r: self.on_our_branch(ops, branch, r),
to_change)
return changed, new_starting_point
- def Branch_GET(self, branch, from_change, to_change, template_name):
+ def Branch_GET(self, ops, branch, from_change, to_change, template_name):
branch = mtn.Branch(branch)
from_change, to_change, next_from, next_to, previous_from, previous_to = self.determine_bounds(from_change, to_change)
- changed, new_starting_point = self.branch_get_last_changes(branch, from_change, to_change)
+ changed, new_starting_point = self.branch_get_last_changes(ops, branch, from_change, to_change)
changed = changed[from_change:to_change]
if len(changed) != to_change - from_change:
next_from, next_to = None, None
@@ -639,9 +644,9 @@ class Changes(object):
previous_to=previous_to,
next_from=next_from,
next_to=next_to,
- display_revs=self.for_template(changed))
+ display_revs=self.for_template(ops, changed))
- def file_get_last_changes(self, from_change, to_change, revision, path):
+ def file_get_last_changes(self, ops, from_change, to_change, revision, path):
def content_changed_fn(start_revision, start_path, in_revision, pathinfo):
uniq = set()
parents = list(ops.parents(in_revision))
@@ -660,15 +665,16 @@ class Changes(object):
pathinfo = {}
# not just the starting revision! we might not have changed 'path' in the starting rev..
start_at = content_changed_fn(revision, path, revision, pathinfo)
- changed, new_starting_point = self.__get_last_changes(start_at,
+ changed, new_starting_point = self.__get_last_changes(ops,
+ start_at,
lambda r: content_changed_fn(revision, path, r, pathinfo),
lambda r: True,
to_change)
return changed, new_starting_point, pathinfo
- def File_GET(self, from_change, to_change, revision, path, template_name):
+ def File_GET(self, ops, from_change, to_change, revision, path, template_name):
from_change, to_change, next_from, next_to, previous_from, previous_to = self.determine_bounds(from_change, to_change)
- changed, new_starting_point, pathinfo = self.file_get_last_changes(from_change, to_change, revision, path)
+ changed, new_starting_point, pathinfo = self.file_get_last_changes(ops, from_change, to_change, revision, path)
changed = changed[from_change:to_change]
if len(changed) != to_change - from_change:
next_from, next_to = None, None
@@ -684,18 +690,18 @@ class Changes(object):
previous_to=previous_to,
next_from=next_from,
next_to=next_to,
- display_revs=self.for_template(changed, pathinfo=pathinfo, constrain_diff_to=revision))
+ display_revs=self.for_template(ops, changed, pathinfo=pathinfo, constrain_diff_to=revision))
class HTMLBranchChanges(Changes):
- def GET(self, branch, from_change, to_change):
- Changes.Branch_GET(self, branch, from_change, to_change, "branchchanges.html")
+ def GET(self, ops, branch, from_change, to_change):
+ Changes.Branch_GET(self, ops, branch, from_change, to_change, "branchchanges.html")
class RSSBranchChanges(Changes):
- def GET(self, branch, from_change, to_change):
- Changes.Branch_GET(self, branch, from_change, to_change, "branchchangesrss.html")
+ def GET(self, ops, branch, from_change, to_change):
+ Changes.Branch_GET(self, ops, branch, from_change, to_change, "branchchangesrss.html")
class RevisionPage(object):
- def get_fileid(self, revision, filename):
+ def get_fileid(self, ops, revision, filename):
rv = None
for stanza in ops.get_manifest_of(revision):
if stanza[0] != 'file':
@@ -703,13 +709,15 @@ class RevisionPage(object):
if stanza[1] == filename:
rv = stanza[3]
return rv
- def exists(self, revision):
+
+ def exists(self, ops, revision):
try:
certs = [t for t in ops.certs(revision)]
return True
except mtn.MonotoneException:
return False
- def branches_for_rev(self, revisions_val):
+
+ def branches_for_rev(self, ops, revisions_val):
rv = []
for stanza in ops.certs(revisions_val):
if stanza[4] == 'name' and stanza[5] == 'branch':
@@ -717,27 +725,27 @@ class RevisionFileChanges(Changes, Revis
return rv
class RevisionFileChanges(Changes, RevisionPage):
- def GET(self, from_change, to_change, revision, path):
+ def GET(self, ops, from_change, to_change, revision, path):
revision = mtn.Revision(revision)
- if not self.exists(revision):
+ if not self.exists(ops, revision):
return web.notfound()
- Changes.File_GET(self, from_change, to_change, revision, path, "revisionfilechanges.html")
+ Changes.File_GET(self, ops, from_change, to_change, revision, path, "revisionfilechanges.html")
class RevisionFileChangesRSS(Changes, RevisionPage):
- def GET(self, from_change, to_change, revision, path):
+ def GET(self, ops, from_change, to_change, revision, path):
revision = mtn.Revision(revision)
- if not self.exists(revision):
+ if not self.exists(ops, revision):
return web.notfound()
- Changes.File_GET(self, from_change, to_change, revision, path, "revisionfilechangesrss.html")
+ Changes.File_GET(self, ops, from_change, to_change, revision, path, "revisionfilechangesrss.html")
class RevisionInfo(RevisionPage):
- def GET(self, revision):
+ def GET(self, ops, revision):
revision = mtn.Revision(revision)
- if not self.exists(revision):
+ if not self.exists(ops, revision):
return web.notfound()
certs = ops.certs(revision)
revisions = ops.get_revision(revision)
- output_png, output_imagemap = ancestry_graph(revision)
+ output_png, output_imagemap = ancestry_graph(ops, revision)
if os.access(output_imagemap, os.R_OK):
imagemap = open(output_imagemap).read().replace('\\n', ' by ')
imageuri = dynamic_join('revision/graph/' + revision)
@@ -752,12 +760,12 @@ class RevisionDiff(RevisionPage):
revisions=revisions_for_template(revision, revisions))
class RevisionDiff(RevisionPage):
- def GET(self, revision_from, revision_to, filename=None):
+ def GET(self, ops, revision_from, revision_to, filename=None):
revision_from = mtn.Revision(revision_from)
revision_to = mtn.Revision(revision_to)
- if not self.exists(revision_from):
+ if not self.exists(ops, revision_from):
return web.notfound()
- if not self.exists(revision_to):
+ if not self.exists(ops, revision_to):
return web.notfound()
if filename != None:
files = [filename]
@@ -775,12 +783,12 @@ class RevisionRawDiff(RevisionPage):
files=files)
class RevisionRawDiff(RevisionPage):
- def GET(self, revision_from, revision_to, filename=None):
+ def GET(self, ops, revision_from, revision_to, filename=None):
revision_from = mtn.Revision(revision_from)
revision_to = mtn.Revision(revision_to)
- if not self.exists(revision_from):
+ if not self.exists(ops, revision_from):
return web.notfound()
- if not self.exists(revision_to):
+ if not self.exists(ops, revision_to):
return web.notfound()
if filename != None:
files = [filename]
@@ -793,12 +801,12 @@ class RevisionFile(RevisionPage):
sys.stdout.flush()
class RevisionFile(RevisionPage):
- def GET(self, revision, filename):
+ def GET(self, ops, revision, filename):
revision = mtn.Revision(revision)
- if not self.exists(revision):
+ if not self.exists(ops, revision):
return web.notfound()
language = filename.rsplit('.', 1)[-1]
- fileid = RevisionPage.get_fileid(self, revision, filename)
+ fileid = RevisionPage.get_fileid(self, ops, revision, filename)
if not fileid:
return web.notfound()
contents = ops.get_file(fileid)
@@ -826,12 +834,12 @@ class RevisionDownloadFile(RevisionPage)
contents=syntax.highlight(contents, language))
class RevisionDownloadFile(RevisionPage):
- def GET(self, revision, filename):
+ def GET(self, ops, revision, filename):
web.header('Content-Disposition', 'attachment; filename=%s' % filename)
revision = mtn.Revision(revision)
- if not self.exists(revision):
+ if not self.exists(ops, revision):
return web.notfound()
- fileid = RevisionPage.get_fileid(self, revision, filename)
+ fileid = RevisionPage.get_fileid(self, ops, revision, filename)
if not fileid:
return web.notfound()
for idx, data in enumerate(ops.get_file(fileid)):
@@ -842,11 +850,11 @@ class RevisionTar(RevisionPage):
sys.stdout.flush()
class RevisionTar(RevisionPage):
- def GET(self, revision):
+ def GET(self, ops, revision):
# we'll output in the USTAR tar format; documentation taken from:
# http://en.wikipedia.org/wiki/Tar_%28file_format%29
revision = mtn.Revision(revision)
- if not self.exists(revision):
+ if not self.exists(ops, revision):
return web.notfound()
filename = "%s.tar" % revision
web.header('Content-Disposition', 'attachment; filename=%s' % filename)
@@ -886,11 +894,11 @@ class RevisionBrowse(RevisionPage):
tarobj.addfile(ti, filecontents)
class RevisionBrowse(RevisionPage):
- def GET(self, revision, path):
+ def GET(self, ops, revision, path):
revision = mtn.Revision(revision)
- if not self.exists(revision):
+ if not self.exists(ops, revision):
return web.notfound()
- branches = RevisionPage.branches_for_rev(self, revision)
+ branches = RevisionPage.branches_for_rev(self, ops, revision)
revisions = ops.get_revision(revision)
def components(path):
@@ -1036,7 +1044,7 @@ class RevisionBrowse(RevisionPage):
mime_icon=mime_icon,
entries=info_for_manifest(cut_manifest_to_subdir()))
-def ancestry_dot(revision):
+def ancestry_dot(ops, revision):
def dot_escape(s):
# kinda paranoid, should probably revise later
permitted=string.digits + string.letters + ' -<>-:,*@!$%^&.+_~?/'
@@ -1172,8 +1180,8 @@ digraph ancestry {
graph += '}'
return graph
-def ancestry_graph(revision):
- dot_data = ancestry_dot(revision)
+def ancestry_graph(ops, revision):
+ dot_data = ancestry_dot(ops, revision)
# okay, let's output the graph
graph_sha = sha.new(dot_data).hexdigest()
if not os.access(config.graphopts['directory'], os.R_OK):
@@ -1195,8 +1203,8 @@ class RevisionGraph(object):
return output_png, output_imagemap
class RevisionGraph(object):
- def GET(self, revision):
- output_png, output_imagemap = ancestry_graph(revision)
+ def GET(self, ops, revision):
+ output_png, output_imagemap = ancestry_graph(ops, revision)
if os.access(output_png, os.R_OK):
web.header('Content-Type', 'image/png')
sys.stdout.write(open(output_png).read())
@@ -1214,13 +1222,13 @@ class Json(object):
revdate = common.parse_timecert(cert[7])
rv['ago'] = common.ago(revdate)
- def BranchLink(self, for_branch):
+ def BranchLink(self, ops, for_branch):
rv = {
'type' : 'branch',
'branch' : for_branch,
}
branch = mtn.Branch(for_branch)
- changes, new_starting_point = Changes().branch_get_last_changes(branch, 0, 1)
+ changes, new_starting_point = Changes().branch_get_last_changes(ops, branch, 0, 1)
if len(changes) < 1:
return web.notfound()
if not changes:
@@ -1230,7 +1238,7 @@ class Json(object):
self.fill_from_certs(rv, certs)
return rv
- def RevisionLink(self, revision_id):
+ def RevisionLink(self, ops, revision_id):
rv = {
'type' : 'revision',
'revision_id' : revision_id,
@@ -1240,19 +1248,19 @@ class Json(object):
self.fill_from_certs(rv, certs)
return rv
- def GET(self, method, encoded_args):
+ def GET(self, ops, method, encoded_args):
writer = json.JsonWriter()
if not encoded_args.startswith('js_'):
return web.notfound()
args = json.read(binascii.unhexlify((encoded_args[3:])))
if hasattr(self, method):
- rv = getattr(self, method)(*args)
+ rv = getattr(self, method)(ops, *args)
else:
return web.notfound()
print writer.write(rv)
class BranchHead(object):
- def GET(self, head_method, proxy_to, branch, extra_path):
+ def GET(self, ops, head_method, proxy_to, branch, extra_path):
branch = mtn.Branch(branch)
valid = ('browse', 'file', 'downloadfile', 'info', 'tar', 'graph')
if not proxy_to in valid:
@@ -1355,7 +1363,6 @@ def per_request_wrapper(func, *args, **k
web.wsgi.runfcgi(func, None)
def per_request_wrapper(func, *args, **kwargs):
- ops.per_request()
return func(*args, **kwargs)
if __name__ == '__main__':
@@ -1377,10 +1384,11 @@ if __name__ == '__main__':
class PerDBClosure(object):
def GET (self, *args, **kwargs):
db, other_args = args[0], args[1:]
- print >>sys.stderr, "-> selected db", db
- the_cls.GET (*other_args, **kwargs)
+ ops = op_fact.get_ops (db)
+ if ops is None:
+ return web.notfound()
+ return the_cls.GET (ops, *other_args, **kwargs)
rv = PerDBClosure
- print >>sys.stderr, rv
return rv
for url, fn in grouper (2, perdb_urls):