mercurial/hgweb/webcommands.py
changeset 36887 4daa22071d5d
parent 36886 563fd95a6efb
child 36977 a82fc3922446
equal deleted inserted replaced
36886:563fd95a6efb 36887:4daa22071d5d
    63     to render a template.
    63     to render a template.
    64 
    64 
    65     Usage:
    65     Usage:
    66 
    66 
    67     @webcommand('mycommand')
    67     @webcommand('mycommand')
    68     def mycommand(web, req, tmpl):
    68     def mycommand(web):
    69         pass
    69         pass
    70     """
    70     """
    71 
    71 
    72     def __init__(self, name):
    72     def __init__(self, name):
    73         self.name = name
    73         self.name = name
    76         __all__.append(self.name)
    76         __all__.append(self.name)
    77         commands[self.name] = func
    77         commands[self.name] = func
    78         return func
    78         return func
    79 
    79 
    80 @webcommand('log')
    80 @webcommand('log')
    81 def log(web, req, tmpl):
    81 def log(web):
    82     """
    82     """
    83     /log[/{revision}[/{path}]]
    83     /log[/{revision}[/{path}]]
    84     --------------------------
    84     --------------------------
    85 
    85 
    86     Show repository or file history.
    86     Show repository or file history.
    93     For URLs of the form ``/log/{revision}/{file}``, the history for a specific
    93     For URLs of the form ``/log/{revision}/{file}``, the history for a specific
    94     file will be shown. This form is equivalent to the ``filelog`` handler.
    94     file will be shown. This form is equivalent to the ``filelog`` handler.
    95     """
    95     """
    96 
    96 
    97     if web.req.qsparams.get('file'):
    97     if web.req.qsparams.get('file'):
    98         return filelog(web, req, None)
    98         return filelog(web)
    99     else:
    99     else:
   100         return changelog(web, req, None)
   100         return changelog(web)
   101 
   101 
   102 @webcommand('rawfile')
   102 @webcommand('rawfile')
   103 def rawfile(web, req, tmpl):
   103 def rawfile(web):
   104     guessmime = web.configbool('web', 'guessmime')
   104     guessmime = web.configbool('web', 'guessmime')
   105 
   105 
   106     path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
   106     path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
   107     if not path:
   107     if not path:
   108         return manifest(web, req, None)
   108         return manifest(web)
   109 
   109 
   110     try:
   110     try:
   111         fctx = webutil.filectx(web.repo, web.req)
   111         fctx = webutil.filectx(web.repo, web.req)
   112     except error.LookupError as inst:
   112     except error.LookupError as inst:
   113         try:
   113         try:
   114             return manifest(web, req, None)
   114             return manifest(web)
   115         except ErrorResponse:
   115         except ErrorResponse:
   116             raise inst
   116             raise inst
   117 
   117 
   118     path = fctx.path()
   118     path = fctx.path()
   119     text = fctx.data()
   119     text = fctx.data()
   133                 .replace('\\', '\\\\').replace('"', '\\"'))
   133                 .replace('\\', '\\\\').replace('"', '\\"'))
   134     web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename
   134     web.res.headers['Content-Disposition'] = 'inline; filename="%s"' % filename
   135     web.res.setbodybytes(text)
   135     web.res.setbodybytes(text)
   136     return web.res.sendresponse()
   136     return web.res.sendresponse()
   137 
   137 
   138 def _filerevision(web, req, fctx):
   138 def _filerevision(web, fctx):
   139     f = fctx.path()
   139     f = fctx.path()
   140     text = fctx.data()
   140     text = fctx.data()
   141     parity = paritygen(web.stripecount)
   141     parity = paritygen(web.stripecount)
   142     ishead = fctx.filerev() in fctx.filelog().headrevs()
   142     ishead = fctx.filerev() in fctx.filelog().headrevs()
   143 
   143 
   162         permissions=fctx.manifest().flags(f),
   162         permissions=fctx.manifest().flags(f),
   163         ishead=int(ishead),
   163         ishead=int(ishead),
   164         **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
   164         **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
   165 
   165 
   166 @webcommand('file')
   166 @webcommand('file')
   167 def file(web, req, tmpl):
   167 def file(web):
   168     """
   168     """
   169     /file/{revision}[/{path}]
   169     /file/{revision}[/{path}]
   170     -------------------------
   170     -------------------------
   171 
   171 
   172     Show information about a directory or file in the repository.
   172     Show information about a directory or file in the repository.
   182 
   182 
   183     If ``path`` is not defined, information about the root directory will
   183     If ``path`` is not defined, information about the root directory will
   184     be rendered.
   184     be rendered.
   185     """
   185     """
   186     if web.req.qsparams.get('style') == 'raw':
   186     if web.req.qsparams.get('style') == 'raw':
   187         return rawfile(web, req, None)
   187         return rawfile(web)
   188 
   188 
   189     path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
   189     path = webutil.cleanpath(web.repo, web.req.qsparams.get('file', ''))
   190     if not path:
   190     if not path:
   191         return manifest(web, req, None)
   191         return manifest(web)
   192     try:
   192     try:
   193         return _filerevision(web, req, webutil.filectx(web.repo, web.req))
   193         return _filerevision(web, webutil.filectx(web.repo, web.req))
   194     except error.LookupError as inst:
   194     except error.LookupError as inst:
   195         try:
   195         try:
   196             return manifest(web, req, None)
   196             return manifest(web)
   197         except ErrorResponse:
   197         except ErrorResponse:
   198             raise inst
   198             raise inst
   199 
   199 
   200 def _search(web):
   200 def _search(web):
   201     MODE_REVISION = 'rev'
   201     MODE_REVISION = 'rev'
   352         modedesc=searchfunc[1],
   352         modedesc=searchfunc[1],
   353         showforcekw=showforcekw,
   353         showforcekw=showforcekw,
   354         showunforcekw=showunforcekw)
   354         showunforcekw=showunforcekw)
   355 
   355 
   356 @webcommand('changelog')
   356 @webcommand('changelog')
   357 def changelog(web, req, tmpl, shortlog=False):
   357 def changelog(web, shortlog=False):
   358     """
   358     """
   359     /changelog[/{revision}]
   359     /changelog[/{revision}]
   360     -----------------------
   360     -----------------------
   361 
   361 
   362     Show information about multiple changesets.
   362     Show information about multiple changesets.
   450         morevars=morevars,
   450         morevars=morevars,
   451         lessvars=lessvars,
   451         lessvars=lessvars,
   452         query=query)
   452         query=query)
   453 
   453 
   454 @webcommand('shortlog')
   454 @webcommand('shortlog')
   455 def shortlog(web, req, tmpl):
   455 def shortlog(web):
   456     """
   456     """
   457     /shortlog
   457     /shortlog
   458     ---------
   458     ---------
   459 
   459 
   460     Show basic information about a set of changesets.
   460     Show basic information about a set of changesets.
   461 
   461 
   462     This accepts the same parameters as the ``changelog`` handler. The only
   462     This accepts the same parameters as the ``changelog`` handler. The only
   463     difference is the ``shortlog`` template will be rendered instead of the
   463     difference is the ``shortlog`` template will be rendered instead of the
   464     ``changelog`` template.
   464     ``changelog`` template.
   465     """
   465     """
   466     return changelog(web, req, None, shortlog=True)
   466     return changelog(web, shortlog=True)
   467 
   467 
   468 @webcommand('changeset')
   468 @webcommand('changeset')
   469 def changeset(web, req, tmpl):
   469 def changeset(web):
   470     """
   470     """
   471     /changeset[/{revision}]
   471     /changeset[/{revision}]
   472     -----------------------
   472     -----------------------
   473 
   473 
   474     Show information about a single changeset.
   474     Show information about a single changeset.
   496     Extensions (e.g., largefiles) can override this to remap files in
   496     Extensions (e.g., largefiles) can override this to remap files in
   497     the virtual file system presented by the manifest command below."""
   497     the virtual file system presented by the manifest command below."""
   498     return path
   498     return path
   499 
   499 
   500 @webcommand('manifest')
   500 @webcommand('manifest')
   501 def manifest(web, req, tmpl):
   501 def manifest(web):
   502     """
   502     """
   503     /manifest[/{revision}[/{path}]]
   503     /manifest[/{revision}[/{path}]]
   504     -------------------------------
   504     -------------------------------
   505 
   505 
   506     Show information about a directory.
   506     Show information about a directory.
   596         dentries=dirlist,
   596         dentries=dirlist,
   597         archives=web.archivelist(hex(node)),
   597         archives=web.archivelist(hex(node)),
   598         **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
   598         **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
   599 
   599 
   600 @webcommand('tags')
   600 @webcommand('tags')
   601 def tags(web, req, tmpl):
   601 def tags(web):
   602     """
   602     """
   603     /tags
   603     /tags
   604     -----
   604     -----
   605 
   605 
   606     Show information about tags.
   606     Show information about tags.
   630         entries=lambda **x: entries(False, False, **x),
   630         entries=lambda **x: entries(False, False, **x),
   631         entriesnotip=lambda **x: entries(True, False, **x),
   631         entriesnotip=lambda **x: entries(True, False, **x),
   632         latestentry=lambda **x: entries(True, True, **x))
   632         latestentry=lambda **x: entries(True, True, **x))
   633 
   633 
   634 @webcommand('bookmarks')
   634 @webcommand('bookmarks')
   635 def bookmarks(web, req, tmpl):
   635 def bookmarks(web):
   636     """
   636     """
   637     /bookmarks
   637     /bookmarks
   638     ----------
   638     ----------
   639 
   639 
   640     Show information about bookmarks.
   640     Show information about bookmarks.
   669         lastchange=[{'date': web.repo[latestrev].date()}],
   669         lastchange=[{'date': web.repo[latestrev].date()}],
   670         entries=lambda **x: entries(latestonly=False, **x),
   670         entries=lambda **x: entries(latestonly=False, **x),
   671         latestentry=lambda **x: entries(latestonly=True, **x))
   671         latestentry=lambda **x: entries(latestonly=True, **x))
   672 
   672 
   673 @webcommand('branches')
   673 @webcommand('branches')
   674 def branches(web, req, tmpl):
   674 def branches(web):
   675     """
   675     """
   676     /branches
   676     /branches
   677     ---------
   677     ---------
   678 
   678 
   679     Show information about branches.
   679     Show information about branches.
   692         node=hex(web.repo.changelog.tip()),
   692         node=hex(web.repo.changelog.tip()),
   693         entries=entries,
   693         entries=entries,
   694         latestentry=latestentry)
   694         latestentry=latestentry)
   695 
   695 
   696 @webcommand('summary')
   696 @webcommand('summary')
   697 def summary(web, req, tmpl):
   697 def summary(web):
   698     """
   698     """
   699     /summary
   699     /summary
   700     --------
   700     --------
   701 
   701 
   702     Show a summary of repository state.
   702     Show a summary of repository state.
   776         symrev='tip',
   776         symrev='tip',
   777         archives=web.archivelist('tip'),
   777         archives=web.archivelist('tip'),
   778         labels=web.configlist('web', 'labels'))
   778         labels=web.configlist('web', 'labels'))
   779 
   779 
   780 @webcommand('filediff')
   780 @webcommand('filediff')
   781 def filediff(web, req, tmpl):
   781 def filediff(web):
   782     """
   782     """
   783     /diff/{revision}/{path}
   783     /diff/{revision}/{path}
   784     -----------------------
   784     -----------------------
   785 
   785 
   786     Show how a file changed in a particular commit.
   786     Show how a file changed in a particular commit.
   825         **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
   825         **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
   826 
   826 
   827 diff = webcommand('diff')(filediff)
   827 diff = webcommand('diff')(filediff)
   828 
   828 
   829 @webcommand('comparison')
   829 @webcommand('comparison')
   830 def comparison(web, req, tmpl):
   830 def comparison(web):
   831     """
   831     """
   832     /comparison/{revision}/{path}
   832     /comparison/{revision}/{path}
   833     -----------------------------
   833     -----------------------------
   834 
   834 
   835     Show a comparison between the old and new versions of a file from changes
   835     Show a comparison between the old and new versions of a file from changes
   900         rightnode=hex(rightnode),
   900         rightnode=hex(rightnode),
   901         comparison=comparison,
   901         comparison=comparison,
   902         **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
   902         **pycompat.strkwargs(webutil.commonentry(web.repo, ctx)))
   903 
   903 
   904 @webcommand('annotate')
   904 @webcommand('annotate')
   905 def annotate(web, req, tmpl):
   905 def annotate(web):
   906     """
   906     """
   907     /annotate/{revision}/{path}
   907     /annotate/{revision}/{path}
   908     ---------------------------
   908     ---------------------------
   909 
   909 
   910     Show changeset information for each line in a file.
   910     Show changeset information for each line in a file.
   992         ishead=int(ishead),
   992         ishead=int(ishead),
   993         diffopts=diffopts,
   993         diffopts=diffopts,
   994         **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
   994         **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
   995 
   995 
   996 @webcommand('filelog')
   996 @webcommand('filelog')
   997 def filelog(web, req, tmpl):
   997 def filelog(web):
   998     """
   998     """
   999     /filelog/{revision}/{path}
   999     /filelog/{revision}/{path}
  1000     --------------------------
  1000     --------------------------
  1001 
  1001 
  1002     Show information about the history of a file in the repository.
  1002     Show information about the history of a file in the repository.
  1130         morevars=morevars,
  1130         morevars=morevars,
  1131         lessvars=lessvars,
  1131         lessvars=lessvars,
  1132         **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
  1132         **pycompat.strkwargs(webutil.commonentry(web.repo, fctx)))
  1133 
  1133 
  1134 @webcommand('archive')
  1134 @webcommand('archive')
  1135 def archive(web, req, tmpl):
  1135 def archive(web):
  1136     """
  1136     """
  1137     /archive/{revision}.{format}[/{path}]
  1137     /archive/{revision}.{format}[/{path}]
  1138     -------------------------------------
  1138     -------------------------------------
  1139 
  1139 
  1140     Obtain an archive of repository content.
  1140     Obtain an archive of repository content.
  1204                      subrepos=web.configbool("web", "archivesubrepos"))
  1204                      subrepos=web.configbool("web", "archivesubrepos"))
  1205 
  1205 
  1206     return []
  1206     return []
  1207 
  1207 
  1208 @webcommand('static')
  1208 @webcommand('static')
  1209 def static(web, req, tmpl):
  1209 def static(web):
  1210     fname = web.req.qsparams['file']
  1210     fname = web.req.qsparams['file']
  1211     # a repo owner may set web.static in .hg/hgrc to get any file
  1211     # a repo owner may set web.static in .hg/hgrc to get any file
  1212     # readable by the user running the CGI script
  1212     # readable by the user running the CGI script
  1213     static = web.config("web", "static", None, untrusted=False)
  1213     static = web.config("web", "static", None, untrusted=False)
  1214     if not static:
  1214     if not static:
  1219 
  1219 
  1220     staticfile(static, fname, web.res)
  1220     staticfile(static, fname, web.res)
  1221     return web.res.sendresponse()
  1221     return web.res.sendresponse()
  1222 
  1222 
  1223 @webcommand('graph')
  1223 @webcommand('graph')
  1224 def graph(web, req, tmpl):
  1224 def graph(web):
  1225     """
  1225     """
  1226     /graph[/{revision}]
  1226     /graph[/{revision}]
  1227     -------------------
  1227     -------------------
  1228 
  1228 
  1229     Show information about the graphical topology of the repository.
  1229     Show information about the graphical topology of the repository.
  1386     else:
  1386     else:
  1387         doc = _('(no help text available)')
  1387         doc = _('(no help text available)')
  1388     return doc
  1388     return doc
  1389 
  1389 
  1390 @webcommand('help')
  1390 @webcommand('help')
  1391 def help(web, req, tmpl):
  1391 def help(web):
  1392     """
  1392     """
  1393     /help[/{topic}]
  1393     /help[/{topic}]
  1394     ---------------
  1394     ---------------
  1395 
  1395 
  1396     Render help documentation.
  1396     Render help documentation.