Mercurial > public > mercurial-scm > hg
comparison hgweb.py @ 61:1215bf60468f
Add server side of hg:// protocol to hgweb
author | mpm@selenic.com |
---|---|
date | Thu, 12 May 2005 01:22:37 -0800 |
parents | 115106376f45 |
children | db5eb6a86179 58039eddbdda |
comparison
equal
deleted
inserted
replaced
60:e32fdbd97839 | 61:1215bf60468f |
---|---|
8 | 8 |
9 # useful for debugging | 9 # useful for debugging |
10 import cgitb | 10 import cgitb |
11 cgitb.enable() | 11 cgitb.enable() |
12 | 12 |
13 import os, cgi, time, re, difflib | 13 import os, cgi, time, re, difflib, sys, zlib |
14 from mercurial import hg, mdiff | 14 from mercurial import hg, mdiff |
15 | 15 |
16 repo_path = "." # change as needed | 16 repo_path = "." # change as needed |
17 | 17 |
18 def nl2br(text): | 18 def nl2br(text): |
22 l = [] | 22 l = [] |
23 for c in text: | 23 for c in text: |
24 l.append('&#%d;' % ord(c)) | 24 l.append('&#%d;' % ord(c)) |
25 return ''.join(l) | 25 return ''.join(l) |
26 | 26 |
27 def httphdr(): | 27 def httphdr(type = "text/html"): |
28 print 'Content-type: text/html\n\n' | 28 print 'Content-type: %s\n' % type |
29 | 29 |
30 def htmldoctype(): | 30 def htmldoctype(): |
31 print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">' | 31 print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">' |
32 | 32 |
33 def htmlhead(title): | 33 def htmlhead(title): |
42 print '.plusline { color: green; }' | 42 print '.plusline { color: green; }' |
43 print '.minusline { color: red; }' | 43 print '.minusline { color: red; }' |
44 print '.atline { color: purple; }' | 44 print '.atline { color: purple; }' |
45 print '</style>' | 45 print '</style>' |
46 | 46 |
47 def startpage(title): | |
48 httphdr() | |
49 htmldoctype() | |
50 htmlhead(title) | |
51 print '<BODY>' | |
52 | |
53 def endpage(): | |
54 print '</BODY>' | |
55 print '</HTML>' | |
56 | |
57 | |
58 | |
47 def ent_change(repo, nodeid): | 59 def ent_change(repo, nodeid): |
48 changes = repo.changelog.read(nodeid) | 60 changes = repo.changelog.read(nodeid) |
49 hn = hg.hex(nodeid) | 61 hn = hg.hex(nodeid) |
50 i = repo.changelog.rev(nodeid) | 62 i = repo.changelog.rev(nodeid) |
51 (h1, h2) = [ hg.hex(x) for x in repo.changelog.parents(nodeid) ] | 63 (h1, h2) = [ hg.hex(x) for x in repo.changelog.parents(nodeid) ] |
52 datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0]))) | 64 datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0]))) |
53 mf = repo.manifest.read(changes[0]) | |
54 print '<table width="100%" border="1">' | 65 print '<table width="100%" border="1">' |
55 print '\t<tr><td valign="top" width="10%%">author:</td>' + \ | 66 print '\t<tr><td valign="top" width="10%%">author:</td>' + \ |
56 '<td valign="top" width="20%%">%s</td>' % (obfuscate(changes[1]), ) | 67 '<td valign="top" width="20%%">%s</td>' % (obfuscate(changes[1]), ) |
57 print '\t\t<td valign="top" width="10%%">description:</td>' + \ | 68 print '\t\t<td valign="top" width="10%%">description:</td>' + \ |
58 '<td width="60%%">' + \ | 69 '<td width="60%%">' + \ |
59 '<a href="?cmd=chkin;nd=%s">%s</a></td></tr>' % \ | 70 '<a href="?cmd=chkin;nd=%s">%s</a></td></tr>' % \ |
60 (hn, nl2br(changes[4]), ) | 71 (hn, nl2br(changes[4]), ) |
61 print '\t<tr><td>date:</td><td>%s UTC</td>' % (datestr, ) | 72 print '\t<tr><td>date:</td><td>%s UTC</td>' % (datestr, ) |
62 print '\t\t<td valign="top">files:</td><td valign="top">' | 73 print '\t\t<td valign="top">files:</td><td valign="top">' |
63 for f in changes[3]: | 74 for f in changes[3]: |
64 print '\t\t<a href="?cmd=file;nd=%s;fn=%s">%s</a>' % \ | 75 print '\t\t%s ' % f |
65 (hg.hex(mf[f]), f, f, ), | |
66 print ' ' | |
67 print '\t</td></tr>' | 76 print '\t</td></tr>' |
68 # print '\t<tr><td>revision:</td><td colspan="3">%d:<a ' % (i, ) + \ | 77 # print '\t<tr><td>revision:</td><td colspan="3">%d:<a ' % (i, ) + \ |
69 # 'href="?cmd=rev;nd=%s">%s</a></td></tr>' % (hn, hn, ) | 78 # 'href="?cmd=rev;nd=%s">%s</a></td></tr>' % (hn, hn, ) |
70 print '</table><br />' | 79 print '</table><br />' |
71 | 80 |
85 else: | 94 else: |
86 print line | 95 print line |
87 print '</pre>' | 96 print '</pre>' |
88 | 97 |
89 def ent_checkin(repo, nodeid): | 98 def ent_checkin(repo, nodeid): |
99 startpage("Mercurial Web") | |
100 | |
90 changes = repo.changelog.read(nodeid) | 101 changes = repo.changelog.read(nodeid) |
91 hn = hg.hex(nodeid) | 102 hn = hg.hex(nodeid) |
92 i = repo.changelog.rev(nodeid) | 103 i = repo.changelog.rev(nodeid) |
93 parents = repo.changelog.parents(nodeid) | 104 parents = repo.changelog.parents(nodeid) |
94 (h1, h2) = [ hg.hex(x) for x in parents ] | 105 (h1, h2) = [ hg.hex(x) for x in parents ] |
133 for f in a: | 144 for f in a: |
134 ent_diff('', repo.file(f).read(mf[f]), f) | 145 ent_diff('', repo.file(f).read(mf[f]), f) |
135 for f in d: | 146 for f in d: |
136 ent_diff(repo.file(f).read(mf2[f]), '', f) | 147 ent_diff(repo.file(f).read(mf2[f]), '', f) |
137 | 148 |
149 endpage() | |
150 | |
151 | |
138 def ent_file(repo, nodeid, fn): | 152 def ent_file(repo, nodeid, fn): |
139 print '<div class="filename">%s (%s)</div>' % (fn, hg.hex(nodeid), ) | 153 print '<div class="filename">%s (%s)</div>' % (fn, hg.hex(nodeid), ) |
140 print '<pre>' | 154 print '<pre>' |
141 print cgi.escape(repo.file(fn).read(nodeid)) | 155 print cgi.escape(repo.file(fn).read(nodeid)) |
142 print '</pre>' | 156 print '</pre>' |
143 | 157 |
144 httphdr() | 158 def change_page(): |
145 htmldoctype() | 159 startpage("Mercurial Web") |
146 htmlhead('Mercurial Web') | |
147 | |
148 print '<BODY>' | |
149 | |
150 | |
151 args = cgi.parse() | |
152 | |
153 ui = hg.ui() | |
154 repo = hg.repository(ui, repo_path) | |
155 | |
156 if not args.has_key('cmd'): | |
157 print '<table width="100%" align="center">' | 160 print '<table width="100%" align="center">' |
158 for i in xrange(repo.changelog.count()-1, -1, -1): | 161 for i in xrange(0, repo.changelog.count()): |
159 n = repo.changelog.node(i) | 162 n = repo.changelog.node(i) |
160 print '<tr><td>' | 163 print '<tr><td>' |
161 ent_change(repo, n) | 164 ent_change(repo, n) |
162 print '</td></th>' | 165 print '</td></th>' |
163 | 166 |
164 print '</table>' | 167 print '</table>' |
168 endpage() | |
169 | |
170 args = cgi.parse() | |
171 | |
172 ui = hg.ui() | |
173 repo = hg.repository(ui, repo_path) | |
174 | |
175 if not args.has_key('cmd'): | |
176 change_page() | |
177 | |
165 elif args['cmd'][0] == 'chkin': | 178 elif args['cmd'][0] == 'chkin': |
166 if not args.has_key('nd'): | 179 if not args.has_key('nd'): |
167 print '<div class="errmsg">No Node!</div>' | 180 print '<div class="errmsg">No Node!</div>' |
168 else: | 181 else: |
169 ent_checkin(repo, hg.bin(args['nd'][0])) | 182 ent_checkin(repo, hg.bin(args['nd'][0])) |
183 | |
170 elif args['cmd'][0] == 'file': | 184 elif args['cmd'][0] == 'file': |
185 startpage("Mercurial Web") | |
186 | |
171 if not args.has_key('nd'): | 187 if not args.has_key('nd'): |
172 print '<div class="errmsg">No Node!</div>' | 188 print '<div class="errmsg">No Node!</div>' |
173 elif not args.has_key('fn'): | 189 elif not args.has_key('fn'): |
174 print '<div class="errmsg">No Filename!</div>' | 190 print '<div class="errmsg">No Filename!</div>' |
175 else: | 191 else: |
176 ent_file(repo, hg.bin(args['nd'][0]), args['fn'][0]) | 192 ent_file(repo, hg.bin(args['nd'][0]), args['fn'][0]) |
193 endpage() | |
194 | |
195 elif args['cmd'][0] == 'branches': | |
196 httphdr("text/plain") | |
197 nodes = [] | |
198 if args.has_key('nodes'): | |
199 nodes = map(hg.bin, args['nodes'][0].split(" ")) | |
200 for b in repo.branches(nodes): | |
201 print " ".join(map(hg.hex, b)) | |
202 | |
203 elif args['cmd'][0] == 'between': | |
204 httphdr("text/plain") | |
205 nodes = [] | |
206 if args.has_key('pairs'): | |
207 pairs = [ map(hg.bin, p.split("-")) | |
208 for p in args['pairs'][0].split(" ") ] | |
209 for b in repo.between(pairs): | |
210 print " ".join(map(hg.hex, b)) | |
211 | |
212 elif args['cmd'][0] == 'changegroup': | |
213 httphdr("application/hg-changegroup") | |
214 nodes = [] | |
215 if args.has_key('roots'): | |
216 nodes = map(hg.bin, args['roots'][0].split(" ")) | |
217 | |
218 z = zlib.compressobj() | |
219 for chunk in repo.changegroup(nodes): | |
220 sys.stdout.write(z.compress(chunk)) | |
221 | |
222 sys.stdout.write(z.flush()) | |
177 | 223 |
178 else: | 224 else: |
225 startpage("Mercurial Web Error") | |
179 print '<div class="errmsg">unknown command: ', args['cmd'][0], '</div>' | 226 print '<div class="errmsg">unknown command: ', args['cmd'][0], '</div>' |
180 | 227 endpage() |
181 print '</BODY>' | |
182 print '</HTML>' |