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().
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| 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(): | ||||