##// END OF EJS Templates
Pager extension: switch it off if --debugger is set...
Pager extension: switch it off if --debugger is set The pager is preventing the debugger prompt and much of the debugger output to be refreshed. Moreover the pager does not make sense when debugging line by line. (This supersedes the similar ui.debugflag patch. Disabling the pager for debug output doesn't make that much sense, as this is actually when the pager might be useful.)

File last commit:

r6393:894875ea default
r6456:db5324d3 default
Show More
hgweb_mod.py
993 lines | 35.2 KiB | text/x-python | PythonLexer
Eric Hopper
Fixing up comment headers for split up code.
r2391 # hgweb/hgweb_mod.py - Web interface for a repository.
Eric Hopper
Final stage of the hgweb split up....
r2356 #
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
Eric Hopper
Final stage of the hgweb split up....
r2356 #
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Alexis S. L. Carvalho
hgweb: add compatibility code for old templates...
r6379 import os, mimetypes, re, mimetools, cStringIO
Joel Rosdahl
Expand import * to allow Pyflakes to find problems
r6211 from mercurial.node import hex, nullid, short
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 from mercurial.repo import RepoError
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833 from mercurial import mdiff, ui, hg, util, archival, patch, hook
Dirkjan Ochtman
hgweb: use bundletypes from mercurial.changegroup
r6152 from mercurial import revlog, templater, templatefilters, changegroup
Thomas Arendsen Hein
merged Edward Lee's line anchors patch
r6123 from common import get_mtime, style_map, paritygen, countgen, get_contact
from common import ErrorResponse
Dirkjan Ochtman
hgweb: explicit response status
r5993 from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
Dirkjan Ochtman
Less indirection in the WSGI web interface. This simplifies some code, and makes it more compliant with WSGI.
r5566 from request import wsgirequest
Dirkjan Ochtman
separate the wire protocol commands from the user interface commands
r5598 import webcommands, protocol
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: extract constant to global level
r5597 shortcuts = {
'cl': [('cmd', ['changelog']), ('rev', None)],
'sl': [('cmd', ['shortlog']), ('rev', None)],
'cs': [('cmd', ['changeset']), ('node', None)],
'f': [('cmd', ['file']), ('filenode', None)],
'fl': [('cmd', ['filelog']), ('filenode', None)],
'fd': [('cmd', ['filediff']), ('node', None)],
'fa': [('cmd', ['annotate']), ('filenode', None)],
'mf': [('cmd', ['manifest']), ('manifest', None)],
'ca': [('cmd', ['archive']), ('node', None)],
'tags': [('cmd', ['tags'])],
'tip': [('cmd', ['changeset']), ('node', ['tip'])],
'static': [('cmd', ['static']), ('file', None)]
}
Eric Hopper
Final stage of the hgweb split up....
r2356
def _up(p):
if p[0] != "/":
p = "/" + p
if p[-1] == "/":
p = p[:-1]
up = os.path.dirname(p)
if up == "/":
return "/"
return up + "/"
Brendan Cully
Convert changenav bar from revisions to hashes (closes issue189)
r3422 def revnavgen(pos, pagelen, limit, nodefunc):
Brendan Cully
hgweb: hoist changenav up, and use it in the filelog
r3407 def seq(factor, limit=None):
if limit:
yield limit
if limit >= 20 and limit <= 40:
yield 50
else:
yield 1 * factor
yield 3 * factor
for f in seq(factor * 10):
yield f
def nav(**map):
l = []
last = 0
for f in seq(1, pagelen):
if f < pagelen or f <= last:
continue
if f > limit:
break
last = f
if pos + f < limit:
Brendan Cully
Convert changenav bar from revisions to hashes (closes issue189)
r3422 l.append(("+%d" % f, hex(nodefunc(pos + f).node())))
Brendan Cully
hgweb: hoist changenav up, and use it in the filelog
r3407 if pos - f >= 0:
Brendan Cully
Convert changenav bar from revisions to hashes (closes issue189)
r3422 l.insert(0, ("-%d" % f, hex(nodefunc(pos - f).node())))
Brendan Cully
hgweb: hoist changenav up, and use it in the filelog
r3407
Brendan Cully
Fix test-oldcgi after navbar update
r3424 try:
yield {"label": "(0)", "node": hex(nodefunc('0').node())}
Brendan Cully
hgweb: hoist changenav up, and use it in the filelog
r3407
Brendan Cully
Fix test-oldcgi after navbar update
r3424 for label, node in l:
yield {"label": label, "node": node}
Brendan Cully
hgweb: hoist changenav up, and use it in the filelog
r3407
Thomas Arendsen Hein
Explicitly use "tip" in revision navigation....
r3427 yield {"label": "tip", "node": "tip"}
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 except RepoError:
Brendan Cully
Fix test-oldcgi after navbar update
r3424 pass
Brendan Cully
hgweb: hoist changenav up, and use it in the filelog
r3407
return nav
Eric Hopper
Final stage of the hgweb split up....
r2356 class hgweb(object):
Thomas Arendsen Hein
Backed out changeset b913d3aacddc (see issue971/msg5317)
r6141 def __init__(self, repo, name=None):
Christian Ebert
Use isinstance instead of type == type
r4874 if isinstance(repo, str):
Thomas Arendsen Hein
Backed out changeset b913d3aacddc (see issue971/msg5317)
r6141 parentui = ui.ui(report_untrusted=False, interactive=False)
Dirkjan Ochtman
Prevent WSGI apps from touching sys.stdin by setting ui.interactive to False.
r5289 self.repo = hg.repository(parentui, repo)
Eric Hopper
Final stage of the hgweb split up....
r2356 else:
self.repo = repo
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833 hook.redirect(True)
Eric Hopper
Final stage of the hgweb split up....
r2356 self.mtime = -1
self.reponame = name
self.archives = 'zip', 'gz', 'bz2'
Frank Kingswood
hgweb: Configurable zebra stripes...
r2666 self.stripecount = 1
Dirkjan Ochtman
hgweb: use bundletypes from mercurial.changegroup
r6152 self._capabilities = None
Alexis S. L. Carvalho
use untrusted settings in hgweb...
r3555 # a repo owner may set web.templates in .hg/hgrc to get any file
# readable by the user running the CGI script
self.templatepath = self.config("web", "templates",
templater.templatepath(),
untrusted=False)
# The CGI scripts are often run by a user different from the repo owner.
# Trust the settings from the .hg/hgrc files by default.
def config(self, section, name, default=None, untrusted=True):
return self.repo.ui.config(section, name, default,
untrusted=untrusted)
def configbool(self, section, name, default=False, untrusted=True):
return self.repo.ui.configbool(section, name, default,
untrusted=untrusted)
def configlist(self, section, name, default=None, untrusted=True):
return self.repo.ui.configlist(section, name, default,
untrusted=untrusted)
Eric Hopper
Final stage of the hgweb split up....
r2356
def refresh(self):
mtime = get_mtime(self.repo.root)
if mtime != self.mtime:
self.mtime = mtime
self.repo = hg.repository(self.repo.ui, self.repo.root)
Alexis S. L. Carvalho
use untrusted settings in hgweb...
r3555 self.maxchanges = int(self.config("web", "maxchanges", 10))
self.stripecount = int(self.config("web", "stripes", 1))
self.maxshortchanges = int(self.config("web", "maxshortchanges", 60))
self.maxfiles = int(self.config("web", "maxfiles", 10))
self.allowpull = self.configbool("web", "allowpull", True)
OHASHI Hideya <ohachige at gmail.com>
Enable to select encoding in hgrc web section...
r4690 self.encoding = self.config("web", "encoding", util._encoding)
Dirkjan Ochtman
hgweb: use bundletypes from mercurial.changegroup
r6152 self._capabilities = None
def capabilities(self):
if self._capabilities is not None:
return self._capabilities
caps = ['lookup', 'changegroupsubset']
if self.configbool('server', 'uncompressed'):
caps.append('stream=%d' % self.repo.changelog.version)
if changegroup.bundlepriority:
caps.append('unbundle=%s' % ','.join(changegroup.bundlepriority))
self._capabilities = caps
return caps
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591 def run(self):
if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
raise RuntimeError("This function is only intended to be called while running as a CGI script.")
import mercurial.hgweb.wsgicgi as wsgicgi
wsgicgi.launch(self)
def __call__(self, env, respond):
req = wsgirequest(env, respond)
self.run_wsgi(req)
return req
def run_wsgi(self, req):
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 self.refresh()
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 # expand form shortcuts
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 for k in shortcuts.iterkeys():
if k in req.form:
for name, value in shortcuts[k]:
if value is None:
value = req.form[k]
req.form[name] = value
del req.form[k]
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 # work with CGI variables to create coherent structure
# use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 req.url = req.env['SCRIPT_NAME']
if not req.url.endswith('/'):
req.url += '/'
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 if 'REPO_NAME' in req.env:
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 req.url += req.env['REPO_NAME'] + '/'
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 if req.env.get('PATH_INFO'):
parts = req.env.get('PATH_INFO').strip('/').split('/')
repo_parts = req.env.get('REPO_NAME', '').split('/')
if parts[:len(repo_parts)] == repo_parts:
parts = parts[len(repo_parts):]
query = '/'.join(parts)
else:
query = req.env['QUERY_STRING'].split('&', 1)[0]
query = query.split(';', 1)[0]
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 # translate user-visible url structure to internal structure
args = query.split('/', 2)
if 'cmd' not in req.form and args and args[0]:
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591
cmd = args.pop(0)
style = cmd.rfind('-')
if style != -1:
req.form['style'] = [cmd[:style]]
cmd = cmd[style+1:]
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591 # avoid accepting e.g. style parameter as command
Dirkjan Ochtman
separate the wire protocol commands from the user interface commands
r5598 if hasattr(webcommands, cmd) or hasattr(protocol, cmd):
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591 req.form['cmd'] = [cmd]
if args and args[0]:
node = args.pop(0)
req.form['node'] = [node]
if args:
req.form['file'] = args
if cmd == 'static':
req.form['file'] = req.form['node']
elif cmd == 'archive':
fn = req.form['node'][0]
for type_, spec in self.archive_specs.iteritems():
ext = spec[2]
if fn.endswith(ext):
req.form['node'] = [fn[:-len(ext)]]
req.form['type'] = [type_]
Dirkjan Ochtman
hgweb: separate protocol calls from interface calls (issue996)...
r6149 # process this if it's a protocol request
cmd = req.form.get('cmd', [''])[0]
if cmd in protocol.__all__:
method = getattr(protocol, cmd)
method(self, req)
return
# process the web interface request
Dirkjan Ochtman
hgweb: split out templater definition
r5599
try:
Dirkjan Ochtman
hgweb: separate protocol calls from interface calls (issue996)...
r6149 tmpl = self.templater(req)
Alexis S. L. Carvalho
hgweb: add compatibility code for old templates...
r6379 try:
ctype = tmpl('mimetype', encoding=self.encoding)
ctype = templater.stringify(ctype)
except KeyError:
# old templates with inline HTTP headers?
if 'mimetype' in tmpl:
raise
header = tmpl('header', encoding=self.encoding)
header_file = cStringIO.StringIO(templater.stringify(header))
msg = mimetools.Message(header_file, 0)
ctype = msg['content-type']
Dirkjan Ochtman
hgweb: separate protocol calls from interface calls (issue996)...
r6149
if cmd == '':
req.form['cmd'] = [tmpl.cache['default']]
cmd = req.form['cmd'][0]
Dirkjan Ochtman
hgweb: fast path for sending raw files
r5890
Dirkjan Ochtman
hgweb: separate protocol calls from interface calls (issue996)...
r6149 if cmd not in webcommands.__all__:
Dirkjan Ochtman
hgweb: better error messages
r6368 msg = 'no such method: %s' % cmd
Dirkjan Ochtman
hgweb: separate protocol calls from interface calls (issue996)...
r6149 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
elif cmd == 'file' and 'raw' in req.form.get('style', []):
self.ctype = ctype
content = webcommands.rawfile(self, req, tmpl)
else:
content = getattr(webcommands, cmd)(self, req, tmpl)
req.respond(HTTP_OK, ctype)
Dirkjan Ochtman
hgweb: fast path for sending raw files
r5890
Dirkjan Ochtman
hgweb: separate protocol calls from interface calls (issue996)...
r6149 req.write(content)
del tmpl
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600
except revlog.LookupError, err:
Dirkjan Ochtman
hgweb: explicit response status
r5993 req.respond(HTTP_NOT_FOUND, ctype)
Dirkjan Ochtman
hgweb: fix breakage in python < 2.5 introduced in 2c370f08c486
r6374 msg = str(err)
if 'manifest' not in msg:
Dirkjan Ochtman
hgweb: better error messages
r6368 msg = 'revision not found: %s' % err.name
req.write(tmpl('error', error=msg))
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 except (RepoError, revlog.RevlogError), inst:
Dirkjan Ochtman
hgweb: explicit response status
r5993 req.respond(HTTP_SERVER_ERROR, ctype)
req.write(tmpl('error', error=str(inst)))
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 except ErrorResponse, inst:
Dirkjan Ochtman
hgweb: explicit response status
r5993 req.respond(inst.code, ctype)
req.write(tmpl('error', error=inst.message))
Dirkjan Ochtman
hgweb: split out templater definition
r5599
def templater(self, req):
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 # determine scheme, port and server name
# this is needed to create absolute urls
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591
proto = req.env.get('wsgi.url_scheme')
if proto == 'https':
proto = 'https'
default_port = "443"
else:
proto = 'http'
default_port = "80"
port = req.env["SERVER_PORT"]
port = port != default_port and (":" + port) or ""
urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
staticurl = self.config("web", "staticurl") or req.url + 'static/'
if not staticurl.endswith('/'):
staticurl += '/'
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 # some functions for the templater
def header(**map):
Alexis S. L. Carvalho
hgweb: add compatibility code for old templates...
r6379 header = tmpl('header', encoding=self.encoding, **map)
if 'mimetype' not in tmpl:
# old template with inline HTTP headers
header_file = cStringIO.StringIO(templater.stringify(header))
msg = mimetools.Message(header_file, 0)
header = header_file.read()
yield header
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596
def footer(**map):
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 yield tmpl("footer", **map)
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596
def motd(**map):
yield self.config("web", "motd", "")
def sessionvars(**map):
fields = []
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 if 'style' in req.form:
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 style = req.form['style'][0]
if style != self.config('web', 'style', ''):
fields.append(('style', style))
separator = req.url[-1] == '?' and ';' or '?'
for name, value in fields:
yield dict(name=name, value=value, separator=separator)
separator = ';'
Dirkjan Ochtman
hgweb: split out templater definition
r5599 # figure out which style to use
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 style = self.config("web", "style", "")
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 if 'style' in req.form:
Dirkjan Ochtman
hgweb: get rid of some nested functions
r5596 style = req.form['style'][0]
mapfile = style_map(self.templatepath, style)
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591 if not self.reponame:
self.reponame = (self.config("web", "name")
or req.env.get('REPO_NAME')
or req.url.strip('/') or self.repo.root)
Dirkjan Ochtman
hgweb: split out templater definition
r5599 # create the templater
Matt Mackall
templates: move filters to their own module...
r5976 tmpl = templater.templater(mapfile, templatefilters.filters,
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 defaults={"url": req.url,
"staticurl": staticurl,
"urlbase": urlbase,
"repo": self.reponame,
"header": header,
"footer": footer,
"motd": motd,
"sessionvars": sessionvars
})
return tmpl
Dirkjan Ochtman
split out hgweb commands into a separate file, move some code around
r5591
Eric Hopper
Final stage of the hgweb split up....
r2356 def archivelist(self, nodeid):
Alexis S. L. Carvalho
use untrusted settings in hgweb...
r3555 allowed = self.configlist("web", "allow_archive")
Brendan Cully
hgweb: accept NewWebInterface URLs
r3260 for i, spec in self.archive_specs.iteritems():
Alexis S. L. Carvalho
use untrusted settings in hgweb...
r3555 if i in allowed or self.configbool("web", "allow" + i):
Brendan Cully
hgweb: accept NewWebInterface URLs
r3260 yield {"type" : i, "extension" : spec[2], "node" : nodeid}
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def listfilediffs(self, tmpl, files, changeset):
Eric Hopper
Final stage of the hgweb split up....
r2356 for f in files[:self.maxfiles]:
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 yield tmpl("filedifflink", node=hex(changeset), file=f)
Eric Hopper
Final stage of the hgweb split up....
r2356 if len(files) > self.maxfiles:
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 yield tmpl("fileellipses")
Eric Hopper
Final stage of the hgweb split up....
r2356
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 def siblings(self, siblings=[], hiderev=None, **args):
siblings = [s for s in siblings if s.node() != nullid]
if len(siblings) == 1 and siblings[0].rev() == hiderev:
Eric Hopper
Final stage of the hgweb split up....
r2356 return
for s in siblings:
Brendan Cully
hgweb: fix parent/child links across renames
r3392 d = {'node': hex(s.node()), 'rev': s.rev()}
Brendan Cully
hgweb: really fix parent/child rename links
r3394 if hasattr(s, 'path'):
d['file'] = s.path()
Brendan Cully
hgweb: fix parent/child links across renames
r3392 d.update(args)
yield d
Eric Hopper
Final stage of the hgweb split up....
r2356
def renamelink(self, fl, node):
r = fl.renamed(node)
if r:
return [dict(file=r[0], node=hex(r[1]))]
return []
Brendan Cully
Small cleanups for the new tag code
r4539 def nodetagsdict(self, node):
return [{"name": i} for i in self.repo.nodetags(node)]
Josef "Jeff" Sipek
gitweb: Display branch and tag labels...
r4538
Brendan Cully
Small cleanups for the new tag code
r4539 def nodebranchdict(self, ctx):
branches = []
branch = ctx.branch()
Alexis S. L. Carvalho
hgweb: don't raise an exception when displying empty repos...
r5331 # If this is an empty repo, ctx.node() == nullid,
# ctx.branch() == 'default', but branchtags() is
# an empty dict. Using dict.get avoids a traceback.
if self.repo.branchtags().get(branch) == ctx.node():
Brendan Cully
Small cleanups for the new tag code
r4539 branches.append({"name": branch})
return branches
Josef "Jeff" Sipek
gitweb: Display branch and tag labels...
r4538
Florent Guillaume
hgweb_mod: add branch helper functions to use in templates
r6249 def nodeinbranch(self, ctx):
branches = []
branch = ctx.branch()
if branch != 'default' and self.repo.branchtags().get(branch) != ctx.node():
branches.append({"name": branch})
return branches
def nodebranchnodefault(self, ctx):
branches = []
branch = ctx.branch()
if branch != 'default':
branches.append({"name": branch})
return branches
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def showtag(self, tmpl, t1, node=nullid, **args):
Eric Hopper
Final stage of the hgweb split up....
r2356 for t in self.repo.nodetags(node):
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 yield tmpl(t1, tag=t, **args)
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def diff(self, tmpl, node1, node2, files):
Eric Hopper
Final stage of the hgweb split up....
r2356 def filterfiles(filters, files):
l = [x for x in files if x in filters]
for t in filters:
if t and t[-1] != os.sep:
t += os.sep
l += [x for x in files if x.startswith(t)]
return l
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount)
Eric Hopper
Final stage of the hgweb split up....
r2356 def diffblock(diff, f, fn):
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 yield tmpl("diffblock",
lines=prettyprintlines(diff),
parity=parity.next(),
file=f,
filenode=hex(fn or nullid))
Eric Hopper
Final stage of the hgweb split up....
r2356
Edward Lee
Add line anchors to annotate, changeset, diff, file views for hgweb
r6122 blockcount = countgen()
Eric Hopper
Final stage of the hgweb split up....
r2356 def prettyprintlines(diff):
Edward Lee
Add line anchors to annotate, changeset, diff, file views for hgweb
r6122 blockno = blockcount.next()
for lineno, l in enumerate(diff.splitlines(1)):
if blockno == 0:
lineno = lineno + 1
else:
lineno = "%d.%d" % (blockno, lineno + 1)
Eric Hopper
Final stage of the hgweb split up....
r2356 if l.startswith('+'):
Thomas Arendsen Hein
merged Edward Lee's line anchors patch
r6123 ltype = "difflineplus"
Eric Hopper
Final stage of the hgweb split up....
r2356 elif l.startswith('-'):
Thomas Arendsen Hein
merged Edward Lee's line anchors patch
r6123 ltype = "difflineminus"
Eric Hopper
Final stage of the hgweb split up....
r2356 elif l.startswith('@'):
Thomas Arendsen Hein
merged Edward Lee's line anchors patch
r6123 ltype = "difflineat"
Eric Hopper
Final stage of the hgweb split up....
r2356 else:
Thomas Arendsen Hein
merged Edward Lee's line anchors patch
r6123 ltype = "diffline"
yield tmpl(ltype,
line=l,
lineid="l%s" % lineno,
linenumber="% 8s" % lineno)
Eric Hopper
Final stage of the hgweb split up....
r2356
r = self.repo
Benoit Boissinot
hgweb: use contexts, fix coding style
r3973 c1 = r.changectx(node1)
c2 = r.changectx(node2)
date1 = util.datestr(c1.date())
date2 = util.datestr(c2.date())
Eric Hopper
Final stage of the hgweb split up....
r2356
Giorgos Keramidas
hgweb: repo.changes() is now called repo.status()
r2876 modified, added, removed, deleted, unknown = r.status(node1, node2)[:5]
Eric Hopper
Final stage of the hgweb split up....
r2356 if files:
modified, added, removed = map(lambda x: filterfiles(files, x),
(modified, added, removed))
Alexis S. L. Carvalho
use untrusted settings in hgweb...
r3555 diffopts = patch.diffopts(self.repo.ui, untrusted=True)
Eric Hopper
Final stage of the hgweb split up....
r2356 for f in modified:
Benoit Boissinot
hgweb: use contexts, fix coding style
r3973 to = c1.filectx(f).data()
tn = c2.filectx(f).data()
Rocco Rutte
hgweb_mod: update unidiff() calls and finish e5eedd74e70f job
r5486 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
Vadim Gelfer
refactor text diff/patch code....
r2874 opts=diffopts), f, tn)
Eric Hopper
Final stage of the hgweb split up....
r2356 for f in added:
to = None
Benoit Boissinot
hgweb: use contexts, fix coding style
r3973 tn = c2.filectx(f).data()
Rocco Rutte
hgweb_mod: update unidiff() calls and finish e5eedd74e70f job
r5486 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
Vadim Gelfer
refactor text diff/patch code....
r2874 opts=diffopts), f, tn)
Eric Hopper
Final stage of the hgweb split up....
r2356 for f in removed:
Benoit Boissinot
hgweb: use contexts, fix coding style
r3973 to = c1.filectx(f).data()
Eric Hopper
Final stage of the hgweb split up....
r2356 tn = None
Rocco Rutte
hgweb_mod: update unidiff() calls and finish e5eedd74e70f job
r5486 yield diffblock(mdiff.unidiff(to, date1, tn, date2, f, f,
Vadim Gelfer
refactor text diff/patch code....
r2874 opts=diffopts), f, tn)
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def changelog(self, tmpl, ctx, shortlog=False):
Robert Bachmann
Added support for the Atom syndication format
r5269 def changelist(limit=0,**map):
Eric Hopper
Final stage of the hgweb split up....
r2356 cl = self.repo.changelog
l = [] # build a list in forward order for efficiency
Benoit Boissinot
use xrange instead of range
r3473 for i in xrange(start, end):
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 ctx = self.repo.changectx(i)
n = ctx.node()
Dirkjan Ochtman
hgweb: fix parameter mixup (issue1001)
r6168 showtags = self.showtag(tmpl, 'changelogtag', n)
Eric Hopper
Final stage of the hgweb split up....
r2356
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 l.insert(0, {"parity": parity.next(),
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 "author": ctx.user(),
"parent": self.siblings(ctx.parents(), i - 1),
"child": self.siblings(ctx.children(), i + 1),
Dirkjan Ochtman
hgweb: fix parameter mixup (issue1001)
r6168 "changelogtag": showtags,
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 "desc": ctx.description(),
"date": ctx.date(),
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 "files": self.listfilediffs(tmpl, ctx.files(), n),
Eric Hopper
Final stage of the hgweb split up....
r2356 "rev": i,
Josef "Jeff" Sipek
gitweb: Display branch and tag labels...
r4538 "node": hex(n),
Brendan Cully
Small cleanups for the new tag code
r4539 "tags": self.nodetagsdict(n),
Florent Guillaume
hgweb_mod: add branch helper functions to use in templates
r6249 "inbranch": self.nodeinbranch(ctx),
Brendan Cully
Small cleanups for the new tag code
r4539 "branches": self.nodebranchdict(ctx)})
Eric Hopper
Final stage of the hgweb split up....
r2356
Robert Bachmann
Added support for the Atom syndication format
r5269 if limit > 0:
l = l[:limit]
Eric Hopper
Final stage of the hgweb split up....
r2356 for e in l:
yield e
Josef "Jeff" Sipek
[hgweb] Implemented shortlog (gitweb templates only)
r2684 maxchanges = shortlog and self.maxshortchanges or self.maxchanges
Eric Hopper
Final stage of the hgweb split up....
r2356 cl = self.repo.changelog
count = cl.count()
Brendan Cully
hgweb: hoist changenav up, and use it in the filelog
r3407 pos = ctx.rev()
Josef "Jeff" Sipek
[hgweb] Implemented shortlog (gitweb templates only)
r2684 start = max(0, pos - maxchanges + 1)
end = min(count, start + maxchanges)
Eric Hopper
Final stage of the hgweb split up....
r2356 pos = end - 1
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount, offset=start-end)
Eric Hopper
Final stage of the hgweb split up....
r2356
Brendan Cully
Convert changenav bar from revisions to hashes (closes issue189)
r3422 changenav = revnavgen(pos, maxchanges, count, self.repo.changectx)
Brendan Cully
hgweb: hoist changenav up, and use it in the filelog
r3407
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 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"))
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def search(self, tmpl, query):
Eric Hopper
Final stage of the hgweb split up....
r2356
def changelist(**map):
cl = self.repo.changelog
count = 0
qw = query.lower().split()
def revgen():
Benoit Boissinot
use xrange instead of range
r3473 for i in xrange(cl.count() - 1, 0, -100):
Eric Hopper
Final stage of the hgweb split up....
r2356 l = []
Dirkjan Ochtman
hgweb: fix search skipping tip
r6017 for j in xrange(max(0, i - 100), i + 1):
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 ctx = self.repo.changectx(j)
l.append(ctx)
Eric Hopper
Final stage of the hgweb split up....
r2356 l.reverse()
for e in l:
yield e
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 for ctx in revgen():
Eric Hopper
Final stage of the hgweb split up....
r2356 miss = 0
for q in qw:
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 if not (q in ctx.user().lower() or
q in ctx.description().lower() or
TK Soh
hgweb: expand keyword search to full list of files
r4323 q in " ".join(ctx.files()).lower()):
Eric Hopper
Final stage of the hgweb split up....
r2356 miss = 1
break
if miss:
continue
count += 1
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 n = ctx.node()
Dirkjan Ochtman
hgweb: fix parameter mixup (issue1001)
r6168 showtags = self.showtag(tmpl, 'changelogtag', n)
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 yield tmpl('searchentry',
parity=parity.next(),
author=ctx.user(),
parent=self.siblings(ctx.parents()),
child=self.siblings(ctx.children()),
Dirkjan Ochtman
hgweb: fix parameter mixup (issue1001)
r6168 changelogtag=showtags,
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 desc=ctx.description(),
date=ctx.date(),
files=self.listfilediffs(tmpl, ctx.files(), n),
rev=ctx.rev(),
node=hex(n),
tags=self.nodetagsdict(n),
Florent Guillaume
hgweb_mod: add branch helper functions to use in templates
r6249 inbranch=self.nodeinbranch(ctx),
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 branches=self.nodebranchdict(ctx))
Eric Hopper
Final stage of the hgweb split up....
r2356
if count >= self.maxchanges:
break
cl = self.repo.changelog
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount)
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 return tmpl('search',
query=query,
node=hex(cl.tip()),
entries=changelist,
archives=self.archivelist("tip"))
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def changeset(self, tmpl, ctx):
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 n = ctx.node()
Dirkjan Ochtman
hgweb: fix parameter mixup (issue1001)
r6168 showtags = self.showtag(tmpl, 'changesettag', n)
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 parents = ctx.parents()
p1 = parents[0].node()
Eric Hopper
Final stage of the hgweb split up....
r2356
files = []
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount)
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 for f in ctx.files():
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 files.append(tmpl("filenodelink",
node=hex(n), file=f,
parity=parity.next()))
Eric Hopper
Final stage of the hgweb split up....
r2356
def diff(**map):
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 yield self.diff(tmpl, p1, n, None)
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 return tmpl('changeset',
diff=diff,
rev=ctx.rev(),
node=hex(n),
parent=self.siblings(parents),
child=self.siblings(ctx.children()),
Dirkjan Ochtman
hgweb: fix parameter mixup (issue1001)
r6168 changesettag=showtags,
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 author=ctx.user(),
desc=ctx.description(),
date=ctx.date(),
files=files,
archives=self.archivelist(hex(n)),
tags=self.nodetagsdict(n),
Florent Guillaume
hgweb_mod: add branch helper functions to use in templates
r6249 branch=self.nodebranchnodefault(ctx),
inbranch=self.nodeinbranch(ctx),
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 branches=self.nodebranchdict(ctx))
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def filelog(self, tmpl, fctx):
Brendan Cully
hgweb: kill off #filenode#
r3206 f = fctx.path()
fl = fctx.filelog()
Eric Hopper
Final stage of the hgweb split up....
r2356 count = fl.count()
Brendan Cully
hgweb: hoist changenav up, and use it in the filelog
r3407 pagelen = self.maxshortchanges
Thomas Arendsen Hein
Fixed page overlap for file revision links in hgweb....
r3409 pos = fctx.filerev()
Thomas Arendsen Hein
white space and line break cleanups
r3673 start = max(0, pos - pagelen + 1)
Thomas Arendsen Hein
Fixed page overlap for file revision links in hgweb....
r3409 end = min(count, start + pagelen)
pos = end - 1
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount, offset=start-end)
Eric Hopper
Final stage of the hgweb split up....
r2356
Robert Bachmann
Added support for the Atom syndication format
r5269 def entries(limit=0, **map):
Eric Hopper
Final stage of the hgweb split up....
r2356 l = []
Benoit Boissinot
use xrange instead of range
r3473 for i in xrange(start, end):
Brendan Cully
hgweb: teach siblings and callers to use contexts
r3208 ctx = fctx.filectx(i)
Eric Hopper
Final stage of the hgweb split up....
r2356 n = fl.node(i)
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 l.insert(0, {"parity": parity.next(),
Eric Hopper
Final stage of the hgweb split up....
r2356 "filerev": i,
"file": f,
Brendan Cully
hgweb: kill off #filenode#
r3206 "node": hex(ctx.node()),
"author": ctx.user(),
"date": ctx.date(),
Eric Hopper
Final stage of the hgweb split up....
r2356 "rename": self.renamelink(fl, n),
Brendan Cully
hgweb: fix parent/child links across renames
r3392 "parent": self.siblings(fctx.parents()),
"child": self.siblings(fctx.children()),
Brendan Cully
hgweb: kill off #filenode#
r3206 "desc": ctx.description()})
Eric Hopper
Final stage of the hgweb split up....
r2356
Robert Bachmann
Added support for the Atom syndication format
r5269 if limit > 0:
l = l[:limit]
Eric Hopper
Final stage of the hgweb split up....
r2356 for e in l:
yield e
Brendan Cully
Convert changenav bar from revisions to hashes (closes issue189)
r3422 nodefunc = lambda x: fctx.filectx(fileid=x)
nav = revnavgen(pos, pagelen, count, nodefunc)
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 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))
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def filerevision(self, tmpl, fctx):
Brendan Cully
hgweb: kill off #filenode#
r3206 f = fctx.path()
text = fctx.data()
fl = fctx.filelog()
n = fctx.filenode()
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount)
Eric Hopper
Final stage of the hgweb split up....
r2356
if util.binary(text):
Dirkjan Ochtman
hgweb: get rid of raw-related code in hgweb.filerevision()
r5962 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
text = '(binary:%s)' % mt
Eric Hopper
Final stage of the hgweb split up....
r2356
def lines():
Edward Lee
Add line anchors to annotate, changeset, diff, file views for hgweb
r6122 for lineno, t in enumerate(text.splitlines(1)):
Eric Hopper
Final stage of the hgweb split up....
r2356 yield {"line": t,
Edward Lee
Add line anchors to annotate, changeset, diff, file views for hgweb
r6122 "lineid": "l%d" % (lineno + 1),
"linenumber": "% 6d" % (lineno + 1),
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 "parity": parity.next()}
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 return tmpl("filerevision",
file=f,
path=_up(f),
text=lines(),
rev=fctx.rev(),
node=hex(fctx.node()),
author=fctx.user(),
date=fctx.date(),
desc=fctx.description(),
Florent Guillaume
hgweb_mod: add branch helper functions to use in templates
r6249 branch=self.nodebranchnodefault(fctx),
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 parent=self.siblings(fctx.parents()),
child=self.siblings(fctx.children()),
rename=self.renamelink(fl, n),
permissions=fctx.manifest().flags(f))
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def fileannotate(self, tmpl, fctx):
Brendan Cully
hgweb: kill off #filenode#
r3206 f = fctx.path()
Brendan Cully
hgweb: use filectx.annotate instead of filelog
r3173 n = fctx.filenode()
fl = fctx.filelog()
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount)
Eric Hopper
Final stage of the hgweb split up....
r2356
def annotate(**map):
last = None
Thomas Arendsen Hein
hgweb/annotate: handle binary files like hgweb/file
r6203 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))
Thomas Arendsen Hein
Make hgweb annotate link to target line numbers (issue623)
r6125 for lineno, ((f, targetline), l) in lines:
Brendan Cully
hgweb: make annotate line revisions point to annotation for that rev
r3175 fnode = f.filenode()
Brendan Cully
hgweb: use filectx.annotate instead of filelog
r3173 name = self.repo.ui.shortuser(f.user())
Eric Hopper
Final stage of the hgweb split up....
r2356
Brendan Cully
hgweb: make annotate line revisions point to annotation for that rev
r3175 if last != fnode:
last = fnode
Eric Hopper
Final stage of the hgweb split up....
r2356
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 yield {"parity": parity.next(),
Brendan Cully
hgweb: yield filenode as well as node in annotate, use filenode in annotateline
r3178 "node": hex(f.node()),
Brendan Cully
Back out d8eba1c3ce9b and a004164dbeef
r3403 "rev": f.rev(),
Eric Hopper
Final stage of the hgweb split up....
r2356 "author": name,
Brendan Cully
hgweb: use filectx.annotate instead of filelog
r3173 "file": f.path(),
Thomas Arendsen Hein
Make hgweb annotate link to target line numbers (issue623)
r6125 "targetline": targetline,
Edward Lee
Add line anchors to annotate, changeset, diff, file views for hgweb
r6122 "line": l,
"lineid": "l%d" % (lineno + 1),
"linenumber": "% 6d" % (lineno + 1)}
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 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),
Florent Guillaume
hgweb_mod: add branch helper functions to use in templates
r6249 branch=self.nodebranchnodefault(fctx),
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 parent=self.siblings(fctx.parents()),
child=self.siblings(fctx.children()),
permissions=fctx.manifest().flags(f))
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def manifest(self, tmpl, ctx, path):
Brendan Cully
hgweb: kill #manifest#
r3205 mf = ctx.manifest()
node = ctx.node()
Eric Hopper
Final stage of the hgweb split up....
r2356
files = {}
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount)
Eric Hopper
Final stage of the hgweb split up....
r2356
Benoit Boissinot
hgweb: fix handling of path for old style template...
r3595 if path and path[-1] != "/":
path += "/"
l = len(path)
abspath = "/" + path
Eric Hopper
Final stage of the hgweb split up....
r2356
Thomas Arendsen Hein
white space and line break cleanups
r3673 for f, n in mf.items():
Benoit Boissinot
hgweb: fix handling of path for old style template...
r3595 if f[:l] != path:
Eric Hopper
Final stage of the hgweb split up....
r2356 continue
remain = f[l:]
if "/" in remain:
Benoit Boissinot
use __contains__, index or split instead of str.find...
r2579 short = remain[:remain.index("/") + 1] # bleah
Eric Hopper
Final stage of the hgweb split up....
r2356 files[short] = (f, None)
else:
short = os.path.basename(remain)
files[short] = (f, n)
Bryan O'Sullivan
hgweb: return meaningful HTTP status codes instead of nonsense
r5561 if not files:
Dirkjan Ochtman
hgweb: better error messages
r6368 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
Bryan O'Sullivan
hgweb: return meaningful HTTP status codes instead of nonsense
r5561
Eric Hopper
Final stage of the hgweb split up....
r2356 def filelist(**map):
fl = files.keys()
fl.sort()
for f in fl:
full, fnode = files[f]
if not fnode:
continue
Thomas Arendsen Hein
hgweb: Show date of last change for each file in manifest
r5273 fctx = ctx.filectx(full)
Eric Hopper
Final stage of the hgweb split up....
r2356 yield {"file": full,
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 "parity": parity.next(),
Eric Hopper
Final stage of the hgweb split up....
r2356 "basename": f,
Thomas Arendsen Hein
hgweb: Show date of last change for each file in manifest
r5273 "date": fctx.changectx().date(),
"size": fctx.size(),
Alexis S. L. Carvalho
hgweb: use lrwxrwxrwx as the permissions of a symlink
r4745 "permissions": mf.flags(full)}
Eric Hopper
Final stage of the hgweb split up....
r2356
def dirlist(**map):
fl = files.keys()
fl.sort()
for f in fl:
full, fnode = files[f]
if fnode:
continue
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 yield {"parity": parity.next(),
Alexis S. L. Carvalho
hgweb: don't use os.path.join to build URL parts
r5064 "path": "%s%s" % (abspath, f),
Eric Hopper
Final stage of the hgweb split up....
r2356 "basename": f[:-1]}
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 return tmpl("manifest",
rev=ctx.rev(),
node=hex(node),
path=abspath,
up=_up(abspath),
upparity=parity.next(),
fentries=filelist,
dentries=dirlist,
archives=self.archivelist(hex(node)),
tags=self.nodetagsdict(node),
Florent Guillaume
hgweb_mod: add branch helper functions to use in templates
r6249 inbranch=self.nodeinbranch(ctx),
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 branches=self.nodebranchdict(ctx))
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def tags(self, tmpl):
Eric Hopper
Final stage of the hgweb split up....
r2356 i = self.repo.tagslist()
i.reverse()
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount)
Eric Hopper
Final stage of the hgweb split up....
r2356
Robert Bachmann
Added support for the Atom syndication format
r5269 def entries(notip=False,limit=0, **map):
count = 0
Thomas Arendsen Hein
white space and line break cleanups
r3673 for k, n in i:
if notip and k == "tip":
continue
Robert Bachmann
Added support for the Atom syndication format
r5269 if limit > 0 and count >= limit:
continue
count = count + 1
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 yield {"parity": parity.next(),
Eric Hopper
Final stage of the hgweb split up....
r2356 "tag": k,
Benoit Boissinot
hgweb: use contexts, fix coding style
r3973 "date": self.repo.changectx(n).date(),
Eric Hopper
Final stage of the hgweb split up....
r2356 "node": hex(n)}
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 return tmpl("tags",
node=hex(self.repo.changelog.tip()),
entries=lambda **x: entries(False,0, **x),
entriesnotip=lambda **x: entries(True,0, **x),
latestentry=lambda **x: entries(True,1, **x))
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def summary(self, tmpl):
Eric Hopper
Final stage of the hgweb split up....
r2356 i = self.repo.tagslist()
i.reverse()
def tagentries(**map):
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount)
Eric Hopper
Final stage of the hgweb split up....
r2356 count = 0
Thomas Arendsen Hein
white space and line break cleanups
r3673 for k, n in i:
Eric Hopper
Final stage of the hgweb split up....
r2356 if k == "tip": # skip tip
continue;
count += 1
if count > 10: # limit to 10 tags
break;
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 yield tmpl("tagentry",
parity=parity.next(),
tag=k,
node=hex(n),
date=self.repo.changectx(n).date())
Eric Hopper
Final stage of the hgweb split up....
r2356
greg@maptuit.com
hgweb: display named branches in gitweb-style summary page
r4300
def branches(**map):
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount)
Brendan Cully
hgweb: add heads to gitweb summary
r3499
greg@maptuit.com
hgweb: display named branches in gitweb-style summary page
r4300 b = self.repo.branchtags()
l = [(-self.repo.changelog.rev(n), n, t) for t, n in b.items()]
l.sort()
Brendan Cully
hgweb: add heads to gitweb summary
r3499
greg@maptuit.com
hgweb: display named branches in gitweb-style summary page
r4300 for r,n,t in l:
ctx = self.repo.changectx(n)
Brendan Cully
hgweb: add heads to gitweb summary
r3499
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 yield {'parity': parity.next(),
greg@maptuit.com
hgweb: display named branches in gitweb-style summary page
r4300 'branch': t,
'node': hex(n),
Brendan Cully
hgweb: add heads to gitweb summary
r3499 'date': ctx.date()}
Eric Hopper
Final stage of the hgweb split up....
r2356 def changelist(**map):
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity = paritygen(self.stripecount, offset=start-end)
Eric Hopper
Final stage of the hgweb split up....
r2356 l = [] # build a list in forward order for efficiency
Benoit Boissinot
use xrange instead of range
r3473 for i in xrange(start, end):
Benoit Boissinot
hgweb: use contexts, fix coding style
r3973 ctx = self.repo.changectx(i)
Josef "Jeff" Sipek
gitweb: Display branch and tag labels...
r4538 n = ctx.node()
hn = hex(n)
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 l.insert(0, tmpl(
'shortlogentry',
Thomas Arendsen Hein
hgweb: use generator to count parity of horizontal stripes for easier reading....
r4462 parity=parity.next(),
Benoit Boissinot
hgweb: use contexts, fix coding style
r3973 author=ctx.user(),
desc=ctx.description(),
date=ctx.date(),
rev=i,
Josef "Jeff" Sipek
gitweb: Display branch and tag labels...
r4538 node=hn,
Brendan Cully
Small cleanups for the new tag code
r4539 tags=self.nodetagsdict(n),
Florent Guillaume
hgweb_mod: add branch helper functions to use in templates
r6249 inbranch=self.nodeinbranch(ctx),
Brendan Cully
Small cleanups for the new tag code
r4539 branches=self.nodebranchdict(ctx)))
Eric Hopper
Final stage of the hgweb split up....
r2356
yield l
Benoit Boissinot
hgweb: use contexts, fix coding style
r3973 cl = self.repo.changelog
Eric Hopper
Final stage of the hgweb split up....
r2356 count = cl.count()
start = max(0, count - self.maxchanges)
end = min(count, start + self.maxchanges)
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 return tmpl("summary",
desc=self.config("web", "description", "unknown"),
owner=get_contact(self.config) or "unknown",
lastchange=cl.read(cl.tip())[2],
tags=tagentries,
branches=branches,
shortlog=changelist,
node=hex(cl.tip()),
archives=self.archivelist("tip"))
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def filediff(self, tmpl, fctx):
Brendan Cully
hgweb: use contexts in more handlers
r3220 n = fctx.node()
path = fctx.path()
Brendan Cully
hgweb: link to file parents in filediff, rather than changeset parents
r3406 parents = fctx.parents()
p1 = parents and parents[0].node() or nullid
Eric Hopper
Final stage of the hgweb split up....
r2356
def diff(**map):
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 yield self.diff(tmpl, p1, n, [path])
Eric Hopper
Final stage of the hgweb split up....
r2356
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 return tmpl("filediff",
file=path,
node=hex(n),
rev=fctx.rev(),
Florent Guillaume
hgweb_mod: add branch helper functions to use in templates
r6249 branch=self.nodebranchnodefault(fctx),
Dirkjan Ochtman
hgweb: just return iterables instead of yielding them
r5889 parent=self.siblings(parents),
child=self.siblings(fctx.children()),
diff=diff)
Eric Hopper
Final stage of the hgweb split up....
r2356
archive_specs = {
Thomas Arendsen Hein
Fix automatic decompression of tarballs with Firefox....
r2361 'bz2': ('application/x-tar', 'tbz2', '.tar.bz2', None),
'gz': ('application/x-tar', 'tgz', '.tar.gz', None),
Eric Hopper
Final stage of the hgweb split up....
r2356 'zip': ('application/zip', 'zip', '.zip', None),
}
Dirkjan Ochtman
hgweb: explicitly pass around the templater
r5600 def archive(self, tmpl, req, key, type_):
Eric Hopper
Final stage of the hgweb split up....
r2356 reponame = re.sub(r"\W+", "-", os.path.basename(self.reponame))
Thomas Arendsen Hein
hgweb_mod.archive(): Use 'key' instead of builtin 'id'.
r4669 cnode = self.repo.lookup(key)
arch_version = key
if cnode == key or key == 'tip':
Michael Gebetsroither
hgweb: use the given revision in the name of the archive...
r4164 arch_version = short(cnode)
name = "%s-%s" % (reponame, arch_version)
Benoit Boissinot
hgweb: fix errors and warnings found by pychecker...
r2394 mimetype, artype, extension, encoding = self.archive_specs[type_]
Dirkjan Ochtman
send conservatively capitalized HTTP headers
r5930 headers = [
('Content-Type', mimetype),
('Content-Disposition', 'attachment; filename=%s%s' %
(name, extension))
]
Eric Hopper
Final stage of the hgweb split up....
r2356 if encoding:
Dirkjan Ochtman
send conservatively capitalized HTTP headers
r5930 headers.append(('Content-Encoding', encoding))
Eric Hopper
Final stage of the hgweb split up....
r2356 req.header(headers)
Dirkjan Ochtman
hgweb: explicit response status
r5993 req.respond(HTTP_OK)
Dirkjan Ochtman
hgweb: remove some legacy code
r5886 archival.archive(self.repo, req, cnode, artype, prefix=name)
Eric Hopper
Final stage of the hgweb split up....
r2356
# add tags to things
# tags -> list of changesets corresponding to tags
# find tag, changeset, file
Vadim Gelfer
hgweb: split "verbs" into methods.
r2436 def cleanpath(self, path):
Benoit Boissinot
hgweb: fix handling of path for old style template...
r3595 path = path.lstrip('/')
Benoit Boissinot
hgweb: fix path cleaning
r3382 return util.canonpath(self.repo.root, '', path)
Vadim Gelfer
hgweb: split "verbs" into methods.
r2436
Brendan Cully
hgweb: add methods to get contexts from request
r3226 def changectx(self, req):
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 if 'node' in req.form:
Brendan Cully
hgweb: add methods to get contexts from request
r3226 changeid = req.form['node'][0]
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 elif 'manifest' in req.form:
Brendan Cully
hgweb: globally default to tip if no revision is specified
r3333 changeid = req.form['manifest'][0]
Brendan Cully
hgweb: add methods to get contexts from request
r3226 else:
Brendan Cully
hgweb: globally default to tip if no revision is specified
r3333 changeid = self.repo.changelog.count() - 1
Brendan Cully
hgweb: add methods to get contexts from request
r3226 try:
ctx = self.repo.changectx(changeid)
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 except RepoError:
Brendan Cully
hgweb: add methods to get contexts from request
r3226 man = self.repo.manifest
mn = man.lookup(changeid)
ctx = self.repo.changectx(man.linkrev(mn))
return ctx
def filectx(self, req):
path = self.cleanpath(req.form['file'][0])
Christian Ebert
Prefer i in d over d.has_key(i)
r5915 if 'node' in req.form:
Brendan Cully
hgweb: add methods to get contexts from request
r3226 changeid = req.form['node'][0]
else:
changeid = req.form['filenode'][0]
try:
ctx = self.repo.changectx(changeid)
fctx = ctx.filectx(path)
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 except RepoError:
Brendan Cully
hgweb: add methods to get contexts from request
r3226 fctx = self.repo.filectx(path, fileid=changeid)
return fctx
Vadim Gelfer
push over http: server side authorization support....
r2466 def check_perm(self, req, op, default):
'''check permission for operation based on user auth.
return true if op allowed, else false.
default is policy to use if no config given.'''
user = req.env.get('REMOTE_USER')
Alexis S. L. Carvalho
use untrusted settings in hgweb...
r3555 deny = self.configlist('web', 'deny_' + op)
Vadim Gelfer
push over http: server side authorization support....
r2466 if deny and (not user or deny == ['*'] or user in deny):
return False
Alexis S. L. Carvalho
use untrusted settings in hgweb...
r3555 allow = self.configlist('web', 'allow_' + op)
Vadim Gelfer
push over http: server side authorization support....
r2466 return (allow and (allow == ['*'] or user in allow)) or default