Show More
@@ -0,0 +1,16 b'' | |||||
|
1 | Content-Type: text/html | |||
|
2 | ||||
|
3 | <html> | |||
|
4 | <body> | |||
|
5 | <h2>changelog for #repo#</h2> | |||
|
6 | ||||
|
7 | navigate: #changenav#<br> | |||
|
8 | ||||
|
9 | <table> | |||
|
10 | #changelist# | |||
|
11 | </table> | |||
|
12 | ||||
|
13 | navigate: #changenav#<br> | |||
|
14 | ||||
|
15 | </body> | |||
|
16 | </html> No newline at end of file |
@@ -0,0 +1,26 b'' | |||||
|
1 | <tr> | |||
|
2 | <td align=right width="15%"><b>#age# ago:</b></td> | |||
|
3 | <td><b>#shortdesc#</b></td</tr> | |||
|
4 | <tr> | |||
|
5 | <td align=right>revision:</td> | |||
|
6 | <td><a href="?cmd=changeset;node=#node#">#rev#:#node#</a></td></tr> | |||
|
7 | <tr> | |||
|
8 | <td align=right>parent:</td> | |||
|
9 | <td><a href="?cmd=changeset;node=#p1#">#p1rev#:#p1#</a></td></tr> | |||
|
10 | <tr> | |||
|
11 | <td align=right>parent:</td> | |||
|
12 | <td><a href="?cmd=changeset;node=#p2#">#p2rev#:#p2#</a></td></tr> | |||
|
13 | <tr> | |||
|
14 | <td align=right>manifest:</td> | |||
|
15 | <td><a href="?cmd=manifest;manifest=#manifest#;path=/">#rev#:#manifest#</a></td></tr> | |||
|
16 | <tr> | |||
|
17 | <td align=right>author:</td> | |||
|
18 | <td>#author#</td></tr> | |||
|
19 | <tr> | |||
|
20 | <td align=right>date:</td> | |||
|
21 | <td>#date#</td></tr> | |||
|
22 | <tr> | |||
|
23 | <td align=right valign=top>files:</td> | |||
|
24 | <td>#files#</td></tr> | |||
|
25 | ||||
|
26 |
@@ -0,0 +1,46 b'' | |||||
|
1 | Content-type: text/html | |||
|
2 | ||||
|
3 | <html> | |||
|
4 | <body> | |||
|
5 | <a href="?cmd=changelog&pos=#rev#">changelog</a> | |||
|
6 | <a href="?cmd=manifest;manifest=#manifest#;path=/">manifest</a> | |||
|
7 | ||||
|
8 | <h2>changeset: #shortdesc#</h2> | |||
|
9 | ||||
|
10 | <table> | |||
|
11 | <tr> | |||
|
12 | <td align=right>revision:</td> | |||
|
13 | <td><a href="?cmd=changeset;node=#node#">#rev#:#node#</a></td></tr> | |||
|
14 | <tr> | |||
|
15 | <td align=right>parent:</td> | |||
|
16 | <td><a href="?cmd=changeset;node=#p1#">#p1rev#:#p1#</a></td></tr> | |||
|
17 | <tr> | |||
|
18 | <td align=right>parent:</td> | |||
|
19 | <td><a href="?cmd=changeset;node=#p2#">#p2rev#:#p2#</a></td></tr> | |||
|
20 | <tr> | |||
|
21 | <td align=right>manifest:</td> | |||
|
22 | <td><a href="?cmd=manifest;manifest=#manifest#;path=/">#rev#:#manifest#</a></td></tr> | |||
|
23 | <tr> | |||
|
24 | <td align=right>author:</td> | |||
|
25 | <td>#author#</td></tr> | |||
|
26 | <tr> | |||
|
27 | <td align=right>date:</td> | |||
|
28 | <td>#date#</td></tr> | |||
|
29 | <tr> | |||
|
30 | <td align=right valign=top>files:</td> | |||
|
31 | <td>#files#</td></tr> | |||
|
32 | <tr> | |||
|
33 | <td align=right valign=top>description:</td> | |||
|
34 | <td>#desc#</td></tr> | |||
|
35 | </table> | |||
|
36 | ||||
|
37 | <hr /> | |||
|
38 | ||||
|
39 | <pre> | |||
|
40 | #diff# | |||
|
41 | </pre> | |||
|
42 | ||||
|
43 | </body> | |||
|
44 | </html | |||
|
45 | ||||
|
46 |
@@ -0,0 +1,42 b'' | |||||
|
1 | Content-type: text/html | |||
|
2 | ||||
|
3 | <html> | |||
|
4 | <body> | |||
|
5 | ||||
|
6 | <a href="?cmd=changelog&rev=#rev#">changelog</a> | |||
|
7 | <a href="?cmd=changeset&node=#node#">changeset</a> | |||
|
8 | <a href="?cmd=manifest&manifest=#manifest#;path=#path#">manifest</a> | |||
|
9 | <a href="?cmd=file&file=#file#&filenode=#filenode#">file</a> | |||
|
10 | <a href="?cmd=filelog&file=#file#;filenode=#filenode#">revisions</a> | |||
|
11 | ||||
|
12 | <h2>Annotate #file# (#filenode#)</h2> | |||
|
13 | ||||
|
14 | <table> | |||
|
15 | <tr> | |||
|
16 | <td align=right>changeset:</td> | |||
|
17 | <td><a href="?cmd=changeset;node=#node#">#rev#:#node#</a></td></tr> | |||
|
18 | <tr> | |||
|
19 | <td align=right>parent:</td> | |||
|
20 | <td><a href="?cmd=file;file=#file#;node=#p1#">#p1rev#:#p1#</a></td></tr> | |||
|
21 | <tr> | |||
|
22 | <td align=right>parent:</td> | |||
|
23 | <td><a href="?cmd=file;file=#file#;node=#p2#">#p2rev#:#p2#</a></td></tr> | |||
|
24 | <tr> | |||
|
25 | <td align=right>manifest:</td> | |||
|
26 | <td><a href="?cmd=manifest;manifest=#manifest#;path=/">#rev#:#manifest#</a></td></tr> | |||
|
27 | <tr> | |||
|
28 | <td align=right>author:</td> | |||
|
29 | <td>#author#</td></tr> | |||
|
30 | <tr> | |||
|
31 | <td align=right>date:</td> | |||
|
32 | <td>#date#</td></tr> | |||
|
33 | </table> | |||
|
34 | ||||
|
35 | <hr /> | |||
|
36 | ||||
|
37 | <table> | |||
|
38 | #annotate# | |||
|
39 | </table> | |||
|
40 | ||||
|
41 | </body> | |||
|
42 | </html> No newline at end of file |
@@ -0,0 +1,30 b'' | |||||
|
1 | Content-type: text/html | |||
|
2 | ||||
|
3 | <html> | |||
|
4 | <body> | |||
|
5 | <a href="?cmd=changelog&rev=#rev#">changelog</a> | |||
|
6 | <a href="?cmd=changeset&node=#node#">changeset</a> | |||
|
7 | <a href="?cmd=file&file=#file#&filenode=#filenode#">file</a> | |||
|
8 | <a href="?cmd=filelog&file=#file#&filenode=#filenode#">revisions</a> | |||
|
9 | <a href="?cmd=annotate&file=#file#&filenode=#filenode#">annotate</a> | |||
|
10 | ||||
|
11 | <h2>#file#</h2> | |||
|
12 | ||||
|
13 | <table> | |||
|
14 | <tr> | |||
|
15 | <td align=right>revision:</td> | |||
|
16 | <td><a href="?cmd=changeset;node=#node#">#rev#:#node#</a></td></tr> | |||
|
17 | <tr> | |||
|
18 | <td align=right>parent:</td> | |||
|
19 | <td><a href="?cmd=changeset;node=#p1#">#p1rev#:#p1#</a></td></tr> | |||
|
20 | </table> | |||
|
21 | ||||
|
22 | <hr /> | |||
|
23 | <pre> | |||
|
24 | #diff# | |||
|
25 | </pre> | |||
|
26 | ||||
|
27 | </body> | |||
|
28 | </html | |||
|
29 | ||||
|
30 |
@@ -0,0 +1,17 b'' | |||||
|
1 | Content-type: text/html | |||
|
2 | ||||
|
3 | <html> | |||
|
4 | <body> | |||
|
5 | ||||
|
6 | <a href="?cmd=changelog">changelog</a> | |||
|
7 | <a href="?cmd=file&file=#file#&filenode=#filenode#">file</a> | |||
|
8 | <a href="?cmd=annotate&file=#file#&filenode=#filenode#">annotate</a> | |||
|
9 | ||||
|
10 | <h2>#file# revision history</h2> | |||
|
11 | ||||
|
12 | <table> | |||
|
13 | #entries# | |||
|
14 | </table> | |||
|
15 | ||||
|
16 | </body> | |||
|
17 | </html> No newline at end of file |
@@ -0,0 +1,18 b'' | |||||
|
1 | <tr> | |||
|
2 | <td align=right width="15%"><b>#age# ago:</b></td> | |||
|
3 | <td><b><a href="?cmd=changeset;node=#changeset#">#shortdesc#</a></b></td</tr> | |||
|
4 | <tr> | |||
|
5 | <td align=right>revision:</td> | |||
|
6 | <td><a href="?cmd=file;file=#file#;filenode=#filenode#">#filerev#:#filenode#</a> | |||
|
7 | <a href="?cmd=filediff;file=#file#;node=#node#">(diff)</a> | |||
|
8 | <a href="?cmd=annotate;file=#file#;filenode=#filenode#">(annotate)</a> | |||
|
9 | </td></tr> | |||
|
10 | <tr> | |||
|
11 | <td align=right>author:</td> | |||
|
12 | <td>#author#</td></tr> | |||
|
13 | <tr> | |||
|
14 | <td align=right>date:</td> | |||
|
15 | <td>#date#</td></tr> | |||
|
16 | ||||
|
17 | ||||
|
18 |
@@ -0,0 +1,42 b'' | |||||
|
1 | Content-type: text/html | |||
|
2 | ||||
|
3 | <html> | |||
|
4 | <body> | |||
|
5 | ||||
|
6 | <a href="?cmd=changelog&rev=#rev#">changelog</a> | |||
|
7 | <a href="?cmd=changeset&node=#node#">changeset</a> | |||
|
8 | <a href="?cmd=manifest&manifest=#manifest#;path=#path#">manifest</a> | |||
|
9 | <a href="?cmd=filelog&file=#file#;filenode=#filenode#">revisions</a> | |||
|
10 | <a href="?cmd=annotate&file=#file#&filenode=#filenode#">annotate</a> | |||
|
11 | ||||
|
12 | <h2>#file# (revision #filenode#)</h2> | |||
|
13 | ||||
|
14 | <table> | |||
|
15 | <tr> | |||
|
16 | <td align=right>changeset:</td> | |||
|
17 | <td><a href="?cmd=changeset;node=#node#">#rev#:#node#</a></td></tr> | |||
|
18 | <tr> | |||
|
19 | <td align=right>parent:</td> | |||
|
20 | <td><a href="?cmd=file;file=#file#;node=#p1#">#p1rev#:#p1#</a></td></tr> | |||
|
21 | <tr> | |||
|
22 | <td align=right>parent:</td> | |||
|
23 | <td><a href="?cmd=file;file=#file#;node=#p2#">#p2rev#:#p2#</a></td></tr> | |||
|
24 | <tr> | |||
|
25 | <td align=right>manifest:</td> | |||
|
26 | <td><a href="?cmd=manifest;manifest=#manifest#;path=/">#rev#:#manifest#</a></td></tr> | |||
|
27 | <tr> | |||
|
28 | <td align=right>author:</td> | |||
|
29 | <td>#author#</td></tr> | |||
|
30 | <tr> | |||
|
31 | <td align=right>date:</td> | |||
|
32 | <td>#date#</td></tr> | |||
|
33 | </table> | |||
|
34 | ||||
|
35 | <hr /> | |||
|
36 | ||||
|
37 | <pre> | |||
|
38 | #text# | |||
|
39 | </pre> | |||
|
40 | ||||
|
41 | </body> | |||
|
42 | </html> No newline at end of file |
@@ -0,0 +1,19 b'' | |||||
|
1 | Content-Type: text/html | |||
|
2 | ||||
|
3 | <html> | |||
|
4 | <body> | |||
|
5 | ||||
|
6 | <a href="?cmd=changelog&rev=#rev#">changelog</a> | |||
|
7 | <a href="?cmd=changeset&node=#node#">changeset</a> | |||
|
8 | ||||
|
9 | <h2>manifest: #path#</h2> | |||
|
10 | <p>(#rev#:#manifest#)</p> | |||
|
11 | ||||
|
12 | <p> | |||
|
13 | <a href="?cmd=manifest;manifest=#manifest#;path=#up#">[up]</a><br /> | |||
|
14 | #dirs#</p> | |||
|
15 | ||||
|
16 | <p>#files#</p> | |||
|
17 | ||||
|
18 | </body> | |||
|
19 | </html> No newline at end of file |
@@ -0,0 +1,20 b'' | |||||
|
1 | changelog = changelog.tmpl | |||
|
2 | naventry = "<a href="?cmd=changelog;pos=#rev#">#rev#</a> " | |||
|
3 | filedifflink = "<a href="?cmd=filediff;node=#node#;file=#file#">#file#</a> " | |||
|
4 | filenodelink = "<a href="?cmd=file;filenode=#filenode#;file=#file#">#file#</a> " | |||
|
5 | fileellipses = "..." | |||
|
6 | changelogentry = changelogentry.tmpl | |||
|
7 | changeset = changeset.tmpl | |||
|
8 | manifest = manifest.tmpl | |||
|
9 | manifestdirentry = "<a href="?cmd=manifest;manifest=#manifest#;path=#path#">#basename#/</a><br />" | |||
|
10 | manifestfileentry = "<a href="?cmd=file;filenode=#filenode#;file=#file#">#basename#</a><br /> " | |||
|
11 | filerevision = filerevision.tmpl | |||
|
12 | fileannotate = fileannotate.tmpl | |||
|
13 | filediff = filediff.tmpl | |||
|
14 | filelog = filelog.tmpl | |||
|
15 | filelogentry = filelogentry.tmpl | |||
|
16 | annotateline = "<tr><td align = right><a href="?cmd=changeset;node=#node#">#author#@#rev#</a>:</td><td><pre>#line#</pre></td></tr>" | |||
|
17 | difflineplus = "<span class=plusline>#line#</span>" | |||
|
18 | difflineminus = "<span class=minusline>#line#</span>" | |||
|
19 | difflineat = "<span class=atline>#line#</span>" | |||
|
20 | diffline = "#line#" No newline at end of file |
@@ -0,0 +1,38 b'' | |||||
|
1 | repo the name of the repo | |||
|
2 | rev a changeset.manifest revision | |||
|
3 | node a changeset node | |||
|
4 | changesets total number of changesets | |||
|
5 | file a filename | |||
|
6 | filenode a file node | |||
|
7 | filerev a file revision | |||
|
8 | filerevs total number of file revisions | |||
|
9 | up the directory of the relevant file | |||
|
10 | path a path in the manifest, starting with "/" | |||
|
11 | basename a short pathname | |||
|
12 | manifest a manifest node | |||
|
13 | manifestrev a manifest revision | |||
|
14 | date a date string | |||
|
15 | age age in hours, days, etc | |||
|
16 | line a line of text (escaped) | |||
|
17 | desc a description (escaped, with breaks) | |||
|
18 | shortdesc a short description (escaped) | |||
|
19 | author a name or email addressv(obfuscated) | |||
|
20 | p1, p2 parent nodes | |||
|
21 | p1rev, p2rev parent revs | |||
|
22 | ||||
|
23 | header the global page header | |||
|
24 | footer the global page footer | |||
|
25 | ||||
|
26 | files a list of file links | |||
|
27 | dirs a set of directory links | |||
|
28 | diff a diff of one or more files | |||
|
29 | annotate an annotated file | |||
|
30 | entries the entries relevant to the page | |||
|
31 | ||||
|
32 | Templates and commands: | |||
|
33 | changelog(rev) - a page for browsing changesets | |||
|
34 | naventry - a link for jumping to a changeset number | |||
|
35 | filenodelink - jump to file diff | |||
|
36 | fileellipses - printed after maxfiles | |||
|
37 | changelogentry - an entry in the log | |||
|
38 | manifest - browse a manifest as a directory tree No newline at end of file |
This diff has been collapsed as it changes many lines, (759 lines changed) Show them Hide them | |||||
@@ -11,16 +11,45 b' import cgitb' | |||||
11 | cgitb.enable() |
|
11 | cgitb.enable() | |
12 |
|
12 | |||
13 | import os, cgi, time, re, difflib, sys, zlib |
|
13 | import os, cgi, time, re, difflib, sys, zlib | |
14 |
from mercurial import |
|
14 | from mercurial.hg import * | |
|
15 | ||||
|
16 | def age(t): | |||
|
17 | def plural(t, c): | |||
|
18 | if c == 1: return t | |||
|
19 | return t + "s" | |||
|
20 | def fmt(t, c): | |||
|
21 | return "%d %s" % (c, plural(t, c)) | |||
|
22 | ||||
|
23 | now = time.time() | |||
|
24 | delta = max(1, int(now - t)) | |||
|
25 | ||||
|
26 | scales = [["second", 1], | |||
|
27 | ["minute", 60], | |||
|
28 | ["hour", 3600], | |||
|
29 | ["day", 3600 * 24], | |||
|
30 | ["week", 3600 * 24 * 7], | |||
|
31 | ["month", 3600 * 24 * 30], | |||
|
32 | ["year", 3600 * 24 * 365]] | |||
|
33 | ||||
|
34 | scales.reverse() | |||
|
35 | ||||
|
36 | for t, s in scales: | |||
|
37 | n = delta / s | |||
|
38 | if n >= 1: return fmt(t, n) | |||
15 |
|
39 | |||
16 | def nl2br(text): |
|
40 | def nl2br(text): | |
17 |
return |
|
41 | return text.replace('\n', '<br/>') | |
18 |
|
42 | |||
19 | def obfuscate(text): |
|
43 | def obfuscate(text): | |
20 | l = [] |
|
44 | return ''.join([ '&#%d' % ord(c) for c in text ]) | |
21 | for c in text: |
|
45 | ||
22 | l.append('&#%d;' % ord(c)) |
|
46 | def up(p): | |
23 | return ''.join(l) |
|
47 | if p[0] != "/": p = "/" + p | |
|
48 | if p[-1] == "/": p = p[:-1] | |||
|
49 | up = os.path.dirname(p) | |||
|
50 | if up == "/": | |||
|
51 | return "/" | |||
|
52 | return up + "/" | |||
24 |
|
53 | |||
25 | def httphdr(type): |
|
54 | def httphdr(type): | |
26 | print 'Content-type: %s\n' % type |
|
55 | print 'Content-type: %s\n' % type | |
@@ -33,365 +62,451 b' def write(*things):' | |||||
33 | else: |
|
62 | else: | |
34 | sys.stdout.write(str(thing)) |
|
63 | sys.stdout.write(str(thing)) | |
35 |
|
64 | |||
36 | class template: |
|
65 | def template(tmpl, **map): | |
37 | def __init__(self, tmpl_dir): |
|
66 | while tmpl: | |
38 | self.tmpl_dir = tmpl_dir |
|
67 | m = re.search(r"#([a-zA-Z0-9]+)#", tmpl) | |
39 | def do_page(self, tmpl_fn, **map): |
|
|||
40 | txt = file(os.path.join(self.tmpl_dir, tmpl_fn)).read() |
|
|||
41 | while txt: |
|
|||
42 | m = re.search(r"#([a-zA-Z0-9]+)#", txt) |
|
|||
43 |
|
|
68 | if m: | |
44 |
|
|
69 | yield tmpl[:m.start(0)] | |
45 |
|
|
70 | v = map.get(m.group(1), "") | |
46 |
|
|
71 | yield callable(v) and v() or v | |
47 | for y in v(**map): yield y |
|
72 | tmpl = tmpl[m.end(0):] | |
48 | else: |
|
|||
49 | yield v |
|
|||
50 | txt = txt[m.end(0):] |
|
|||
51 |
|
|
73 | else: | |
52 |
|
|
74 | yield tmpl | |
53 |
|
|
75 | return | |
54 |
|
||||
55 | class page: |
|
|||
56 | def __init__(self, tmpl_dir = "", type="text/html", title="Mercurial Web", |
|
|||
57 | charset="ISO-8859-1"): |
|
|||
58 | self.tmpl = template(tmpl_dir) |
|
|||
59 |
|
||||
60 | print 'Content-type: %s; charset=%s\n' % (type, charset) |
|
|||
61 | write(self.tmpl.do_page('htmlstart.tmpl', title = title)) |
|
|||
62 |
|
||||
63 | def endpage(self): |
|
|||
64 | print '</BODY>' |
|
|||
65 | print '</HTML>' |
|
|||
66 |
|
||||
67 | def show_diff(self, a, b, fn): |
|
|||
68 | a = a.splitlines(1) |
|
|||
69 | b = b.splitlines(1) |
|
|||
70 | l = difflib.unified_diff(a, b, fn, fn) |
|
|||
71 | print '<pre>' |
|
|||
72 | for line in l: |
|
|||
73 | line = cgi.escape(line[:-1]) |
|
|||
74 | if line.startswith('+'): |
|
|||
75 | print '<span class="plusline">%s</span>' % (line, ) |
|
|||
76 | elif line.startswith('-'): |
|
|||
77 | print '<span class="minusline">%s</span>' % (line, ) |
|
|||
78 | elif line.startswith('@'): |
|
|||
79 | print '<span class="atline">%s</span>' % (line, ) |
|
|||
80 | else: |
|
|||
81 | print line |
|
|||
82 | print '</pre>' |
|
|||
83 |
|
||||
84 | class errpage(page): |
|
|||
85 | def __init__(self, tmpl_dir): |
|
|||
86 | page.__init__(self, tmpl_dir, title="Mercurial Web Error Page") |
|
|||
87 |
|
||||
88 | class change_list(page): |
|
|||
89 | def __init__(self, repo, tmpl_dir, reponame, numchanges = 50): |
|
|||
90 | page.__init__(self, tmpl_dir) |
|
|||
91 | self.repo = repo |
|
|||
92 | self.numchanges = numchanges |
|
|||
93 | write(self.tmpl.do_page('changestitle.tmpl', reponame=reponame)) |
|
|||
94 |
|
76 | |||
95 | def content(self, hi=None): |
|
77 | class templater: | |
96 | cl = [] |
|
78 | def __init__(self, mapfile): | |
97 | count = self.repo.changelog.count() |
|
79 | self.cache = {} | |
98 | if not hi: |
|
80 | self.map = {} | |
99 | hi = count |
|
81 | self.base = os.path.dirname(mapfile) | |
100 | elif hi < self.numchanges: |
|
|||
101 | hi = self.numchanges |
|
|||
102 |
|
||||
103 | start = 0 |
|
|||
104 | if hi - self.numchanges >= 0: |
|
|||
105 | start = hi - self.numchanges |
|
|||
106 |
|
||||
107 | nav = "Displaying Revisions: %d-%d" % (start, hi-1) |
|
|||
108 | if start != 0: |
|
|||
109 | nav = ('<a href="?cmd=changes;hi=%d">Previous %d</a> ' \ |
|
|||
110 | % (start, self.numchanges)) + nav |
|
|||
111 | if hi != count: |
|
|||
112 | if hi + self.numchanges <= count: |
|
|||
113 | nav += ' <a href="?cmd=changes;hi=%d">Next %d</a>' \ |
|
|||
114 | % (hi + self.numchanges, self.numchanges) |
|
|||
115 | else: |
|
|||
116 | nav += ' <a href="?cmd=changes">Next %d</a>' % \ |
|
|||
117 | self.numchanges |
|
|||
118 |
|
||||
119 | print '<center>%s</center>' % nav |
|
|||
120 |
|
||||
121 | for i in xrange(start, hi): |
|
|||
122 | n = self.repo.changelog.node(i) |
|
|||
123 | cl.append((n, self.repo.changelog.read(n))) |
|
|||
124 | cl.reverse() |
|
|||
125 |
|
||||
126 | print '<table summary="" width="100%" align="center">' |
|
|||
127 | for n, ch in cl: |
|
|||
128 | print '<tr><td>' |
|
|||
129 | self.change_table(n, ch) |
|
|||
130 | print '</td></tr>' |
|
|||
131 | print '</table>' |
|
|||
132 |
|
||||
133 | print '<center>%s</center>' % nav |
|
|||
134 |
|
||||
135 | def change_table(self, nodeid, changes): |
|
|||
136 | hn = hg.hex(nodeid) |
|
|||
137 | i = self.repo.changelog.rev(nodeid) |
|
|||
138 | (h1, h2) = [ hg.hex(x) for x in self.repo.changelog.parents(nodeid) ] |
|
|||
139 | datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0]))) |
|
|||
140 | files = [] |
|
|||
141 | for f in changes[3]: |
|
|||
142 | files.append('<a href="?cmd=file;cs=%s;fn=%s">%s</a> ' \ |
|
|||
143 | % (hn, f, cgi.escape(f))) |
|
|||
144 | write(self.tmpl.do_page('change_table.tmpl', |
|
|||
145 | author=obfuscate(changes[1]), |
|
|||
146 | desc=nl2br(cgi.escape(changes[4])), date=datestr, |
|
|||
147 | files=' '.join(files), revnum=i, revnode=hn)) |
|
|||
148 |
|
||||
149 | class checkin(page): |
|
|||
150 | def __init__(self, repo, tmpl_dir, nodestr): |
|
|||
151 | page.__init__(self, tmpl_dir) |
|
|||
152 | self.repo = repo |
|
|||
153 | self.node = hg.bin(nodestr) |
|
|||
154 | self.nodestr = nodestr |
|
|||
155 | print '<h3>Checkin: %s</h3>' % nodestr |
|
|||
156 |
|
82 | |||
157 | def content(self): |
|
83 | for l in file(mapfile): | |
158 | changes = self.repo.changelog.read(self.node) |
|
84 | m = re.match(r'(\S+)\s*=\s*"(.*)"$', l) | |
159 | i = self.repo.changelog.rev(self.node) |
|
85 | if m: | |
160 | parents = self.repo.changelog.parents(self.node) |
|
86 | self.cache[m.group(1)] = m.group(2) | |
161 | (h1, h2) = [ hg.hex(x) for x in parents ] |
|
|||
162 | (i1, i2) = [ self.repo.changelog.rev(x) for x in parents ] |
|
|||
163 | datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0]))) |
|
|||
164 | mf = self.repo.manifest.read(changes[0]) |
|
|||
165 | files = [] |
|
|||
166 | for f in changes[3]: |
|
|||
167 | files.append('<a href="?cmd=file;nd=%s;fn=%s">%s</a> ' \ |
|
|||
168 | % (hg.hex(mf[f]), f, cgi.escape(f))) |
|
|||
169 | p2link = h2 |
|
|||
170 | if i2 != -1: |
|
|||
171 | p2link = '<a href="?cmd=chkin;nd=%s">%s</a>' % (h2, h2) |
|
|||
172 |
|
||||
173 | write(self.tmpl.do_page('checkin.tmpl', revnum=i, revnode=self.nodestr, |
|
|||
174 | p1num=i1, p1node=h1, p2num=i2, p2node=h2, p2link=p2link, |
|
|||
175 | mfnum=self.repo.manifest.rev(changes[0]), |
|
|||
176 | mfnode=hg.hex(changes[0]), author=obfuscate(changes[1]), |
|
|||
177 | desc=nl2br(cgi.escape(changes[4])), date=datestr, |
|
|||
178 | files=' '.join(files))) |
|
|||
179 |
|
||||
180 | (c, a, d) = self.repo.diffrevs(parents[0], self.node) |
|
|||
181 | change = self.repo.changelog.read(parents[0]) |
|
|||
182 | mf2 = self.repo.manifest.read(change[0]) |
|
|||
183 | for f in c: |
|
|||
184 | self.show_diff(self.repo.file(f).read(mf2[f]), \ |
|
|||
185 | self.repo.file(f).read(mf[f]), f) |
|
|||
186 | for f in a: |
|
|||
187 | self.show_diff('', self.repo.file(f).read(mf[f]), f) |
|
|||
188 | for f in d: |
|
|||
189 | self.show_diff(self.repo.file(f).read(mf2[f]), '', f) |
|
|||
190 |
|
||||
191 | class filepage(page): |
|
|||
192 | def __init__(self, repo, tmpl_dir, fn, node=None, cs=None): |
|
|||
193 | page.__init__(self, tmpl_dir) |
|
|||
194 | self.repo = repo |
|
|||
195 | self.fn = fn |
|
|||
196 | if cs: |
|
|||
197 | chng = self.repo.changelog.read(hg.bin(cs)) |
|
|||
198 | mf = self.repo.manifest.read(chng[0]) |
|
|||
199 | self.node = mf[self.fn] |
|
|||
200 | self.nodestr = hg.hex(self.node) |
|
|||
201 | else: |
|
87 | else: | |
202 | self.nodestr = node |
|
88 | m = re.match(r'(\S+)\s*=\s*(\S+)', l) | |
203 | self.node = hg.bin(node) |
|
89 | if m: | |
204 | print '<div class="filename">%s (%s)</div>' % \ |
|
90 | self.map[m.group(1)] = os.path.join(self.base, m.group(2)) | |
205 | (cgi.escape(self.fn), self.nodestr, ) |
|
91 | else: | |
206 | print '<a href="?cmd=hist;fn=%s">history</a><br />' % self.fn |
|
92 | raise "unknown map entry '%s'" % l | |
207 | print '<a href="?cmd=ann;fn=%s;nd=%s">annotate</a><br />' % \ |
|
|||
208 | (self.fn, self.nodestr) |
|
|||
209 |
|
||||
210 | def content(self): |
|
|||
211 | print '<pre>' |
|
|||
212 | print cgi.escape(self.repo.file(self.fn).read(self.node)) |
|
|||
213 | print '</pre>' |
|
|||
214 |
|
93 | |||
215 | class annpage(page): |
|
94 | def __call__(self, t, **map): | |
216 | def __init__(self, repo, tmpl_dir, fn, node): |
|
95 | try: | |
217 | page.__init__(self, tmpl_dir) |
|
96 | tmpl = self.cache[t] | |
218 | self.repo = repo |
|
97 | except KeyError: | |
219 | self.fn = fn |
|
98 | tmpl = self.cache[t] = file(self.map[t]).read() | |
220 | self.nodestr = node |
|
99 | return template(tmpl, **map) | |
221 | self.node = hg.bin(node) |
|
|||
222 | print '<div class="annotation">Annotated: %s (%s)</div>' % \ |
|
|||
223 | (cgi.escape(self.fn), self.nodestr, ) |
|
|||
224 |
|
||||
225 | def content(self): |
|
|||
226 | print '<pre>' |
|
|||
227 | for n, l in self.repo.file(self.fn).annotate(self.node): |
|
|||
228 | cnode = self.repo.changelog.lookup(n) |
|
|||
229 | write(self.tmpl.do_page('annline.tmpl', cnode=hg.hex(cnode), |
|
|||
230 | cnum='% 6s' % n, fn=self.fn, line=cgi.escape(l[:-1]))) |
|
|||
231 | print '</pre>' |
|
|||
232 |
|
||||
233 | class mfpage(page): |
|
|||
234 | def __init__(self, repo, tmpl_dir, node): |
|
|||
235 | page.__init__(self, tmpl_dir) |
|
|||
236 | self.repo = repo |
|
|||
237 | self.nodestr = node |
|
|||
238 | self.node = hg.bin(node) |
|
|||
239 |
|
||||
240 | def content(self): |
|
|||
241 | mf = self.repo.manifest.read(self.node) |
|
|||
242 | fns = mf.keys() |
|
|||
243 | fns.sort() |
|
|||
244 | write(self.tmpl.do_page('mftitle.tmpl', node = self.nodestr)) |
|
|||
245 | for f in fns: |
|
|||
246 | write(self.tmpl.do_page('mfentry.tmpl', fn=f, node=hg.hex(mf[f]))) |
|
|||
247 |
|
||||
248 | class histpage(page): |
|
|||
249 | def __init__(self, repo, tmpl_dir, fn): |
|
|||
250 | page.__init__(self, tmpl_dir) |
|
|||
251 | self.repo = repo |
|
|||
252 | self.fn = fn |
|
|||
253 |
|
||||
254 | def content(self): |
|
|||
255 | print '<div class="filehist">File History: %s</div>' % self.fn |
|
|||
256 | r = self.repo.file(self.fn) |
|
|||
257 | print '<br />' |
|
|||
258 | print '<table summary="" width="100%" align="center">' |
|
|||
259 | for i in xrange(r.count()-1, -1, -1): |
|
|||
260 | print '<tr><td>' |
|
|||
261 | self.hist_ent(i, r) |
|
|||
262 | print '</tr></td>' |
|
|||
263 | print '</table>' |
|
|||
264 |
|
||||
265 | def hist_ent(self, i, r): |
|
|||
266 | n = r.node(i) |
|
|||
267 | (p1, p2) = r.parents(n) |
|
|||
268 | (h, h1, h2) = map(hg.hex, (n, p1, p2)) |
|
|||
269 | (i1, i2) = map(r.rev, (p1, p2)) |
|
|||
270 | ci = r.linkrev(n) |
|
|||
271 | cn = self.repo.changelog.node(ci) |
|
|||
272 | cs = hg.hex(cn) |
|
|||
273 | changes = self.repo.changelog.read(cn) |
|
|||
274 | datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0]))) |
|
|||
275 | p2entry = '' |
|
|||
276 | if i2 != -1: |
|
|||
277 | p2entry = ' %d:<a href="?cmd=file;nd=%s;fn=%s">%s</a>' \ |
|
|||
278 | % (i2, h2, self.fn, h2 ), |
|
|||
279 | write(self.tmpl.do_page('hist_ent.tmpl', author=obfuscate(changes[1]), |
|
|||
280 | csnode=cs, desc=nl2br(cgi.escape(changes[4])), |
|
|||
281 | date = datestr, fn=self.fn, revnode=h, p1num = i1, |
|
|||
282 | p1node=h1, p2entry=p2entry)) |
|
|||
283 |
|
|
100 | ||
284 | class hgweb: |
|
101 | class hgweb: | |
285 | repo_path = "." |
|
102 | maxchanges = 20 | |
286 |
|
|
103 | maxfiles = 10 | |
287 | tmpl_dir = "templates" |
|
104 | ||
|
105 | def __init__(self, path, name, templatemap): | |||
|
106 | self.reponame = name | |||
|
107 | self.repo = repository(ui(), path) | |||
|
108 | self.t = templater(templatemap) | |||
|
109 | ||||
|
110 | def date(self, cs): | |||
|
111 | return time.asctime(time.gmtime(float(cs[2].split(' ')[0]))) | |||
|
112 | ||||
|
113 | def listfiles(self, files, mf): | |||
|
114 | for f in files[:self.maxfiles]: | |||
|
115 | yield self.t("filenodelink", node = hex(mf[f]), file = f) | |||
|
116 | if len(files) > self.maxfiles: | |||
|
117 | yield self.t("fileellipses") | |||
|
118 | ||||
|
119 | def listfilediffs(self, files, changeset): | |||
|
120 | for f in files[:self.maxfiles]: | |||
|
121 | yield self.t("filedifflink", node = hex(changeset), file = f) | |||
|
122 | if len(files) > self.maxfiles: | |||
|
123 | yield self.t("fileellipses") | |||
|
124 | ||||
|
125 | def diff(self, node1, node2, files): | |||
|
126 | def filterfiles(list, files): | |||
|
127 | l = [ x for x in list if x in files ] | |||
|
128 | ||||
|
129 | for f in files: | |||
|
130 | if f[-1] != os.sep: f += os.sep | |||
|
131 | l += [ x for x in list if x.startswith(f) ] | |||
|
132 | return l | |||
|
133 | ||||
|
134 | def prettyprint(diff): | |||
|
135 | for l in diff.splitlines(1): | |||
|
136 | line = cgi.escape(l) | |||
|
137 | if line.startswith('+'): | |||
|
138 | yield self.t("difflineplus", line = line) | |||
|
139 | elif line.startswith('-'): | |||
|
140 | yield self.t("difflineminus", line = line) | |||
|
141 | elif line.startswith('@'): | |||
|
142 | yield self.t("difflineat", line = line) | |||
|
143 | else: | |||
|
144 | yield self.t("diffline", line = line) | |||
|
145 | ||||
|
146 | r = self.repo | |||
|
147 | cl = r.changelog | |||
|
148 | mf = r.manifest | |||
|
149 | change1 = cl.read(node1) | |||
|
150 | change2 = cl.read(node2) | |||
|
151 | mmap1 = mf.read(change1[0]) | |||
|
152 | mmap2 = mf.read(change2[0]) | |||
|
153 | date1 = self.date(change1) | |||
|
154 | date2 = self.date(change2) | |||
|
155 | ||||
|
156 | c, a, d = r.diffrevs(node1, node2) | |||
|
157 | c, a, d = map(lambda x: filterfiles(x, files), (c, a, d)) | |||
|
158 | ||||
|
159 | for f in c: | |||
|
160 | to = r.file(f).read(mmap1[f]) | |||
|
161 | tn = r.file(f).read(mmap2[f]) | |||
|
162 | yield prettyprint(mdiff.unidiff(to, date1, tn, date2, f)) | |||
|
163 | for f in a: | |||
|
164 | to = "" | |||
|
165 | tn = r.file(f).read(mmap2[f]) | |||
|
166 | yield prettyprint(mdiff.unidiff(to, date1, tn, date2, f)) | |||
|
167 | for f in d: | |||
|
168 | to = r.file(f).read(mmap1[f]) | |||
|
169 | tn = "" | |||
|
170 | yield prettyprint(mdiff.unidiff(to, date1, tn, date2, f)) | |||
|
171 | ||||
|
172 | def changelog(self, pos=None): | |||
|
173 | def changenav(): | |||
|
174 | def seq(factor = 1): | |||
|
175 | yield 1 * factor | |||
|
176 | yield 2 * factor | |||
|
177 | yield 5 * factor | |||
|
178 | for f in seq(factor * 10): | |||
|
179 | yield f | |||
|
180 | ||||
|
181 | linear = range(0, count - 2, self.maxchanges)[0:8] | |||
|
182 | ||||
|
183 | for i in linear: | |||
|
184 | yield self.t("naventry", rev = max(i, 1)) | |||
|
185 | ||||
|
186 | for s in seq(): | |||
|
187 | if s > count - 2: break | |||
|
188 | if s > linear[-1]: | |||
|
189 | yield self.t("naventry", rev = s) | |||
|
190 | ||||
|
191 | yield self.t("naventry", rev = count - 1) | |||
|
192 | ||||
|
193 | def changelist(): | |||
|
194 | cl = self.repo.changelog | |||
|
195 | l = [] # build a list in forward order for efficiency | |||
|
196 | for i in range(start, end + 1): | |||
|
197 | n = cl.node(i) | |||
|
198 | changes = cl.read(n) | |||
|
199 | hn = hex(n) | |||
|
200 | p1, p2 = cl.parents(n) | |||
|
201 | t = float(changes[2].split(' ')[0]) | |||
|
202 | ||||
|
203 | l.insert(0, self.t( | |||
|
204 | 'changelogentry', | |||
|
205 | author = obfuscate(changes[1]), | |||
|
206 | shortdesc = cgi.escape(changes[4].splitlines()[0]), | |||
|
207 | age = age(t), | |||
|
208 | p1 = hex(p1), p2 = hex(p2), | |||
|
209 | p1rev = cl.rev(p1), p2rev = cl.rev(p2), | |||
|
210 | manifest = hex(changes[0]), | |||
|
211 | desc = nl2br(cgi.escape(changes[4])), | |||
|
212 | date = time.asctime(time.gmtime(t)), | |||
|
213 | files = self.listfilediffs(changes[3], n), | |||
|
214 | rev = i, | |||
|
215 | node = hn)) | |||
|
216 | ||||
|
217 | yield l | |||
|
218 | ||||
|
219 | count = self.repo.changelog.count() | |||
|
220 | pos = pos or count - 1 | |||
|
221 | end = min(pos, count - 1) | |||
|
222 | start = max(0, pos - self.maxchanges) | |||
|
223 | end = min(count - 1, start + self.maxchanges) | |||
|
224 | ||||
|
225 | yield self.t('changelog', repo = self.reponame, changenav = changenav, | |||
|
226 | rev = pos, changesets = count, changelist = changelist) | |||
|
227 | ||||
|
228 | def changeset(self, nodeid): | |||
|
229 | n = bin(nodeid) | |||
|
230 | cl = self.repo.changelog | |||
|
231 | changes = cl.read(n) | |||
|
232 | p1, p2 = cl.parents(n) | |||
|
233 | p1rev, p2rev = cl.rev(p1), cl.rev(p2) | |||
|
234 | t = float(changes[2].split(' ')[0]) | |||
|
235 | ||||
|
236 | files = [] | |||
|
237 | mf = self.repo.manifest.read(changes[0]) | |||
|
238 | for f in changes[3]: | |||
|
239 | files.append(self.t("filenodelink", | |||
|
240 | filenode = hex(mf[f]), file = f)) | |||
|
241 | ||||
|
242 | def diff(): | |||
|
243 | yield self.diff(p1, n, changes[3]) | |||
|
244 | ||||
|
245 | yield self.t('changeset', | |||
|
246 | diff = diff, | |||
|
247 | rev = cl.rev(n), | |||
|
248 | node = nodeid, | |||
|
249 | shortdesc = cgi.escape(changes[4].splitlines()[0]), | |||
|
250 | p1 = hex(p1), p2 = hex(p2), | |||
|
251 | p1rev = cl.rev(p1), p2rev = cl.rev(p2), | |||
|
252 | manifest = hex(changes[0]), | |||
|
253 | author = obfuscate(changes[1]), | |||
|
254 | desc = nl2br(cgi.escape(changes[4])), | |||
|
255 | date = time.asctime(time.gmtime(t)), | |||
|
256 | files = files) | |||
|
257 | ||||
|
258 | def filelog(self, f, filenode): | |||
|
259 | cl = self.repo.changelog | |||
|
260 | fl = self.repo.file(f) | |||
|
261 | count = fl.count() | |||
|
262 | ||||
|
263 | def entries(): | |||
|
264 | l = [] | |||
|
265 | for i in range(count): | |||
|
266 | ||||
|
267 | n = fl.node(i) | |||
|
268 | lr = fl.linkrev(n) | |||
|
269 | cn = cl.node(lr) | |||
|
270 | cs = cl.read(cl.node(lr)) | |||
|
271 | p1, p2 = fl.parents(n) | |||
|
272 | t = float(cs[2].split(' ')[0]) | |||
288 |
|
273 | |||
289 | def __init__(self): |
|
274 | l.insert(0, self.t("filelogentry", | |
290 | pass |
|
275 | filenode = hex(n), | |
|
276 | filerev = i, | |||
|
277 | file = f, | |||
|
278 | node = hex(cn), | |||
|
279 | author = obfuscate(cs[1]), | |||
|
280 | age = age(t), | |||
|
281 | date = time.asctime(time.gmtime(t)), | |||
|
282 | shortdesc = cgi.escape(cs[4].splitlines()[0]), | |||
|
283 | p1 = hex(p1), p2 = hex(p2), | |||
|
284 | p1rev = fl.rev(p1), p2rev = fl.rev(p2))) | |||
|
285 | ||||
|
286 | yield l | |||
|
287 | ||||
|
288 | yield self.t("filelog", | |||
|
289 | file = f, | |||
|
290 | filenode = filenode, | |||
|
291 | entries = entries) | |||
|
292 | ||||
|
293 | def filerevision(self, f, node): | |||
|
294 | fl = self.repo.file(f) | |||
|
295 | n = bin(node) | |||
|
296 | text = cgi.escape(fl.read(n)) | |||
|
297 | changerev = fl.linkrev(n) | |||
|
298 | cl = self.repo.changelog | |||
|
299 | cn = cl.node(changerev) | |||
|
300 | cs = cl.read(cn) | |||
|
301 | p1, p2 = fl.parents(n) | |||
|
302 | t = float(cs[2].split(' ')[0]) | |||
|
303 | mfn = cs[0] | |||
|
304 | ||||
|
305 | yield self.t("filerevision", file = f, | |||
|
306 | filenode = node, | |||
|
307 | path = up(f), | |||
|
308 | text = text, | |||
|
309 | rev = changerev, | |||
|
310 | node = hex(cn), | |||
|
311 | manifest = hex(mfn), | |||
|
312 | author = obfuscate(cs[1]), | |||
|
313 | age = age(t), | |||
|
314 | date = time.asctime(time.gmtime(t)), | |||
|
315 | shortdesc = cgi.escape(cs[4].splitlines()[0]), | |||
|
316 | p1 = hex(p1), p2 = hex(p2), | |||
|
317 | p1rev = fl.rev(p1), p2rev = fl.rev(p2)) | |||
|
318 | ||||
|
319 | ||||
|
320 | def fileannotate(self, f, node): | |||
|
321 | bcache = {} | |||
|
322 | ncache = {} | |||
|
323 | fl = self.repo.file(f) | |||
|
324 | n = bin(node) | |||
|
325 | changerev = fl.linkrev(n) | |||
|
326 | ||||
|
327 | cl = self.repo.changelog | |||
|
328 | cn = cl.node(changerev) | |||
|
329 | cs = cl.read(cn) | |||
|
330 | p1, p2 = fl.parents(n) | |||
|
331 | t = float(cs[2].split(' ')[0]) | |||
|
332 | mfn = cs[0] | |||
|
333 | ||||
|
334 | def annotate(): | |||
|
335 | for r, l in fl.annotate(n): | |||
|
336 | try: | |||
|
337 | cnode = ncache[r] | |||
|
338 | except KeyError: | |||
|
339 | cnode = ncache[r] = self.repo.changelog.node(r) | |||
|
340 | ||||
|
341 | try: | |||
|
342 | name = bcache[r] | |||
|
343 | except KeyError: | |||
|
344 | cl = self.repo.changelog.read(cnode) | |||
|
345 | name = cl[1] | |||
|
346 | f = name.find('@') | |||
|
347 | if f >= 0: | |||
|
348 | name = name[:f] | |||
|
349 | bcache[r] = name | |||
|
350 | ||||
|
351 | yield self.t("annotateline", | |||
|
352 | node = hex(cnode), | |||
|
353 | rev = r, | |||
|
354 | author = name, | |||
|
355 | file = f, | |||
|
356 | line = cgi.escape(l)) | |||
|
357 | ||||
|
358 | yield self.t("fileannotate", | |||
|
359 | file = f, | |||
|
360 | filenode = node, | |||
|
361 | annotate = annotate, | |||
|
362 | path = up(f), | |||
|
363 | rev = changerev, | |||
|
364 | node = hex(cn), | |||
|
365 | manifest = hex(mfn), | |||
|
366 | author = obfuscate(cs[1]), | |||
|
367 | age = age(t), | |||
|
368 | date = time.asctime(time.gmtime(t)), | |||
|
369 | shortdesc = cgi.escape(cs[4].splitlines()[0]), | |||
|
370 | p1 = hex(p1), p2 = hex(p2), | |||
|
371 | p1rev = fl.rev(p1), p2rev = fl.rev(p2)) | |||
|
372 | ||||
|
373 | def manifest(self, mnode, path): | |||
|
374 | mf = self.repo.manifest.read(bin(mnode)) | |||
|
375 | rev = self.repo.manifest.rev(bin(mnode)) | |||
|
376 | node = self.repo.changelog.node(rev) | |||
|
377 | ||||
|
378 | dirs = {} | |||
|
379 | files = {} | |||
|
380 | short = {} | |||
|
381 | ||||
|
382 | p = path[1:] | |||
|
383 | l = len(p) | |||
|
384 | ||||
|
385 | for f,n in mf.items(): | |||
|
386 | if f[:l] != p: | |||
|
387 | continue | |||
|
388 | remain = f[l:] | |||
|
389 | if "/" in remain: | |||
|
390 | short = remain[:remain.find("/") + 1] # bleah | |||
|
391 | dirs[short] = 1 | |||
|
392 | else: | |||
|
393 | short = os.path.basename(remain) | |||
|
394 | files[short] = (f, n) | |||
|
395 | ||||
|
396 | def dirlist(): | |||
|
397 | dl = dirs.keys() | |||
|
398 | dl.sort() | |||
|
399 | ||||
|
400 | for d in dl: | |||
|
401 | yield self.t("manifestdirentry", | |||
|
402 | path = os.path.join(path, d), | |||
|
403 | manifest = mnode, basename = d[:-1]) | |||
|
404 | ||||
|
405 | def filelist(): | |||
|
406 | fl = files.keys() | |||
|
407 | fl.sort() | |||
|
408 | for f in fl: | |||
|
409 | full, fnode = files[f] | |||
|
410 | yield self.t("manifestfileentry", | |||
|
411 | file = full, manifest = mnode, filenode = hex(fnode), | |||
|
412 | basename = f) | |||
|
413 | ||||
|
414 | yield self.t("manifest", | |||
|
415 | manifest = mnode, | |||
|
416 | rev = rev, | |||
|
417 | node = hex(node), | |||
|
418 | path = path, | |||
|
419 | up = up(path), | |||
|
420 | dirs = dirlist, | |||
|
421 | files = filelist) | |||
|
422 | ||||
|
423 | def filediff(self, file, changeset): | |||
|
424 | n = bin(changeset) | |||
|
425 | cl = self.repo.changelog | |||
|
426 | p1 = cl.parents(n)[0] | |||
|
427 | cs = cl.read(n) | |||
|
428 | mf = self.repo.manifest.read(cs[0]) | |||
|
429 | ||||
|
430 | def diff(): | |||
|
431 | yield self.diff(p1, n, file) | |||
|
432 | ||||
|
433 | yield self.t("filediff", | |||
|
434 | file = file, | |||
|
435 | filenode = hex(mf[file]), | |||
|
436 | node = changeset, | |||
|
437 | rev = self.repo.changelog.rev(n), | |||
|
438 | p1 = hex(p1), | |||
|
439 | p1rev = self.repo.changelog.rev(p1), | |||
|
440 | diff = diff) | |||
|
441 | ||||
|
442 | # header and footer, css | |||
|
443 | # add tags to things | |||
|
444 | # show parents | |||
|
445 | # diff between rev and parent in changeset and file | |||
|
446 | # manifest links | |||
|
447 | # browse at top | |||
|
448 | # tags -> list of changesets corresponding to tags | |||
|
449 | # find tag, changeset, file | |||
291 |
|
450 | |||
292 | def run(self): |
|
451 | def run(self): | |
293 |
|
||||
294 | args = cgi.parse() |
|
452 | args = cgi.parse() | |
295 |
|
453 | |||
296 | ui = hg.ui() |
|
454 | if not args.has_key('cmd') or args['cmd'][0] == 'changelog': | |
297 | repo = hg.repository(ui, self.repo_path) |
|
455 | hi = self.repo.changelog.count() | |
|
456 | if args.has_key('pos'): | |||
|
457 | hi = int(args['pos'][0]) | |||
|
458 | ||||
|
459 | write(self.changelog(hi)) | |||
298 |
|
460 | |||
299 |
if |
|
461 | elif args['cmd'][0] == 'changeset': | |
300 | page = change_list(repo, self.tmpl_dir, 'Mercurial', |
|
462 | write(self.changeset(args['node'][0])) | |
301 | self.numchanges) |
|
|||
302 | hi = args.get('hi', ( repo.changelog.count(), )) |
|
|||
303 | page.content(hi = int(hi[0])) |
|
|||
304 | page.endpage() |
|
|||
305 |
|
463 | |||
306 |
elif args['cmd'][0] == ' |
|
464 | elif args['cmd'][0] == 'manifest': | |
307 | if not args.has_key('nd'): |
|
465 | write(self.manifest(args['manifest'][0], args['path'][0])) | |
308 | page = errpage(self.tmpl_dir) |
|
466 | ||
309 | print '<div class="errmsg">No Node!</div>' |
|
467 | elif args['cmd'][0] == 'filediff': | |
310 | else: |
|
468 | write(self.filediff(args['file'][0], args['node'][0])) | |
311 | page = checkin(repo, self.tmpl_dir, args['nd'][0]) |
|
|||
312 | page.content() |
|
|||
313 | page.endpage() |
|
|||
314 |
|
469 | |||
315 | elif args['cmd'][0] == 'file': |
|
470 | elif args['cmd'][0] == 'file': | |
316 | if not (args.has_key('nd') and args.has_key('fn')) and \ |
|
471 | write(self.filerevision(args['file'][0], args['filenode'][0])) | |
317 | not (args.has_key('cs') and args.has_key('fn')): |
|
|||
318 | page = errpage(self.tmpl_dir) |
|
|||
319 | print '<div class="errmsg">Invalid Args!</div>' |
|
|||
320 | else: |
|
|||
321 | if args.has_key('nd'): |
|
|||
322 | page = filepage(repo, self.tmpl_dir, |
|
|||
323 | args['fn'][0], node=args['nd'][0]) |
|
|||
324 | else: |
|
|||
325 | page = filepage(repo, self.tmpl_dir, |
|
|||
326 | args['fn'][0], cs=args['cs'][0]) |
|
|||
327 | page.content() |
|
|||
328 | page.endpage() |
|
|||
329 |
|
472 | |||
330 |
elif args['cmd'][0] == ' |
|
473 | elif args['cmd'][0] == 'annotate': | |
331 | if not args.has_key('nd'): |
|
474 | write(self.fileannotate(args['file'][0], args['filenode'][0])) | |
332 | page = errpage(self.tmpl_dir) |
|
|||
333 | print '<div class="errmsg">No Node!</div>' |
|
|||
334 | else: |
|
|||
335 | page = mfpage(repo, self.tmpl_dir, args['nd'][0]) |
|
|||
336 | page.content() |
|
|||
337 | page.endpage() |
|
|||
338 |
|
475 | |||
339 |
elif args['cmd'][0] == ' |
|
476 | elif args['cmd'][0] == 'filelog': | |
340 | if not args.has_key('fn'): |
|
477 | write(self.filelog(args['file'][0], args['filenode'][0])) | |
341 | page = errpage(self.tmpl_dir) |
|
|||
342 | print '<div class="errmsg">No Filename!</div>' |
|
|||
343 | else: |
|
|||
344 | page = histpage(repo, self.tmpl_dir, args['fn'][0]) |
|
|||
345 | page.content() |
|
|||
346 | page.endpage() |
|
|||
347 |
|
||||
348 | elif args['cmd'][0] == 'ann': |
|
|||
349 | if not args.has_key('fn'): |
|
|||
350 | page = errpage(self.tmpl_dir) |
|
|||
351 | print '<div class="errmsg">No Filename!</div>' |
|
|||
352 | elif not args.has_key('nd'): |
|
|||
353 | page = errpage(self.tmpl_dir) |
|
|||
354 | print '<div class="errmsg">No Node!</div>' |
|
|||
355 | else: |
|
|||
356 | page = annpage(repo, self.tmpl_dir, args['fn'][0], |
|
|||
357 | args['nd'][0]) |
|
|||
358 | page.content() |
|
|||
359 | page.endpage() |
|
|||
360 |
|
478 | |||
361 | elif args['cmd'][0] == 'branches': |
|
479 | elif args['cmd'][0] == 'branches': | |
362 | httphdr("text/plain") |
|
480 | httphdr("text/plain") | |
363 | nodes = [] |
|
481 | nodes = [] | |
364 | if args.has_key('nodes'): |
|
482 | if args.has_key('nodes'): | |
365 |
nodes = map( |
|
483 | nodes = map(bin, args['nodes'][0].split(" ")) | |
366 | for b in repo.branches(nodes): |
|
484 | for b in self.repo.branches(nodes): | |
367 |
|
|
485 | sys.stdout.write(" ".join(map(hex, b)) + "\n") | |
368 |
|
486 | |||
369 | elif args['cmd'][0] == 'between': |
|
487 | elif args['cmd'][0] == 'between': | |
370 | httphdr("text/plain") |
|
488 | httphdr("text/plain") | |
371 | nodes = [] |
|
489 | nodes = [] | |
372 | if args.has_key('pairs'): |
|
490 | if args.has_key('pairs'): | |
373 |
pairs = [ map( |
|
491 | pairs = [ map(bin, p.split("-")) | |
374 | for p in args['pairs'][0].split(" ") ] |
|
492 | for p in args['pairs'][0].split(" ") ] | |
375 | for b in repo.between(pairs): |
|
493 | for b in self.repo.between(pairs): | |
376 |
|
|
494 | sys.stdout.write(" ".join(map(hex, b)) + "\n") | |
377 |
|
495 | |||
378 | elif args['cmd'][0] == 'changegroup': |
|
496 | elif args['cmd'][0] == 'changegroup': | |
379 | httphdr("application/hg-changegroup") |
|
497 | httphdr("application/hg-changegroup") | |
380 | nodes = [] |
|
498 | nodes = [] | |
381 | if args.has_key('roots'): |
|
499 | if args.has_key('roots'): | |
382 |
nodes = map( |
|
500 | nodes = map(bin, args['roots'][0].split(" ")) | |
383 |
|
501 | |||
384 | z = zlib.compressobj() |
|
502 | z = zlib.compressobj() | |
385 | for chunk in repo.changegroup(nodes): |
|
503 | for chunk in self.repo.changegroup(nodes): | |
386 | sys.stdout.write(z.compress(chunk)) |
|
504 | sys.stdout.write(z.compress(chunk)) | |
387 |
|
505 | |||
388 | sys.stdout.write(z.flush()) |
|
506 | sys.stdout.write(z.flush()) | |
389 |
|
507 | |||
390 | else: |
|
508 | else: | |
391 |
|
|
509 | write(self.t("error")) | |
392 | print '<div class="errmsg">unknown command: %s</div>' % \ |
|
|||
393 | cgi.escape(args['cmd'][0]) |
|
|||
394 | page.endpage() |
|
|||
395 |
|
510 | |||
396 | if __name__ == "__main__": |
|
511 | if __name__ == "__main__": | |
397 | hgweb().run() |
|
512 | hgweb().run() |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now