##// END OF EJS Templates
hgweb: separate out utility functions
Dirkjan Ochtman -
r6392:2540521d default
parent child Browse files
Show More
@@ -0,0 +1,94 b''
1 # hgweb/webutil.py - utility library for the web interface.
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
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 from mercurial.node import hex, nullid
10 from mercurial.repo import RepoError
11 from mercurial import util
12
13 def siblings(siblings=[], hiderev=None, **args):
14 siblings = [s for s in siblings if s.node() != nullid]
15 if len(siblings) == 1 and siblings[0].rev() == hiderev:
16 return
17 for s in siblings:
18 d = {'node': hex(s.node()), 'rev': s.rev()}
19 if hasattr(s, 'path'):
20 d['file'] = s.path()
21 d.update(args)
22 yield d
23
24 def renamelink(fl, node):
25 r = fl.renamed(node)
26 if r:
27 return [dict(file=r[0], node=hex(r[1]))]
28 return []
29
30 def nodetagsdict(repo, node):
31 return [{"name": i} for i in repo.nodetags(node)]
32
33 def nodebranchdict(repo, ctx):
34 branches = []
35 branch = ctx.branch()
36 # If this is an empty repo, ctx.node() == nullid,
37 # ctx.branch() == 'default', but branchtags() is
38 # an empty dict. Using dict.get avoids a traceback.
39 if repo.branchtags().get(branch) == ctx.node():
40 branches.append({"name": branch})
41 return branches
42
43 def nodeinbranch(repo, ctx):
44 branches = []
45 branch = ctx.branch()
46 if branch != 'default' and repo.branchtags().get(branch) != ctx.node():
47 branches.append({"name": branch})
48 return branches
49
50 def nodebranchnodefault(ctx):
51 branches = []
52 branch = ctx.branch()
53 if branch != 'default':
54 branches.append({"name": branch})
55 return branches
56
57 def showtag(repo, tmpl, t1, node=nullid, **args):
58 for t in repo.nodetags(node):
59 yield tmpl(t1, tag=t, **args)
60
61 def cleanpath(repo, path):
62 path = path.lstrip('/')
63 return util.canonpath(repo.root, '', path)
64
65 def changectx(repo, req):
66 if 'node' in req.form:
67 changeid = req.form['node'][0]
68 elif 'manifest' in req.form:
69 changeid = req.form['manifest'][0]
70 else:
71 changeid = self.repo.changelog.count() - 1
72
73 try:
74 ctx = repo.changectx(changeid)
75 except RepoError:
76 man = repo.manifest
77 mn = man.lookup(changeid)
78 ctx = repo.changectx(man.linkrev(mn))
79
80 return ctx
81
82 def filectx(repo, req):
83 path = cleanpath(repo, req.form['file'][0])
84 if 'node' in req.form:
85 changeid = req.form['node'][0]
86 else:
87 changeid = req.form['filenode'][0]
88 try:
89 ctx = repo.changectx(changeid)
90 fctx = ctx.filectx(path)
91 except RepoError:
92 fctx = repo.filectx(path, fileid=changeid)
93
94 return fctx
@@ -15,7 +15,7 b' from common import get_mtime, style_map,'
15 15 from common import ErrorResponse
16 16 from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
17 17 from request import wsgirequest
18 import webcommands, protocol
18 import webcommands, protocol, webutil
19 19
20 20 shortcuts = {
21 21 'cl': [('cmd', ['changelog']), ('rev', None)],
@@ -340,54 +340,6 b' class hgweb(object):'
340 340 if len(files) > self.maxfiles:
341 341 yield tmpl("fileellipses")
342 342
343 def siblings(self, siblings=[], hiderev=None, **args):
344 siblings = [s for s in siblings if s.node() != nullid]
345 if len(siblings) == 1 and siblings[0].rev() == hiderev:
346 return
347 for s in siblings:
348 d = {'node': hex(s.node()), 'rev': s.rev()}
349 if hasattr(s, 'path'):
350 d['file'] = s.path()
351 d.update(args)
352 yield d
353
354 def renamelink(self, fl, node):
355 r = fl.renamed(node)
356 if r:
357 return [dict(file=r[0], node=hex(r[1]))]
358 return []
359
360 def nodetagsdict(self, node):
361 return [{"name": i} for i in self.repo.nodetags(node)]
362
363 def nodebranchdict(self, ctx):
364 branches = []
365 branch = ctx.branch()
366 # If this is an empty repo, ctx.node() == nullid,
367 # ctx.branch() == 'default', but branchtags() is
368 # an empty dict. Using dict.get avoids a traceback.
369 if self.repo.branchtags().get(branch) == ctx.node():
370 branches.append({"name": branch})
371 return branches
372
373 def nodeinbranch(self, ctx):
374 branches = []
375 branch = ctx.branch()
376 if branch != 'default' and self.repo.branchtags().get(branch) != ctx.node():
377 branches.append({"name": branch})
378 return branches
379
380 def nodebranchnodefault(self, ctx):
381 branches = []
382 branch = ctx.branch()
383 if branch != 'default':
384 branches.append({"name": branch})
385 return branches
386
387 def showtag(self, tmpl, t1, node=nullid, **args):
388 for t in self.repo.nodetags(node):
389 yield tmpl(t1, tag=t, **args)
390
391 343 def diff(self, tmpl, node1, node2, files):
392 344 def filterfiles(filters, files):
393 345 l = [x for x in files if x in filters]
@@ -462,21 +414,22 b' class hgweb(object):'
462 414 for i in xrange(start, end):
463 415 ctx = self.repo.changectx(i)
464 416 n = ctx.node()
465 showtags = self.showtag(tmpl, 'changelogtag', n)
417 showtags = webutil.showtag(self.repo, tmpl, 'changelogtag', n)
466 418
467 419 l.insert(0, {"parity": parity.next(),
468 420 "author": ctx.user(),
469 "parent": self.siblings(ctx.parents(), i - 1),
470 "child": self.siblings(ctx.children(), i + 1),
421 "parent": webutil.siblings(ctx.parents(), i - 1),
422 "child": webutil.siblings(ctx.children(), i + 1),
471 423 "changelogtag": showtags,
472 424 "desc": ctx.description(),
473 425 "date": ctx.date(),
474 426 "files": self.listfilediffs(tmpl, ctx.files(), n),
475 427 "rev": i,
476 428 "node": hex(n),
477 "tags": self.nodetagsdict(n),
478 "inbranch": self.nodeinbranch(ctx),
479 "branches": self.nodebranchdict(ctx)})
429 "tags": webutil.nodetagsdict(self.repo, n),
430 "inbranch": webutil.nodeinbranch(self.repo, ctx),
431 "branches": webutil.nodebranchdict(self.repo, ctx)
432 })
480 433
481 434 if limit > 0:
482 435 l = l[:limit]
@@ -533,22 +486,22 b' class hgweb(object):'
533 486
534 487 count += 1
535 488 n = ctx.node()
536 showtags = self.showtag(tmpl, 'changelogtag', n)
489 showtags = webutil.showtag(self.repo, tmpl, 'changelogtag', n)
537 490
538 491 yield tmpl('searchentry',
539 492 parity=parity.next(),
540 493 author=ctx.user(),
541 parent=self.siblings(ctx.parents()),
542 child=self.siblings(ctx.children()),
494 parent=webutil.siblings(ctx.parents()),
495 child=webutil.siblings(ctx.children()),
543 496 changelogtag=showtags,
544 497 desc=ctx.description(),
545 498 date=ctx.date(),
546 499 files=self.listfilediffs(tmpl, ctx.files(), n),
547 500 rev=ctx.rev(),
548 501 node=hex(n),
549 tags=self.nodetagsdict(n),
550 inbranch=self.nodeinbranch(ctx),
551 branches=self.nodebranchdict(ctx))
502 tags=webutil.nodetagsdict(self.repo, n),
503 inbranch=webutil.nodeinbranch(self.repo, ctx),
504 branches=webutil.nodebranchdict(self.repo, ctx))
552 505
553 506 if count >= self.maxchanges:
554 507 break
@@ -564,7 +517,7 b' class hgweb(object):'
564 517
565 518 def changeset(self, tmpl, ctx):
566 519 n = ctx.node()
567 showtags = self.showtag(tmpl, 'changesettag', n)
520 showtags = webutil.showtag(self.repo, tmpl, 'changesettag', n)
568 521 parents = ctx.parents()
569 522 p1 = parents[0].node()
570 523
@@ -582,18 +535,18 b' class hgweb(object):'
582 535 diff=diff,
583 536 rev=ctx.rev(),
584 537 node=hex(n),
585 parent=self.siblings(parents),
586 child=self.siblings(ctx.children()),
538 parent=webutil.siblings(parents),
539 child=webutil.siblings(ctx.children()),
587 540 changesettag=showtags,
588 541 author=ctx.user(),
589 542 desc=ctx.description(),
590 543 date=ctx.date(),
591 544 files=files,
592 545 archives=self.archivelist(hex(n)),
593 tags=self.nodetagsdict(n),
594 branch=self.nodebranchnodefault(ctx),
595 inbranch=self.nodeinbranch(ctx),
596 branches=self.nodebranchdict(ctx))
546 tags=webutil.nodetagsdict(self.repo, n),
547 branch=webutil.nodebranchnodefault(ctx),
548 inbranch=webutil.nodeinbranch(self.repo, ctx),
549 branches=webutil.nodebranchdict(self.repo, ctx))
597 550
598 551 def filelog(self, tmpl, fctx):
599 552 f = fctx.path()
@@ -619,9 +572,9 b' class hgweb(object):'
619 572 "node": hex(ctx.node()),
620 573 "author": ctx.user(),
621 574 "date": ctx.date(),
622 "rename": self.renamelink(fl, n),
623 "parent": self.siblings(fctx.parents()),
624 "child": self.siblings(fctx.children()),
575 "rename": webutil.renamelink(fl, n),
576 "parent": webutil.siblings(fctx.parents()),
577 "child": webutil.siblings(fctx.children()),
625 578 "desc": ctx.description()})
626 579
627 580 if limit > 0:
@@ -663,10 +616,10 b' class hgweb(object):'
663 616 author=fctx.user(),
664 617 date=fctx.date(),
665 618 desc=fctx.description(),
666 branch=self.nodebranchnodefault(fctx),
667 parent=self.siblings(fctx.parents()),
668 child=self.siblings(fctx.children()),
669 rename=self.renamelink(fl, n),
619 branch=webutil.nodebranchnodefault(fctx),
620 parent=webutil.siblings(fctx.parents()),
621 child=webutil.siblings(fctx.children()),
622 rename=webutil.renamelink(fl, n),
670 623 permissions=fctx.manifest().flags(f))
671 624
672 625 def fileannotate(self, tmpl, fctx):
@@ -710,10 +663,10 b' class hgweb(object):'
710 663 author=fctx.user(),
711 664 date=fctx.date(),
712 665 desc=fctx.description(),
713 rename=self.renamelink(fl, n),
714 branch=self.nodebranchnodefault(fctx),
715 parent=self.siblings(fctx.parents()),
716 child=self.siblings(fctx.children()),
666 rename=webutil.renamelink(fl, n),
667 branch=webutil.nodebranchnodefault(fctx),
668 parent=webutil.siblings(fctx.parents()),
669 child=webutil.siblings(fctx.children()),
717 670 permissions=fctx.manifest().flags(f))
718 671
719 672 def manifest(self, tmpl, ctx, path):
@@ -779,9 +732,9 b' class hgweb(object):'
779 732 fentries=filelist,
780 733 dentries=dirlist,
781 734 archives=self.archivelist(hex(node)),
782 tags=self.nodetagsdict(node),
783 inbranch=self.nodeinbranch(ctx),
784 branches=self.nodebranchdict(ctx))
735 tags=webutil.nodetagsdict(self.repo, node),
736 inbranch=webutil.nodeinbranch(self.repo, ctx),
737 branches=webutil.nodebranchdict(self.repo, ctx))
785 738
786 739 def tags(self, tmpl):
787 740 i = self.repo.tagslist()
@@ -860,9 +813,9 b' class hgweb(object):'
860 813 date=ctx.date(),
861 814 rev=i,
862 815 node=hn,
863 tags=self.nodetagsdict(n),
864 inbranch=self.nodeinbranch(ctx),
865 branches=self.nodebranchdict(ctx)))
816 tags=webutil.nodetagsdict(self.repo, n),
817 inbranch=webutil.nodeinbranch(self.repo, ctx),
818 branches=webutil.nodebranchdict(self.repo, ctx)))
866 819
867 820 yield l
868 821
@@ -894,9 +847,9 b' class hgweb(object):'
894 847 file=path,
895 848 node=hex(n),
896 849 rev=fctx.rev(),
897 branch=self.nodebranchnodefault(fctx),
898 parent=self.siblings(parents),
899 child=self.siblings(fctx.children()),
850 branch=webutil.nodebranchnodefault(fctx),
851 parent=webutil.siblings(parents),
852 child=webutil.siblings(fctx.children()),
900 853 diff=diff)
901 854
902 855 archive_specs = {
@@ -924,45 +877,6 b' class hgweb(object):'
924 877 req.respond(HTTP_OK)
925 878 archival.archive(self.repo, req, cnode, artype, prefix=name)
926 879
927 # add tags to things
928 # tags -> list of changesets corresponding to tags
929 # find tag, changeset, file
930
931 def cleanpath(self, path):
932 path = path.lstrip('/')
933 return util.canonpath(self.repo.root, '', path)
934
935 def changectx(self, req):
936 if 'node' in req.form:
937 changeid = req.form['node'][0]
938 elif 'manifest' in req.form:
939 changeid = req.form['manifest'][0]
940 else:
941 changeid = self.repo.changelog.count() - 1
942
943 try:
944 ctx = self.repo.changectx(changeid)
945 except RepoError:
946 man = self.repo.manifest
947 mn = man.lookup(changeid)
948 ctx = self.repo.changectx(man.linkrev(mn))
949
950 return ctx
951
952 def filectx(self, req):
953 path = self.cleanpath(req.form['file'][0])
954 if 'node' in req.form:
955 changeid = req.form['node'][0]
956 else:
957 changeid = req.form['filenode'][0]
958 try:
959 ctx = self.repo.changectx(changeid)
960 fctx = ctx.filectx(path)
961 except RepoError:
962 fctx = self.repo.filectx(path, fileid=changeid)
963
964 return fctx
965
966 880 def check_perm(self, req, op, default):
967 881 '''check permission for operation based on user auth.
968 882 return true if op allowed, else false.
@@ -6,7 +6,9 b''
6 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 8 import os, mimetypes
9 from mercurial import revlog, util
9 import webutil
10 from mercurial import revlog
11 from mercurial.util import binary
10 12 from mercurial.repo import RepoError
11 13 from common import staticfile, ErrorResponse, HTTP_OK, HTTP_NOT_FOUND
12 14
@@ -26,17 +28,17 b' def log(web, req, tmpl):'
26 28 return changelog(web, req, tmpl)
27 29
28 30 def rawfile(web, req, tmpl):
29 path = web.cleanpath(req.form.get('file', [''])[0])
31 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
30 32 if not path:
31 content = web.manifest(tmpl, web.changectx(req), path)
33 content = web.manifest(tmpl, webutil.changectx(web.repo, req), path)
32 34 req.respond(HTTP_OK, web.ctype)
33 35 return content
34 36
35 37 try:
36 fctx = web.filectx(req)
38 fctx = webutil.filectx(web.repo, req)
37 39 except revlog.LookupError, inst:
38 40 try:
39 content = web.manifest(tmpl, web.changectx(req), path)
41 content = web.manifest(tmpl, webutil.changectx(web.repo, req), path)
40 42 req.respond(HTTP_OK, web.ctype)
41 43 return content
42 44 except ErrorResponse:
@@ -45,28 +47,28 b' def rawfile(web, req, tmpl):'
45 47 path = fctx.path()
46 48 text = fctx.data()
47 49 mt = mimetypes.guess_type(path)[0]
48 if mt is None or util.binary(text):
50 if mt is None or binary(text):
49 51 mt = mt or 'application/octet-stream'
50 52
51 53 req.respond(HTTP_OK, mt, path, len(text))
52 54 return [text]
53 55
54 56 def file(web, req, tmpl):
55 path = web.cleanpath(req.form.get('file', [''])[0])
57 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
56 58 if path:
57 59 try:
58 return web.filerevision(tmpl, web.filectx(req))
60 return web.filerevision(tmpl, webutil.filectx(web.repo, req))
59 61 except revlog.LookupError, inst:
60 62 pass
61 63
62 64 try:
63 return web.manifest(tmpl, web.changectx(req), path)
65 return web.manifest(tmpl, webutil.changectx(web.repo, req), path)
64 66 except ErrorResponse:
65 67 raise inst
66 68
67 69 def changelog(web, req, tmpl, shortlog = False):
68 70 if 'node' in req.form:
69 ctx = web.changectx(req)
71 ctx = webutil.changectx(web.repo, req)
70 72 else:
71 73 if 'rev' in req.form:
72 74 hi = req.form['rev'][0]
@@ -83,13 +85,13 b' def shortlog(web, req, tmpl):'
83 85 return changelog(web, req, tmpl, shortlog = True)
84 86
85 87 def changeset(web, req, tmpl):
86 return web.changeset(tmpl, web.changectx(req))
88 return web.changeset(tmpl, webutil.changectx(web.repo, req))
87 89
88 90 rev = changeset
89 91
90 92 def manifest(web, req, tmpl):
91 return web.manifest(tmpl, web.changectx(req),
92 web.cleanpath(req.form['path'][0]))
93 return web.manifest(tmpl, webutil.changectx(web.repo, req),
94 webutil.cleanpath(web.repo, req.form['path'][0]))
93 95
94 96 def tags(web, req, tmpl):
95 97 return web.tags(tmpl)
@@ -98,15 +100,15 b' def summary(web, req, tmpl):'
98 100 return web.summary(tmpl)
99 101
100 102 def filediff(web, req, tmpl):
101 return web.filediff(tmpl, web.filectx(req))
103 return web.filediff(tmpl, webutil.filectx(web.repo, req))
102 104
103 105 diff = filediff
104 106
105 107 def annotate(web, req, tmpl):
106 return web.fileannotate(tmpl, web.filectx(req))
108 return web.fileannotate(tmpl, webutil.filectx(web.repo, req))
107 109
108 110 def filelog(web, req, tmpl):
109 return web.filelog(tmpl, web.filectx(req))
111 return web.filelog(tmpl, webutil.filectx(web.repo, req))
110 112
111 113 def archive(web, req, tmpl):
112 114 type_ = req.form['type'][0]
General Comments 0
You need to be logged in to leave comments. Login now