Mercurial > hg > mercurial-crew-with-dirclash
annotate mercurial/hgweb.py @ 585:51626d888526
[PATCH] Changelogentry template cleanup
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[PATCH] Changelogentry template cleanup
From: Edouard Gomez <edouard.gomez@gmail.com>
Changelogentry template cleanup
Removed unuseful outside div (was probably used to carry the
parity class, it's no use, multiple css classes can be assigned
to the inner table instead)
Removed all hardwired styles in html tags. The style has been
externalized to equivalent CSS classes.
The inner table is now assigned the parity CSS class.
Changed all relevant table cells from td to th.
Added classes to all cells in order to give some semantic rationale
to these table cells.
manifest hash: 2835217df09be445961b865be166c2470173ba58
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCx1g5ywK+sNU5EO8RAhKGAKCWAHrx+lLMAXjd4/vgvG7vmfSkAACfTZ+m
/EyUsDVaYeVcGzFsp8liReI=
=vt2N
-----END PGP SIGNATURE-----
author | mpm@selenic.com |
---|---|
date | Sat, 02 Jul 2005 19:15:05 -0800 |
parents | df8a5a0098d4 |
children | f8d44a2e6928 |
rev | line source |
---|---|
238
3b92f8fe47ae
hgweb.py: kill #! line, clean up copyright notice
mpm@selenic.com
parents:
222
diff
changeset
|
1 # hgweb.py - web interface to a mercurial repository |
131 | 2 # |
238
3b92f8fe47ae
hgweb.py: kill #! line, clean up copyright notice
mpm@selenic.com
parents:
222
diff
changeset
|
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net> |
575 | 4 # Copyright 2005 Matt Mackall <mpm@selenic.com> |
131 | 5 # |
6 # This software may be used and distributed according to the terms | |
7 # of the GNU General Public License, incorporated herein by reference. | |
8 | |
9 import os, cgi, time, re, difflib, sys, zlib | |
138 | 10 from mercurial.hg import * |
215 | 11 from mercurial.ui import * |
138 | 12 |
157
2653740d8118
Install the templates where they can be found by hgweb.py
mpm@selenic.com
parents:
156
diff
changeset
|
13 def templatepath(): |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
14 for f in "templates", "../templates": |
157
2653740d8118
Install the templates where they can be found by hgweb.py
mpm@selenic.com
parents:
156
diff
changeset
|
15 p = os.path.join(os.path.dirname(__file__), f) |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
16 if os.path.isdir(p): return p |
157
2653740d8118
Install the templates where they can be found by hgweb.py
mpm@selenic.com
parents:
156
diff
changeset
|
17 |
138 | 18 def age(t): |
19 def plural(t, c): | |
20 if c == 1: return t | |
21 return t + "s" | |
22 def fmt(t, c): | |
23 return "%d %s" % (c, plural(t, c)) | |
24 | |
25 now = time.time() | |
26 delta = max(1, int(now - t)) | |
27 | |
28 scales = [["second", 1], | |
29 ["minute", 60], | |
30 ["hour", 3600], | |
31 ["day", 3600 * 24], | |
32 ["week", 3600 * 24 * 7], | |
33 ["month", 3600 * 24 * 30], | |
34 ["year", 3600 * 24 * 365]] | |
35 | |
36 scales.reverse() | |
37 | |
38 for t, s in scales: | |
39 n = delta / s | |
195 | 40 if n >= 2 or s == 1: return fmt(t, n) |
131 | 41 |
42 def nl2br(text): | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
43 return text.replace('\n', '<br/>\n') |
131 | 44 |
45 def obfuscate(text): | |
533
b8404005d6d5
[PATCH] Generate correctly XML entities for obfuscated user
mpm@selenic.com
parents:
515
diff
changeset
|
46 return ''.join([ '&#%d;' % ord(c) for c in text ]) |
138 | 47 |
48 def up(p): | |
49 if p[0] != "/": p = "/" + p | |
50 if p[-1] == "/": p = p[:-1] | |
51 up = os.path.dirname(p) | |
52 if up == "/": | |
53 return "/" | |
54 return up + "/" | |
131 | 55 |
56 def httphdr(type): | |
582 | 57 sys.stdout.write('Content-type: %s\n\n' % type) |
131 | 58 |
135 | 59 def write(*things): |
60 for thing in things: | |
61 if hasattr(thing, "__iter__"): | |
62 for part in thing: | |
63 write(part) | |
64 else: | |
65 sys.stdout.write(str(thing)) | |
66 | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
67 def template(tmpl, filters = {}, **map): |
138 | 68 while tmpl: |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
69 m = re.search(r"#([a-zA-Z0-9]+)((\|[a-zA-Z0-9]+)*)#", tmpl) |
138 | 70 if m: |
71 yield tmpl[:m.start(0)] | |
72 v = map.get(m.group(1), "") | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
73 v = callable(v) and v() or v |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
74 |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
75 fl = m.group(2) |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
76 if fl: |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
77 for f in fl.split("|")[1:]: |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
78 v = filters[f](v) |
515 | 79 |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
80 yield v |
138 | 81 tmpl = tmpl[m.end(0):] |
82 else: | |
83 yield tmpl | |
84 return | |
85 | |
86 class templater: | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
87 def __init__(self, mapfile, filters = {}): |
138 | 88 self.cache = {} |
89 self.map = {} | |
90 self.base = os.path.dirname(mapfile) | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
91 self.filters = filters |
515 | 92 |
138 | 93 for l in file(mapfile): |
94 m = re.match(r'(\S+)\s*=\s*"(.*)"$', l) | |
133
fb84d3e71042
added template support for some hgweb output, also, template files for
jake@edge2.net
parents:
132
diff
changeset
|
95 if m: |
138 | 96 self.cache[m.group(1)] = m.group(2) |
97 else: | |
98 m = re.match(r'(\S+)\s*=\s*(\S+)', l) | |
99 if m: | |
100 self.map[m.group(1)] = os.path.join(self.base, m.group(2)) | |
133
fb84d3e71042
added template support for some hgweb output, also, template files for
jake@edge2.net
parents:
132
diff
changeset
|
101 else: |
138 | 102 raise "unknown map entry '%s'" % l |
133
fb84d3e71042
added template support for some hgweb output, also, template files for
jake@edge2.net
parents:
132
diff
changeset
|
103 |
138 | 104 def __call__(self, t, **map): |
105 try: | |
106 tmpl = self.cache[t] | |
107 except KeyError: | |
108 tmpl = self.cache[t] = file(self.map[t]).read() | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
109 return template(tmpl, self.filters, **map) |
515 | 110 |
138 | 111 class hgweb: |
269
24e9e140485f
hgweb: shrink the default changelog list to 10
mpm@selenic.com
parents:
265
diff
changeset
|
112 maxchanges = 10 |
138 | 113 maxfiles = 10 |
133
fb84d3e71042
added template support for some hgweb output, also, template files for
jake@edge2.net
parents:
132
diff
changeset
|
114 |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
115 def __init__(self, path, name, templates = ""): |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
116 self.templates = templates or templatepath() |
138 | 117 self.reponame = name |
258 | 118 self.path = path |
119 self.mtime = -1 | |
197 | 120 self.viewonly = 0 |
131 | 121 |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
122 self.filters = { |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
123 "escape": cgi.escape, |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
124 "age": age, |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
125 "date": (lambda x: time.asctime(time.gmtime(x))), |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
126 "addbreaks": nl2br, |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
127 "obfuscate": obfuscate, |
375 | 128 "short": (lambda x: x[:12]), |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
129 "firstline": (lambda x: x.splitlines(1)[0]), |
359 | 130 "permissions": (lambda x: x and "-rwxr-xr-x" or "-rw-r--r--") |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
131 } |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
132 |
258 | 133 def refresh(self): |
134 s = os.stat(os.path.join(self.path, ".hg", "00changelog.i")) | |
135 if s.st_mtime != self.mtime: | |
322 | 136 self.mtime = s.st_mtime |
258 | 137 self.repo = repository(ui(), self.path) |
138 | |
138 | 139 def date(self, cs): |
140 return time.asctime(time.gmtime(float(cs[2].split(' ')[0]))) | |
141 | |
142 def listfiles(self, files, mf): | |
143 for f in files[:self.maxfiles]: | |
144 yield self.t("filenodelink", node = hex(mf[f]), file = f) | |
145 if len(files) > self.maxfiles: | |
146 yield self.t("fileellipses") | |
147 | |
148 def listfilediffs(self, files, changeset): | |
149 for f in files[:self.maxfiles]: | |
150 yield self.t("filedifflink", node = hex(changeset), file = f) | |
151 if len(files) > self.maxfiles: | |
152 yield self.t("fileellipses") | |
153 | |
569
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
154 def parents(self, t1, nodes=[], rev=None,**args): |
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
155 if not rev: rev = lambda x: "" |
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
156 for node in nodes: |
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
157 if node != nullid: |
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
158 yield self.t(t1, node = hex(node), rev = rev(node), **args) |
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
159 |
568 | 160 def showtag(self, t1, node=nullid, **args): |
161 for t in self.repo.nodetags(node): | |
162 yield self.t(t1, tag = t, **args) | |
163 | |
138 | 164 def diff(self, node1, node2, files): |
165 def filterfiles(list, files): | |
166 l = [ x for x in list if x in files ] | |
515 | 167 |
138 | 168 for f in files: |
169 if f[-1] != os.sep: f += os.sep | |
170 l += [ x for x in list if x.startswith(f) ] | |
171 return l | |
131 | 172 |
172
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
173 parity = [0] |
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
174 def diffblock(diff, f, fn): |
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
175 yield self.t("diffblock", |
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
176 lines = prettyprintlines(diff), |
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
177 parity = parity[0], |
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
178 file = f, |
369
09f24af48b82
hgweb: fix deleted file in changeset key error
mpm@selenic.com
parents:
366
diff
changeset
|
179 filenode = hex(fn or nullid)) |
172
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
180 parity[0] = 1 - parity[0] |
515 | 181 |
172
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
182 def prettyprintlines(diff): |
138 | 183 for l in diff.splitlines(1): |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
184 if l.startswith('+'): |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
185 yield self.t("difflineplus", line = l) |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
186 elif l.startswith('-'): |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
187 yield self.t("difflineminus", line = l) |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
188 elif l.startswith('@'): |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
189 yield self.t("difflineat", line = l) |
138 | 190 else: |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
191 yield self.t("diffline", line = l) |
131 | 192 |
138 | 193 r = self.repo |
194 cl = r.changelog | |
195 mf = r.manifest | |
196 change1 = cl.read(node1) | |
197 change2 = cl.read(node2) | |
198 mmap1 = mf.read(change1[0]) | |
199 mmap2 = mf.read(change2[0]) | |
200 date1 = self.date(change1) | |
201 date2 = self.date(change2) | |
131 | 202 |
539 | 203 c, a, d, u = r.changes(node1, node2) |
138 | 204 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d)) |
131 | 205 |
138 | 206 for f in c: |
207 to = r.file(f).read(mmap1[f]) | |
208 tn = r.file(f).read(mmap2[f]) | |
172
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
209 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn) |
138 | 210 for f in a: |
265
7ca05593bd30
hgweb: fix non-existent source or destination for diff
mpm@selenic.com
parents:
258
diff
changeset
|
211 to = None |
138 | 212 tn = r.file(f).read(mmap2[f]) |
172
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
213 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn) |
138 | 214 for f in d: |
215 to = r.file(f).read(mmap1[f]) | |
265
7ca05593bd30
hgweb: fix non-existent source or destination for diff
mpm@selenic.com
parents:
258
diff
changeset
|
216 tn = None |
172
e9b1147db448
hgweb: alternating colors for multifile diffs
mpm@selenic.com
parents:
168
diff
changeset
|
217 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f), f, tn) |
131 | 218 |
142 | 219 def header(self): |
220 yield self.t("header", repo = self.reponame) | |
221 | |
222 def footer(self): | |
223 yield self.t("footer", repo = self.reponame) | |
224 | |
180 | 225 def changelog(self, pos): |
138 | 226 def changenav(): |
227 def seq(factor = 1): | |
228 yield 1 * factor | |
173
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
229 yield 3 * factor |
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
230 #yield 5 * factor |
138 | 231 for f in seq(factor * 10): |
232 yield f | |
131 | 233 |
173
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
234 l = [] |
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
235 for f in seq(): |
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
236 if f < self.maxchanges / 2: continue |
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
237 if f > count: break |
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
238 r = "%d" % f |
351 | 239 if pos + f < count: l.append(("+" + r, pos + f)) |
240 if pos - f >= 0: l.insert(0, ("-" + r, pos - f)) | |
173
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
241 |
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
242 yield self.t("naventry", rev = 0, label="(0)") |
515 | 243 |
173
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
244 for label, rev in l: |
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
245 yield self.t("naventry", label = label, rev = rev) |
8da1df932c16
hgweb: make navigation of changesets a bit nicer
mpm@selenic.com
parents:
172
diff
changeset
|
246 |
198
c88ef31fb5c0
hgweb: fix tip so that it doesn't need refreshing
mpm@selenic.com
parents:
197
diff
changeset
|
247 yield self.t("naventry", label="tip") |
131 | 248 |
138 | 249 def changelist(): |
142 | 250 parity = (start - end) & 1 |
138 | 251 cl = self.repo.changelog |
252 l = [] # build a list in forward order for efficiency | |
351 | 253 for i in range(start, end): |
138 | 254 n = cl.node(i) |
255 changes = cl.read(n) | |
256 hn = hex(n) | |
257 p1, p2 = cl.parents(n) | |
258 t = float(changes[2].split(' ')[0]) | |
131 | 259 |
138 | 260 l.insert(0, self.t( |
261 'changelogentry', | |
142 | 262 parity = parity, |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
263 author = changes[1], |
570
2ee819a950aa
[PATCH 2/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
569
diff
changeset
|
264 parent = self.parents("changelogparent", |
569
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
265 cl.parents(n), cl.rev), |
568 | 266 changelogtag = self.showtag("changelogtag",n), |
138 | 267 p1 = hex(p1), p2 = hex(p2), |
268 p1rev = cl.rev(p1), p2rev = cl.rev(p2), | |
269 manifest = hex(changes[0]), | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
270 desc = changes[4], |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
271 date = t, |
138 | 272 files = self.listfilediffs(changes[3], n), |
273 rev = i, | |
274 node = hn)) | |
142 | 275 parity = 1 - parity |
138 | 276 |
277 yield l | |
131 | 278 |
168 | 279 cl = self.repo.changelog |
280 mf = cl.read(cl.tip())[0] | |
281 count = cl.count() | |
351 | 282 start = max(0, pos - self.maxchanges + 1) |
283 end = min(count, start + self.maxchanges) | |
284 pos = end - 1 | |
138 | 285 |
142 | 286 yield self.t('changelog', |
287 header = self.header(), | |
288 footer = self.footer(), | |
289 repo = self.reponame, | |
290 changenav = changenav, | |
168 | 291 manifest = hex(mf), |
142 | 292 rev = pos, changesets = count, entries = changelist) |
131 | 293 |
538 | 294 def search(self, query): |
295 | |
296 def changelist(): | |
297 cl = self.repo.changelog | |
298 count = 0 | |
299 qw = query.lower().split() | |
300 | |
301 def revgen(): | |
302 for i in range(cl.count() - 1, 0, -100): | |
303 l = [] | |
304 for j in range(max(0, i - 100), i): | |
305 n = cl.node(j) | |
306 changes = cl.read(n) | |
307 l.insert(0, (n, j, changes)) | |
308 for e in l: | |
309 yield e | |
310 | |
311 for n, i, changes in revgen(): | |
312 miss = 0 | |
313 for q in qw: | |
314 if not (q in changes[1].lower() or | |
315 q in changes[4].lower() or | |
316 q in " ".join(changes[3][:20]).lower()): | |
317 miss = 1 | |
318 break | |
319 if miss: continue | |
320 | |
321 count += 1 | |
322 hn = hex(n) | |
323 p1, p2 = cl.parents(n) | |
324 t = float(changes[2].split(' ')[0]) | |
325 | |
326 yield self.t( | |
327 'searchentry', | |
328 parity = count & 1, | |
329 author = changes[1], | |
570
2ee819a950aa
[PATCH 2/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
569
diff
changeset
|
330 parent = self.parents("changelogparent", |
569
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
331 cl.parents(n), cl.rev), |
568 | 332 changelogtag = self.showtag("changelogtag",n), |
538 | 333 p1 = hex(p1), p2 = hex(p2), |
334 p1rev = cl.rev(p1), p2rev = cl.rev(p2), | |
335 manifest = hex(changes[0]), | |
336 desc = changes[4], | |
337 date = t, | |
338 files = self.listfilediffs(changes[3], n), | |
339 rev = i, | |
340 node = hn) | |
341 | |
342 if count >= self.maxchanges: break | |
343 | |
344 cl = self.repo.changelog | |
345 mf = cl.read(cl.tip())[0] | |
346 | |
347 yield self.t('search', | |
348 header = self.header(), | |
349 footer = self.footer(), | |
350 query = query, | |
351 repo = self.reponame, | |
352 manifest = hex(mf), | |
353 entries = changelist) | |
354 | |
138 | 355 def changeset(self, nodeid): |
356 n = bin(nodeid) | |
357 cl = self.repo.changelog | |
358 changes = cl.read(n) | |
359 p1, p2 = cl.parents(n) | |
360 p1rev, p2rev = cl.rev(p1), cl.rev(p2) | |
361 t = float(changes[2].split(' ')[0]) | |
515 | 362 |
133
fb84d3e71042
added template support for some hgweb output, also, template files for
jake@edge2.net
parents:
132
diff
changeset
|
363 files = [] |
138 | 364 mf = self.repo.manifest.read(changes[0]) |
131 | 365 for f in changes[3]: |
138 | 366 files.append(self.t("filenodelink", |
369
09f24af48b82
hgweb: fix deleted file in changeset key error
mpm@selenic.com
parents:
366
diff
changeset
|
367 filenode = hex(mf.get(f, nullid)), file = f)) |
138 | 368 |
369 def diff(): | |
370 yield self.diff(p1, n, changes[3]) | |
131 | 371 |
138 | 372 yield self.t('changeset', |
142 | 373 header = self.header(), |
374 footer = self.footer(), | |
375 repo = self.reponame, | |
138 | 376 diff = diff, |
377 rev = cl.rev(n), | |
378 node = nodeid, | |
570
2ee819a950aa
[PATCH 2/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
569
diff
changeset
|
379 parent = self.parents("changesetparent", |
569
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
380 cl.parents(n), cl.rev), |
568 | 381 changesettag = self.showtag("changesettag",n), |
138 | 382 p1 = hex(p1), p2 = hex(p2), |
383 p1rev = cl.rev(p1), p2rev = cl.rev(p2), | |
384 manifest = hex(changes[0]), | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
385 author = changes[1], |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
386 desc = changes[4], |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
387 date = t, |
138 | 388 files = files) |
131 | 389 |
138 | 390 def filelog(self, f, filenode): |
391 cl = self.repo.changelog | |
392 fl = self.repo.file(f) | |
393 count = fl.count() | |
394 | |
395 def entries(): | |
396 l = [] | |
142 | 397 parity = (count - 1) & 1 |
515 | 398 |
138 | 399 for i in range(count): |
400 | |
401 n = fl.node(i) | |
402 lr = fl.linkrev(n) | |
403 cn = cl.node(lr) | |
404 cs = cl.read(cl.node(lr)) | |
405 p1, p2 = fl.parents(n) | |
406 t = float(cs[2].split(' ')[0]) | |
133
fb84d3e71042
added template support for some hgweb output, also, template files for
jake@edge2.net
parents:
132
diff
changeset
|
407 |
138 | 408 l.insert(0, self.t("filelogentry", |
142 | 409 parity = parity, |
138 | 410 filenode = hex(n), |
411 filerev = i, | |
412 file = f, | |
413 node = hex(cn), | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
414 author = cs[1], |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
415 date = t, |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
416 desc = cs[4], |
138 | 417 p1 = hex(p1), p2 = hex(p2), |
418 p1rev = fl.rev(p1), p2rev = fl.rev(p2))) | |
142 | 419 parity = 1 - parity |
138 | 420 |
421 yield l | |
422 | |
423 yield self.t("filelog", | |
142 | 424 header = self.header(), |
425 footer = self.footer(), | |
426 repo = self.reponame, | |
138 | 427 file = f, |
428 filenode = filenode, | |
429 entries = entries) | |
131 | 430 |
138 | 431 def filerevision(self, f, node): |
432 fl = self.repo.file(f) | |
433 n = bin(node) | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
434 text = fl.read(n) |
138 | 435 changerev = fl.linkrev(n) |
436 cl = self.repo.changelog | |
437 cn = cl.node(changerev) | |
438 cs = cl.read(cn) | |
439 p1, p2 = fl.parents(n) | |
440 t = float(cs[2].split(' ')[0]) | |
441 mfn = cs[0] | |
142 | 442 |
443 def lines(): | |
444 for l, t in enumerate(text.splitlines(1)): | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
445 yield self.t("fileline", line = t, |
142 | 446 linenumber = "% 6d" % (l + 1), |
447 parity = l & 1) | |
359 | 448 |
138 | 449 yield self.t("filerevision", file = f, |
142 | 450 header = self.header(), |
451 footer = self.footer(), | |
452 repo = self.reponame, | |
138 | 453 filenode = node, |
454 path = up(f), | |
142 | 455 text = lines(), |
138 | 456 rev = changerev, |
457 node = hex(cn), | |
458 manifest = hex(mfn), | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
459 author = cs[1], |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
460 date = t, |
570
2ee819a950aa
[PATCH 2/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
569
diff
changeset
|
461 parent = self.parents("filerevparent", |
569
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
462 fl.parents(n), fl.rev, file=f), |
138 | 463 p1 = hex(p1), p2 = hex(p2), |
359 | 464 permissions = self.repo.manifest.readflags(mfn)[f], |
138 | 465 p1rev = fl.rev(p1), p2rev = fl.rev(p2)) |
466 | |
467 def fileannotate(self, f, node): | |
468 bcache = {} | |
469 ncache = {} | |
470 fl = self.repo.file(f) | |
471 n = bin(node) | |
472 changerev = fl.linkrev(n) | |
473 | |
474 cl = self.repo.changelog | |
475 cn = cl.node(changerev) | |
476 cs = cl.read(cn) | |
477 p1, p2 = fl.parents(n) | |
478 t = float(cs[2].split(' ')[0]) | |
479 mfn = cs[0] | |
131 | 480 |
138 | 481 def annotate(): |
142 | 482 parity = 1 |
483 last = None | |
138 | 484 for r, l in fl.annotate(n): |
485 try: | |
486 cnode = ncache[r] | |
487 except KeyError: | |
488 cnode = ncache[r] = self.repo.changelog.node(r) | |
515 | 489 |
138 | 490 try: |
491 name = bcache[r] | |
492 except KeyError: | |
493 cl = self.repo.changelog.read(cnode) | |
494 name = cl[1] | |
495 f = name.find('@') | |
496 if f >= 0: | |
497 name = name[:f] | |
534
ab0d1bfeee7c
[PATCH] Handle 'name firstname <email@server>' correctly in annotate
mpm@selenic.com
parents:
533
diff
changeset
|
498 f = name.find('<') |
ab0d1bfeee7c
[PATCH] Handle 'name firstname <email@server>' correctly in annotate
mpm@selenic.com
parents:
533
diff
changeset
|
499 if f >= 0: |
ab0d1bfeee7c
[PATCH] Handle 'name firstname <email@server>' correctly in annotate
mpm@selenic.com
parents:
533
diff
changeset
|
500 name = name[f+1:] |
138 | 501 bcache[r] = name |
131 | 502 |
142 | 503 if last != cnode: |
504 parity = 1 - parity | |
505 last = cnode | |
506 | |
138 | 507 yield self.t("annotateline", |
142 | 508 parity = parity, |
138 | 509 node = hex(cnode), |
510 rev = r, | |
511 author = name, | |
512 file = f, | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
513 line = l) |
138 | 514 |
515 yield self.t("fileannotate", | |
142 | 516 header = self.header(), |
517 footer = self.footer(), | |
518 repo = self.reponame, | |
138 | 519 file = f, |
520 filenode = node, | |
521 annotate = annotate, | |
522 path = up(f), | |
523 rev = changerev, | |
524 node = hex(cn), | |
525 manifest = hex(mfn), | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
526 author = cs[1], |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
527 date = t, |
570
2ee819a950aa
[PATCH 2/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
569
diff
changeset
|
528 parent = self.parents("fileannotateparent", |
569
3e347929f5f9
[PATCH 1/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
568
diff
changeset
|
529 fl.parents(n), fl.rev, file=f), |
138 | 530 p1 = hex(p1), p2 = hex(p2), |
359 | 531 permissions = self.repo.manifest.readflags(mfn)[f], |
138 | 532 p1rev = fl.rev(p1), p2rev = fl.rev(p2)) |
136 | 533 |
138 | 534 def manifest(self, mnode, path): |
535 mf = self.repo.manifest.read(bin(mnode)) | |
536 rev = self.repo.manifest.rev(bin(mnode)) | |
537 node = self.repo.changelog.node(rev) | |
359 | 538 mff=self.repo.manifest.readflags(bin(mnode)) |
138 | 539 |
540 files = {} | |
515 | 541 |
138 | 542 p = path[1:] |
543 l = len(p) | |
131 | 544 |
138 | 545 for f,n in mf.items(): |
546 if f[:l] != p: | |
547 continue | |
548 remain = f[l:] | |
549 if "/" in remain: | |
550 short = remain[:remain.find("/") + 1] # bleah | |
142 | 551 files[short] = (f, None) |
138 | 552 else: |
553 short = os.path.basename(remain) | |
554 files[short] = (f, n) | |
131 | 555 |
138 | 556 def filelist(): |
142 | 557 parity = 0 |
138 | 558 fl = files.keys() |
559 fl.sort() | |
560 for f in fl: | |
561 full, fnode = files[f] | |
142 | 562 if fnode: |
563 yield self.t("manifestfileentry", | |
564 file = full, | |
565 manifest = mnode, | |
566 filenode = hex(fnode), | |
567 parity = parity, | |
515 | 568 basename = f, |
359 | 569 permissions = mff[full]) |
142 | 570 else: |
571 yield self.t("manifestdirentry", | |
572 parity = parity, | |
573 path = os.path.join(path, f), | |
574 manifest = mnode, basename = f[:-1]) | |
575 parity = 1 - parity | |
138 | 576 |
577 yield self.t("manifest", | |
142 | 578 header = self.header(), |
579 footer = self.footer(), | |
580 repo = self.reponame, | |
138 | 581 manifest = mnode, |
582 rev = rev, | |
583 node = hex(node), | |
584 path = path, | |
585 up = up(path), | |
142 | 586 entries = filelist) |
131 | 587 |
168 | 588 def tags(self): |
589 cl = self.repo.changelog | |
590 mf = cl.read(cl.tip())[0] | |
591 | |
343 | 592 i = self.repo.tagslist() |
593 i.reverse() | |
168 | 594 |
595 def entries(): | |
596 parity = 0 | |
597 for k,n in i: | |
598 yield self.t("tagentry", | |
599 parity = parity, | |
600 tag = k, | |
601 node = hex(n)) | |
602 parity = 1 - parity | |
603 | |
604 yield self.t("tags", | |
605 header = self.header(), | |
606 footer = self.footer(), | |
607 repo = self.reponame, | |
608 manifest = hex(mf), | |
609 entries = entries) | |
610 | |
138 | 611 def filediff(self, file, changeset): |
612 n = bin(changeset) | |
613 cl = self.repo.changelog | |
614 p1 = cl.parents(n)[0] | |
615 cs = cl.read(n) | |
616 mf = self.repo.manifest.read(cs[0]) | |
515 | 617 |
138 | 618 def diff(): |
619 yield self.diff(p1, n, file) | |
131 | 620 |
138 | 621 yield self.t("filediff", |
142 | 622 header = self.header(), |
623 footer = self.footer(), | |
624 repo = self.reponame, | |
138 | 625 file = file, |
376
fadc9e126369
hgweb: fix deleted file in filediff key error
Thomas Arendsen Hein <thomas@intevation.de>
parents:
369
diff
changeset
|
626 filenode = hex(mf.get(file, nullid)), |
138 | 627 node = changeset, |
628 rev = self.repo.changelog.rev(n), | |
571
c7364b985ca2
[PATCH 3/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
570
diff
changeset
|
629 parent = self.parents("filediffparent", |
c7364b985ca2
[PATCH 3/5]: cleaning the template parent management in hgweb
mpm@selenic.com
parents:
570
diff
changeset
|
630 cl.parents(n), cl.rev), |
138 | 631 p1rev = self.repo.changelog.rev(p1), |
632 diff = diff) | |
515 | 633 |
138 | 634 # add tags to things |
635 # tags -> list of changesets corresponding to tags | |
636 # find tag, changeset, file | |
131 | 637 |
132 | 638 def run(self): |
258 | 639 self.refresh() |
132 | 640 args = cgi.parse() |
641 | |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
642 m = os.path.join(self.templates, "map") |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
643 if args.has_key('style'): |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
644 b = os.path.basename("map-" + args['style'][0]) |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
645 p = os.path.join(self.templates, b) |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
646 if os.path.isfile(p): m = p |
515 | 647 |
201
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
648 self.t = templater(m, self.filters) |
f918a6fa2572
hgweb: add template filters, template style maps, and raw pages
mpm@selenic.com
parents:
198
diff
changeset
|
649 |
138 | 650 if not args.has_key('cmd') or args['cmd'][0] == 'changelog': |
538 | 651 c = self.repo.changelog.count() - 1 |
652 hi = c | |
153
e8a360cd5a9f
changed pos to rev for changelog cmd, changed & to ;
jake@edge2.net
parents:
142
diff
changeset
|
653 if args.has_key('rev'): |
165 | 654 hi = args['rev'][0] |
166
39624c47060f
hgweb: don't blow up on search for unknown keys
mpm@selenic.com
parents:
165
diff
changeset
|
655 try: |
39624c47060f
hgweb: don't blow up on search for unknown keys
mpm@selenic.com
parents:
165
diff
changeset
|
656 hi = self.repo.changelog.rev(self.repo.lookup(hi)) |
538 | 657 except KeyError: |
658 write(self.search(hi)) | |
659 return | |
575 | 660 |
138 | 661 write(self.changelog(hi)) |
515 | 662 |
138 | 663 elif args['cmd'][0] == 'changeset': |
664 write(self.changeset(args['node'][0])) | |
665 | |
666 elif args['cmd'][0] == 'manifest': | |
667 write(self.manifest(args['manifest'][0], args['path'][0])) | |
668 | |
168 | 669 elif args['cmd'][0] == 'tags': |
670 write(self.tags()) | |
671 | |
138 | 672 elif args['cmd'][0] == 'filediff': |
673 write(self.filediff(args['file'][0], args['node'][0])) | |
131 | 674 |
132 | 675 elif args['cmd'][0] == 'file': |
138 | 676 write(self.filerevision(args['file'][0], args['filenode'][0])) |
131 | 677 |
138 | 678 elif args['cmd'][0] == 'annotate': |
679 write(self.fileannotate(args['file'][0], args['filenode'][0])) | |
131 | 680 |
138 | 681 elif args['cmd'][0] == 'filelog': |
682 write(self.filelog(args['file'][0], args['filenode'][0])) | |
136 | 683 |
222 | 684 elif args['cmd'][0] == 'heads': |
685 httphdr("text/plain") | |
686 h = self.repo.heads() | |
687 sys.stdout.write(" ".join(map(hex, h)) + "\n") | |
688 | |
132 | 689 elif args['cmd'][0] == 'branches': |
690 httphdr("text/plain") | |
691 nodes = [] | |
692 if args.has_key('nodes'): | |
138 | 693 nodes = map(bin, args['nodes'][0].split(" ")) |
694 for b in self.repo.branches(nodes): | |
695 sys.stdout.write(" ".join(map(hex, b)) + "\n") | |
131 | 696 |
132 | 697 elif args['cmd'][0] == 'between': |
698 httphdr("text/plain") | |
699 nodes = [] | |
700 if args.has_key('pairs'): | |
138 | 701 pairs = [ map(bin, p.split("-")) |
132 | 702 for p in args['pairs'][0].split(" ") ] |
138 | 703 for b in self.repo.between(pairs): |
704 sys.stdout.write(" ".join(map(hex, b)) + "\n") | |
132 | 705 |
706 elif args['cmd'][0] == 'changegroup': | |
707 httphdr("application/hg-changegroup") | |
708 nodes = [] | |
197 | 709 if self.viewonly: |
710 return | |
711 | |
132 | 712 if args.has_key('roots'): |
138 | 713 nodes = map(bin, args['roots'][0].split(" ")) |
131 | 714 |
132 | 715 z = zlib.compressobj() |
138 | 716 for chunk in self.repo.changegroup(nodes): |
132 | 717 sys.stdout.write(z.compress(chunk)) |
718 | |
719 sys.stdout.write(z.flush()) | |
131 | 720 |
132 | 721 else: |
138 | 722 write(self.t("error")) |
131 | 723 |
158
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
724 def server(path, name, templates, address, port): |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
725 |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
726 import BaseHTTPServer |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
727 import sys, os |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
728 |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
729 class hgwebhandler(BaseHTTPServer.BaseHTTPRequestHandler): |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
730 def do_POST(self): |
271 | 731 try: |
732 self.do_hgweb() | |
733 except socket.error, inst: | |
734 if inst.args[0] != 32: raise | |
158
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
735 |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
736 def do_GET(self): |
271 | 737 self.do_POST() |
158
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
738 |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
739 def do_hgweb(self): |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
740 query = "" |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
741 p = self.path.find("?") |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
742 if p: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
743 query = self.path[p + 1:] |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
744 query = query.replace('+', ' ') |
515 | 745 |
158
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
746 env = {} |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
747 env['GATEWAY_INTERFACE'] = 'CGI/1.1' |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
748 env['REQUEST_METHOD'] = self.command |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
749 if query: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
750 env['QUERY_STRING'] = query |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
751 host = self.address_string() |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
752 if host != self.client_address[0]: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
753 env['REMOTE_HOST'] = host |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
754 env['REMOTE_ADDR'] = self.client_address[0] |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
755 |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
756 if self.headers.typeheader is None: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
757 env['CONTENT_TYPE'] = self.headers.type |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
758 else: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
759 env['CONTENT_TYPE'] = self.headers.typeheader |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
760 length = self.headers.getheader('content-length') |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
761 if length: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
762 env['CONTENT_LENGTH'] = length |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
763 accept = [] |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
764 for line in self.headers.getallmatchingheaders('accept'): |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
765 if line[:1] in "\t\n\r ": |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
766 accept.append(line.strip()) |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
767 else: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
768 accept = accept + line[7:].split(',') |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
769 env['HTTP_ACCEPT'] = ','.join(accept) |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
770 |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
771 os.environ.update(env) |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
772 |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
773 save = sys.argv, sys.stdin, sys.stdout, sys.stderr |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
774 try: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
775 sys.stdin = self.rfile |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
776 sys.stdout = self.wfile |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
777 sys.argv = ["hgweb.py"] |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
778 if '=' not in query: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
779 sys.argv.append(query) |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
780 self.send_response(200, "Script output follows") |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
781 hg.run() |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
782 finally: |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
783 sys.argv, sys.stdin, sys.stdout, sys.stderr = save |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
784 |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
785 hg = hgweb(path, name, templates) |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
786 httpd = BaseHTTPServer.HTTPServer((address, port), hgwebhandler) |
be7103467d2e
Add 'hg serve' command for stand-alone server
mpm@selenic.com
parents:
157
diff
changeset
|
787 httpd.serve_forever() |