We now have access to the modern request type on the
requestcontext instance. Let's access it from there.
While we're here, remove an unused argument from _search().
durin42 |
hg-reviewers |
We now have access to the modern request type on the
requestcontext instance. Let's access it from there.
While we're here, remove an unused argument from _search().
Lint Skipped |
Unit Tests Skipped |
Path | Packages | |||
---|---|---|---|---|
M | mercurial/hgweb/webcommands.py (80 lines) |
the specified changeset identifier is shown. If ``{revision}`` is not | the specified changeset identifier is shown. If ``{revision}`` is not | ||||
defined, the default is ``tip``. This form is equivalent to the | defined, the default is ``tip``. This form is equivalent to the | ||||
``changelog`` handler. | ``changelog`` handler. | ||||
For URLs of the form ``/log/{revision}/{file}``, the history for a specific | For URLs of the form ``/log/{revision}/{file}``, the history for a specific | ||||
file will be shown. This form is equivalent to the ``filelog`` handler. | file will be shown. This form is equivalent to the ``filelog`` handler. | ||||
""" | """ | ||||
if req.req.qsparams.get('file'): | if web.req.qsparams.get('file'): | ||||
return filelog(web, req, tmpl) | return filelog(web, req, tmpl) | ||||
else: | else: | ||||
return changelog(web, req, tmpl) | return changelog(web, req, tmpl) | ||||
@webcommand('rawfile') | @webcommand('rawfile') | ||||
def rawfile(web, req, tmpl): | def rawfile(web, req, tmpl): | ||||
guessmime = web.configbool('web', 'guessmime') | guessmime = web.configbool('web', 'guessmime') | ||||
path = webutil.cleanpath(web.repo, req.req.qsparams.get('file', '')) | path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', '')) | ||||
if not path: | if not path: | ||||
return manifest(web, req, tmpl) | return manifest(web, req, tmpl) | ||||
try: | try: | ||||
fctx = webutil.filectx(web.repo, req) | fctx = webutil.filectx(web.repo, req) | ||||
except error.LookupError as inst: | except error.LookupError as inst: | ||||
try: | try: | ||||
return manifest(web, req, tmpl) | return manifest(web, req, tmpl) | ||||
the ``filerevision`` template. | the ``filerevision`` template. | ||||
If ``path`` is not defined, information about the root directory will | If ``path`` is not defined, information about the root directory will | ||||
be rendered. | be rendered. | ||||
""" | """ | ||||
if web.req.qsparams.get('style') == 'raw': | if web.req.qsparams.get('style') == 'raw': | ||||
return rawfile(web, req, tmpl) | return rawfile(web, req, tmpl) | ||||
path = webutil.cleanpath(web.repo, req.req.qsparams.get('file', '')) | path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', '')) | ||||
if not path: | if not path: | ||||
return manifest(web, req, tmpl) | return manifest(web, req, tmpl) | ||||
try: | try: | ||||
return _filerevision(web, req, tmpl, webutil.filectx(web.repo, req)) | return _filerevision(web, req, tmpl, webutil.filectx(web.repo, req)) | ||||
except error.LookupError as inst: | except error.LookupError as inst: | ||||
try: | try: | ||||
return manifest(web, req, tmpl) | return manifest(web, req, tmpl) | ||||
except ErrorResponse: | except ErrorResponse: | ||||
raise inst | raise inst | ||||
def _search(web, req, tmpl): | def _search(web, tmpl): | ||||
MODE_REVISION = 'rev' | MODE_REVISION = 'rev' | ||||
MODE_KEYWORD = 'keyword' | MODE_KEYWORD = 'keyword' | ||||
MODE_REVSET = 'revset' | MODE_REVSET = 'revset' | ||||
def revsearch(ctx): | def revsearch(ctx): | ||||
yield ctx | yield ctx | ||||
def keywordsearch(query): | def keywordsearch(query): | ||||
parity=next(parity), | parity=next(parity), | ||||
changelogtag=showtags, | changelogtag=showtags, | ||||
files=files, | files=files, | ||||
**pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) | **pycompat.strkwargs(webutil.commonentry(web.repo, ctx))) | ||||
if count >= revcount: | if count >= revcount: | ||||
break | break | ||||
query = req.req.qsparams['rev'] | query = web.req.qsparams['rev'] | ||||
revcount = web.maxchanges | revcount = web.maxchanges | ||||
if 'revcount' in req.req.qsparams: | if 'revcount' in web.req.qsparams: | ||||
try: | try: | ||||
revcount = int(req.req.qsparams.get('revcount', revcount)) | revcount = int(web.req.qsparams.get('revcount', revcount)) | ||||
revcount = max(revcount, 1) | revcount = max(revcount, 1) | ||||
tmpl.defaults['sessionvars']['revcount'] = revcount | tmpl.defaults['sessionvars']['revcount'] = revcount | ||||
except ValueError: | except ValueError: | ||||
pass | pass | ||||
lessvars = copy.copy(tmpl.defaults['sessionvars']) | lessvars = copy.copy(tmpl.defaults['sessionvars']) | ||||
lessvars['revcount'] = max(revcount // 2, 1) | lessvars['revcount'] = max(revcount // 2, 1) | ||||
lessvars['rev'] = query | lessvars['rev'] = query | ||||
morevars = copy.copy(tmpl.defaults['sessionvars']) | morevars = copy.copy(tmpl.defaults['sessionvars']) | ||||
morevars['revcount'] = revcount * 2 | morevars['revcount'] = revcount * 2 | ||||
morevars['rev'] = query | morevars['rev'] = query | ||||
mode, funcarg = getsearchmode(query) | mode, funcarg = getsearchmode(query) | ||||
if 'forcekw' in req.req.qsparams: | if 'forcekw' in web.req.qsparams: | ||||
showforcekw = '' | showforcekw = '' | ||||
showunforcekw = searchfuncs[mode][1] | showunforcekw = searchfuncs[mode][1] | ||||
mode = MODE_KEYWORD | mode = MODE_KEYWORD | ||||
funcarg = query | funcarg = query | ||||
else: | else: | ||||
if mode != MODE_KEYWORD: | if mode != MODE_KEYWORD: | ||||
showforcekw = searchfuncs[MODE_KEYWORD][1] | showforcekw = searchfuncs[MODE_KEYWORD][1] | ||||
else: | else: | ||||
The ``revcount`` query string argument defines the maximum numbers of | The ``revcount`` query string argument defines the maximum numbers of | ||||
changesets to render. | changesets to render. | ||||
For non-searches, the ``changelog`` template will be rendered. | For non-searches, the ``changelog`` template will be rendered. | ||||
""" | """ | ||||
query = '' | query = '' | ||||
if 'node' in req.req.qsparams: | if 'node' in web.req.qsparams: | ||||
ctx = webutil.changectx(web.repo, req) | ctx = webutil.changectx(web.repo, req) | ||||
symrev = webutil.symrevorshortnode(req, ctx) | symrev = webutil.symrevorshortnode(req, ctx) | ||||
elif 'rev' in req.req.qsparams: | elif 'rev' in web.req.qsparams: | ||||
return _search(web, req, tmpl) | return _search(web, tmpl) | ||||
else: | else: | ||||
ctx = web.repo['tip'] | ctx = web.repo['tip'] | ||||
symrev = 'tip' | symrev = 'tip' | ||||
def changelist(): | def changelist(): | ||||
revs = [] | revs = [] | ||||
if pos != -1: | if pos != -1: | ||||
revs = web.repo.changelog.revs(pos, 0) | revs = web.repo.changelog.revs(pos, 0) | ||||
curcount = 0 | curcount = 0 | ||||
for rev in revs: | for rev in revs: | ||||
curcount += 1 | curcount += 1 | ||||
if curcount > revcount + 1: | if curcount > revcount + 1: | ||||
break | break | ||||
entry = webutil.changelistentry(web, web.repo[rev], tmpl) | entry = webutil.changelistentry(web, web.repo[rev], tmpl) | ||||
entry['parity'] = next(parity) | entry['parity'] = next(parity) | ||||
yield entry | yield entry | ||||
if shortlog: | if shortlog: | ||||
revcount = web.maxshortchanges | revcount = web.maxshortchanges | ||||
else: | else: | ||||
revcount = web.maxchanges | revcount = web.maxchanges | ||||
if 'revcount' in req.req.qsparams: | if 'revcount' in web.req.qsparams: | ||||
try: | try: | ||||
revcount = int(req.req.qsparams.get('revcount', revcount)) | revcount = int(web.req.qsparams.get('revcount', revcount)) | ||||
revcount = max(revcount, 1) | revcount = max(revcount, 1) | ||||
tmpl.defaults['sessionvars']['revcount'] = revcount | tmpl.defaults['sessionvars']['revcount'] = revcount | ||||
except ValueError: | except ValueError: | ||||
pass | pass | ||||
lessvars = copy.copy(tmpl.defaults['sessionvars']) | lessvars = copy.copy(tmpl.defaults['sessionvars']) | ||||
lessvars['revcount'] = max(revcount // 2, 1) | lessvars['revcount'] = max(revcount // 2, 1) | ||||
morevars = copy.copy(tmpl.defaults['sessionvars']) | morevars = copy.copy(tmpl.defaults['sessionvars']) | ||||
directory for the ``tip`` changeset will be shown. | directory for the ``tip`` changeset will be shown. | ||||
Because this handler can only show information for directories, it | Because this handler can only show information for directories, it | ||||
is recommended to use the ``file`` handler instead, as it can handle both | is recommended to use the ``file`` handler instead, as it can handle both | ||||
directories and files. | directories and files. | ||||
The ``manifest`` template will be rendered for this handler. | The ``manifest`` template will be rendered for this handler. | ||||
""" | """ | ||||
if 'node' in req.req.qsparams: | if 'node' in web.req.qsparams: | ||||
ctx = webutil.changectx(web.repo, req) | ctx = webutil.changectx(web.repo, req) | ||||
symrev = webutil.symrevorshortnode(req, ctx) | symrev = webutil.symrevorshortnode(req, ctx) | ||||
else: | else: | ||||
ctx = web.repo['tip'] | ctx = web.repo['tip'] | ||||
symrev = 'tip' | symrev = 'tip' | ||||
path = webutil.cleanpath(web.repo, req.req.qsparams.get('file', '')) | path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', '')) | ||||
mf = ctx.manifest() | mf = ctx.manifest() | ||||
node = ctx.node() | node = ctx.node() | ||||
files = {} | files = {} | ||||
dirs = {} | dirs = {} | ||||
parity = paritygen(web.stripecount) | parity = paritygen(web.stripecount) | ||||
if path and path[-1:] != "/": | if path and path[-1:] != "/": | ||||
This handler is registered under both the ``/diff`` and ``/filediff`` | This handler is registered under both the ``/diff`` and ``/filediff`` | ||||
paths. ``/diff`` is used in modern code. | paths. ``/diff`` is used in modern code. | ||||
""" | """ | ||||
fctx, ctx = None, None | fctx, ctx = None, None | ||||
try: | try: | ||||
fctx = webutil.filectx(web.repo, req) | fctx = webutil.filectx(web.repo, req) | ||||
except LookupError: | except LookupError: | ||||
ctx = webutil.changectx(web.repo, req) | ctx = webutil.changectx(web.repo, req) | ||||
path = webutil.cleanpath(web.repo, req.req.qsparams['file']) | path = webutil.cleanpath(web.repo, web.req.qsparams['file']) | ||||
if path not in ctx.files(): | if path not in ctx.files(): | ||||
raise | raise | ||||
if fctx is not None: | if fctx is not None: | ||||
path = fctx.path() | path = fctx.path() | ||||
ctx = fctx.changectx() | ctx = fctx.changectx() | ||||
basectx = ctx.p1() | basectx = ctx.p1() | ||||
style = web.config('web', 'style') | style = web.config('web', 'style') | ||||
if 'style' in req.req.qsparams: | if 'style' in web.req.qsparams: | ||||
style = req.req.qsparams['style'] | style = web.req.qsparams['style'] | ||||
diffs = webutil.diffs(web, tmpl, ctx, basectx, [path], style) | diffs = webutil.diffs(web, tmpl, ctx, basectx, [path], style) | ||||
if fctx is not None: | if fctx is not None: | ||||
rename = webutil.renamelink(fctx) | rename = webutil.renamelink(fctx) | ||||
ctx = fctx | ctx = fctx | ||||
else: | else: | ||||
rename = [] | rename = [] | ||||
ctx = ctx | ctx = ctx | ||||
a split or side-by-side diff rather than a unified diff. | a split or side-by-side diff rather than a unified diff. | ||||
The ``context`` query string argument can be used to control the lines of | The ``context`` query string argument can be used to control the lines of | ||||
context in the diff. | context in the diff. | ||||
The ``filecomparison`` template is rendered. | The ``filecomparison`` template is rendered. | ||||
""" | """ | ||||
ctx = webutil.changectx(web.repo, req) | ctx = webutil.changectx(web.repo, req) | ||||
if 'file' not in req.req.qsparams: | if 'file' not in web.req.qsparams: | ||||
raise ErrorResponse(HTTP_NOT_FOUND, 'file not given') | raise ErrorResponse(HTTP_NOT_FOUND, 'file not given') | ||||
path = webutil.cleanpath(web.repo, req.req.qsparams['file']) | path = webutil.cleanpath(web.repo, web.req.qsparams['file']) | ||||
parsecontext = lambda v: v == 'full' and -1 or int(v) | parsecontext = lambda v: v == 'full' and -1 or int(v) | ||||
if 'context' in req.req.qsparams: | if 'context' in web.req.qsparams: | ||||
context = parsecontext(req.req.qsparams['context']) | context = parsecontext(web.req.qsparams['context']) | ||||
else: | else: | ||||
context = parsecontext(web.config('web', 'comparisoncontext', '5')) | context = parsecontext(web.config('web', 'comparisoncontext', '5')) | ||||
def filelines(f): | def filelines(f): | ||||
if f.isbinary(): | if f.isbinary(): | ||||
mt = mimetypes.guess_type(f.path())[0] | mt = mimetypes.guess_type(f.path())[0] | ||||
if not mt: | if not mt: | ||||
mt = 'application/octet-stream' | mt = 'application/octet-stream' | ||||
The ``filelog`` template will be rendered. | The ``filelog`` template will be rendered. | ||||
""" | """ | ||||
try: | try: | ||||
fctx = webutil.filectx(web.repo, req) | fctx = webutil.filectx(web.repo, req) | ||||
f = fctx.path() | f = fctx.path() | ||||
fl = fctx.filelog() | fl = fctx.filelog() | ||||
except error.LookupError: | except error.LookupError: | ||||
f = webutil.cleanpath(web.repo, req.req.qsparams['file']) | f = webutil.cleanpath(web.repo, web.req.qsparams['file']) | ||||
fl = web.repo.file(f) | fl = web.repo.file(f) | ||||
numrevs = len(fl) | numrevs = len(fl) | ||||
if not numrevs: # file doesn't exist at all | if not numrevs: # file doesn't exist at all | ||||
raise | raise | ||||
rev = webutil.changectx(web.repo, req).rev() | rev = webutil.changectx(web.repo, req).rev() | ||||
first = fl.linkrev(0) | first = fl.linkrev(0) | ||||
if rev < first: # current rev is from before file existed | if rev < first: # current rev is from before file existed | ||||
raise | raise | ||||
frev = numrevs - 1 | frev = numrevs - 1 | ||||
while fl.linkrev(frev) > rev: | while fl.linkrev(frev) > rev: | ||||
frev -= 1 | frev -= 1 | ||||
fctx = web.repo.filectx(f, fl.linkrev(frev)) | fctx = web.repo.filectx(f, fl.linkrev(frev)) | ||||
revcount = web.maxshortchanges | revcount = web.maxshortchanges | ||||
if 'revcount' in req.req.qsparams: | if 'revcount' in web.req.qsparams: | ||||
try: | try: | ||||
revcount = int(req.req.qsparams.get('revcount', revcount)) | revcount = int(web.req.qsparams.get('revcount', revcount)) | ||||
revcount = max(revcount, 1) | revcount = max(revcount, 1) | ||||
tmpl.defaults['sessionvars']['revcount'] = revcount | tmpl.defaults['sessionvars']['revcount'] = revcount | ||||
except ValueError: | except ValueError: | ||||
pass | pass | ||||
lrange = webutil.linerange(req) | lrange = webutil.linerange(req) | ||||
lessvars = copy.copy(tmpl.defaults['sessionvars']) | lessvars = copy.copy(tmpl.defaults['sessionvars']) | ||||
lessvars['revcount'] = max(revcount // 2, 1) | lessvars['revcount'] = max(revcount // 2, 1) | ||||
morevars = copy.copy(tmpl.defaults['sessionvars']) | morevars = copy.copy(tmpl.defaults['sessionvars']) | ||||
morevars['revcount'] = revcount * 2 | morevars['revcount'] = revcount * 2 | ||||
patch = 'patch' in req.req.qsparams | patch = 'patch' in web.req.qsparams | ||||
if patch: | if patch: | ||||
lessvars['patch'] = morevars['patch'] = req.req.qsparams['patch'] | lessvars['patch'] = morevars['patch'] = web.req.qsparams['patch'] | ||||
descend = 'descend' in req.req.qsparams | descend = 'descend' in web.req.qsparams | ||||
if descend: | if descend: | ||||
lessvars['descend'] = morevars['descend'] = req.req.qsparams['descend'] | lessvars['descend'] = morevars['descend'] = web.req.qsparams['descend'] | ||||
count = fctx.filerev() + 1 | count = fctx.filerev() + 1 | ||||
start = max(0, count - revcount) # first rev on this page | start = max(0, count - revcount) # first rev on this page | ||||
end = min(count, start + revcount) # last rev on this page | end = min(count, start + revcount) # last rev on this page | ||||
parity = paritygen(web.stripecount, offset=start - end) | parity = paritygen(web.stripecount, offset=start - end) | ||||
repo = web.repo | repo = web.repo | ||||
revs = fctx.filelog().revs(start, end - 1) | revs = fctx.filelog().revs(start, end - 1) | ||||
entries = [] | entries = [] | ||||
diffstyle = web.config('web', 'style') | diffstyle = web.config('web', 'style') | ||||
if 'style' in req.req.qsparams: | if 'style' in web.req.qsparams: | ||||
diffstyle = req.req.qsparams['style'] | diffstyle = web.req.qsparams['style'] | ||||
def diff(fctx, linerange=None): | def diff(fctx, linerange=None): | ||||
ctx = fctx.changectx() | ctx = fctx.changectx() | ||||
basectx = ctx.p1() | basectx = ctx.p1() | ||||
path = fctx.path() | path = fctx.path() | ||||
return webutil.diffs(web, tmpl, ctx, basectx, [path], diffstyle, | return webutil.diffs(web, tmpl, ctx, basectx, [path], diffstyle, | ||||
linerange=linerange, | linerange=linerange, | ||||
lineidprefix='%s-' % ctx.hex()[:12]) | lineidprefix='%s-' % ctx.hex()[:12]) | ||||
The optional ``path`` URL parameter controls content to include in the | The optional ``path`` URL parameter controls content to include in the | ||||
archive. If omitted, every file in the specified revision is present in the | archive. If omitted, every file in the specified revision is present in the | ||||
archive. If included, only the specified file or contents of the specified | archive. If included, only the specified file or contents of the specified | ||||
directory will be included in the archive. | directory will be included in the archive. | ||||
No template is used for this handler. Raw, binary content is generated. | No template is used for this handler. Raw, binary content is generated. | ||||
""" | """ | ||||
type_ = req.req.qsparams.get('type') | type_ = web.req.qsparams.get('type') | ||||
allowed = web.configlist("web", "allow_archive") | allowed = web.configlist("web", "allow_archive") | ||||
key = req.req.qsparams['node'] | key = web.req.qsparams['node'] | ||||
if type_ not in web.archivespecs: | if type_ not in web.archivespecs: | ||||
msg = 'Unsupported archive type: %s' % type_ | msg = 'Unsupported archive type: %s' % type_ | ||||
raise ErrorResponse(HTTP_NOT_FOUND, msg) | raise ErrorResponse(HTTP_NOT_FOUND, msg) | ||||
if not ((type_ in allowed or | if not ((type_ in allowed or | ||||
web.configbool("web", "allow" + type_))): | web.configbool("web", "allow" + type_))): | ||||
msg = 'Archive type not allowed: %s' % type_ | msg = 'Archive type not allowed: %s' % type_ | ||||
raise ErrorResponse(HTTP_FORBIDDEN, msg) | raise ErrorResponse(HTTP_FORBIDDEN, msg) | ||||
reponame = re.sub(br"\W+", "-", os.path.basename(web.reponame)) | reponame = re.sub(br"\W+", "-", os.path.basename(web.reponame)) | ||||
cnode = web.repo.lookup(key) | cnode = web.repo.lookup(key) | ||||
arch_version = key | arch_version = key | ||||
if cnode == key or key == 'tip': | if cnode == key or key == 'tip': | ||||
arch_version = short(cnode) | arch_version = short(cnode) | ||||
name = "%s-%s" % (reponame, arch_version) | name = "%s-%s" % (reponame, arch_version) | ||||
ctx = webutil.changectx(web.repo, req) | ctx = webutil.changectx(web.repo, req) | ||||
pats = [] | pats = [] | ||||
match = scmutil.match(ctx, []) | match = scmutil.match(ctx, []) | ||||
file = req.req.qsparams.get('file') | file = web.req.qsparams.get('file') | ||||
if file: | if file: | ||||
pats = ['path:' + file] | pats = ['path:' + file] | ||||
match = scmutil.match(ctx, pats, default='path') | match = scmutil.match(ctx, pats, default='path') | ||||
if pats: | if pats: | ||||
files = [f for f in ctx.manifest().keys() if match(f)] | files = [f for f in ctx.manifest().keys() if match(f)] | ||||
if not files: | if not files: | ||||
raise ErrorResponse(HTTP_NOT_FOUND, | raise ErrorResponse(HTTP_NOT_FOUND, | ||||
'file(s) not found: %s' % file) | 'file(s) not found: %s' % file) | ||||
archival.archive(web.repo, bodyfh, cnode, artype, prefix=name, | archival.archive(web.repo, bodyfh, cnode, artype, prefix=name, | ||||
matchfn=match, | matchfn=match, | ||||
subrepos=web.configbool("web", "archivesubrepos")) | subrepos=web.configbool("web", "archivesubrepos")) | ||||
return [] | return [] | ||||
@webcommand('static') | @webcommand('static') | ||||
def static(web, req, tmpl): | def static(web, req, tmpl): | ||||
fname = req.req.qsparams['file'] | fname = web.req.qsparams['file'] | ||||
# a repo owner may set web.static in .hg/hgrc to get any file | # a repo owner may set web.static in .hg/hgrc to get any file | ||||
# readable by the user running the CGI script | # readable by the user running the CGI script | ||||
static = web.config("web", "static", None, untrusted=False) | static = web.config("web", "static", None, untrusted=False) | ||||
if not static: | if not static: | ||||
tp = web.templatepath or templater.templatepaths() | tp = web.templatepath or templater.templatepaths() | ||||
if isinstance(tp, str): | if isinstance(tp, str): | ||||
tp = [tp] | tp = [tp] | ||||
static = [os.path.join(p, 'static') for p in tp] | static = [os.path.join(p, 'static') for p in tp] | ||||
The ``graphtop`` query string argument can specify the starting changeset | The ``graphtop`` query string argument can specify the starting changeset | ||||
for producing ``jsdata`` variable that is used for rendering graph in | for producing ``jsdata`` variable that is used for rendering graph in | ||||
JavaScript. By default it has the same value as ``revision``. | JavaScript. By default it has the same value as ``revision``. | ||||
This handler will render the ``graph`` template. | This handler will render the ``graph`` template. | ||||
""" | """ | ||||
if 'node' in req.req.qsparams: | if 'node' in web.req.qsparams: | ||||
ctx = webutil.changectx(web.repo, req) | ctx = webutil.changectx(web.repo, req) | ||||
symrev = webutil.symrevorshortnode(req, ctx) | symrev = webutil.symrevorshortnode(req, ctx) | ||||
else: | else: | ||||
ctx = web.repo['tip'] | ctx = web.repo['tip'] | ||||
symrev = 'tip' | symrev = 'tip' | ||||
rev = ctx.rev() | rev = ctx.rev() | ||||
bg_height = 39 | bg_height = 39 | ||||
revcount = web.maxshortchanges | revcount = web.maxshortchanges | ||||
if 'revcount' in req.req.qsparams: | if 'revcount' in web.req.qsparams: | ||||
try: | try: | ||||
revcount = int(req.req.qsparams.get('revcount', revcount)) | revcount = int(web.req.qsparams.get('revcount', revcount)) | ||||
revcount = max(revcount, 1) | revcount = max(revcount, 1) | ||||
tmpl.defaults['sessionvars']['revcount'] = revcount | tmpl.defaults['sessionvars']['revcount'] = revcount | ||||
except ValueError: | except ValueError: | ||||
pass | pass | ||||
lessvars = copy.copy(tmpl.defaults['sessionvars']) | lessvars = copy.copy(tmpl.defaults['sessionvars']) | ||||
lessvars['revcount'] = max(revcount // 2, 1) | lessvars['revcount'] = max(revcount // 2, 1) | ||||
morevars = copy.copy(tmpl.defaults['sessionvars']) | morevars = copy.copy(tmpl.defaults['sessionvars']) | ||||
morevars['revcount'] = revcount * 2 | morevars['revcount'] = revcount * 2 | ||||
graphtop = req.req.qsparams.get('graphtop', ctx.hex()) | graphtop = web.req.qsparams.get('graphtop', ctx.hex()) | ||||
graphvars = copy.copy(tmpl.defaults['sessionvars']) | graphvars = copy.copy(tmpl.defaults['sessionvars']) | ||||
graphvars['graphtop'] = graphtop | graphvars['graphtop'] = graphtop | ||||
count = len(web.repo) | count = len(web.repo) | ||||
pos = rev | pos = rev | ||||
uprev = min(max(0, count - 1), rev + revcount) | uprev = min(max(0, count - 1), rev + revcount) | ||||
downrev = max(0, rev - revcount) | downrev = max(0, rev - revcount) | ||||
is defined, that help topic will be rendered. If not, an index of | is defined, that help topic will be rendered. If not, an index of | ||||
available help topics will be rendered. | available help topics will be rendered. | ||||
The ``help`` template will be rendered when requesting help for a topic. | The ``help`` template will be rendered when requesting help for a topic. | ||||
``helptopics`` will be rendered for the index of help topics. | ``helptopics`` will be rendered for the index of help topics. | ||||
""" | """ | ||||
from .. import commands, help as helpmod # avoid cycle | from .. import commands, help as helpmod # avoid cycle | ||||
topicname = req.req.qsparams.get('node') | topicname = web.req.qsparams.get('node') | ||||
if not topicname: | if not topicname: | ||||
def topics(**map): | def topics(**map): | ||||
for entries, summary, _doc in helpmod.helptable: | for entries, summary, _doc in helpmod.helptable: | ||||
yield {'topic': entries[0], 'summary': summary} | yield {'topic': entries[0], 'summary': summary} | ||||
early, other = [], [] | early, other = [], [] | ||||
primary = lambda s: s.partition('|')[0] | primary = lambda s: s.partition('|')[0] | ||||
for c, e in commands.table.iteritems(): | for c, e in commands.table.iteritems(): |