comparison mercurial/hgweb/hgweb_mod.py @ 5600:9d900f7282e6

hgweb: explicitly pass around the templater
author Dirkjan Ochtman <dirkjan@ochtman.nl>
date Mon, 03 Dec 2007 13:30:08 +0100
parents 3de66c2a9734
children 652f57de3ccf
comparison
equal deleted inserted replaced
5599:3de66c2a9734 5600:9d900f7282e6
196 req.form['node'] = [fn[:-len(ext)]] 196 req.form['node'] = [fn[:-len(ext)]]
197 req.form['type'] = [type_] 197 req.form['type'] = [type_]
198 198
199 # actually process the request 199 # actually process the request
200 200
201 self.templater(req)
202 try: 201 try:
203 if not req.form.has_key('cmd'): 202
204 req.form['cmd'] = [self.t.cache['default']] 203 cmd = req.form.get('cmd', [''])[0]
205 204 if hasattr(protocol, cmd):
206 cmd = req.form['cmd'][0] 205 method = getattr(protocol, cmd)
207
208 try:
209 if hasattr(protocol, cmd):
210 method = getattr(protocol, cmd)
211 else:
212 method = getattr(webcommands, cmd)
213 method(self, req) 206 method(self, req)
214 except revlog.LookupError, err: 207 else:
215 req.respond(404, self.t( 208 tmpl = self.templater(req)
216 'error', error='revision not found: %s' % err.name)) 209 if cmd == '':
217 except (hg.RepoError, revlog.RevlogError), inst: 210 req.form['cmd'] = [tmpl.cache['default']]
218 req.respond('500 Internal Server Error', 211 cmd = req.form['cmd'][0]
219 self.t('error', error=str(inst))) 212 method = getattr(webcommands, cmd)
220 except ErrorResponse, inst: 213 method(self, req, tmpl)
221 req.respond(inst.code, self.t('error', error=inst.message)) 214 del tmpl
222 except AttributeError: 215
223 req.respond(400, 216 except revlog.LookupError, err:
224 self.t('error', error='No such method: ' + cmd)) 217 req.respond(404, tmpl(
225 finally: 218 'error', error='revision not found: %s' % err.name))
226 self.t = None 219 except (hg.RepoError, revlog.RevlogError), inst:
220 req.respond('500 Internal Server Error',
221 tmpl('error', error=str(inst)))
222 except ErrorResponse, inst:
223 req.respond(inst.code, tmpl('error', error=inst.message))
224 except AttributeError:
225 req.respond(400, tmpl('error', error='No such method: ' + cmd))
227 226
228 def templater(self, req): 227 def templater(self, req):
229 228
230 # determine scheme, port and server name 229 # determine scheme, port and server name
231 # this is needed to create absolute urls 230 # this is needed to create absolute urls
247 246
248 # some functions for the templater 247 # some functions for the templater
249 248
250 def header(**map): 249 def header(**map):
251 header_file = cStringIO.StringIO( 250 header_file = cStringIO.StringIO(
252 ''.join(self.t("header", encoding=self.encoding, **map))) 251 ''.join(tmpl("header", encoding=self.encoding, **map)))
253 msg = mimetools.Message(header_file, 0) 252 msg = mimetools.Message(header_file, 0)
254 req.header(msg.items()) 253 req.header(msg.items())
255 yield header_file.read() 254 yield header_file.read()
256 255
257 def rawfileheader(**map): 256 def rawfileheader(**map):
259 ('Content-disposition', 'filename=%s' % map['file']), 258 ('Content-disposition', 'filename=%s' % map['file']),
260 ('Content-length', str(len(map['raw'])))]) 259 ('Content-length', str(len(map['raw'])))])
261 yield '' 260 yield ''
262 261
263 def footer(**map): 262 def footer(**map):
264 yield self.t("footer", **map) 263 yield tmpl("footer", **map)
265 264
266 def motd(**map): 265 def motd(**map):
267 yield self.config("web", "motd", "") 266 yield self.config("web", "motd", "")
268 267
269 def sessionvars(**map): 268 def sessionvars(**map):
290 or req.env.get('REPO_NAME') 289 or req.env.get('REPO_NAME')
291 or req.url.strip('/') or self.repo.root) 290 or req.url.strip('/') or self.repo.root)
292 291
293 # create the templater 292 # create the templater
294 293
295 self.t = templater.templater(mapfile, templater.common_filters, 294 tmpl = templater.templater(mapfile, templater.common_filters,
296 defaults={"url": req.url, 295 defaults={"url": req.url,
297 "staticurl": staticurl, 296 "staticurl": staticurl,
298 "urlbase": urlbase, 297 "urlbase": urlbase,
299 "repo": self.reponame, 298 "repo": self.reponame,
300 "header": header, 299 "header": header,
301 "footer": footer, 300 "footer": footer,
302 "motd": motd, 301 "motd": motd,
303 "rawfileheader": rawfileheader, 302 "rawfileheader": rawfileheader,
304 "sessionvars": sessionvars 303 "sessionvars": sessionvars
305 }) 304 })
305 return tmpl
306 306
307 def archivelist(self, nodeid): 307 def archivelist(self, nodeid):
308 allowed = self.configlist("web", "allow_archive") 308 allowed = self.configlist("web", "allow_archive")
309 for i, spec in self.archive_specs.iteritems(): 309 for i, spec in self.archive_specs.iteritems():
310 if i in allowed or self.configbool("web", "allow" + i): 310 if i in allowed or self.configbool("web", "allow" + i):
311 yield {"type" : i, "extension" : spec[2], "node" : nodeid} 311 yield {"type" : i, "extension" : spec[2], "node" : nodeid}
312 312
313 def listfilediffs(self, files, changeset): 313 def listfilediffs(self, tmpl, files, changeset):
314 for f in files[:self.maxfiles]: 314 for f in files[:self.maxfiles]:
315 yield self.t("filedifflink", node=hex(changeset), file=f) 315 yield tmpl("filedifflink", node=hex(changeset), file=f)
316 if len(files) > self.maxfiles: 316 if len(files) > self.maxfiles:
317 yield self.t("fileellipses") 317 yield tmpl("fileellipses")
318 318
319 def siblings(self, siblings=[], hiderev=None, **args): 319 def siblings(self, siblings=[], hiderev=None, **args):
320 siblings = [s for s in siblings if s.node() != nullid] 320 siblings = [s for s in siblings if s.node() != nullid]
321 if len(siblings) == 1 and siblings[0].rev() == hiderev: 321 if len(siblings) == 1 and siblings[0].rev() == hiderev:
322 return 322 return
344 # an empty dict. Using dict.get avoids a traceback. 344 # an empty dict. Using dict.get avoids a traceback.
345 if self.repo.branchtags().get(branch) == ctx.node(): 345 if self.repo.branchtags().get(branch) == ctx.node():
346 branches.append({"name": branch}) 346 branches.append({"name": branch})
347 return branches 347 return branches
348 348
349 def showtag(self, t1, node=nullid, **args): 349 def showtag(self, tmpl, t1, node=nullid, **args):
350 for t in self.repo.nodetags(node): 350 for t in self.repo.nodetags(node):
351 yield self.t(t1, tag=t, **args) 351 yield tmpl(t1, tag=t, **args)
352 352
353 def diff(self, node1, node2, files): 353 def diff(self, tmpl, node1, node2, files):
354 def filterfiles(filters, files): 354 def filterfiles(filters, files):
355 l = [x for x in files if x in filters] 355 l = [x for x in files if x in filters]
356 356
357 for t in filters: 357 for t in filters:
358 if t and t[-1] != os.sep: 358 if t and t[-1] != os.sep:
360 l += [x for x in files if x.startswith(t)] 360 l += [x for x in files if x.startswith(t)]
361 return l 361 return l
362 362
363 parity = paritygen(self.stripecount) 363 parity = paritygen(self.stripecount)
364 def diffblock(diff, f, fn): 364 def diffblock(diff, f, fn):
365 yield self.t("diffblock", 365 yield tmpl("diffblock",
366 lines=prettyprintlines(diff), 366 lines=prettyprintlines(diff),
367 parity=parity.next(), 367 parity=parity.next(),
368 file=f, 368 file=f,
369 filenode=hex(fn or nullid)) 369 filenode=hex(fn or nullid))
370 370
371 def prettyprintlines(diff): 371 def prettyprintlines(diff):
372 for l in diff.splitlines(1): 372 for l in diff.splitlines(1):
373 if l.startswith('+'): 373 if l.startswith('+'):
374 yield self.t("difflineplus", line=l) 374 yield tmpl("difflineplus", line=l)
375 elif l.startswith('-'): 375 elif l.startswith('-'):
376 yield self.t("difflineminus", line=l) 376 yield tmpl("difflineminus", line=l)
377 elif l.startswith('@'): 377 elif l.startswith('@'):
378 yield self.t("difflineat", line=l) 378 yield tmpl("difflineat", line=l)
379 else: 379 else:
380 yield self.t("diffline", line=l) 380 yield tmpl("diffline", line=l)
381 381
382 r = self.repo 382 r = self.repo
383 c1 = r.changectx(node1) 383 c1 = r.changectx(node1)
384 c2 = r.changectx(node2) 384 c2 = r.changectx(node2)
385 date1 = util.datestr(c1.date()) 385 date1 = util.datestr(c1.date())
405 to = c1.filectx(f).data() 405 to = c1.filectx(f).data()
406 tn = None 406 tn = None
407 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f, 407 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
408 opts=diffopts), f, tn) 408 opts=diffopts), f, tn)
409 409
410 def changelog(self, ctx, shortlog=False): 410 def changelog(self, tmpl, ctx, shortlog=False):
411 def changelist(limit=0,**map): 411 def changelist(limit=0,**map):
412 cl = self.repo.changelog 412 cl = self.repo.changelog
413 l = [] # build a list in forward order for efficiency 413 l = [] # build a list in forward order for efficiency
414 for i in xrange(start, end): 414 for i in xrange(start, end):
415 ctx = self.repo.changectx(i) 415 ctx = self.repo.changectx(i)
420 "parent": self.siblings(ctx.parents(), i - 1), 420 "parent": self.siblings(ctx.parents(), i - 1),
421 "child": self.siblings(ctx.children(), i + 1), 421 "child": self.siblings(ctx.children(), i + 1),
422 "changelogtag": self.showtag("changelogtag",n), 422 "changelogtag": self.showtag("changelogtag",n),
423 "desc": ctx.description(), 423 "desc": ctx.description(),
424 "date": ctx.date(), 424 "date": ctx.date(),
425 "files": self.listfilediffs(ctx.files(), n), 425 "files": self.listfilediffs(tmpl, ctx.files(), n),
426 "rev": i, 426 "rev": i,
427 "node": hex(n), 427 "node": hex(n),
428 "tags": self.nodetagsdict(n), 428 "tags": self.nodetagsdict(n),
429 "branches": self.nodebranchdict(ctx)}) 429 "branches": self.nodebranchdict(ctx)})
430 430
443 pos = end - 1 443 pos = end - 1
444 parity = paritygen(self.stripecount, offset=start-end) 444 parity = paritygen(self.stripecount, offset=start-end)
445 445
446 changenav = revnavgen(pos, maxchanges, count, self.repo.changectx) 446 changenav = revnavgen(pos, maxchanges, count, self.repo.changectx)
447 447
448 yield self.t(shortlog and 'shortlog' or 'changelog', 448 yield tmpl(shortlog and 'shortlog' or 'changelog',
449 changenav=changenav, 449 changenav=changenav,
450 node=hex(cl.tip()), 450 node=hex(cl.tip()),
451 rev=pos, changesets=count, 451 rev=pos, changesets=count,
452 entries=lambda **x: changelist(limit=0,**x), 452 entries=lambda **x: changelist(limit=0,**x),
453 latestentry=lambda **x: changelist(limit=1,**x), 453 latestentry=lambda **x: changelist(limit=1,**x),
454 archives=self.archivelist("tip")) 454 archives=self.archivelist("tip"))
455 455
456 def search(self, query): 456 def search(self, tmpl, query):
457 457
458 def changelist(**map): 458 def changelist(**map):
459 cl = self.repo.changelog 459 cl = self.repo.changelog
460 count = 0 460 count = 0
461 qw = query.lower().split() 461 qw = query.lower().split()
482 continue 482 continue
483 483
484 count += 1 484 count += 1
485 n = ctx.node() 485 n = ctx.node()
486 486
487 yield self.t('searchentry', 487 yield tmpl('searchentry',
488 parity=parity.next(), 488 parity=parity.next(),
489 author=ctx.user(), 489 author=ctx.user(),
490 parent=self.siblings(ctx.parents()), 490 parent=self.siblings(ctx.parents()),
491 child=self.siblings(ctx.children()), 491 child=self.siblings(ctx.children()),
492 changelogtag=self.showtag("changelogtag",n), 492 changelogtag=self.showtag("changelogtag",n),
493 desc=ctx.description(), 493 desc=ctx.description(),
494 date=ctx.date(), 494 date=ctx.date(),
495 files=self.listfilediffs(ctx.files(), n), 495 files=self.listfilediffs(tmpl, ctx.files(), n),
496 rev=ctx.rev(), 496 rev=ctx.rev(),
497 node=hex(n), 497 node=hex(n),
498 tags=self.nodetagsdict(n), 498 tags=self.nodetagsdict(n),
499 branches=self.nodebranchdict(ctx)) 499 branches=self.nodebranchdict(ctx))
500 500
501 if count >= self.maxchanges: 501 if count >= self.maxchanges:
502 break 502 break
503 503
504 cl = self.repo.changelog 504 cl = self.repo.changelog
505 parity = paritygen(self.stripecount) 505 parity = paritygen(self.stripecount)
506 506
507 yield self.t('search', 507 yield tmpl('search',
508 query=query, 508 query=query,
509 node=hex(cl.tip()), 509 node=hex(cl.tip()),
510 entries=changelist, 510 entries=changelist,
511 archives=self.archivelist("tip")) 511 archives=self.archivelist("tip"))
512 512
513 def changeset(self, ctx): 513 def changeset(self, tmpl, ctx):
514 n = ctx.node() 514 n = ctx.node()
515 parents = ctx.parents() 515 parents = ctx.parents()
516 p1 = parents[0].node() 516 p1 = parents[0].node()
517 517
518 files = [] 518 files = []
519 parity = paritygen(self.stripecount) 519 parity = paritygen(self.stripecount)
520 for f in ctx.files(): 520 for f in ctx.files():
521 files.append(self.t("filenodelink", 521 files.append(tmpl("filenodelink",
522 node=hex(n), file=f, 522 node=hex(n), file=f,
523 parity=parity.next())) 523 parity=parity.next()))
524 524
525 def diff(**map): 525 def diff(**map):
526 yield self.diff(p1, n, None) 526 yield self.diff(tmpl, p1, n, None)
527 527
528 yield self.t('changeset', 528 yield tmpl('changeset',
529 diff=diff, 529 diff=diff,
530 rev=ctx.rev(), 530 rev=ctx.rev(),
531 node=hex(n), 531 node=hex(n),
532 parent=self.siblings(parents), 532 parent=self.siblings(parents),
533 child=self.siblings(ctx.children()), 533 child=self.siblings(ctx.children()),
534 changesettag=self.showtag("changesettag",n), 534 changesettag=self.showtag("changesettag",n),
535 author=ctx.user(), 535 author=ctx.user(),
536 desc=ctx.description(), 536 desc=ctx.description(),
537 date=ctx.date(), 537 date=ctx.date(),
538 files=files, 538 files=files,
539 archives=self.archivelist(hex(n)), 539 archives=self.archivelist(hex(n)),
540 tags=self.nodetagsdict(n), 540 tags=self.nodetagsdict(n),
541 branches=self.nodebranchdict(ctx)) 541 branches=self.nodebranchdict(ctx))
542 542
543 def filelog(self, fctx): 543 def filelog(self, tmpl, fctx):
544 f = fctx.path() 544 f = fctx.path()
545 fl = fctx.filelog() 545 fl = fctx.filelog()
546 count = fl.count() 546 count = fl.count()
547 pagelen = self.maxshortchanges 547 pagelen = self.maxshortchanges
548 pos = fctx.filerev() 548 pos = fctx.filerev()
575 for e in l: 575 for e in l:
576 yield e 576 yield e
577 577
578 nodefunc = lambda x: fctx.filectx(fileid=x) 578 nodefunc = lambda x: fctx.filectx(fileid=x)
579 nav = revnavgen(pos, pagelen, count, nodefunc) 579 nav = revnavgen(pos, pagelen, count, nodefunc)
580 yield self.t("filelog", file=f, node=hex(fctx.node()), nav=nav, 580 yield tmpl("filelog", file=f, node=hex(fctx.node()), nav=nav,
581 entries=lambda **x: entries(limit=0, **x), 581 entries=lambda **x: entries(limit=0, **x),
582 latestentry=lambda **x: entries(limit=1, **x)) 582 latestentry=lambda **x: entries(limit=1, **x))
583 583
584 def filerevision(self, fctx): 584 def filerevision(self, tmpl, fctx):
585 f = fctx.path() 585 f = fctx.path()
586 text = fctx.data() 586 text = fctx.data()
587 fl = fctx.filelog() 587 fl = fctx.filelog()
588 n = fctx.filenode() 588 n = fctx.filenode()
589 parity = paritygen(self.stripecount) 589 parity = paritygen(self.stripecount)
599 for l, t in enumerate(text.splitlines(1)): 599 for l, t in enumerate(text.splitlines(1)):
600 yield {"line": t, 600 yield {"line": t,
601 "linenumber": "% 6d" % (l + 1), 601 "linenumber": "% 6d" % (l + 1),
602 "parity": parity.next()} 602 "parity": parity.next()}
603 603
604 yield self.t("filerevision", 604 yield tmpl("filerevision",
605 file=f, 605 file=f,
606 path=_up(f), 606 path=_up(f),
607 text=lines(), 607 text=lines(),
608 raw=rawtext, 608 raw=rawtext,
609 mimetype=mt, 609 mimetype=mt,
610 rev=fctx.rev(), 610 rev=fctx.rev(),
611 node=hex(fctx.node()), 611 node=hex(fctx.node()),
612 author=fctx.user(), 612 author=fctx.user(),
613 date=fctx.date(), 613 date=fctx.date(),
614 desc=fctx.description(), 614 desc=fctx.description(),
615 parent=self.siblings(fctx.parents()), 615 parent=self.siblings(fctx.parents()),
616 child=self.siblings(fctx.children()), 616 child=self.siblings(fctx.children()),
617 rename=self.renamelink(fl, n), 617 rename=self.renamelink(fl, n),
618 permissions=fctx.manifest().flags(f)) 618 permissions=fctx.manifest().flags(f))
619 619
620 def fileannotate(self, fctx): 620 def fileannotate(self, tmpl, fctx):
621 f = fctx.path() 621 f = fctx.path()
622 n = fctx.filenode() 622 n = fctx.filenode()
623 fl = fctx.filelog() 623 fl = fctx.filelog()
624 parity = paritygen(self.stripecount) 624 parity = paritygen(self.stripecount)
625 625
637 "rev": f.rev(), 637 "rev": f.rev(),
638 "author": name, 638 "author": name,
639 "file": f.path(), 639 "file": f.path(),
640 "line": l} 640 "line": l}
641 641
642 yield self.t("fileannotate", 642 yield tmpl("fileannotate",
643 file=f, 643 file=f,
644 annotate=annotate, 644 annotate=annotate,
645 path=_up(f), 645 path=_up(f),
646 rev=fctx.rev(), 646 rev=fctx.rev(),
647 node=hex(fctx.node()), 647 node=hex(fctx.node()),
648 author=fctx.user(), 648 author=fctx.user(),
649 date=fctx.date(), 649 date=fctx.date(),
650 desc=fctx.description(), 650 desc=fctx.description(),
651 rename=self.renamelink(fl, n), 651 rename=self.renamelink(fl, n),
652 parent=self.siblings(fctx.parents()), 652 parent=self.siblings(fctx.parents()),
653 child=self.siblings(fctx.children()), 653 child=self.siblings(fctx.children()),
654 permissions=fctx.manifest().flags(f)) 654 permissions=fctx.manifest().flags(f))
655 655
656 def manifest(self, ctx, path): 656 def manifest(self, tmpl, ctx, path):
657 mf = ctx.manifest() 657 mf = ctx.manifest()
658 node = ctx.node() 658 node = ctx.node()
659 659
660 files = {} 660 files = {}
661 parity = paritygen(self.stripecount) 661 parity = paritygen(self.stripecount)
705 705
706 yield {"parity": parity.next(), 706 yield {"parity": parity.next(),
707 "path": "%s%s" % (abspath, f), 707 "path": "%s%s" % (abspath, f),
708 "basename": f[:-1]} 708 "basename": f[:-1]}
709 709
710 yield self.t("manifest", 710 yield tmpl("manifest",
711 rev=ctx.rev(), 711 rev=ctx.rev(),
712 node=hex(node), 712 node=hex(node),
713 path=abspath, 713 path=abspath,
714 up=_up(abspath), 714 up=_up(abspath),
715 upparity=parity.next(), 715 upparity=parity.next(),
716 fentries=filelist, 716 fentries=filelist,
717 dentries=dirlist, 717 dentries=dirlist,
718 archives=self.archivelist(hex(node)), 718 archives=self.archivelist(hex(node)),
719 tags=self.nodetagsdict(node), 719 tags=self.nodetagsdict(node),
720 branches=self.nodebranchdict(ctx)) 720 branches=self.nodebranchdict(ctx))
721 721
722 def tags(self): 722 def tags(self, tmpl):
723 i = self.repo.tagslist() 723 i = self.repo.tagslist()
724 i.reverse() 724 i.reverse()
725 parity = paritygen(self.stripecount) 725 parity = paritygen(self.stripecount)
726 726
727 def entries(notip=False,limit=0, **map): 727 def entries(notip=False,limit=0, **map):
735 yield {"parity": parity.next(), 735 yield {"parity": parity.next(),
736 "tag": k, 736 "tag": k,
737 "date": self.repo.changectx(n).date(), 737 "date": self.repo.changectx(n).date(),
738 "node": hex(n)} 738 "node": hex(n)}
739 739
740 yield self.t("tags", 740 yield tmpl("tags",
741 node=hex(self.repo.changelog.tip()), 741 node=hex(self.repo.changelog.tip()),
742 entries=lambda **x: entries(False,0, **x), 742 entries=lambda **x: entries(False,0, **x),
743 entriesnotip=lambda **x: entries(True,0, **x), 743 entriesnotip=lambda **x: entries(True,0, **x),
744 latestentry=lambda **x: entries(True,1, **x)) 744 latestentry=lambda **x: entries(True,1, **x))
745 745
746 def summary(self): 746 def summary(self, tmpl):
747 i = self.repo.tagslist() 747 i = self.repo.tagslist()
748 i.reverse() 748 i.reverse()
749 749
750 def tagentries(**map): 750 def tagentries(**map):
751 parity = paritygen(self.stripecount) 751 parity = paritygen(self.stripecount)
756 756
757 count += 1 757 count += 1
758 if count > 10: # limit to 10 tags 758 if count > 10: # limit to 10 tags
759 break; 759 break;
760 760
761 yield self.t("tagentry", 761 yield tmpl("tagentry",
762 parity=parity.next(), 762 parity=parity.next(),
763 tag=k, 763 tag=k,
764 node=hex(n), 764 node=hex(n),
765 date=self.repo.changectx(n).date()) 765 date=self.repo.changectx(n).date())
766 766
767 767
768 def branches(**map): 768 def branches(**map):
769 parity = paritygen(self.stripecount) 769 parity = paritygen(self.stripecount)
770 770
786 for i in xrange(start, end): 786 for i in xrange(start, end):
787 ctx = self.repo.changectx(i) 787 ctx = self.repo.changectx(i)
788 n = ctx.node() 788 n = ctx.node()
789 hn = hex(n) 789 hn = hex(n)
790 790
791 l.insert(0, self.t( 791 l.insert(0, tmpl(
792 'shortlogentry', 792 'shortlogentry',
793 parity=parity.next(), 793 parity=parity.next(),
794 author=ctx.user(), 794 author=ctx.user(),
795 desc=ctx.description(), 795 desc=ctx.description(),
796 date=ctx.date(), 796 date=ctx.date(),
797 rev=i, 797 rev=i,
804 cl = self.repo.changelog 804 cl = self.repo.changelog
805 count = cl.count() 805 count = cl.count()
806 start = max(0, count - self.maxchanges) 806 start = max(0, count - self.maxchanges)
807 end = min(count, start + self.maxchanges) 807 end = min(count, start + self.maxchanges)
808 808
809 yield self.t("summary", 809 yield tmpl("summary",
810 desc=self.config("web", "description", "unknown"), 810 desc=self.config("web", "description", "unknown"),
811 owner=(self.config("ui", "username") or # preferred 811 owner=(self.config("ui", "username") or # preferred
812 self.config("web", "contact") or # deprecated 812 self.config("web", "contact") or # deprecated
813 self.config("web", "author", "unknown")), # also 813 self.config("web", "author", "unknown")), # also
814 lastchange=cl.read(cl.tip())[2], 814 lastchange=cl.read(cl.tip())[2],
815 tags=tagentries, 815 tags=tagentries,
816 branches=branches, 816 branches=branches,
817 shortlog=changelist, 817 shortlog=changelist,
818 node=hex(cl.tip()), 818 node=hex(cl.tip()),
819 archives=self.archivelist("tip")) 819 archives=self.archivelist("tip"))
820 820
821 def filediff(self, fctx): 821 def filediff(self, tmpl, fctx):
822 n = fctx.node() 822 n = fctx.node()
823 path = fctx.path() 823 path = fctx.path()
824 parents = fctx.parents() 824 parents = fctx.parents()
825 p1 = parents and parents[0].node() or nullid 825 p1 = parents and parents[0].node() or nullid
826 826
827 def diff(**map): 827 def diff(**map):
828 yield self.diff(p1, n, [path]) 828 yield self.diff(tmpl, p1, n, [path])
829 829
830 yield self.t("filediff", 830 yield tmpl("filediff",
831 file=path, 831 file=path,
832 node=hex(n), 832 node=hex(n),
833 rev=fctx.rev(), 833 rev=fctx.rev(),
834 parent=self.siblings(parents), 834 parent=self.siblings(parents),
835 child=self.siblings(fctx.children()), 835 child=self.siblings(fctx.children()),
836 diff=diff) 836 diff=diff)
837 837
838 archive_specs = { 838 archive_specs = {
839 'bz2': ('application/x-tar', 'tbz2', '.tar.bz2', None), 839 'bz2': ('application/x-tar', 'tbz2', '.tar.bz2', None),
840 'gz': ('application/x-tar', 'tgz', '.tar.gz', None), 840 'gz': ('application/x-tar', 'tgz', '.tar.gz', None),
841 'zip': ('application/zip', 'zip', '.zip', None), 841 'zip': ('application/zip', 'zip', '.zip', None),
842 } 842 }
843 843
844 def archive(self, req, key, type_): 844 def archive(self, tmpl, req, key, type_):
845 reponame = re.sub(r"\W+", "-", os.path.basename(self.reponame)) 845 reponame = re.sub(r"\W+", "-", os.path.basename(self.reponame))
846 cnode = self.repo.lookup(key) 846 cnode = self.repo.lookup(key)
847 arch_version = key 847 arch_version = key
848 if cnode == key or key == 'tip': 848 if cnode == key or key == 'tip':
849 arch_version = short(cnode) 849 arch_version = short(cnode)