##// END OF EJS Templates
hgweb: descend empty directories in web view...
Ry4an Brase -
r7305:c21d236c default
parent child Browse files
Show More
@@ -0,0 +1,28
1 #!/bin/sh
2 # Test chains of near empty directories, terminating 3 different ways:
3 # - a1: file at level 4 (deepest)
4 # - b1: two dirs at level 3
5 # - e1: file at level 2
6
7 echo % Set up the repo
8 hg init test
9 cd test
10 mkdir -p a1/a2/a3/a4
11 mkdir -p b1/b2/b3/b4
12 mkdir -p b1/b2/c3/c4
13 mkdir -p d1/d2/d3/d4
14 echo foo > a1/a2/a3/a4/foo
15 echo foo > b1/b2/b3/b4/foo
16 echo foo > b1/b2/c3/c4/foo
17 echo foo > d1/d2/d3/d4/foo
18 echo foo > d1/d2/foo
19 hg ci -Ama
20
21 hg serve -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
22 cat hg.pid >> $DAEMON_PIDS
23
24 echo % manifest with descending
25 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file'
26
27 echo % ERRORS ENCOUNTERED
28 cat errors.log
@@ -0,0 +1,51
1 % Set up the repo
2 adding a1/a2/a3/a4/foo
3 adding b1/b2/b3/b4/foo
4 adding b1/b2/c3/c4/foo
5 adding d1/d2/d3/d4/foo
6 adding d1/d2/foo
7 % manifest with descending
8 200 Script output follows
9
10 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
11 <html>
12 <head>
13 <link rel="icon" href="/static/hgicon.png" type="image/png">
14 <meta name="robots" content="index, nofollow" />
15 <link rel="stylesheet" href="/static/style.css" type="text/css" />
16
17 <title>test: files for changeset 9087c84a0f5d</title>
18 </head>
19 <body>
20
21 <div class="buttons">
22 <a href="/log/0">changelog</a>
23 <a href="/shortlog/0">shortlog</a>
24 <a href="/graph">graph</a>
25 <a href="/tags">tags</a>
26 <a href="/rev/9087c84a0f5d">changeset</a>
27
28 </div>
29
30 <h2>files for changeset 9087c84a0f5d: /</h2>
31
32 <table cellpadding="0" cellspacing="0">
33 <tr class="parity0">
34 <td><tt>drwxr-xr-x</tt>&nbsp;
35 <td>&nbsp;
36 <td>&nbsp;
37 <td><a href="/file/9087c84a0f5d/">[up]</a>
38 </tr>
39 <tr class="parity1"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="/file/9087c84a0f5d/a1">a1/</a> <a href="/file/9087c84a0f5d/a1/a2/a3/a4">a2/a3/a4</a><tr class="parity0"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="/file/9087c84a0f5d/b1">b1/</a> <a href="/file/9087c84a0f5d/b1/b2">b2</a><tr class="parity1"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="/file/9087c84a0f5d/d1">d1/</a> <a href="/file/9087c84a0f5d/d1/d2">d2</a>
40
41 </table>
42
43 <div class="logo">
44 <a href="http://www.selenic.com/mercurial/">
45 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial"></a>
46 </div>
47
48 </body>
49 </html>
50
51 % ERRORS ENCOUNTERED
@@ -1,638 +1,651
1 1 #
2 2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 import os, mimetypes, re, cgi
9 9 import webutil
10 10 from mercurial import revlog, archival, templatefilters
11 11 from mercurial.node import short, hex, nullid
12 12 from mercurial.util import binary, datestr
13 13 from mercurial.repo import RepoError
14 14 from common import paritygen, staticfile, get_contact, ErrorResponse
15 15 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
16 16 from mercurial import graphmod, util
17 17
18 18 # __all__ is populated with the allowed commands. Be sure to add to it if
19 19 # you're adding a new command, or the new command won't work.
20 20
21 21 __all__ = [
22 22 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
23 23 'manifest', 'tags', 'summary', 'filediff', 'diff', 'annotate', 'filelog',
24 24 'archive', 'static', 'graph',
25 25 ]
26 26
27 27 def log(web, req, tmpl):
28 28 if 'file' in req.form and req.form['file'][0]:
29 29 return filelog(web, req, tmpl)
30 30 else:
31 31 return changelog(web, req, tmpl)
32 32
33 33 def rawfile(web, req, tmpl):
34 34 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
35 35 if not path:
36 36 content = manifest(web, req, tmpl)
37 37 req.respond(HTTP_OK, web.ctype)
38 38 return content
39 39
40 40 try:
41 41 fctx = webutil.filectx(web.repo, req)
42 42 except revlog.LookupError, inst:
43 43 try:
44 44 content = manifest(web, req, tmpl)
45 45 req.respond(HTTP_OK, web.ctype)
46 46 return content
47 47 except ErrorResponse:
48 48 raise inst
49 49
50 50 path = fctx.path()
51 51 text = fctx.data()
52 52 mt = mimetypes.guess_type(path)[0]
53 53 if mt is None:
54 54 mt = binary(text) and 'application/octet-stream' or 'text/plain'
55 55
56 56 req.respond(HTTP_OK, mt, path, len(text))
57 57 return [text]
58 58
59 59 def _filerevision(web, tmpl, fctx):
60 60 f = fctx.path()
61 61 text = fctx.data()
62 62 parity = paritygen(web.stripecount)
63 63
64 64 if binary(text):
65 65 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
66 66 text = '(binary:%s)' % mt
67 67
68 68 def lines():
69 69 for lineno, t in enumerate(text.splitlines(1)):
70 70 yield {"line": t,
71 71 "lineid": "l%d" % (lineno + 1),
72 72 "linenumber": "% 6d" % (lineno + 1),
73 73 "parity": parity.next()}
74 74
75 75 return tmpl("filerevision",
76 76 file=f,
77 77 path=webutil.up(f),
78 78 text=lines(),
79 79 rev=fctx.rev(),
80 80 node=hex(fctx.node()),
81 81 author=fctx.user(),
82 82 date=fctx.date(),
83 83 desc=fctx.description(),
84 84 branch=webutil.nodebranchnodefault(fctx),
85 85 parent=webutil.siblings(fctx.parents()),
86 86 child=webutil.siblings(fctx.children()),
87 87 rename=webutil.renamelink(fctx),
88 88 permissions=fctx.manifest().flags(f))
89 89
90 90 def file(web, req, tmpl):
91 91 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
92 92 if not path:
93 93 return manifest(web, req, tmpl)
94 94 try:
95 95 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
96 96 except revlog.LookupError, inst:
97 97 try:
98 98 return manifest(web, req, tmpl)
99 99 except ErrorResponse:
100 100 raise inst
101 101
102 102 def _search(web, tmpl, query):
103 103
104 104 def changelist(**map):
105 105 cl = web.repo.changelog
106 106 count = 0
107 107 qw = query.lower().split()
108 108
109 109 def revgen():
110 110 for i in xrange(len(cl) - 1, 0, -100):
111 111 l = []
112 112 for j in xrange(max(0, i - 100), i + 1):
113 113 ctx = web.repo[j]
114 114 l.append(ctx)
115 115 l.reverse()
116 116 for e in l:
117 117 yield e
118 118
119 119 for ctx in revgen():
120 120 miss = 0
121 121 for q in qw:
122 122 if not (q in ctx.user().lower() or
123 123 q in ctx.description().lower() or
124 124 q in " ".join(ctx.files()).lower()):
125 125 miss = 1
126 126 break
127 127 if miss:
128 128 continue
129 129
130 130 count += 1
131 131 n = ctx.node()
132 132 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
133 133
134 134 yield tmpl('searchentry',
135 135 parity=parity.next(),
136 136 author=ctx.user(),
137 137 parent=webutil.siblings(ctx.parents()),
138 138 child=webutil.siblings(ctx.children()),
139 139 changelogtag=showtags,
140 140 desc=ctx.description(),
141 141 date=ctx.date(),
142 142 files=web.listfilediffs(tmpl, ctx.files(), n),
143 143 rev=ctx.rev(),
144 144 node=hex(n),
145 145 tags=webutil.nodetagsdict(web.repo, n),
146 146 inbranch=webutil.nodeinbranch(web.repo, ctx),
147 147 branches=webutil.nodebranchdict(web.repo, ctx))
148 148
149 149 if count >= web.maxchanges:
150 150 break
151 151
152 152 cl = web.repo.changelog
153 153 parity = paritygen(web.stripecount)
154 154
155 155 return tmpl('search',
156 156 query=query,
157 157 node=hex(cl.tip()),
158 158 entries=changelist,
159 159 archives=web.archivelist("tip"))
160 160
161 161 def changelog(web, req, tmpl, shortlog = False):
162 162 if 'node' in req.form:
163 163 ctx = webutil.changectx(web.repo, req)
164 164 else:
165 165 if 'rev' in req.form:
166 166 hi = req.form['rev'][0]
167 167 else:
168 168 hi = len(web.repo) - 1
169 169 try:
170 170 ctx = web.repo[hi]
171 171 except RepoError:
172 172 return _search(web, tmpl, hi) # XXX redirect to 404 page?
173 173
174 174 def changelist(limit=0, **map):
175 175 cl = web.repo.changelog
176 176 l = [] # build a list in forward order for efficiency
177 177 for i in xrange(start, end):
178 178 ctx = web.repo[i]
179 179 n = ctx.node()
180 180 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
181 181
182 182 l.insert(0, {"parity": parity.next(),
183 183 "author": ctx.user(),
184 184 "parent": webutil.siblings(ctx.parents(), i - 1),
185 185 "child": webutil.siblings(ctx.children(), i + 1),
186 186 "changelogtag": showtags,
187 187 "desc": ctx.description(),
188 188 "date": ctx.date(),
189 189 "files": web.listfilediffs(tmpl, ctx.files(), n),
190 190 "rev": i,
191 191 "node": hex(n),
192 192 "tags": webutil.nodetagsdict(web.repo, n),
193 193 "inbranch": webutil.nodeinbranch(web.repo, ctx),
194 194 "branches": webutil.nodebranchdict(web.repo, ctx)
195 195 })
196 196
197 197 if limit > 0:
198 198 l = l[:limit]
199 199
200 200 for e in l:
201 201 yield e
202 202
203 203 maxchanges = shortlog and web.maxshortchanges or web.maxchanges
204 204 cl = web.repo.changelog
205 205 count = len(cl)
206 206 pos = ctx.rev()
207 207 start = max(0, pos - maxchanges + 1)
208 208 end = min(count, start + maxchanges)
209 209 pos = end - 1
210 210 parity = paritygen(web.stripecount, offset=start-end)
211 211
212 212 changenav = webutil.revnavgen(pos, maxchanges, count, web.repo.changectx)
213 213
214 214 return tmpl(shortlog and 'shortlog' or 'changelog',
215 215 changenav=changenav,
216 216 node=hex(ctx.node()),
217 217 rev=pos, changesets=count,
218 218 entries=lambda **x: changelist(limit=0,**x),
219 219 latestentry=lambda **x: changelist(limit=1,**x),
220 220 archives=web.archivelist("tip"))
221 221
222 222 def shortlog(web, req, tmpl):
223 223 return changelog(web, req, tmpl, shortlog = True)
224 224
225 225 def changeset(web, req, tmpl):
226 226 ctx = webutil.changectx(web.repo, req)
227 227 n = ctx.node()
228 228 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', n)
229 229 parents = ctx.parents()
230 230 p1 = parents[0].node()
231 231
232 232 files = []
233 233 parity = paritygen(web.stripecount)
234 234 for f in ctx.files():
235 235 template = f in ctx and 'filenodelink' or 'filenolink'
236 236 files.append(tmpl(template,
237 237 node=hex(n), file=f,
238 238 parity=parity.next()))
239 239
240 240 diffs = web.diff(tmpl, p1, n, None)
241 241 return tmpl('changeset',
242 242 diff=diffs,
243 243 rev=ctx.rev(),
244 244 node=hex(n),
245 245 parent=webutil.siblings(parents),
246 246 child=webutil.siblings(ctx.children()),
247 247 changesettag=showtags,
248 248 author=ctx.user(),
249 249 desc=ctx.description(),
250 250 date=ctx.date(),
251 251 files=files,
252 252 archives=web.archivelist(hex(n)),
253 253 tags=webutil.nodetagsdict(web.repo, n),
254 254 branch=webutil.nodebranchnodefault(ctx),
255 255 inbranch=webutil.nodeinbranch(web.repo, ctx),
256 256 branches=webutil.nodebranchdict(web.repo, ctx))
257 257
258 258 rev = changeset
259 259
260 260 def manifest(web, req, tmpl):
261 261 ctx = webutil.changectx(web.repo, req)
262 262 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
263 263 mf = ctx.manifest()
264 264 node = ctx.node()
265 265
266 266 files = {}
267 dirs = {}
267 268 parity = paritygen(web.stripecount)
268 269
269 270 if path and path[-1] != "/":
270 271 path += "/"
271 272 l = len(path)
272 273 abspath = "/" + path
273 274
274 275 for f, n in mf.items():
275 276 if f[:l] != path:
276 277 continue
277 278 remain = f[l:]
278 idx = remain.find('/')
279 if idx != -1:
280 remain = remain[:idx+1]
281 n = None
282 files[remain] = (f, n)
279 elements = remain.split('/')
280 if len(elements) == 1:
281 files[remain] = f
282 else:
283 h = dirs # need to retain ref to dirs (root)
284 for elem in elements[0:-1]:
285 if elem not in h:
286 h[elem] = {}
287 h = h[elem]
288 if len(h) > 1:
289 break
290 h[None] = None # denotes files present
283 291
284 if not files:
292 if not files and not dirs:
285 293 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
286 294
287 295 def filelist(**map):
288 296 for f in util.sort(files):
289 full, fnode = files[f]
290 if not fnode:
291 continue
297 full = files[f]
292 298
293 299 fctx = ctx.filectx(full)
294 300 yield {"file": full,
295 301 "parity": parity.next(),
296 302 "basename": f,
297 303 "date": fctx.date(),
298 304 "size": fctx.size(),
299 305 "permissions": mf.flags(full)}
300 306
301 307 def dirlist(**map):
302 for f in util.sort(files):
303 full, fnode = files[f]
304 if fnode:
305 continue
308 for d in util.sort(dirs):
306 309
310 emptydirs = []
311 h = dirs[d]
312 while isinstance(h, dict) and len(h) == 1:
313 k,v = h.items()[0]
314 if v:
315 emptydirs.append(k)
316 h = v
317
318 path = "%s%s" % (abspath, d)
307 319 yield {"parity": parity.next(),
308 "path": "%s%s" % (abspath, f),
309 "basename": f[:-1]}
320 "path": path,
321 "emptydirs": "/".join(emptydirs),
322 "basename": d}
310 323
311 324 return tmpl("manifest",
312 325 rev=ctx.rev(),
313 326 node=hex(node),
314 327 path=abspath,
315 328 up=webutil.up(abspath),
316 329 upparity=parity.next(),
317 330 fentries=filelist,
318 331 dentries=dirlist,
319 332 archives=web.archivelist(hex(node)),
320 333 tags=webutil.nodetagsdict(web.repo, node),
321 334 inbranch=webutil.nodeinbranch(web.repo, ctx),
322 335 branches=webutil.nodebranchdict(web.repo, ctx))
323 336
324 337 def tags(web, req, tmpl):
325 338 i = web.repo.tagslist()
326 339 i.reverse()
327 340 parity = paritygen(web.stripecount)
328 341
329 342 def entries(notip=False,limit=0, **map):
330 343 count = 0
331 344 for k, n in i:
332 345 if notip and k == "tip":
333 346 continue
334 347 if limit > 0 and count >= limit:
335 348 continue
336 349 count = count + 1
337 350 yield {"parity": parity.next(),
338 351 "tag": k,
339 352 "date": web.repo[n].date(),
340 353 "node": hex(n)}
341 354
342 355 return tmpl("tags",
343 356 node=hex(web.repo.changelog.tip()),
344 357 entries=lambda **x: entries(False,0, **x),
345 358 entriesnotip=lambda **x: entries(True,0, **x),
346 359 latestentry=lambda **x: entries(True,1, **x))
347 360
348 361 def summary(web, req, tmpl):
349 362 i = web.repo.tagslist()
350 363 i.reverse()
351 364
352 365 def tagentries(**map):
353 366 parity = paritygen(web.stripecount)
354 367 count = 0
355 368 for k, n in i:
356 369 if k == "tip": # skip tip
357 370 continue
358 371
359 372 count += 1
360 373 if count > 10: # limit to 10 tags
361 374 break
362 375
363 376 yield tmpl("tagentry",
364 377 parity=parity.next(),
365 378 tag=k,
366 379 node=hex(n),
367 380 date=web.repo[n].date())
368 381
369 382 def branches(**map):
370 383 parity = paritygen(web.stripecount)
371 384
372 385 b = web.repo.branchtags()
373 386 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.items()]
374 387 for r,n,t in util.sort(l):
375 388 yield {'parity': parity.next(),
376 389 'branch': t,
377 390 'node': hex(n),
378 391 'date': web.repo[n].date()}
379 392
380 393 def changelist(**map):
381 394 parity = paritygen(web.stripecount, offset=start-end)
382 395 l = [] # build a list in forward order for efficiency
383 396 for i in xrange(start, end):
384 397 ctx = web.repo[i]
385 398 n = ctx.node()
386 399 hn = hex(n)
387 400
388 401 l.insert(0, tmpl(
389 402 'shortlogentry',
390 403 parity=parity.next(),
391 404 author=ctx.user(),
392 405 desc=ctx.description(),
393 406 date=ctx.date(),
394 407 rev=i,
395 408 node=hn,
396 409 tags=webutil.nodetagsdict(web.repo, n),
397 410 inbranch=webutil.nodeinbranch(web.repo, ctx),
398 411 branches=webutil.nodebranchdict(web.repo, ctx)))
399 412
400 413 yield l
401 414
402 415 cl = web.repo.changelog
403 416 count = len(cl)
404 417 start = max(0, count - web.maxchanges)
405 418 end = min(count, start + web.maxchanges)
406 419
407 420 return tmpl("summary",
408 421 desc=web.config("web", "description", "unknown"),
409 422 owner=get_contact(web.config) or "unknown",
410 423 lastchange=cl.read(cl.tip())[2],
411 424 tags=tagentries,
412 425 branches=branches,
413 426 shortlog=changelist,
414 427 node=hex(cl.tip()),
415 428 archives=web.archivelist("tip"))
416 429
417 430 def filediff(web, req, tmpl):
418 431 fctx, ctx = None, None
419 432 try:
420 433 fctx = webutil.filectx(web.repo, req)
421 434 except LookupError:
422 435 ctx = webutil.changectx(web.repo, req)
423 436 path = webutil.cleanpath(web.repo, req.form['file'][0])
424 437 if path not in ctx.files():
425 438 raise
426 439
427 440 if fctx is not None:
428 441 n = fctx.node()
429 442 path = fctx.path()
430 443 parents = fctx.parents()
431 444 p1 = parents and parents[0].node() or nullid
432 445 else:
433 446 n = ctx.node()
434 447 # path already defined in except clause
435 448 parents = ctx.parents()
436 449 p1 = parents and parents[0].node() or nullid
437 450
438 451 diffs = web.diff(tmpl, p1, n, [path])
439 452 rename = fctx and webutil.renamelink(fctx) or []
440 453 ctx = fctx and fctx or ctx
441 454 return tmpl("filediff",
442 455 file=path,
443 456 node=hex(n),
444 457 rev=ctx.rev(),
445 458 date=ctx.date(),
446 459 desc=ctx.description(),
447 460 author=ctx.user(),
448 461 rename=rename,
449 462 branch=webutil.nodebranchnodefault(ctx),
450 463 parent=webutil.siblings(parents),
451 464 child=webutil.siblings(ctx.children()),
452 465 diff=diffs)
453 466
454 467 diff = filediff
455 468
456 469 def annotate(web, req, tmpl):
457 470 fctx = webutil.filectx(web.repo, req)
458 471 f = fctx.path()
459 472 parity = paritygen(web.stripecount)
460 473
461 474 def annotate(**map):
462 475 last = None
463 476 if binary(fctx.data()):
464 477 mt = (mimetypes.guess_type(fctx.path())[0]
465 478 or 'application/octet-stream')
466 479 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
467 480 '(binary:%s)' % mt)])
468 481 else:
469 482 lines = enumerate(fctx.annotate(follow=True, linenumber=True))
470 483 for lineno, ((f, targetline), l) in lines:
471 484 fnode = f.filenode()
472 485
473 486 if last != fnode:
474 487 last = fnode
475 488
476 489 yield {"parity": parity.next(),
477 490 "node": hex(f.node()),
478 491 "rev": f.rev(),
479 492 "author": f.user(),
480 493 "desc": f.description(),
481 494 "file": f.path(),
482 495 "targetline": targetline,
483 496 "line": l,
484 497 "lineid": "l%d" % (lineno + 1),
485 498 "linenumber": "% 6d" % (lineno + 1)}
486 499
487 500 return tmpl("fileannotate",
488 501 file=f,
489 502 annotate=annotate,
490 503 path=webutil.up(f),
491 504 rev=fctx.rev(),
492 505 node=hex(fctx.node()),
493 506 author=fctx.user(),
494 507 date=fctx.date(),
495 508 desc=fctx.description(),
496 509 rename=webutil.renamelink(fctx),
497 510 branch=webutil.nodebranchnodefault(fctx),
498 511 parent=webutil.siblings(fctx.parents()),
499 512 child=webutil.siblings(fctx.children()),
500 513 permissions=fctx.manifest().flags(f))
501 514
502 515 def filelog(web, req, tmpl):
503 516
504 517 try:
505 518 fctx = webutil.filectx(web.repo, req)
506 519 f = fctx.path()
507 520 fl = fctx.filelog()
508 521 except revlog.LookupError:
509 522 f = webutil.cleanpath(web.repo, req.form['file'][0])
510 523 fl = web.repo.file(f)
511 524 numrevs = len(fl)
512 525 if not numrevs: # file doesn't exist at all
513 526 raise
514 527 rev = webutil.changectx(web.repo, req).rev()
515 528 first = fl.linkrev(fl.node(0))
516 529 if rev < first: # current rev is from before file existed
517 530 raise
518 531 frev = numrevs - 1
519 532 while fl.linkrev(fl.node(frev)) > rev:
520 533 frev -= 1
521 534 fctx = web.repo.filectx(f, fl.linkrev(fl.node(frev)))
522 535
523 536 count = fctx.filerev() + 1
524 537 pagelen = web.maxshortchanges
525 538 start = max(0, fctx.filerev() - pagelen + 1) # first rev on this page
526 539 end = min(count, start + pagelen) # last rev on this page
527 540 parity = paritygen(web.stripecount, offset=start-end)
528 541
529 542 def entries(limit=0, **map):
530 543 l = []
531 544
532 545 for i in xrange(start, end):
533 546 ctx = fctx.filectx(i)
534 547
535 548 l.insert(0, {"parity": parity.next(),
536 549 "filerev": i,
537 550 "file": f,
538 551 "node": hex(ctx.node()),
539 552 "author": ctx.user(),
540 553 "date": ctx.date(),
541 554 "rename": webutil.renamelink(fctx),
542 555 "parent": webutil.siblings(fctx.parents()),
543 556 "child": webutil.siblings(fctx.children()),
544 557 "desc": ctx.description()})
545 558
546 559 if limit > 0:
547 560 l = l[:limit]
548 561
549 562 for e in l:
550 563 yield e
551 564
552 565 nodefunc = lambda x: fctx.filectx(fileid=x)
553 566 nav = webutil.revnavgen(end - 1, pagelen, count, nodefunc)
554 567 return tmpl("filelog", file=f, node=hex(fctx.node()), nav=nav,
555 568 entries=lambda **x: entries(limit=0, **x),
556 569 latestentry=lambda **x: entries(limit=1, **x))
557 570
558 571
559 572 def archive(web, req, tmpl):
560 573 type_ = req.form.get('type', [None])[0]
561 574 allowed = web.configlist("web", "allow_archive")
562 575 key = req.form['node'][0]
563 576
564 577 if type_ not in web.archives:
565 578 msg = 'Unsupported archive type: %s' % type_
566 579 raise ErrorResponse(HTTP_NOT_FOUND, msg)
567 580
568 581 if not ((type_ in allowed or
569 582 web.configbool("web", "allow" + type_, False))):
570 583 msg = 'Archive type not allowed: %s' % type_
571 584 raise ErrorResponse(HTTP_FORBIDDEN, msg)
572 585
573 586 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
574 587 cnode = web.repo.lookup(key)
575 588 arch_version = key
576 589 if cnode == key or key == 'tip':
577 590 arch_version = short(cnode)
578 591 name = "%s-%s" % (reponame, arch_version)
579 592 mimetype, artype, extension, encoding = web.archive_specs[type_]
580 593 headers = [
581 594 ('Content-Type', mimetype),
582 595 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
583 596 ]
584 597 if encoding:
585 598 headers.append(('Content-Encoding', encoding))
586 599 req.header(headers)
587 600 req.respond(HTTP_OK)
588 601 archival.archive(web.repo, req, cnode, artype, prefix=name)
589 602 return []
590 603
591 604
592 605 def static(web, req, tmpl):
593 606 fname = req.form['file'][0]
594 607 # a repo owner may set web.static in .hg/hgrc to get any file
595 608 # readable by the user running the CGI script
596 609 static = web.config("web", "static", None, untrusted=False)
597 610 if not static:
598 611 tp = web.templatepath
599 612 if isinstance(tp, str):
600 613 tp = [tp]
601 614 static = [os.path.join(p, 'static') for p in tp]
602 615 return [staticfile(static, fname, req)]
603 616
604 617 def graph(web, req, tmpl):
605 618 rev = webutil.changectx(web.repo, req).rev()
606 619 bg_height = 39
607 620
608 621 max_rev = len(web.repo) - 1
609 622 revcount = min(max_rev, int(req.form.get('revcount', [25])[0]))
610 623 revnode = web.repo.changelog.node(rev)
611 624 revnode_hex = hex(revnode)
612 625 uprev = min(max_rev, rev + revcount)
613 626 downrev = max(0, rev - revcount)
614 627 lessrev = max(0, rev - revcount / 2)
615 628
616 629 maxchanges = web.maxshortchanges or web.maxchanges
617 630 count = len(web.repo)
618 631 changenav = webutil.revnavgen(rev, maxchanges, count, web.repo.changectx)
619 632
620 633 tree = list(graphmod.graph(web.repo, rev, downrev))
621 634 canvasheight = (len(tree) + 1) * bg_height - 27;
622 635
623 636 data = []
624 637 for i, (ctx, vtx, edges) in enumerate(tree):
625 638 node = short(ctx.node())
626 639 age = templatefilters.age(ctx.date())
627 640 desc = templatefilters.firstline(ctx.description())
628 641 desc = cgi.escape(desc)
629 642 user = cgi.escape(templatefilters.person(ctx.user()))
630 643 branch = ctx.branch()
631 644 branch = branch, web.repo.branchtags().get(branch) == ctx.node()
632 645 data.append((node, vtx, edges, desc, user, age, branch, ctx.tags()))
633 646
634 647 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
635 648 lessrev=lessrev, revcountmore=revcount and 2 * revcount or 1,
636 649 revcountless=revcount / 2, downrev=downrev,
637 650 canvasheight=canvasheight, bg_height=bg_height,
638 651 jsdata=data, node=revnode_hex, changenav=changenav)
@@ -1,72 +1,72
1 1 default = 'shortlog'
2 2
3 3 mimetype = 'text/html; charset={encoding}'
4 4 header = header.tmpl
5 5 footer = footer.tmpl
6 6 search = search.tmpl
7 7
8 8 changelog = shortlog.tmpl
9 9 shortlog = shortlog.tmpl
10 10 shortlogentry = shortlogentry.tmpl
11 11 graph = graph.tmpl
12 12
13 13 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
14 14 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
15 15 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
16 16 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
17 17 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
18 18 filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
19 19 filenolink = '{file|escape} '
20 20 fileellipses = '...'
21 21 changelogentry = shortlogentry.tmpl
22 22 searchentry = shortlogentry.tmpl
23 23 changeset = changeset.tmpl
24 24 manifest = manifest.tmpl
25 25
26 direntry = '<tr class="fileline parity{parity}"><td class="name"><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}"><img src="{staticurl}coal-folder.png"> {basename|escape}/</a><td class="size"></td><td class="permissions">drwxr-xr-x</td></tr>'
26 direntry = '<tr class="fileline parity{parity}"><td class="name"><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}"><img src="{staticurl}coal-folder.png"> {basename|escape}/</a> <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a><td class="size"></td><td class="permissions">drwxr-xr-x</td></tr>'
27 27 fileentry = '<tr class="fileline parity{parity}"><td class="filename"><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l1"><img src="{staticurl}coal-file.png"> {basename|escape}</a></td><td class="size">{size}</td><td class="permissions">{permissions|permissions}</td></tr>'
28 28
29 29 filerevision = filerevision.tmpl
30 30 fileannotate = fileannotate.tmpl
31 31 filediff = filediff.tmpl
32 32 filelog = filelog.tmpl
33 33 fileline = '<tr class="parity{parity}"><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source">{line|escape}</td></tr>'
34 34 filelogentry = filelogentry.tmpl
35 35
36 36 annotateline = '<tr class="parity{parity}"><td class="annotate"><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#{targetline}" title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a></td><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source">{line|escape}</td></tr>'
37 37
38 38 diffblock = '<table class="bigtable parity{parity}">{lines}</table>'
39 39 difflineplus = '<tr><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source plusline">{line|escape}</td></tr>'
40 40 difflineminus = '<tr><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source minusline">{line|escape}</td></tr>'
41 41 difflineat = '<tr><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source atline">{line|escape}</td></tr>'
42 42 diffline = '<tr><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source">{line|escape}</td></tr>'
43 43
44 44 changelogparent = '<tr><th class="parent">parent {rev}:</th><td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
45 45
46 46 changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
47 47
48 48 filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
49 49 filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
50 50
51 51 filerename = '{file|escape}@'
52 52 filelogrename = '<tr><th>base:</th><td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}@{node|short}</a></td></tr>'
53 53 fileannotateparent = '<tr><td class="metatag">parent:</td><td><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a></td></tr>'
54 54 changesetchild = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
55 55 changelogchild = '<tr><th class="child">child</th><td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
56 56 fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
57 57 tags = tags.tmpl
58 58 tagentry = '<tr class="tagEntry parity{parity}"><td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td><td class="node">{node|short}</td></tr>'
59 59 changelogtag = '<span class="tag">{name|escape}</span> '
60 60 changesettag = '<span class="tag">{tag|escape}</span> '
61 61 filediffparent = '<tr><th class="parent">parent {rev}:</th><td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
62 62 filelogparent = '<tr><th>parent {rev}:</th><td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
63 63 filediffchild = '<tr><th class="child">child {rev}:</th><td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
64 64 filelogchild = '<tr><th>child {rev}:</th><td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
65 65 indexentry = '<tr class="parity{parity}"><td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td><td>{description}</td><td>{contact|obfuscate}</td><td class="age">{lastchange|age} ago</td><td class="indexlinks">{archives%indexarchiveentry}</td></tr>\n'
66 66 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
67 67 index = index.tmpl
68 68 archiveentry = '<li><a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a></li>'
69 69 notfound = notfound.tmpl
70 70 error = error.tmpl
71 71 urlparameter = '{separator}{name}={value|urlescape}'
72 72 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
@@ -1,66 +1,66
1 1 default = 'summary'
2 2 mimetype = 'text/html; charset={encoding}'
3 3 header = header.tmpl
4 4 footer = footer.tmpl
5 5 search = search.tmpl
6 6 changelog = changelog.tmpl
7 7 summary = summary.tmpl
8 8 error = error.tmpl
9 9 notfound = notfound.tmpl
10 10 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
11 11 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
12 12 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
13 13 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
14 14 filedifflink = '<a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#</a> '
15 15 filenodelink = '<tr class="parity#parity#"><td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">#file|escape#</a></td><td></td><td class="link"><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a> | <a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a> | <a href="#url#log/#node|short#/#file|urlescape#{sessionvars%urlparameter}">revisions</a></td></tr>'
16 16 filenolink = '<tr class="parity#parity#"><td><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">#file|escape#</a></td><td></td><td class="link">file | annotate | <a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a> | <a href="#url#log/#node|short#/#file|urlescape#{sessionvars%urlparameter}">revisions</a></td></tr>'
17 17 fileellipses = '...'
18 18 changelogentry = changelogentry.tmpl
19 19 searchentry = changelogentry.tmpl
20 20 changeset = changeset.tmpl
21 21 manifest = manifest.tmpl
22 direntry = '<tr class="parity#parity#"><td style="font-family:monospace">drwxr-xr-x</td><td style="font-family:monospace"></td><td style="font-family:monospace"></td><td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#</a></td><td class="link"><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">files</a></td></tr>'
22 direntry = '<tr class="parity#parity#"><td style="font-family:monospace">drwxr-xr-x</td><td style="font-family:monospace"></td><td style="font-family:monospace"></td><td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#</a> <a href="#url#file/#node|short##path|urlescape#/#emptydirs|urlescape#{sessionvars%urlparameter}">#emptydirs|escape#</a></td><td class="link"><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">files</a></td></tr>'
23 23 fileentry = '<tr class="parity#parity#"><td style="font-family:monospace">#permissions|permissions#</td><td style="font-family:monospace" align=right>#date|isodate#</td><td style="font-family:monospace" align=right>#size#</td><td class="list"><a class="list" href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a></td><td class="link"><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a> | <a href="#url#log/#node|short#/#file|urlescape#{sessionvars%urlparameter}">revisions</a> | <a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a></td></tr>'
24 24 filerevision = filerevision.tmpl
25 25 fileannotate = fileannotate.tmpl
26 26 filediff = filediff.tmpl
27 27 filelog = filelog.tmpl
28 28 fileline = '<div style="font-family:monospace" class="parity#parity#"><pre><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</pre></div>'
29 29 annotateline = '<tr style="font-family:monospace" class="parity#parity#"><td class="linenr" style="text-align: right;"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}#l{targetline}" title="{node|short}: {desc|escape|firstline}">#author|user#@#rev#</a></td><td><pre><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a></pre></td><td><pre>#line|escape#</pre></td></tr>'
30 30 difflineplus = '<span style="color:#008800;"><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</span>'
31 31 difflineminus = '<span style="color:#cc0000;"><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</span>'
32 32 difflineat = '<span style="color:#990099;"><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</span>'
33 33 diffline = '<span><a class="linenr" href="##lineid#" id="#lineid#">#linenumber#</a> #line|escape#</span>'
34 34 changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
35 35 changesetbranch = '<tr><td>branch</td><td>{name}</td></tr>'
36 36 changesetparent = '<tr><td>parent {rev}</td><td style="font-family:monospace"><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
37 37 filerevbranch = '<tr><td>branch</td><td>{name}</td></tr>'
38 38 filerevparent = '<tr><td>parent {rev}</td><td style="font-family:monospace"><a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a></td></tr>'
39 39 filerename = '{file|escape}@'
40 40 filelogrename = '| <a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">base</a>'
41 41 fileannotateparent = '<tr><td>parent {rev}</td><td style="font-family:monospace"><a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a></td></tr>'
42 42 changelogchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
43 43 changesetchild = '<tr><td>child {rev}</td><td style="font-family:monospace"><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
44 44 filerevchild = '<tr><td>child {rev}</td><td style="font-family:monospace"><a class="list" href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
45 45 fileannotatechild = '<tr><td>child {rev}</td><td style="font-family:monospace"><a class="list" href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
46 46 tags = tags.tmpl
47 47 tagentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>#tag|escape#</b></a></td><td class="link"><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}log/#node|short#{sessionvars%urlparameter}">changelog</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">files</a></td></tr>'
48 48 branchentry = '<tr class="parity{parity}"><td class="age"><i>{date|age} ago</i></td><td><a class="list" href="{url}rev/{node|short}{sessionvars%urlparameter}"><b>{node|short}</b></a></td><td>{branch|escape}</td><td class="link"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">changeset</a> | <a href="{url}log/{node|short}{sessionvars%urlparameter}">changelog</a> | <a href="{url}file/{node|short}{sessionvars%urlparameter}">files</a></td></tr>'
49 49 diffblock = '<pre>#lines#</pre>'
50 50 filediffparent = '<tr><td>parent {rev}</td><td style="font-family:monospace"><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
51 51 filelogparent = '<tr><td align="right">parent #rev#:&nbsp;</td><td><a href="{url}file/{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
52 52 filediffchild = '<tr><td>child {rev}</td><td style="font-family:monospace"><a class="list" href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
53 53 filelogchild = '<tr><td align="right">child #rev#:&nbsp;</td><td><a href="{url}file{node|short}/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
54 54 shortlog = shortlog.tmpl
55 55 graph = graph.tmpl
56 56 tagtag = '<span class="tagtag" title="{name}">{name}</span> '
57 57 branchtag = '<span class="branchtag" title="{name}">{name}</span> '
58 58 inbranchtag = '<span class="inbranchtag" title="{name}">{name}</span> '
59 59 shortlogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><i>#author|person#</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b> <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}</span></a></td><td class="link" nowrap><a href="{url}rev/#node|short#{sessionvars%urlparameter}">changeset</a> | <a href="{url}file/#node|short#{sessionvars%urlparameter}">files</a></td></tr>'
60 60 filelogentry = '<tr class="parity#parity#"><td class="age"><i>#date|age# ago</i></td><td><a class="list" href="{url}rev/#node|short#{sessionvars%urlparameter}"><b>#desc|strip|firstline|escape#</b></a></td><td class="link"><a href="{url}file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">file</a>&nbsp;|&nbsp;<a href="{url}diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">diff</a>&nbsp;|&nbsp;<a href="{url}annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">annotate</a> #rename%filelogrename#</td></tr>'
61 61 archiveentry = ' | <a href="{url}archive/{node|short}{extension}">#type|escape#</a> '
62 62 indexentry = '<tr class="parity{parity}"><td><a class="list" href="{url}{sessionvars%urlparameter}"><b>{name|escape}</b></a></td><td>{description}</td><td>{contact|obfuscate}</td><td class="age">{lastchange|age} ago</td><td class="indexlinks">{archives%indexarchiveentry}</td><td><div class="rss_logo"><a href="{url}rss-log">RSS</a> <a href="{url}atom-log">Atom</a></div></td></tr>\n'
63 63 indexarchiveentry = ' <a href="{url}archive/{node|short}{extension}">{type|escape}</a> '
64 64 index = index.tmpl
65 65 urlparameter = '#separator##name#=#value|urlescape#'
66 66 hiddenformentry = '<input type="hidden" name="#name#" value="#value|escape#" />'
@@ -1,60 +1,60
1 1 default = 'shortlog'
2 2 mimetype = 'text/html; charset={encoding}'
3 3 header = header.tmpl
4 4 footer = footer.tmpl
5 5 search = search.tmpl
6 6 changelog = changelog.tmpl
7 7 shortlog = shortlog.tmpl
8 8 shortlogentry = shortlogentry.tmpl
9 9 graph = graph.tmpl
10 10 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
11 11 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
12 12 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
13 13 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
14 14 filedifflink = '<a href="#url#diff/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#</a> '
15 15 filenodelink = '<a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#</a> '
16 16 filenolink = '{file|escape} '
17 17 fileellipses = '...'
18 18 changelogentry = changelogentry.tmpl
19 19 searchentry = changelogentry.tmpl
20 20 changeset = changeset.tmpl
21 21 manifest = manifest.tmpl
22 direntry = '<tr class="parity#parity#"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#/</a>'
22 direntry = '<tr class="parity#parity#"><td><tt>drwxr-xr-x</tt>&nbsp;<td>&nbsp;<td>&nbsp;<td><a href="#url#file/#node|short##path|urlescape#{sessionvars%urlparameter}">#basename|escape#/</a> <a href="#url#file/#node|short##path|urlescape#/#emptydirs|urlescape#{sessionvars%urlparameter}">#emptydirs|urlescape#</a>'
23 23 fileentry = '<tr class="parity#parity#"><td><tt>#permissions|permissions#</tt>&nbsp;<td align=right><tt class="date">#date|isodate#</tt>&nbsp;<td align=right><tt>#size#</tt>&nbsp;<td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#basename|escape#</a>'
24 24 filerevision = filerevision.tmpl
25 25 fileannotate = fileannotate.tmpl
26 26 filediff = filediff.tmpl
27 27 filelog = filelog.tmpl
28 28 fileline = '<div class="parity#parity#"><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#</div>'
29 29 filelogentry = filelogentry.tmpl
30 30 annotateline = '<tr class="parity#parity#"><td class="annotate"><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}#l{targetline}" title="{node|short}: {desc|escape|firstline}">#author|user#@#rev#</a></td><td><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a></td><td><pre>#line|escape#</pre></td></tr>'
31 31 difflineplus = '<span class="plusline"><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#</span>'
32 32 difflineminus = '<span class="minusline"><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#</span>'
33 33 difflineat = '<span class="atline"><a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#</span>'
34 34 diffline = '<a class="lineno" href="##lineid#" id="#lineid#">#linenumber#</a>#line|escape#'
35 35 changelogparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
36 36 changesetparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
37 37 filerevparent = '<tr><td class="metatag">parent:</td><td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a></td></tr>'
38 38 filerename = '{file|escape}@'
39 39 filelogrename = '<tr><th>base:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#file|escape#@#node|short#</a></td></tr>'
40 40 fileannotateparent = '<tr><td class="metatag">parent:</td><td><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a></td></tr>'
41 41 changesetchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
42 42 changelogchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
43 43 filerevchild = '<tr><td class="metatag">child:</td><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
44 44 fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="#url#annotate/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
45 45 tags = tags.tmpl
46 46 tagentry = '<li class="tagEntry parity#parity#"><tt class="node">#node#</tt> <a href="#url#rev/#node|short#{sessionvars%urlparameter}">#tag|escape#</a></li>'
47 47 diffblock = '<pre class="parity#parity#">#lines#</pre>'
48 48 changelogtag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
49 49 changesettag = '<tr><th class="tag">tag:</th><td class="tag">#tag|escape#</td></tr>'
50 50 filediffparent = '<tr><th class="parent">parent #rev#:</th><td class="parent"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
51 51 filelogparent = '<tr><th>parent #rev#:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
52 52 filediffchild = '<tr><th class="child">child #rev#:</th><td class="child"><a href="#url#rev/#node|short#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
53 53 filelogchild = '<tr><th>child #rev#:</th><td><a href="#url#file/#node|short#/#file|urlescape#{sessionvars%urlparameter}">#node|short#</a></td></tr>'
54 54 indexentry = '<tr class="parity#parity#"><td><a href="#url#{sessionvars%urlparameter}">#name|escape#</a></td><td>#description#</td><td>#contact|obfuscate#</td><td class="age">#lastchange|age# ago</td><td class="indexlinks"><a href="#url#rss-log">RSS</a> <a href="#url#atom-log">Atom</a> #archives%archiveentry#</td></tr>'
55 55 index = index.tmpl
56 56 archiveentry = '<a href="#url#archive/#node|short##extension|urlescape#">#type|escape#</a> '
57 57 notfound = notfound.tmpl
58 58 error = error.tmpl
59 59 urlparameter = '#separator##name#=#value|urlescape#'
60 60 hiddenformentry = '<input type="hidden" name="#name#" value="#value|escape#" />'
@@ -1,73 +1,73
1 1 default = 'shortlog'
2 2
3 3 mimetype = 'text/html; charset={encoding}'
4 4 header = header.tmpl
5 5 footer = ../coal/footer.tmpl
6 6 search = ../coal/search.tmpl
7 7
8 8 changelog = ../coal/shortlog.tmpl
9 9 shortlog = ../coal/shortlog.tmpl
10 10 shortlogentry = ../coal/shortlogentry.tmpl
11 11 graph = ../coal/graph.tmpl
12 12
13 13 naventry = '<a href="{url}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
14 14 navshortentry = '<a href="{url}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
15 15 navgraphentry = '<a href="{url}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
16 16 filenaventry = '<a href="{url}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
17 17 filedifflink = '<a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
18 18 filenodelink = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
19 19 filenolink = '{file|escape} '
20 20 fileellipses = '...'
21 21 changelogentry = ../coal/shortlogentry.tmpl
22 22 searchentry = ../coal/shortlogentry.tmpl
23 23 changeset = ../coal/changeset.tmpl
24 24 manifest = ../coal/manifest.tmpl
25 25
26 direntry = '<tr class="fileline parity{parity}"><td class="name"><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}"><img src="{staticurl}coal-folder.png"> {basename|escape}/</a><td class="size"></td><td class="permissions">drwxr-xr-x</td></tr>'
26 direntry = '<tr class="fileline parity{parity}"><td class="name"><a href="{url}file/{node|short}{path|urlescape}{sessionvars%urlparameter}"><img src="{staticurl}coal-folder.png"> {basename|escape}/</a> <a href="{url}file/{node|short}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a><td class="size"></td><td class="permissions">drwxr-xr-x</td></tr>'
27 27 fileentry = '<tr class="fileline parity{parity}"><td class="filename"><a href="{url}file/{node|short}/{file|urlescape}#l1{sessionvars%urlparameter}"><img src="{staticurl}coal-file.png"> {basename|escape}</a></td><td class="size">{size}</td><td class="permissions">{permissions|permissions}</td></tr>'
28 28
29 29 filerevision = ../coal/filerevision.tmpl
30 30 fileannotate = ../coal/fileannotate.tmpl
31 31 filediff = ../coal/filediff.tmpl
32 32 filelog = ../coal/filelog.tmpl
33 33 fileline = '<tr class="parity{parity}"><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source">{line|escape}</td></tr>'
34 34 filelogentry = ../coal/filelogentry.tmpl
35 35
36 36 annotateline = '<tr class="parity{parity}"><td class="annotate"><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#{targetline}" title="{node|short}: {desc|escape|firstline}">{author|user}@{rev}</a></td><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source">{line|escape}</td></tr>'
37 37
38 38 diffblock = '<table class="bigtable parity{parity}">{lines}</table>'
39 39 difflineplus = '<tr><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source plusline">{line|escape}</td></tr>'
40 40 difflineminus = '<tr><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source minusline">{line|escape}</td></tr>'
41 41 difflineat = '<tr><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source atline">{line|escape}</td></tr>'
42 42 diffline = '<tr><td class="lineno"><a href="#{lineid}" id="{lineid}">{linenumber}</a></td><td class="source">{line|escape}</td></tr>'
43 43
44 44 changelogparent = '<tr><th class="parent">parent {rev}:</th><td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
45 45
46 46 changesetparent = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
47 47
48 48 filerevparent = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
49 49 filerevchild = '<a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
50 50
51 51 filerename = '{file|escape}@'
52 52 filelogrename = '<tr><th>base:</th><td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}@{node|short}</a></td></tr>'
53 53 fileannotateparent = '<tr><td class="metatag">parent:</td><td><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a></td></tr>'
54 54 changesetchild = '<a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
55 55 changelogchild = '<tr><th class="child">child</th><td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
56 56 fileannotatechild = '<tr><td class="metatag">child:</td><td><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
57 57 tags = ../coal/tags.tmpl
58 58 tagentry = '<tr class="tagEntry parity{parity}"><td><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{tag|escape}</a></td><td class="node">{node|short}</td></tr>'
59 59 changelogtag = '<tr><th class="tag">tag:</th><td class="tag">{tag|escape}</td></tr>'
60 60 changelogtag = '<span class="tag">{name|escape}</span> '
61 61 changesettag = '<span class="tag">{tag|escape}</span> '
62 62 filediffparent = '<tr><th class="parent">parent {rev}:</th><td class="parent"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
63 63 filelogparent = '<tr><th>parent {rev}:</th><td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
64 64 filediffchild = '<tr><th class="child">child {rev}:</th><td class="child"><a href="{url}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
65 65 filelogchild = '<tr><th>child {rev}:</th><td><a href="{url}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td></tr>'
66 66 indexentry = '<tr class="parity{parity}"><td><a href="{url}{sessionvars%urlparameter}">{name|escape}</a></td><td>{description}</td><td>{contact|obfuscate}</td><td class="age">{lastchange|age} ago</td><td class="indexlinks">{archives%indexarchiveentry}</td></tr>\n'
67 67 indexarchiveentry = '<a href="{url}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
68 68 index = ../coal/index.tmpl
69 69 archiveentry = '<li><a href="{url}archive/{node|short}{extension|urlescape}">{type|escape}</a></li>'
70 70 notfound = ../coal/notfound.tmpl
71 71 error = ../coal/error.tmpl
72 72 urlparameter = '{separator}{name}={value|urlescape}'
73 73 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
General Comments 0
You need to be logged in to leave comments. Login now