##// END OF EJS Templates
added annotate...
jake@edge2.net -
r136:0e8d60d2 default
parent child Browse files
Show More
@@ -0,0 +1,1 b''
1 <a class="revnumlink" href="?cmd=chkin;nd=#cnode#">#cnum#</a>:<a class="annlinelink" href="?cmd=file;fn=#fn#;cs=#cnode#">#line#</a>
@@ -1,364 +1,397 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # hgweb.py - 0.2 - 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # hgweb.py - 0.2 - 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # - web interface to a mercurial repository
4 # - web interface to a mercurial repository
5 #
5 #
6 # This software may be used and distributed according to the terms
6 # This software may be used and distributed according to the terms
7 # of the GNU General Public License, incorporated herein by reference.
7 # of the GNU General Public License, incorporated herein by reference.
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, sys, zlib
13 import os, cgi, time, re, difflib, sys, zlib
14 from mercurial import hg, mdiff
14 from mercurial import hg, mdiff
15
15
16 def nl2br(text):
16 def nl2br(text):
17 return re.sub('\n', '<br />', text)
17 return re.sub('\n', '<br />', text)
18
18
19 def obfuscate(text):
19 def obfuscate(text):
20 l = []
20 l = []
21 for c in text:
21 for c in text:
22 l.append('&#%d;' % ord(c))
22 l.append('&#%d;' % ord(c))
23 return ''.join(l)
23 return ''.join(l)
24
24
25 def httphdr(type):
25 def httphdr(type):
26 print 'Content-type: %s\n' % type
26 print 'Content-type: %s\n' % type
27
27
28 def write(*things):
28 def write(*things):
29 for thing in things:
29 for thing in things:
30 if hasattr(thing, "__iter__"):
30 if hasattr(thing, "__iter__"):
31 for part in thing:
31 for part in thing:
32 write(part)
32 write(part)
33 else:
33 else:
34 sys.stdout.write(str(thing))
34 sys.stdout.write(str(thing))
35
35
36 class template:
36 class template:
37 def __init__(self, tmpl_dir):
37 def __init__(self, tmpl_dir):
38 self.tmpl_dir = tmpl_dir
38 self.tmpl_dir = tmpl_dir
39 def do_page(self, tmpl_fn, **map):
39 def do_page(self, tmpl_fn, **map):
40 txt = file(os.path.join(self.tmpl_dir, tmpl_fn)).read()
40 txt = file(os.path.join(self.tmpl_dir, tmpl_fn)).read()
41 while txt:
41 while txt:
42 m = re.search(r"#([a-zA-Z0-9]+)#", txt)
42 m = re.search(r"#([a-zA-Z0-9]+)#", txt)
43 if m:
43 if m:
44 yield txt[:m.start(0)]
44 yield txt[:m.start(0)]
45 v = map.get(m.group(1), "")
45 v = map.get(m.group(1), "")
46 if callable(v):
46 if callable(v):
47 for y in v(**map): yield y
47 for y in v(**map): yield y
48 else:
48 else:
49 yield v
49 yield v
50 txt = txt[m.end(0):]
50 txt = txt[m.end(0):]
51 else:
51 else:
52 yield txt
52 yield txt
53 txt = ''
53 txt = ''
54
54
55 class page:
55 class page:
56 def __init__(self, tmpl_dir = "", type="text/html", title="Mercurial Web",
56 def __init__(self, tmpl_dir = "", type="text/html", title="Mercurial Web",
57 charset="ISO-8859-1"):
57 charset="ISO-8859-1"):
58 self.tmpl = template(tmpl_dir)
58 self.tmpl = template(tmpl_dir)
59
59
60 print 'Content-type: %s; charset=%s\n' % (type, charset)
60 print 'Content-type: %s; charset=%s\n' % (type, charset)
61 write(self.tmpl.do_page('htmlstart.tmpl', title = title))
61 write(self.tmpl.do_page('htmlstart.tmpl', title = title))
62
62
63 def endpage(self):
63 def endpage(self):
64 print '</BODY>'
64 print '</BODY>'
65 print '</HTML>'
65 print '</HTML>'
66
66
67 def show_diff(self, a, b, fn):
67 def show_diff(self, a, b, fn):
68 a = a.splitlines(1)
68 a = a.splitlines(1)
69 b = b.splitlines(1)
69 b = b.splitlines(1)
70 l = difflib.unified_diff(a, b, fn, fn)
70 l = difflib.unified_diff(a, b, fn, fn)
71 print '<pre>'
71 print '<pre>'
72 for line in l:
72 for line in l:
73 line = cgi.escape(line[:-1])
73 line = cgi.escape(line[:-1])
74 if line.startswith('+'):
74 if line.startswith('+'):
75 print '<span class="plusline">%s</span>' % (line, )
75 print '<span class="plusline">%s</span>' % (line, )
76 elif line.startswith('-'):
76 elif line.startswith('-'):
77 print '<span class="minusline">%s</span>' % (line, )
77 print '<span class="minusline">%s</span>' % (line, )
78 elif line.startswith('@'):
78 elif line.startswith('@'):
79 print '<span class="atline">%s</span>' % (line, )
79 print '<span class="atline">%s</span>' % (line, )
80 else:
80 else:
81 print line
81 print line
82 print '</pre>'
82 print '</pre>'
83
83
84 class errpage(page):
84 class errpage(page):
85 def __init__(self):
85 def __init__(self, tmpl_dir):
86 page.__init__(self, title="Mercurial Web Error Page")
86 page.__init__(self, tmpl_dir, title="Mercurial Web Error Page")
87
87
88 class change_list(page):
88 class change_list(page):
89 def __init__(self, repo, tmpl_dir, reponame, numchanges = 50):
89 def __init__(self, repo, tmpl_dir, reponame, numchanges = 50):
90 page.__init__(self, tmpl_dir)
90 page.__init__(self, tmpl_dir)
91 self.repo = repo
91 self.repo = repo
92 self.numchanges = numchanges
92 self.numchanges = numchanges
93 write(self.tmpl.do_page('changestitle.tmpl', reponame=reponame))
93 write(self.tmpl.do_page('changestitle.tmpl', reponame=reponame))
94
94
95 def content(self, hi=None):
95 def content(self, hi=None):
96 cl = []
96 cl = []
97 count = self.repo.changelog.count()
97 count = self.repo.changelog.count()
98 if not hi:
98 if not hi:
99 hi = count
99 hi = count
100 elif hi < self.numchanges:
100 elif hi < self.numchanges:
101 hi = self.numchanges
101 hi = self.numchanges
102
102
103 start = 0
103 start = 0
104 if hi - self.numchanges >= 0:
104 if hi - self.numchanges >= 0:
105 start = hi - self.numchanges
105 start = hi - self.numchanges
106
106
107 nav = "Displaying Revisions: %d-%d" % (start, hi-1)
107 nav = "Displaying Revisions: %d-%d" % (start, hi-1)
108 if start != 0:
108 if start != 0:
109 nav = ('<a href="?cmd=changes;hi=%d">Previous %d</a>&nbsp;&nbsp;' \
109 nav = ('<a href="?cmd=changes;hi=%d">Previous %d</a>&nbsp;&nbsp;' \
110 % (start, self.numchanges)) + nav
110 % (start, self.numchanges)) + nav
111 if hi != count:
111 if hi != count:
112 if hi + self.numchanges <= count:
112 if hi + self.numchanges <= count:
113 nav += '&nbsp;&nbsp;<a href="?cmd=changes;hi=%d">Next %d</a>' \
113 nav += '&nbsp;&nbsp;<a href="?cmd=changes;hi=%d">Next %d</a>' \
114 % (hi + self.numchanges, self.numchanges)
114 % (hi + self.numchanges, self.numchanges)
115 else:
115 else:
116 nav += '&nbsp;&nbsp;<a href="?cmd=changes">Next %d</a>' % \
116 nav += '&nbsp;&nbsp;<a href="?cmd=changes">Next %d</a>' % \
117 self.numchanges
117 self.numchanges
118
118
119 print '<center>%s</center>' % nav
119 print '<center>%s</center>' % nav
120
120
121 for i in xrange(start, hi):
121 for i in xrange(start, hi):
122 n = self.repo.changelog.node(i)
122 n = self.repo.changelog.node(i)
123 cl.append((n, self.repo.changelog.read(n)))
123 cl.append((n, self.repo.changelog.read(n)))
124 cl.reverse()
124 cl.reverse()
125
125
126 print '<table summary="" width="100%" align="center">'
126 print '<table summary="" width="100%" align="center">'
127 for n, ch in cl:
127 for n, ch in cl:
128 print '<tr><td>'
128 print '<tr><td>'
129 self.change_table(n, ch)
129 self.change_table(n, ch)
130 print '</td></tr>'
130 print '</td></tr>'
131 print '</table>'
131 print '</table>'
132
132
133 print '<center>%s</center>' % nav
133 print '<center>%s</center>' % nav
134
134
135 def change_table(self, nodeid, changes):
135 def change_table(self, nodeid, changes):
136 hn = hg.hex(nodeid)
136 hn = hg.hex(nodeid)
137 i = self.repo.changelog.rev(nodeid)
137 i = self.repo.changelog.rev(nodeid)
138 (h1, h2) = [ hg.hex(x) for x in self.repo.changelog.parents(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])))
139 datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0])))
140 files = []
140 files = []
141 for f in changes[3]:
141 for f in changes[3]:
142 files.append('<a href="?cmd=file;cs=%s;fn=%s">%s</a>&nbsp;&nbsp;' \
142 files.append('<a href="?cmd=file;cs=%s;fn=%s">%s</a>&nbsp;&nbsp;' \
143 % (hn, f, cgi.escape(f)))
143 % (hn, f, cgi.escape(f)))
144 write(self.tmpl.do_page('change_table.tmpl',
144 write(self.tmpl.do_page('change_table.tmpl',
145 author=obfuscate(changes[1]),
145 author=obfuscate(changes[1]),
146 desc=nl2br(cgi.escape(changes[4])), date=datestr,
146 desc=nl2br(cgi.escape(changes[4])), date=datestr,
147 files=' '.join(files), revnum=i, revnode=hn))
147 files=' '.join(files), revnum=i, revnode=hn))
148
148
149 class checkin(page):
149 class checkin(page):
150 def __init__(self, repo, tmpl_dir, nodestr):
150 def __init__(self, repo, tmpl_dir, nodestr):
151 page.__init__(self, tmpl_dir)
151 page.__init__(self, tmpl_dir)
152 self.repo = repo
152 self.repo = repo
153 self.node = hg.bin(nodestr)
153 self.node = hg.bin(nodestr)
154 self.nodestr = nodestr
154 self.nodestr = nodestr
155 print '<h3>Checkin: %s</h3>' % nodestr
155 print '<h3>Checkin: %s</h3>' % nodestr
156
156
157 def content(self):
157 def content(self):
158 changes = self.repo.changelog.read(self.node)
158 changes = self.repo.changelog.read(self.node)
159 i = self.repo.changelog.rev(self.node)
159 i = self.repo.changelog.rev(self.node)
160 parents = self.repo.changelog.parents(self.node)
160 parents = self.repo.changelog.parents(self.node)
161 (h1, h2) = [ hg.hex(x) for x in parents ]
161 (h1, h2) = [ hg.hex(x) for x in parents ]
162 (i1, i2) = [ self.repo.changelog.rev(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])))
163 datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0])))
164 mf = self.repo.manifest.read(changes[0])
164 mf = self.repo.manifest.read(changes[0])
165 files = []
165 files = []
166 for f in changes[3]:
166 for f in changes[3]:
167 files.append('<a href="?cmd=file;nd=%s;fn=%s">%s</a>&nbsp;&nbsp;' \
167 files.append('<a href="?cmd=file;nd=%s;fn=%s">%s</a>&nbsp;&nbsp;' \
168 % (hg.hex(mf[f]), f, cgi.escape(f)))
168 % (hg.hex(mf[f]), f, cgi.escape(f)))
169 p2link = h2
169 p2link = h2
170 if i2 != -1:
170 if i2 != -1:
171 p2link = '<a href="?cmd=chkin;nd=%s">%s</a>' % (h2, h2)
171 p2link = '<a href="?cmd=chkin;nd=%s">%s</a>' % (h2, h2)
172
172
173 write(self.tmpl.do_page('checkin.tmpl', revnum=i, revnode=self.nodestr,
173 write(self.tmpl.do_page('checkin.tmpl', revnum=i, revnode=self.nodestr,
174 p1num=i1, p1node=h1, p2num=i2, p2node=h2, p2link=p2link,
174 p1num=i1, p1node=h1, p2num=i2, p2node=h2, p2link=p2link,
175 mfnum=self.repo.manifest.rev(changes[0]),
175 mfnum=self.repo.manifest.rev(changes[0]),
176 mfnode=hg.hex(changes[0]), author=obfuscate(changes[1]),
176 mfnode=hg.hex(changes[0]), author=obfuscate(changes[1]),
177 desc=nl2br(cgi.escape(changes[4])), date=datestr,
177 desc=nl2br(cgi.escape(changes[4])), date=datestr,
178 files=' '.join(files)))
178 files=' '.join(files)))
179
179
180 (c, a, d) = self.repo.diffrevs(parents[0], self.node)
180 (c, a, d) = self.repo.diffrevs(parents[0], self.node)
181 change = self.repo.changelog.read(parents[0])
181 change = self.repo.changelog.read(parents[0])
182 mf2 = self.repo.manifest.read(change[0])
182 mf2 = self.repo.manifest.read(change[0])
183 for f in c:
183 for f in c:
184 self.show_diff(self.repo.file(f).read(mf2[f]), \
184 self.show_diff(self.repo.file(f).read(mf2[f]), \
185 self.repo.file(f).read(mf[f]), f)
185 self.repo.file(f).read(mf[f]), f)
186 for f in a:
186 for f in a:
187 self.show_diff('', self.repo.file(f).read(mf[f]), f)
187 self.show_diff('', self.repo.file(f).read(mf[f]), f)
188 for f in d:
188 for f in d:
189 self.show_diff(self.repo.file(f).read(mf2[f]), '', f)
189 self.show_diff(self.repo.file(f).read(mf2[f]), '', f)
190
190
191 class filepage(page):
191 class filepage(page):
192 def __init__(self, repo, tmpl_dir, fn, node=None, cs=None):
192 def __init__(self, repo, tmpl_dir, fn, node=None, cs=None):
193 page.__init__(self, tmpl_dir)
193 page.__init__(self, tmpl_dir)
194 self.repo = repo
194 self.repo = repo
195 self.fn = fn
195 self.fn = fn
196 if cs:
196 if cs:
197 chng = self.repo.changelog.read(hg.bin(cs))
197 chng = self.repo.changelog.read(hg.bin(cs))
198 mf = self.repo.manifest.read(chng[0])
198 mf = self.repo.manifest.read(chng[0])
199 self.node = mf[self.fn]
199 self.node = mf[self.fn]
200 self.nodestr = hg.hex(self.node)
200 self.nodestr = hg.hex(self.node)
201 else:
201 else:
202 self.nodestr = node
202 self.nodestr = node
203 self.node = hg.bin(node)
203 self.node = hg.bin(node)
204 print '<div class="filename">%s (%s)</div>' % \
204 print '<div class="filename">%s (%s)</div>' % \
205 (cgi.escape(self.fn), self.nodestr, )
205 (cgi.escape(self.fn), self.nodestr, )
206 print '<a href="?cmd=hist;fn=%s">history</a><br />' % self.fn
206 print '<a href="?cmd=hist;fn=%s">history</a><br />' % self.fn
207 print '<a href="?cmd=ann;fn=%s;nd=%s">annotate</a><br />' % \
208 (self.fn, self.nodestr)
207
209
208 def content(self):
210 def content(self):
209 print '<pre>'
211 print '<pre>'
210 print cgi.escape(self.repo.file(self.fn).read(self.node))
212 print cgi.escape(self.repo.file(self.fn).read(self.node))
211 print '</pre>'
213 print '</pre>'
212
214
215 class annpage(page):
216 def __init__(self, repo, tmpl_dir, fn, node):
217 page.__init__(self, tmpl_dir)
218 self.repo = repo
219 self.fn = fn
220 self.nodestr = node
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
213 class mfpage(page):
233 class mfpage(page):
214 def __init__(self, repo, tmpl_dir, node):
234 def __init__(self, repo, tmpl_dir, node):
215 page.__init__(self, tmpl_dir)
235 page.__init__(self, tmpl_dir)
216 self.repo = repo
236 self.repo = repo
217 self.nodestr = node
237 self.nodestr = node
218 self.node = hg.bin(node)
238 self.node = hg.bin(node)
219
239
220 def content(self):
240 def content(self):
221 mf = self.repo.manifest.read(self.node)
241 mf = self.repo.manifest.read(self.node)
222 fns = mf.keys()
242 fns = mf.keys()
223 fns.sort()
243 fns.sort()
224 write(self.tmpl.do_page('mftitle.tmpl', node = self.nodestr))
244 write(self.tmpl.do_page('mftitle.tmpl', node = self.nodestr))
225 for f in fns:
245 for f in fns:
226 write(self.tmpl.do_page('mfentry.tmpl', fn=f, node=hg.hex(mf[f])))
246 write(self.tmpl.do_page('mfentry.tmpl', fn=f, node=hg.hex(mf[f])))
227
247
228 class histpage(page):
248 class histpage(page):
229 def __init__(self, repo, tmpl_dir, fn):
249 def __init__(self, repo, tmpl_dir, fn):
230 page.__init__(self, tmpl_dir)
250 page.__init__(self, tmpl_dir)
231 self.repo = repo
251 self.repo = repo
232 self.fn = fn
252 self.fn = fn
233
253
234 def content(self):
254 def content(self):
235 print '<div class="filehist">File History: %s</div>' % self.fn
255 print '<div class="filehist">File History: %s</div>' % self.fn
236 r = self.repo.file(self.fn)
256 r = self.repo.file(self.fn)
237 print '<br />'
257 print '<br />'
238 print '<table summary="" width="100%" align="center">'
258 print '<table summary="" width="100%" align="center">'
239 for i in xrange(r.count()-1, -1, -1):
259 for i in xrange(r.count()-1, -1, -1):
240 print '<tr><td>'
260 print '<tr><td>'
241 self.hist_ent(i, r)
261 self.hist_ent(i, r)
242 print '</tr></td>'
262 print '</tr></td>'
243 print '</table>'
263 print '</table>'
244
264
245 def hist_ent(self, i, r):
265 def hist_ent(self, i, r):
246 n = r.node(i)
266 n = r.node(i)
247 (p1, p2) = r.parents(n)
267 (p1, p2) = r.parents(n)
248 (h, h1, h2) = map(hg.hex, (n, p1, p2))
268 (h, h1, h2) = map(hg.hex, (n, p1, p2))
249 (i1, i2) = map(r.rev, (p1, p2))
269 (i1, i2) = map(r.rev, (p1, p2))
250 ci = r.linkrev(n)
270 ci = r.linkrev(n)
251 cn = self.repo.changelog.node(ci)
271 cn = self.repo.changelog.node(ci)
252 cs = hg.hex(cn)
272 cs = hg.hex(cn)
253 changes = self.repo.changelog.read(cn)
273 changes = self.repo.changelog.read(cn)
254 datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0])))
274 datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0])))
255 p2entry = ''
275 p2entry = ''
256 if i2 != -1:
276 if i2 != -1:
257 p2entry = '&nbsp;&nbsp;%d:<a href="?cmd=file;nd=%s;fn=%s">%s</a>' \
277 p2entry = '&nbsp;&nbsp;%d:<a href="?cmd=file;nd=%s;fn=%s">%s</a>' \
258 % (i2, h2, self.fn, h2 ),
278 % (i2, h2, self.fn, h2 ),
259 write(self.tmpl.do_page('hist_ent.tmpl', author=obfuscate(changes[1]),
279 write(self.tmpl.do_page('hist_ent.tmpl', author=obfuscate(changes[1]),
260 csnode=cs, desc=nl2br(cgi.escape(changes[4])),
280 csnode=cs, desc=nl2br(cgi.escape(changes[4])),
261 date = datestr, fn=self.fn, revnode=h, p1num = i1,
281 date = datestr, fn=self.fn, revnode=h, p1num = i1,
262 p1node=h1, p2entry=p2entry))
282 p1node=h1, p2entry=p2entry))
263
283
264 class hgweb:
284 class hgweb:
265 repo_path = "."
285 repo_path = "."
266 numchanges = 50
286 numchanges = 50
267 tmpl_dir = "templates"
287 tmpl_dir = "templates"
268
288
269 def __init__(self):
289 def __init__(self):
270 pass
290 pass
271
291
272 def run(self):
292 def run(self):
273
293
274 args = cgi.parse()
294 args = cgi.parse()
275
295
276 ui = hg.ui()
296 ui = hg.ui()
277 repo = hg.repository(ui, self.repo_path)
297 repo = hg.repository(ui, self.repo_path)
278
298
279 if not args.has_key('cmd') or args['cmd'][0] == 'changes':
299 if not args.has_key('cmd') or args['cmd'][0] == 'changes':
280 page = change_list(repo, self.tmpl_dir, 'Mercurial',
300 page = change_list(repo, self.tmpl_dir, 'Mercurial',
281 self.numchanges)
301 self.numchanges)
282 hi = args.get('hi', ( repo.changelog.count(), ))
302 hi = args.get('hi', ( repo.changelog.count(), ))
283 page.content(hi = int(hi[0]))
303 page.content(hi = int(hi[0]))
284 page.endpage()
304 page.endpage()
285
305
286 elif args['cmd'][0] == 'chkin':
306 elif args['cmd'][0] == 'chkin':
287 if not args.has_key('nd'):
307 if not args.has_key('nd'):
288 page = errpage()
308 page = errpage(self.tmpl_dir)
289 print '<div class="errmsg">No Node!</div>'
309 print '<div class="errmsg">No Node!</div>'
290 else:
310 else:
291 page = checkin(repo, self.tmpl_dir, args['nd'][0])
311 page = checkin(repo, self.tmpl_dir, args['nd'][0])
292 page.content()
312 page.content()
293 page.endpage()
313 page.endpage()
294
314
295 elif args['cmd'][0] == 'file':
315 elif args['cmd'][0] == 'file':
296 if not (args.has_key('nd') and args.has_key('fn')) and \
316 if not (args.has_key('nd') and args.has_key('fn')) and \
297 not (args.has_key('cs') and args.has_key('fn')):
317 not (args.has_key('cs') and args.has_key('fn')):
298 page = errpage()
318 page = errpage(self.tmpl_dir)
299 print '<div class="errmsg">Invalid Args!</div>'
319 print '<div class="errmsg">Invalid Args!</div>'
300 else:
320 else:
301 if args.has_key('nd'):
321 if args.has_key('nd'):
302 page = filepage(repo, self.tmpl_dir,
322 page = filepage(repo, self.tmpl_dir,
303 args['fn'][0], node=args['nd'][0])
323 args['fn'][0], node=args['nd'][0])
304 else:
324 else:
305 page = filepage(repo, self.tmpl_dir,
325 page = filepage(repo, self.tmpl_dir,
306 args['fn'][0], cs=args['cs'][0])
326 args['fn'][0], cs=args['cs'][0])
307 page.content()
327 page.content()
308 page.endpage()
328 page.endpage()
309
329
310 elif args['cmd'][0] == 'mf':
330 elif args['cmd'][0] == 'mf':
311 if not args.has_key('nd'):
331 if not args.has_key('nd'):
312 page = errpage()
332 page = errpage(self.tmpl_dir)
313 print '<div class="errmsg">No Node!</div>'
333 print '<div class="errmsg">No Node!</div>'
314 else:
334 else:
315 page = mfpage(repo, self.tmpl_dir, args['nd'][0])
335 page = mfpage(repo, self.tmpl_dir, args['nd'][0])
316 page.content()
336 page.content()
317 page.endpage()
337 page.endpage()
318
338
319 elif args['cmd'][0] == 'hist':
339 elif args['cmd'][0] == 'hist':
320 if not args.has_key('fn'):
340 if not args.has_key('fn'):
321 page = errpage()
341 page = errpage(self.tmpl_dir)
322 print '<div class="errmsg">No Filename!</div>'
342 print '<div class="errmsg">No Filename!</div>'
323 else:
343 else:
324 page = histpage(repo, self.tmpl_dir, args['fn'][0])
344 page = histpage(repo, self.tmpl_dir, args['fn'][0])
325 page.content()
345 page.content()
326 page.endpage()
346 page.endpage()
327
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
328 elif args['cmd'][0] == 'branches':
361 elif args['cmd'][0] == 'branches':
329 httphdr("text/plain")
362 httphdr("text/plain")
330 nodes = []
363 nodes = []
331 if args.has_key('nodes'):
364 if args.has_key('nodes'):
332 nodes = map(hg.bin, args['nodes'][0].split(" "))
365 nodes = map(hg.bin, args['nodes'][0].split(" "))
333 for b in repo.branches(nodes):
366 for b in repo.branches(nodes):
334 print " ".join(map(hg.hex, b))
367 print " ".join(map(hg.hex, b))
335
368
336 elif args['cmd'][0] == 'between':
369 elif args['cmd'][0] == 'between':
337 httphdr("text/plain")
370 httphdr("text/plain")
338 nodes = []
371 nodes = []
339 if args.has_key('pairs'):
372 if args.has_key('pairs'):
340 pairs = [ map(hg.bin, p.split("-"))
373 pairs = [ map(hg.bin, p.split("-"))
341 for p in args['pairs'][0].split(" ") ]
374 for p in args['pairs'][0].split(" ") ]
342 for b in repo.between(pairs):
375 for b in repo.between(pairs):
343 print " ".join(map(hg.hex, b))
376 print " ".join(map(hg.hex, b))
344
377
345 elif args['cmd'][0] == 'changegroup':
378 elif args['cmd'][0] == 'changegroup':
346 httphdr("application/hg-changegroup")
379 httphdr("application/hg-changegroup")
347 nodes = []
380 nodes = []
348 if args.has_key('roots'):
381 if args.has_key('roots'):
349 nodes = map(hg.bin, args['roots'][0].split(" "))
382 nodes = map(hg.bin, args['roots'][0].split(" "))
350
383
351 z = zlib.compressobj()
384 z = zlib.compressobj()
352 for chunk in repo.changegroup(nodes):
385 for chunk in repo.changegroup(nodes):
353 sys.stdout.write(z.compress(chunk))
386 sys.stdout.write(z.compress(chunk))
354
387
355 sys.stdout.write(z.flush())
388 sys.stdout.write(z.flush())
356
389
357 else:
390 else:
358 page = errpage()
391 page = errpage(self.tmpl_dir)
359 print '<div class="errmsg">unknown command: %s</div>' % \
392 print '<div class="errmsg">unknown command: %s</div>' % \
360 cgi.escape(args['cmd'][0])
393 cgi.escape(args['cmd'][0])
361 page.endpage()
394 page.endpage()
362
395
363 if __name__ == "__main__":
396 if __name__ == "__main__":
364 hgweb().run()
397 hgweb().run()
@@ -1,18 +1,23 b''
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <HTML>
2 <HTML>
3 <!-- created by hgweb 0.1 - jake@edge2.net -->
3 <!-- created by hgweb 0.1 - jake@edge2.net -->
4 <HEAD><TITLE>#title#</TITLE>
4 <HEAD><TITLE>#title#</TITLE>
5 <style type="text/css">
5 <style type="text/css">
6 body { font-family: sans-serif; font-size: 12px; }
6 body { font-family: sans-serif; font-size: 12px; }
7 table { font-size: 12px; }
7 table { font-size: 12px; }
8 .errmsg { font-size: 200%; color: red; }
8 .errmsg { font-size: 200%; color: red; }
9 .filename { font-size: 150%; color: purple; }
9 .filename { font-size: 150%; color: purple; }
10 .manifest { font-size: 150%; color: purple; }
10 .manifest { font-size: 150%; color: purple; }
11 .filehist { font-size: 150%; color: purple; }
11 .filehist { font-size: 150%; color: purple; }
12 .annotation { font-size: 150%; color: purple; }
12 .plusline { color: green; }
13 .plusline { color: green; }
13 .minusline { color: red; }
14 .minusline { color: red; }
14 .atline { color: purple; }
15 .atline { color: purple; }
16 a.annlinelink { text-decoration: none; color: black; }
17 a.revnumlink { text-decoration: none; color: black; }
18 a.annlinelink:hover { text-decoration: none; color: blue; }
19 a.revnumlink:hover { text-decoration: none; color: blue; }
15 </style>
20 </style>
16 </HEAD>
21 </HEAD>
17 <BODY>
22 <BODY>
18
23
General Comments 0
You need to be logged in to leave comments. Login now