def changeset(web, req, tmpl): ctx = webutil.changectx(web.repo, req) showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node()) showbranch = webutil.nodebranchnodefault(ctx) files = [] parity = paritygen(web.stripecount) for f in ctx.files(): template = f in ctx and 'filenodelink' or 'filenolink' files.append(tmpl(template, node=ctx.hex(), file=f, parity=parity.next())) parity = paritygen(web.stripecount) diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity) return tmpl('changeset', diff=diffs, rev=ctx.rev(), node=ctx.hex(), parent=webutil.parents(ctx), child=webutil.children(ctx), changesettag=showtags, changesetbranch=showbranch, author=ctx.user(), desc=ctx.description(), date=ctx.date(), files=files, archives=web.archivelist(ctx.hex()), tags=webutil.nodetagsdict(web.repo, ctx.node()), branch=webutil.nodebranchnodefault(ctx), inbranch=webutil.nodeinbranch(web.repo, ctx), branches=webutil.nodebranchdict(web.repo, ctx))
def changeset(web, req, tmpl): ctx = webutil.changectx(web.repo, req) showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node()) showbranch = webutil.nodebranchnodefault(ctx) files = [] parity = paritygen(web.stripecount) for f in ctx.files(): template = f in ctx and 'filenodelink' or 'filenolink' files.append( tmpl(template, node=ctx.hex(), file=f, parity=parity.next())) parity = paritygen(web.stripecount) style = web.config('web', 'style', 'paper') if 'style' in req.form: style = req.form['style'][0] diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style) return tmpl('changeset', diff=diffs, rev=ctx.rev(), node=ctx.hex(), parent=webutil.parents(ctx), child=webutil.children(ctx), changesettag=showtags, changesetbranch=showbranch, author=ctx.user(), desc=ctx.description(), date=ctx.date(), files=files, archives=web.archivelist(ctx.hex()), tags=webutil.nodetagsdict(web.repo, ctx.node()), branch=webutil.nodebranchnodefault(ctx), inbranch=webutil.nodeinbranch(web.repo, ctx), branches=webutil.nodebranchdict(web.repo, ctx))
def changesetentry(web, req, tmpl, ctx): '''Obtain a dictionary to be used to render the "changeset" template.''' showtags = showtag(web.repo, tmpl, 'changesettag', ctx.node()) showbookmarks = showbookmark(web.repo, tmpl, 'changesetbookmark', ctx.node()) showbranch = nodebranchnodefault(ctx) files = [] parity = paritygen(web.stripecount) for blockno, f in enumerate(ctx.files()): template = f in ctx and 'filenodelink' or 'filenolink' files.append( tmpl(template, node=ctx.hex(), file=f, blockno=blockno + 1, parity=parity.next())) basectx = basechangectx(web.repo, req) if basectx is None: basectx = ctx.p1() style = web.config('web', 'style', 'paper') if 'style' in req.form: style = req.form['style'][0] parity = paritygen(web.stripecount) diff = diffs(web.repo, tmpl, ctx, basectx, None, parity, style) parity = paritygen(web.stripecount) diffstatsgen = diffstatgen(ctx, basectx) diffstats = diffstat(tmpl, ctx, diffstatsgen, parity) return dict(diff=diff, rev=ctx.rev(), node=ctx.hex(), symrev=symrevorshortnode(req, ctx), parent=tuple(parents(ctx)), child=children(ctx), basenode=basectx.hex(), changesettag=showtags, changesetbookmark=showbookmarks, changesetbranch=showbranch, author=ctx.user(), desc=ctx.description(), extra=ctx.extra(), date=ctx.date(), phase=ctx.phasestr(), files=files, diffsummary=lambda **x: diffsummary(diffstatsgen), diffstat=diffstats, archives=web.archivelist(ctx.hex()), tags=nodetagsdict(web.repo, ctx.node()), bookmarks=nodebookmarksdict(web.repo, ctx.node()), branch=showbranch, inbranch=nodeinbranch(web.repo, ctx), branches=nodebranchdict(web.repo, ctx))
def changesetentry(web, req, tmpl, ctx): '''Obtain a dictionary to be used to render the "changeset" template.''' showtags = showtag(web.repo, tmpl, 'changesettag', ctx.node()) showbookmarks = showbookmark(web.repo, tmpl, 'changesetbookmark', ctx.node()) showbranch = nodebranchnodefault(ctx) files = [] parity = paritygen(web.stripecount) for blockno, f in enumerate(ctx.files()): template = f in ctx and 'filenodelink' or 'filenolink' files.append(tmpl(template, node=ctx.hex(), file=f, blockno=blockno + 1, parity=parity.next())) basectx = basechangectx(web.repo, req) if basectx is None: basectx = ctx.p1() style = web.config('web', 'style', 'paper') if 'style' in req.form: style = req.form['style'][0] parity = paritygen(web.stripecount) diff = diffs(web.repo, tmpl, ctx, basectx, None, parity, style) parity = paritygen(web.stripecount) diffstatsgen = diffstatgen(ctx, basectx) diffstats = diffstat(tmpl, ctx, diffstatsgen, parity) return dict( diff=diff, rev=ctx.rev(), node=ctx.hex(), symrev=symrevorshortnode(req, ctx), parent=tuple(parents(ctx)), child=children(ctx), basenode=basectx.hex(), changesettag=showtags, changesetbookmark=showbookmarks, changesetbranch=showbranch, author=ctx.user(), desc=ctx.description(), extra=ctx.extra(), date=ctx.date(), phase=ctx.phasestr(), files=files, diffsummary=lambda **x: diffsummary(diffstatsgen), diffstat=diffstats, archives=web.archivelist(ctx.hex()), tags=nodetagsdict(web.repo, ctx.node()), bookmarks=nodebookmarksdict(web.repo, ctx.node()), branch=showbranch, inbranch=nodeinbranch(web.repo, ctx), branches=nodebranchdict(web.repo, ctx))
def changeset(web, req, tmpl): ctx = webutil.changectx(web.repo, req) basectx = webutil.basechangectx(web.repo, req) if basectx is None: basectx = ctx.p1() showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node()) showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark', ctx.node()) showbranch = webutil.nodebranchnodefault(ctx) files = [] parity = paritygen(web.stripecount) for blockno, f in enumerate(ctx.files()): template = f in ctx and 'filenodelink' or 'filenolink' files.append( tmpl(template, node=ctx.hex(), file=f, blockno=blockno + 1, parity=parity.next())) style = web.config('web', 'style', 'paper') if 'style' in req.form: style = req.form['style'][0] parity = paritygen(web.stripecount) diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, None, parity, style) parity = paritygen(web.stripecount) diffstatgen = webutil.diffstatgen(ctx, basectx) diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity) return tmpl('changeset', diff=diffs, rev=ctx.rev(), node=ctx.hex(), parent=webutil.parents(ctx), child=webutil.children(ctx), basenode=basectx.hex(), changesettag=showtags, changesetbookmark=showbookmarks, changesetbranch=showbranch, author=ctx.user(), desc=ctx.description(), extra=ctx.extra(), date=ctx.date(), files=files, diffsummary=lambda **x: webutil.diffsummary(diffstatgen), diffstat=diffstat, archives=web.archivelist(ctx.hex()), tags=webutil.nodetagsdict(web.repo, ctx.node()), bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()), branch=webutil.nodebranchnodefault(ctx), inbranch=webutil.nodeinbranch(web.repo, ctx), branches=webutil.nodebranchdict(web.repo, ctx))
def changeset(web, req, tmpl): ctx = webutil.changectx(web.repo, req) basectx = webutil.basechangectx(web.repo, req) if basectx is None: basectx = ctx.p1() showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node()) showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark', ctx.node()) showbranch = webutil.nodebranchnodefault(ctx) files = [] parity = paritygen(web.stripecount) for blockno, f in enumerate(ctx.files()): template = f in ctx and 'filenodelink' or 'filenolink' files.append(tmpl(template, node=ctx.hex(), file=f, blockno=blockno + 1, parity=parity.next())) style = web.config('web', 'style', 'paper') if 'style' in req.form: style = req.form['style'][0] parity = paritygen(web.stripecount) diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, None, parity, style) parity = paritygen(web.stripecount) diffstatgen = webutil.diffstatgen(ctx, basectx) diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity) return tmpl('changeset', diff=diffs, rev=ctx.rev(), node=ctx.hex(), parent=webutil.parents(ctx), child=webutil.children(ctx), basenode=basectx.hex(), changesettag=showtags, changesetbookmark=showbookmarks, changesetbranch=showbranch, author=ctx.user(), desc=ctx.description(), extra=ctx.extra(), date=ctx.date(), files=files, diffsummary=lambda **x: webutil.diffsummary(diffstatgen), diffstat=diffstat, archives=web.archivelist(ctx.hex()), tags=webutil.nodetagsdict(web.repo, ctx.node()), bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()), branch=webutil.nodebranchnodefault(ctx), inbranch=webutil.nodeinbranch(web.repo, ctx), branches=webutil.nodebranchdict(web.repo, ctx))
def branches(web, req, tmpl): b = web.repo.branchtags() tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems()) heads = web.repo.heads() parity = paritygen(web.stripecount) sortkey = lambda ctx: ('close' not in ctx.extra(), ctx.rev()) def entries(limit, **map): count = 0 for ctx in sorted(tips, key=sortkey, reverse=True): if limit > 0 and count >= limit: return count += 1 if ctx.node() not in heads: status = 'inactive' elif not web.repo.branchheads(ctx.branch()): status = 'closed' else: status = 'open' yield {'parity': parity.next(), 'branch': ctx.branch(), 'status': status, 'node': ctx.hex(), 'date': ctx.date()} return tmpl('branches', node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(0, **x), latestentry=lambda **x: entries(1, **x))
def branches(web, req, tmpl): tips = [] heads = web.repo.heads() parity = paritygen(web.stripecount) sortkey = lambda item: (not item[1], item[0].rev()) def entries(limit, **map): count = 0 if not tips: for tag, hs, tip, closed in web.repo.branchmap().iterbranches(): tips.append((web.repo[tip], closed)) for ctx, closed in sorted(tips, key=sortkey, reverse=True): if limit > 0 and count >= limit: return count += 1 if closed: status = 'closed' elif ctx.node() not in heads: status = 'inactive' else: status = 'open' yield {'parity': parity.next(), 'branch': ctx.branch(), 'status': status, 'node': ctx.hex(), 'date': ctx.date()} return tmpl('branches', node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(0, **x), latestentry=lambda **x: entries(1, **x))
def filediff(web, req, tmpl): fctx, ctx = None, None try: fctx = webutil.filectx(web.repo, req) except LookupError: ctx = webutil.changectx(web.repo, req) path = webutil.cleanpath(web.repo, req.form['file'][0]) if path not in ctx.files(): raise if fctx is not None: n = fctx.node() path = fctx.path() else: n = ctx.node() # path already defined in except clause parity = paritygen(web.stripecount) diffs = webutil.diffs(web.repo, tmpl, fctx or ctx, [path], parity) rename = fctx and webutil.renamelink(fctx) or [] ctx = fctx and fctx or ctx return tmpl("filediff", file=path, node=hex(n), rev=ctx.rev(), date=ctx.date(), desc=ctx.description(), author=ctx.user(), rename=rename, branch=webutil.nodebranchnodefault(ctx), parent=webutil.parents(ctx), child=webutil.children(ctx), diff=diffs)
def annotate(web, req, tmpl): """ /annotate/{revision}/{path} --------------------------- Show changeset information for each line in a file. The ``fileannotate`` template is rendered. """ fctx = webutil.filectx(web.repo, req) f = fctx.path() parity = paritygen(web.stripecount) diffopts = patch.difffeatureopts(web.repo.ui, untrusted=True, section='annotate', whitespace=True) def annotate(**map): last = None if util.binary(fctx.data()): mt = (mimetypes.guess_type(fctx.path())[0] or 'application/octet-stream') lines = enumerate([((fctx.filectx(fctx.filerev()), 1), '(binary:%s)' % mt)]) else: lines = enumerate(fctx.annotate(follow=True, linenumber=True, diffopts=diffopts)) for lineno, ((f, targetline), l) in lines: fnode = f.filenode() if last != fnode: last = fnode yield {"parity": parity.next(), "node": f.hex(), "rev": f.rev(), "author": f.user(), "desc": f.description(), "extra": f.extra(), "file": f.path(), "targetline": targetline, "line": l, "lineno": lineno + 1, "lineid": "l%d" % (lineno + 1), "linenumber": "% 6d" % (lineno + 1), "revdate": f.date()} return tmpl("fileannotate", file=f, annotate=annotate, path=webutil.up(f), rev=fctx.rev(), node=fctx.hex(), author=fctx.user(), date=fctx.date(), desc=fctx.description(), extra=fctx.extra(), rename=webutil.renamelink(fctx), branch=webutil.nodebranchnodefault(fctx), parent=webutil.parents(fctx), child=webutil.children(fctx), permissions=fctx.manifest().flags(f))
def bookmarks(web, req, tmpl): """ /bookmarks ---------- Show information about bookmarks. No arguments are accepted. The ``bookmarks`` template is rendered. """ i = [b for b in web.repo._bookmarks.items() if b[1] in web.repo] parity = paritygen(web.stripecount) def entries(latestonly, **map): if latestonly: t = [min(i)] else: t = sorted(i) for k, n in t: yield {"parity": parity.next(), "bookmark": k, "date": web.repo[n].date(), "node": hex(n)} return tmpl("bookmarks", node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(latestonly=False, **x), latestentry=lambda **x: entries(latestonly=True, **x))
def tags(web, req, tmpl): """ /tags ----- Show information about tags. No arguments are accepted. The ``tags`` template is rendered. """ i = list(reversed(web.repo.tagslist())) parity = paritygen(web.stripecount) def entries(notip, latestonly, **map): t = i if notip: t = [(k, n) for k, n in i if k != "tip"] if latestonly: t = t[:1] for k, n in t: yield {"parity": parity.next(), "tag": k, "date": web.repo[n].date(), "node": hex(n)} return tmpl("tags", node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(False, False, **x), entriesnotip=lambda **x: entries(True, False, **x), latestentry=lambda **x: entries(True, True, **x))
def branchentries(repo, stripecount, limit=0): tips = [] heads = repo.heads() parity = paritygen(stripecount) sortkey = lambda item: (not item[1], item[0].rev()) def entries(**map): count = 0 if not tips: for tag, hs, tip, closed in repo.branchmap().iterbranches(): tips.append((repo[tip], closed)) for ctx, closed in sorted(tips, key=sortkey, reverse=True): if limit > 0 and count >= limit: return count += 1 if closed: status = 'closed' elif ctx.node() not in heads: status = 'inactive' else: status = 'open' yield { 'parity': parity.next(), 'branch': ctx.branch(), 'status': status, 'node': ctx.hex(), 'date': ctx.date() } return entries
def filelog(web, req, tmpl): try: fctx = webutil.filectx(web.repo, req) f = fctx.path() fl = fctx.filelog() except error.LookupError: f = webutil.cleanpath(web.repo, req.form['file'][0]) fl = web.repo.file(f) numrevs = len(fl) if not numrevs: # file doesn't exist at all raise rev = webutil.changectx(web.repo, req).rev() first = fl.linkrev(0) if rev < first: # current rev is from before file existed raise frev = numrevs - 1 while fl.linkrev(frev) > rev: frev -= 1 fctx = web.repo.filectx(f, fl.linkrev(frev)) count = fctx.filerev() + 1 pagelen = web.maxshortchanges start = max(0, fctx.filerev() - pagelen + 1) # first rev on this page end = min(count, start + pagelen) # last rev on this page parity = paritygen(web.stripecount, offset=start-end) def entries(limit=0, **map): l = [] repo = web.repo for i in xrange(start, end): iterfctx = fctx.filectx(i) l.insert(0, {"parity": parity.next(), "filerev": i, "file": f, "node": hex(iterfctx.node()), "author": iterfctx.user(), "date": iterfctx.date(), "rename": webutil.renamelink(iterfctx), "parent": webutil.parents(iterfctx), "child": webutil.children(iterfctx), "desc": iterfctx.description(), "tags": webutil.nodetagsdict(repo, iterfctx.node()), "branch": webutil.nodebranchnodefault(iterfctx), "inbranch": webutil.nodeinbranch(repo, iterfctx), "branches": webutil.nodebranchdict(repo, iterfctx)}) if limit > 0: l = l[:limit] for e in l: yield e nodefunc = lambda x: fctx.filectx(fileid=x) nav = webutil.revnavgen(end - 1, pagelen, count, nodefunc) return tmpl("filelog", file=f, node=hex(fctx.node()), nav=nav, entries=lambda **x: entries(limit=0, **x), latestentry=lambda **x: entries(limit=1, **x))
def tags(web, req, tmpl): i = web.repo.tagslist() i.reverse() parity = paritygen(web.stripecount) def entries(notip=False, limit=0, **map): count = 0 for k, n in i: if notip and k == "tip": continue if limit > 0 and count >= limit: continue count = count + 1 yield { "parity": parity.next(), "tag": k, "date": web.repo[n].date(), "node": hex(n) } return tmpl("tags", node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(False, 0, **x), entriesnotip=lambda **x: entries(True, 0, **x), latestentry=lambda **x: entries(True, 1, **x))
def changelist(**map): parity = paritygen(web.stripecount, offset=start - end) l = [] # build a list in forward order for efficiency for i in xrange(start, end): ctx = web.repo[i] n = ctx.node() hn = hex(n) l.insert( 0, tmpl( "shortlogentry", parity=parity.next(), author=ctx.user(), desc=ctx.description(), date=ctx.date(), rev=i, node=hn, tags=webutil.nodetagsdict(web.repo, n), bookmarks=webutil.nodebookmarksdict(web.repo, n), inbranch=webutil.nodeinbranch(web.repo, ctx), branches=webutil.nodebranchdict(web.repo, ctx), ), ) yield l
def branches(**map): parity = paritygen(web.stripecount) b = web.repo.branchtags() l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()] for r, n, t in sorted(l): yield {"parity": parity.next(), "branch": t, "node": hex(n), "date": web.repo[n].date()}
def bookmarks(web, req, tmpl): """ /bookmarks ---------- Show information about bookmarks. No arguments are accepted. The ``bookmarks`` template is rendered. """ i = [b for b in web.repo._bookmarks.items() if b[1] in web.repo] parity = paritygen(web.stripecount) def entries(latestonly, **map): if latestonly: t = [min(i)] else: t = sorted(i) for k, n in t: yield { "parity": parity.next(), "bookmark": k, "date": web.repo[n].date(), "node": hex(n) } return tmpl("bookmarks", node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(latestonly=False, **x), latestentry=lambda **x: entries(latestonly=True, **x))
def changelist(**map): parity = paritygen(web.stripecount, offset=start - end) l = [] # build a list in forward order for efficiency revs = [] if start < end: revs = web.repo.changelog.revs(start, end - 1) for i in revs: ctx = web.repo[i] n = ctx.node() hn = hex(n) l.append( tmpl('shortlogentry', parity=parity.next(), author=ctx.user(), desc=ctx.description(), extra=ctx.extra(), date=ctx.date(), rev=i, node=hn, tags=webutil.nodetagsdict(web.repo, n), bookmarks=webutil.nodebookmarksdict(web.repo, n), inbranch=webutil.nodeinbranch(web.repo, ctx), branches=webutil.nodebranchdict(web.repo, ctx))) l.reverse() yield l
def changelist(**map): parity = paritygen(web.stripecount, offset=start - end) l = [] # build a list in forward order for efficiency revs = [] if start < end: revs = web.repo.changelog.revs(start, end - 1) for i in revs: ctx = web.repo[i] n = ctx.node() hn = hex(n) l.append(tmpl( 'shortlogentry', parity=parity.next(), author=ctx.user(), desc=ctx.description(), extra=ctx.extra(), date=ctx.date(), rev=i, node=hn, tags=webutil.nodetagsdict(web.repo, n), bookmarks=webutil.nodebookmarksdict(web.repo, n), inbranch=webutil.nodeinbranch(web.repo, ctx), branches=webutil.nodebranchdict(web.repo, ctx))) l.reverse() yield l
def tags(web, req, tmpl): """ /tags ----- Show information about tags. No arguments are accepted. The ``tags`` template is rendered. """ i = list(reversed(web.repo.tagslist())) parity = paritygen(web.stripecount) def entries(notip, latestonly, **map): t = i if notip: t = [(k, n) for k, n in i if k != "tip"] if latestonly: t = t[:1] for k, n in t: yield { "parity": parity.next(), "tag": k, "date": web.repo[n].date(), "node": hex(n) } return tmpl("tags", node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(False, False, **x), entriesnotip=lambda **x: entries(True, False, **x), latestentry=lambda **x: entries(True, True, **x))
def changeset(self, tmpl, ctx): n = ctx.node() showtags = self.showtag(tmpl, 'changesettag', n) parents = ctx.parents() p1 = parents[0].node() files = [] parity = paritygen(self.stripecount) for f in ctx.files(): files.append(tmpl("filenodelink", node=hex(n), file=f, parity=parity.next())) def diff(**map): yield self.diff(tmpl, p1, n, None) return tmpl('changeset', diff=diff, rev=ctx.rev(), node=hex(n), parent=self.siblings(parents), child=self.siblings(ctx.children()), changesettag=showtags, author=ctx.user(), desc=ctx.description(), date=ctx.date(), files=files, archives=self.archivelist(hex(n)), tags=self.nodetagsdict(n), branch=self.nodebranchnodefault(ctx), inbranch=self.nodeinbranch(ctx), branches=self.nodebranchdict(ctx))
def _filerevision(web, tmpl, fctx): f = fctx.path() text = fctx.data() parity = paritygen(web.stripecount) if binary(text): mt = mimetypes.guess_type(f)[0] or 'application/octet-stream' text = '(binary:%s)' % mt def lines(): for lineno, t in enumerate(text.splitlines(True)): yield { "line": t, "lineid": "l%d" % (lineno + 1), "linenumber": "% 6d" % (lineno + 1), "parity": parity.next() } return tmpl("filerevision", file=f, path=webutil.up(f), text=lines(), rev=fctx.rev(), node=hex(fctx.node()), author=fctx.user(), date=fctx.date(), desc=fctx.description(), branch=webutil.nodebranchnodefault(fctx), parent=webutil.parents(fctx), child=webutil.children(fctx), rename=webutil.renamelink(fctx), permissions=fctx.manifest().flags(f))
def branches(web, req, tmpl): b = web.repo.branchtags() tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems()) heads = web.repo.heads() parity = paritygen(web.stripecount) sortkey = lambda ctx: ('close' not in ctx.extra(), ctx.rev()) def entries(limit, **map): count = 0 for ctx in sorted(tips, key=sortkey, reverse=True): if limit > 0 and count >= limit: return count += 1 if ctx.node() not in heads: status = 'inactive' elif not web.repo.branchheads(ctx.branch()): status = 'closed' else: status = 'open' yield { 'parity': parity.next(), 'branch': ctx.branch(), 'status': status, 'node': ctx.hex(), 'date': ctx.date() } return tmpl('branches', node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(0, **x), latestentry=lambda **x: entries(1, **x))
def changelog(web, req, tmpl, shortlog = False): if 'node' in req.form: ctx = webutil.changectx(web.repo, req) else: if 'rev' in req.form: hi = req.form['rev'][0] else: hi = len(web.repo) - 1 try: ctx = web.repo[hi] except error.RepoError: return _search(web, tmpl, hi) # XXX redirect to 404 page? def changelist(limit=0, **map): l = [] # build a list in forward order for efficiency for i in xrange(start, end): ctx = web.repo[i] n = ctx.node() showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n) files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles) l.insert(0, {"parity": parity.next(), "author": ctx.user(), "parent": webutil.parents(ctx, i - 1), "child": webutil.children(ctx, i + 1), "changelogtag": showtags, "desc": ctx.description(), "date": ctx.date(), "files": files, "rev": i, "node": hex(n), "tags": webutil.nodetagsdict(web.repo, n), "inbranch": webutil.nodeinbranch(web.repo, ctx), "branches": webutil.nodebranchdict(web.repo, ctx) }) if limit > 0: l = l[:limit] for e in l: yield e maxchanges = shortlog and web.maxshortchanges or web.maxchanges cl = web.repo.changelog count = len(cl) pos = ctx.rev() start = max(0, pos - maxchanges + 1) end = min(count, start + maxchanges) pos = end - 1 parity = paritygen(web.stripecount, offset=start-end) changenav = webutil.revnavgen(pos, maxchanges, count, web.repo.changectx) return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav, node=hex(ctx.node()), rev=pos, changesets=count, entries=lambda **x: changelist(limit=0,**x), latestentry=lambda **x: changelist(limit=1,**x), archives=web.archivelist("tip"))
def branches(web, req, tmpl): tips = (web.repo[n] for t, n in web.repo.branchtags().iteritems()) heads = web.repo.heads() parity = paritygen(web.stripecount) sortkey = lambda ctx: ("close" not in ctx.extra(), ctx.rev()) def entries(limit, **map): count = 0 for ctx in sorted(tips, key=sortkey, reverse=True): if limit > 0 and count >= limit: return count += 1 if not web.repo.branchheads(ctx.branch()): status = "closed" elif ctx.node() not in heads: status = "inactive" else: status = "open" yield { "parity": parity.next(), "branch": ctx.branch(), "status": status, "node": ctx.hex(), "date": ctx.date(), } return tmpl( "branches", node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(0, **x), latestentry=lambda **x: entries(1, **x), )
def _filerevision(web, tmpl, fctx): f = fctx.path() text = fctx.data() parity = paritygen(web.stripecount) if binary(text): mt = mimetypes.guess_type(f)[0] or 'application/octet-stream' text = '(binary:%s)' % mt def lines(): for lineno, t in enumerate(text.splitlines(True)): yield {"line": t, "lineid": "l%d" % (lineno + 1), "linenumber": "% 6d" % (lineno + 1), "parity": parity.next()} return tmpl("filerevision", file=f, path=webutil.up(f), text=lines(), rev=fctx.rev(), node=hex(fctx.node()), author=fctx.user(), date=fctx.date(), desc=fctx.description(), branch=webutil.nodebranchnodefault(fctx), parent=webutil.parents(fctx), child=webutil.children(fctx), rename=webutil.renamelink(fctx), permissions=fctx.manifest().flags(f))
def _search(web, tmpl, query): def changelist(**map): cl = web.repo.changelog count = 0 qw = query.lower().split() def revgen(): for i in xrange(len(cl) - 1, 0, -100): l = [] for j in xrange(max(0, i - 100), i + 1): ctx = web.repo[j] l.append(ctx) l.reverse() for e in l: yield e for ctx in revgen(): miss = 0 for q in qw: if not (q in ctx.user().lower() or q in ctx.description().lower() or q in " ".join(ctx.files()).lower()): miss = 1 break if miss: continue count += 1 n = ctx.node() showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n) files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles) yield tmpl('searchentry', parity=parity.next(), author=ctx.user(), parent=webutil.parents(ctx), child=webutil.children(ctx), changelogtag=showtags, desc=ctx.description(), date=ctx.date(), files=files, rev=ctx.rev(), node=hex(n), tags=webutil.nodetagsdict(web.repo, n), inbranch=webutil.nodeinbranch(web.repo, ctx), branches=webutil.nodebranchdict(web.repo, ctx)) if count >= web.maxchanges: break cl = web.repo.changelog parity = paritygen(web.stripecount) return tmpl('search', query=query, node=hex(cl.tip()), entries=changelist, archives=web.archivelist("tip"))
def changeset(web, req, tmpl): ctx = webutil.changectx(web.repo, req) showtags = webutil.showtag(web.repo, tmpl, "changesettag", ctx.node()) showbookmarks = webutil.showbookmark(web.repo, tmpl, "changesetbookmark", ctx.node()) showbranch = webutil.nodebranchnodefault(ctx) files = [] parity = paritygen(web.stripecount) for blockno, f in enumerate(ctx.files()): template = f in ctx and "filenodelink" or "filenolink" files.append(tmpl(template, node=ctx.hex(), file=f, blockno=blockno + 1, parity=parity.next())) style = web.config("web", "style", "paper") if "style" in req.form: style = req.form["style"][0] parity = paritygen(web.stripecount) diffs = webutil.diffs(web.repo, tmpl, ctx, None, parity, style) parity = paritygen(web.stripecount) diffstatgen = webutil.diffstatgen(ctx) diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity) return tmpl( "changeset", diff=diffs, rev=ctx.rev(), node=ctx.hex(), parent=webutil.parents(ctx), child=webutil.children(ctx), changesettag=showtags, changesetbookmark=showbookmarks, changesetbranch=showbranch, author=ctx.user(), desc=ctx.description(), date=ctx.date(), files=files, diffsummary=lambda **x: webutil.diffsummary(diffstatgen), diffstat=diffstat, archives=web.archivelist(ctx.hex()), tags=webutil.nodetagsdict(web.repo, ctx.node()), bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()), branch=webutil.nodebranchnodefault(ctx), inbranch=webutil.nodeinbranch(web.repo, ctx), branches=webutil.nodebranchdict(web.repo, ctx), )
def bookmarks(**map): parity = paritygen(web.stripecount) marks = [b for b in web.repo._bookmarks.items() if b[1] in web.repo] for k, n in sorted(marks)[:10]: # limit to 10 bookmarks yield {'parity': parity.next(), 'bookmark': k, 'date': web.repo[n].date(), 'node': hex(n)}
def bookmarks(**map): parity = paritygen(web.stripecount) b = web.repo._bookmarks.items() for k, n in sorted(b)[:10]: # limit to 10 bookmarks yield {'parity': parity.next(), 'bookmark': k, 'date': web.repo[n].date(), 'node': hex(n)}
def changelog(web, req, tmpl, shortlog=False): query = '' if 'node' in req.form: ctx = webutil.changectx(web.repo, req) elif 'rev' in req.form: return _search(web, req, tmpl) else: ctx = web.repo['tip'] def changelist(): revs = [] if pos != -1: revs = web.repo.changelog.revs(pos, 0) curcount = 0 for rev in revs: curcount += 1 if curcount > revcount + 1: break entry = webutil.changelistentry(web, web.repo[rev], tmpl) entry['parity'] = parity.next() yield entry revcount = shortlog and web.maxshortchanges or web.maxchanges if 'revcount' in req.form: try: revcount = int(req.form.get('revcount', [revcount])[0]) revcount = max(revcount, 1) tmpl.defaults['sessionvars']['revcount'] = revcount except ValueError: pass lessvars = copy.copy(tmpl.defaults['sessionvars']) lessvars['revcount'] = max(revcount / 2, 1) morevars = copy.copy(tmpl.defaults['sessionvars']) morevars['revcount'] = revcount * 2 count = len(web.repo) pos = ctx.rev() parity = paritygen(web.stripecount) changenav = webutil.revnav(web.repo).gen(pos, revcount, count) entries = list(changelist()) latestentry = entries[:1] if len(entries) > revcount: nextentry = entries[-1:] entries = entries[:-1] else: nextentry = [] return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav, node=ctx.hex(), rev=pos, changesets=count, entries=entries, latestentry=latestentry, nextentry=nextentry, archives=web.archivelist("tip"), revcount=revcount, morevars=morevars, lessvars=lessvars, query=query)
def search(self, tmpl, query): def changelist(**map): cl = self.repo.changelog count = 0 qw = query.lower().split() def revgen(): for i in xrange(cl.count() - 1, 0, -100): l = [] for j in xrange(max(0, i - 100), i + 1): ctx = self.repo.changectx(j) l.append(ctx) l.reverse() for e in l: yield e for ctx in revgen(): miss = 0 for q in qw: if not (q in ctx.user().lower() or q in ctx.description().lower() or q in " ".join(ctx.files()).lower()): miss = 1 break if miss: continue count += 1 n = ctx.node() showtags = self.showtag(tmpl, 'changelogtag', n) yield tmpl('searchentry', parity=parity.next(), author=ctx.user(), parent=self.siblings(ctx.parents()), child=self.siblings(ctx.children()), changelogtag=showtags, desc=ctx.description(), date=ctx.date(), files=self.listfilediffs(tmpl, ctx.files(), n), rev=ctx.rev(), node=hex(n), tags=self.nodetagsdict(n), inbranch=self.nodeinbranch(ctx), branches=self.nodebranchdict(ctx)) if count >= self.maxchanges: break cl = self.repo.changelog parity = paritygen(self.stripecount) return tmpl('search', query=query, node=hex(cl.tip()), entries=changelist, archives=self.archivelist("tip"))
def entries(sortcolumn="", descending=False, subdir="", **map): rows = [] parity = paritygen(self.stripecount) for name, path in self.repos: if not name.startswith(subdir): continue name = name[len(subdir):] u = self.ui.copy() try: u.readconfig(os.path.join(path, '.hg', 'hgrc')) except Exception, e: u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e)) continue def get(section, name, default=None): return u.config(section, name, default, untrusted=True) if u.configbool("web", "hidden", untrusted=True): continue if not self.read_allowed(u, req): continue parts = [name] if 'PATH_INFO' in req.env: parts.insert(0, req.env['PATH_INFO'].rstrip('/')) if req.env['SCRIPT_NAME']: parts.insert(0, req.env['SCRIPT_NAME']) m = re.match('((?:https?://)?)(.*)', '/'.join(parts)) # squish repeated slashes out of the path component url = m.group(1) + re.sub('/+', '/', m.group(2)) + '/' # update time with local timezone try: d = (get_mtime(path), util.makedate()[1]) except OSError: continue contact = get_contact(get) description = get("web", "description", "") name = get("web", "name", name) row = dict(contact=contact or "unknown", contact_sort=contact.upper() or "unknown", name=name, name_sort=name, url=url, description=description or "unknown", description_sort=description.upper() or "unknown", lastchange=d, lastchange_sort=d[1] - d[0], archives=archivelist(u, "tip", url)) if (not sortcolumn or (sortcolumn, descending) == sortdefault): # fast path for unsorted output row['parity'] = parity.next() yield row else: rows.append((row["%s_sort" % sortcolumn], row))
def entries(sortcolumn="", descending=False, subdir="", **map): rows = [] parity = paritygen(self.stripecount) for name, path in self.repos: if not name.startswith(subdir): continue name = name[len(subdir):] u = self.ui.copy() try: u.readconfig(os.path.join(path, '.hg', 'hgrc')) except Exception, e: u.warn(_('error reading %s/.hg/hgrc: %s\n') % (path, e)) continue def get(section, name, default=None): return u.config(section, name, default, untrusted=True) if u.configbool("web", "hidden", untrusted=True): continue if not self.read_allowed(u, req): continue parts = [name] if 'PATH_INFO' in req.env: parts.insert(0, req.env['PATH_INFO'].rstrip('/')) if req.env['SCRIPT_NAME']: parts.insert(0, req.env['SCRIPT_NAME']) m = re.match('((?:https?://)?)(.*)', '/'.join(parts)) # squish repeated slashes out of the path component url = m.group(1) + re.sub('/+', '/', m.group(2)) + '/' # update time with local timezone try: d = (get_mtime(path), util.makedate()[1]) except OSError: continue contact = get_contact(get) description = get("web", "description", "") name = get("web", "name", name) row = dict(contact=contact or "unknown", contact_sort=contact.upper() or "unknown", name=name, name_sort=name, url=url, description=description or "unknown", description_sort=description.upper() or "unknown", lastchange=d, lastchange_sort=d[1]-d[0], archives=archivelist(u, "tip", url)) if (not sortcolumn or (sortcolumn, descending) == sortdefault): # fast path for unsorted output row['parity'] = parity.next() yield row else: rows.append((row["%s_sort" % sortcolumn], row))
def filediff(web, req, tmpl): """ /diff/{revision}/{path} ----------------------- Show how a file changed in a particular commit. The ``filediff`` template is rendered. This hander is registered under both the ``/diff`` and ``/filediff`` paths. ``/diff`` is used in modern code. """ fctx, ctx = None, None try: fctx = webutil.filectx(web.repo, req) except LookupError: ctx = webutil.changectx(web.repo, req) path = webutil.cleanpath(web.repo, req.form['file'][0]) if path not in ctx.files(): raise if fctx is not None: n = fctx.node() path = fctx.path() ctx = fctx.changectx() else: n = ctx.node() # path already defined in except clause parity = paritygen(web.stripecount) style = web.config('web', 'style', 'paper') if 'style' in req.form: style = req.form['style'][0] diffs = webutil.diffs(web.repo, tmpl, ctx, None, [path], parity, style) if fctx: rename = webutil.renamelink(fctx) ctx = fctx else: rename = [] ctx = ctx return tmpl("filediff", file=path, node=hex(n), rev=ctx.rev(), symrev=webutil.symrevorshortnode(req, ctx), date=ctx.date(), desc=ctx.description(), extra=ctx.extra(), author=ctx.user(), rename=rename, branch=webutil.nodebranchnodefault(ctx), parent=webutil.parents(ctx), child=webutil.children(ctx), tags=webutil.nodetagsdict(web.repo, n), bookmarks=webutil.nodebookmarksdict(web.repo, n), diff=diffs)
def branches(**map): parity = paritygen(web.stripecount) b = web.repo.branchtags() l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()] for r, n, t in sorted(l): yield {'parity': parity.next(), 'branch': t, 'node': hex(n), 'date': web.repo[n].date()}
def branches(**map): parity = paritygen(web.stripecount) b = web.repo.branchtags() l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()] for r,n,t in sorted(l): yield {'parity': parity.next(), 'branch': t, 'node': hex(n), 'date': web.repo[n].date()}
def entries(sortcolumn="", descending=False, subdir="", **map): rows = rawentries(subdir=subdir, **map) if sortcolumn and sortdefault != (sortcolumn, descending): sortkey = '%s_sort' % sortcolumn rows = sorted(rows, key=lambda x: x[sortkey], reverse=descending) for row, parity in zip(rows, paritygen(self.stripecount)): row['parity'] = parity yield row
def branches(**map): parity = paritygen(web.stripecount) b = web.repo.branchmap() l = [(-web.repo.changelog.rev(tip), tip, tag) for tag, heads, tip, closed in b.iterbranches()] for r, n, t in sorted(l): yield {'parity': parity.next(), 'branch': t, 'node': hex(n), 'date': web.repo[n].date()}
def tagentries(**map): parity = paritygen(web.stripecount) count = 0 for k, n in i: if k == "tip": # skip tip continue count += 1 if count > 10: # limit to 10 tags break yield tmpl("tagentry", parity=parity.next(), tag=k, node=hex(n), date=web.repo[n].date())
def annotate(web, req, tmpl): fctx = webutil.filectx(web.repo, req) f = fctx.path() parity = paritygen(web.stripecount) diffopts = patch.diffopts(web.repo.ui, untrusted=True, section='annotate') def annotate(**map): last = None if binary(fctx.data()): mt = (mimetypes.guess_type(fctx.path())[0] or 'application/octet-stream') lines = enumerate([((fctx.filectx(fctx.filerev()), 1), '(binary:%s)' % mt)]) else: lines = enumerate( fctx.annotate(follow=True, linenumber=True, diffopts=diffopts)) for lineno, ((f, targetline), l) in lines: fnode = f.filenode() if last != fnode: last = fnode yield { "parity": parity.next(), "node": f.hex(), "rev": f.rev(), "author": f.user(), "desc": f.description(), "extra": f.extra(), "file": f.path(), "targetline": targetline, "line": l, "lineid": "l%d" % (lineno + 1), "linenumber": "% 6d" % (lineno + 1), "revdate": f.date() } return tmpl("fileannotate", file=f, annotate=annotate, path=webutil.up(f), rev=fctx.rev(), node=fctx.hex(), author=fctx.user(), date=fctx.date(), desc=fctx.description(), extra=fctx.extra(), rename=webutil.renamelink(fctx), branch=webutil.nodebranchnodefault(fctx), parent=webutil.parents(fctx), child=webutil.children(fctx), permissions=fctx.manifest().flags(f))
def annotate(web, req, tmpl): fctx = webutil.filectx(web.repo, req) f = fctx.path() parity = paritygen(web.stripecount) diffopts = patch.diffopts(web.repo.ui, untrusted=True, section="annotate") def annotate(**map): last = None if binary(fctx.data()): mt = mimetypes.guess_type(fctx.path())[0] or "application/octet-stream" lines = enumerate([((fctx.filectx(fctx.filerev()), 1), "(binary:%s)" % mt)]) else: lines = enumerate(fctx.annotate(follow=True, linenumber=True, diffopts=diffopts)) for lineno, ((f, targetline), l) in lines: fnode = f.filenode() if last != fnode: last = fnode yield { "parity": parity.next(), "node": f.hex(), "rev": f.rev(), "author": f.user(), "desc": f.description(), "extra": f.extra(), "file": f.path(), "targetline": targetline, "line": l, "lineid": "l%d" % (lineno + 1), "linenumber": "% 6d" % (lineno + 1), "revdate": f.date(), } return tmpl( "fileannotate", file=f, annotate=annotate, path=webutil.up(f), rev=fctx.rev(), node=fctx.hex(), author=fctx.user(), date=fctx.date(), desc=fctx.description(), extra=fctx.extra(), rename=webutil.renamelink(fctx), branch=webutil.nodebranchnodefault(fctx), parent=webutil.parents(fctx), child=webutil.children(fctx), permissions=fctx.manifest().flags(f), )
def branches(**map): parity = paritygen(self.stripecount) b = self.repo.branchtags() l = [(-self.repo.changelog.rev(n), n, t) for t, n in b.items()] l.sort() for r,n,t in l: ctx = self.repo.changectx(n) yield {'parity': parity.next(), 'branch': t, 'node': hex(n), 'date': ctx.date()}
def tagentries(**map): parity = paritygen(self.stripecount) count = 0 for k, n in i: if k == "tip": # skip tip continue; count += 1 if count > 10: # limit to 10 tags break; yield tmpl("tagentry", parity=parity.next(), tag=k, node=hex(n), date=self.repo.changectx(n).date())
def changelog(self, tmpl, ctx, shortlog=False): def changelist(limit=0,**map): cl = self.repo.changelog l = [] # build a list in forward order for efficiency for i in xrange(start, end): ctx = self.repo.changectx(i) n = ctx.node() showtags = self.showtag(tmpl, 'changelogtag', n) l.insert(0, {"parity": parity.next(), "author": ctx.user(), "parent": self.siblings(ctx.parents(), i - 1), "child": self.siblings(ctx.children(), i + 1), "changelogtag": showtags, "desc": ctx.description(), "date": ctx.date(), "files": self.listfilediffs(tmpl, ctx.files(), n), "rev": i, "node": hex(n), "tags": self.nodetagsdict(n), "inbranch": self.nodeinbranch(ctx), "branches": self.nodebranchdict(ctx)}) if limit > 0: l = l[:limit] for e in l: yield e maxchanges = shortlog and self.maxshortchanges or self.maxchanges cl = self.repo.changelog count = cl.count() pos = ctx.rev() start = max(0, pos - maxchanges + 1) end = min(count, start + maxchanges) pos = end - 1 parity = paritygen(self.stripecount, offset=start-end) changenav = revnavgen(pos, maxchanges, count, self.repo.changectx) return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav, node=hex(cl.tip()), rev=pos, changesets=count, entries=lambda **x: changelist(limit=0,**x), latestentry=lambda **x: changelist(limit=1,**x), archives=self.archivelist("tip"))
def fileannotate(self, tmpl, fctx): f = fctx.path() n = fctx.filenode() fl = fctx.filelog() parity = paritygen(self.stripecount) def annotate(**map): last = None if util.binary(fctx.data()): mt = (mimetypes.guess_type(fctx.path())[0] or 'application/octet-stream') lines = enumerate([((fctx.filectx(fctx.filerev()), 1), '(binary:%s)' % mt)]) else: lines = enumerate(fctx.annotate(follow=True, linenumber=True)) for lineno, ((f, targetline), l) in lines: fnode = f.filenode() name = self.repo.ui.shortuser(f.user()) if last != fnode: last = fnode yield {"parity": parity.next(), "node": hex(f.node()), "rev": f.rev(), "author": name, "file": f.path(), "targetline": targetline, "line": l, "lineid": "l%d" % (lineno + 1), "linenumber": "% 6d" % (lineno + 1)} return tmpl("fileannotate", file=f, annotate=annotate, path=_up(f), rev=fctx.rev(), node=hex(fctx.node()), author=fctx.user(), date=fctx.date(), desc=fctx.description(), rename=self.renamelink(fl, n), branch=self.nodebranchnodefault(fctx), parent=self.siblings(fctx.parents()), child=self.siblings(fctx.children()), permissions=fctx.manifest().flags(f))
def branches(web, req, tmpl): """ /branches --------- Show information about branches. All known branches are contained in the output, even closed branches. No arguments are accepted. The ``branches`` template is rendered. """ tips = [] heads = web.repo.heads() parity = paritygen(web.stripecount) sortkey = lambda item: (not item[1], item[0].rev()) def entries(limit, **map): count = 0 if not tips: for tag, hs, tip, closed in web.repo.branchmap().iterbranches(): tips.append((web.repo[tip], closed)) for ctx, closed in sorted(tips, key=sortkey, reverse=True): if limit > 0 and count >= limit: return count += 1 if closed: status = 'closed' elif ctx.node() not in heads: status = 'inactive' else: status = 'open' yield { 'parity': parity.next(), 'branch': ctx.branch(), 'status': status, 'node': ctx.hex(), 'date': ctx.date() } return tmpl('branches', node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(0, **x), latestentry=lambda **x: entries(1, **x))
def bookmarks(web, req, tmpl): i = [b for b in web.repo._bookmarks.items() if b[1] in web.repo] parity = paritygen(web.stripecount) def entries(latestonly, **map): if latestonly: t = [min(i)] else: t = sorted(i) for k, n in t: yield {"parity": parity.next(), "bookmark": k, "date": web.repo[n].date(), "node": hex(n)} return tmpl("bookmarks", node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(latestonly=False, **x), latestentry=lambda **x: entries(latestonly=True, **x))
def bookmarks(web, req, tmpl): i = web.repo._bookmarks.items() parity = paritygen(web.stripecount) def entries(limit=0, **map): count = 0 for k, n in sorted(i): if limit > 0 and count >= limit: continue count = count + 1 yield {"parity": parity.next(), "bookmark": k, "date": web.repo[n].date(), "node": hex(n)} return tmpl("bookmarks", node=hex(web.repo.changelog.tip()), entries=lambda **x: entries(0, **x), latestentry=lambda **x: entries(1, **x))