# # # patch "viewmtn.py" # from [25ef3613dbdc3d4bbf01f2924a3955f6713e7647] # to [0443b09ed056e81f2c97a511d0612f9dcc05f6c1] # ============================================================ --- viewmtn.py 25ef3613dbdc3d4bbf01f2924a3955f6713e7647 +++ viewmtn.py 0443b09ed056e81f2c97a511d0612f9dcc05f6c1 @@ -326,10 +326,12 @@ class Tags: tags = map(None, ops.tags()) tags.sort(lambda t1, t2: cmp(t1.name, t2.name)) def revision_ago(rev): + rv = "" for cert in ops.certs(rev): if cert[4] == 'name' and cert[5] == 'date': revdate = common.parse_timecert(cert[7]) - return common.ago(revdate) + rv = common.ago(revdate) + return rv renderer.render('tags.html', page_title="Tags", tags=tags, revision_ago=revision_ago) class Help: @@ -337,8 +339,8 @@ class BranchChanges: renderer.render('help.html', page_title="Help") class BranchChanges: - def get_last_changes(self, branch, from_change, to_change): - revs = map(None, ops.heads(branch.name)) + def get_last_changes(self, branch, heads, from_change, to_change): + revs = heads if len(revs) == 0: raise Exception("get_last_changes() unable to find somewhere to start - probably a non-existent branch?") to_parent = revs+[] # copy @@ -412,6 +414,9 @@ class BranchChanges: return rv branch = mtn.Branch(branch) + heads = [t for t in ops.heads(branch.name)] + if not heads: + return web.notfound() per_page = 10 if from_change: from_change = int(from_change) @@ -421,7 +426,7 @@ class BranchChanges: to_change = int(to_change) else: to_change = per_page - changed, new_starting_point = self.get_last_changes(branch, from_change, to_change) + changed, new_starting_point = self.get_last_changes(branch, heads, from_change, to_change) # next and previous 'from' and 'to' indexes if len(changed) == to_change - from_change: next_from, next_to = to_change, to_change + per_page @@ -453,7 +458,7 @@ class RSSBranchChanges(BranchChanges): def GET(self, branch, from_change, to_change): BranchChanges.GET(self, branch, from_change, to_change, "branchchangesrss.html") -class RevisionPage: +class RevisionPage(object): def get_fileid(self, revision, filename): rv = None for stanza in ops.get_manifest_of(revision): @@ -462,6 +467,12 @@ class RevisionPage: if stanza[1] == filename: rv = stanza[3] return rv + def exists(self, revision): + try: + certs = [t for t in ops.certs(revision)] + return True + except mtn.MonotoneException: + return False def branches_for_rev(self, revisions_val): rv = [] for stanza in ops.certs(revisions_val): @@ -472,6 +483,8 @@ class RevisionInfo(RevisionPage): class RevisionInfo(RevisionPage): def GET(self, revision): revision = mtn.Revision(revision) + if not self.exists(revision): + return web.notfound() certs = ops.certs(revision) revisions = ops.get_revision(revision) output_png, output_imagemap = ancestry_graph(revision) @@ -492,6 +505,10 @@ class RevisionDiff(RevisionPage): def GET(self, revision_from, revision_to, filename=None): revision_from = mtn.Revision(revision_from) revision_to = mtn.Revision(revision_to) + if not self.exists(revision_from): + return web.notfound() + if not self.exists(revision_to): + return web.notfound() if filename != None: files = [filename] else: @@ -508,6 +525,8 @@ class RevisionFile(RevisionPage): class RevisionFile(RevisionPage): def GET(self, revision, filename): revision = mtn.Revision(revision) + if not self.exists(revision_to): + return web.notfound() language = filename.rsplit('.', 1)[-1] fileid = RevisionPage.get_fileid(self, revision, filename) if not fileid: @@ -515,9 +534,11 @@ class RevisionFile(RevisionPage): contents = ops.get_file(fileid) mimetype = mimehelp.lookup(filename, '') mime_to_template = { - 'image/jpeg' : 'revisionfileimg.html', - 'image/png' : 'revisionfileimg.html', - 'image/gif' : 'revisionfileimg.html' + 'image/jpeg' : 'revisionfileimg.html', + 'image/png' : 'revisionfileimg.html', + 'image/gif' : 'revisionfileimg.html', + 'application/x-python' : 'revisionfiletxt.html', + 'application/x-perl' : 'revisionfiletxt.html', } template = mime_to_template.get(mimetype, None) if not template: @@ -536,6 +557,8 @@ class RevisionDownloadFile(RevisionPage) def GET(self, revision, filename): web.header('Content-Disposition', 'attachment; filename=%s' % filename) revision = mtn.Revision(revision) + if not self.exists(revision_to): + return web.notfound() fileid = RevisionPage.get_fileid(self, revision, filename) if not fileid: return web.notfound() @@ -546,11 +569,13 @@ class RevisionDownloadFile(RevisionPage) sys.stdout.write(data) sys.stdout.flush() -class RevisionTar: +class RevisionTar(RevisionPage): def GET(self, 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_to): + return web.notfound() web.header('Content-Disposition', 'attachment; filename=%s.tar' % revision) web.header('Content-Type', 'application/x-tar') manifest = [stanza for stanza in ops.get_manifest_of(revision)] @@ -590,6 +615,8 @@ class RevisionBrowse(RevisionPage): class RevisionBrowse(RevisionPage): def GET(self, revision, path): revision = mtn.Revision(revision) + if not self.exists(revision_to): + return web.notfound() branches = RevisionPage.branches_for_rev(self, revision) revisions = ops.get_revision(revision)