# # # patch ".htaccess" # from [32f18fb3ae3287627ec6cba1a5ab8513ec58b06a] # to [21143b11977f7a6c554e97c6270ffd6a9207febb] # # patch "index.psp" # from [4d51e2425e0b157425e6360e97268c15712f43b3] # to [f43a8e5926d4b7828765299cf23beba6bca256a7] # # patch "monotone.py" # from [7f1c3f7f328134e117328056199a1a092d0f9583] # to [2dff75c63bf007f86d0b3806c5a085890d27757f] # # patch "revision.psp" # from [c8fd63ea4c16d9b8cd446ff765f773f20c7adf74] # to [65c3b846ff13c46662f9ed4f1aafb3017181e354] # ============================================================ --- .htaccess 32f18fb3ae3287627ec6cba1a5ab8513ec58b06a +++ .htaccess 21143b11977f7a6c554e97c6270ffd6a9207febb @@ -1,5 +1,6 @@ AddHandler mod_python .psp #PythonHandler mod_python.psp PythonHandler wrapper +PythonInterpreter viewmtn AddHandler mod_python .py DirectoryIndex index.psp ============================================================ --- index.psp 4d51e2425e0b157425e6360e97268c15712f43b3 +++ index.psp f43a8e5926d4b7828765299cf23beba6bca256a7 @@ -44,6 +44,7 @@ <% + branches.sort() for branch in branches: req.write('' % (urllib.quote(branch), hq(branch))) @@ -69,6 +70,7 @@
Branch
%s
<% + tags.sort(lambda x,y: cmp(x[0], y[0])) for tag in tags: req.write('' % (urllib.quote(tag[1]), hq(tag[0]), hq(tag[2]))) ============================================================ --- monotone.py 7f1c3f7f328134e117328056199a1a092d0f9583 +++ monotone.py 2dff75c63bf007f86d0b3806c5a085890d27757f @@ -9,15 +9,19 @@ # should really use the "automate" interface as much as possible # +id_re = re.compile(r'^[0-9a-f]+$') + dash_re = re.compile(r'^-+$') cert_value_re = re.compile(r'^(\S*) *: (.*)$') -new_manifest_re = re.compile("^new_manifest \[(\S+)\]$") -old_revision_re = re.compile("^old_revision \[(\S+)\]$") -old_manifest_re = re.compile("^old_manifest \[(\S+)\]$") +new_manifest_re = re.compile(r'^new_manifest \[(\S+)\]$') +old_revision_re = re.compile(r'^old_revision \[(\S+)\]$') +old_manifest_re = re.compile(r'^old_manifest \[(\S+)\]$') -manifest_entry_re = re.compile("^(\S+) *(.*)$") +manifest_entry_re = re.compile(r'^(\S+) *(.*)$') +log_entry_re = re.compile(r'^(\S+): (.*)$') + class Monotone: def __init__(self, mt, dbfile): self.mt = mt @@ -47,8 +51,11 @@ c_key = c_value = None for line in utility.iter_command(self.base_command + " ls certs %s" % (pipes.quote(id))): if dash_re.match(line): - if c_key != None: c_cert[c_key] = c_value - if c_cert: rv.append(c_cert) + if c_cert: + if c_key != None: + c_cert[c_key] = c_value + c_key = c_value = None + rv.append(c_cert) c_cert = {} elif c_cert != None: m = cert_value_re.match(line) @@ -60,6 +67,11 @@ c_key, c_value = key, [value] else: c_value.append(value) + if c_cert: + if c_key != None: + c_cert[c_key] = c_value + c_key = c_value = None + rv.append(c_cert) return rv def revision(self, id): rv = {} @@ -82,4 +94,24 @@ raise Exception("Unable to retrieve file: %s" % (result['childerr'])) else: return result['fromchild'] + def ancestry(self, id, limit=0): + rv = [] + entry = None + for line in utility.iter_command(self.base_command + " log %s" % (pipes.quote(id))): + if dash_re.match(line): + print "dash" + entry = {} + elif entry != None: + if not line: + rv.append(entry) + entry = None + if limit > 0 and len(rv) >= limit: break + else: + m = log_entry_re.match(line) + if m: entry[m.groups()[0]] = m.groups()[1] + if entry: rv.append(entry) + return rv +def is_valid_id(s): + return len(s) == 40 and id_re.match(s) != None + ============================================================ --- revision.psp c8fd63ea4c16d9b8cd446ff765f773f20c7adf74 +++ revision.psp 65c3b846ff13c46662f9ed4f1aafb3017181e354 @@ -22,6 +22,8 @@ if not form.has_key('id'): raise Exception("No revision ID specified.") id = form['id'] +if not monotone.is_valid_id(id): + raise Exception("Specified revision ID is not valid.") mt = Monotone(config.monotone, config.dbfile)
TagSigned by
%s%s