hgkw/keyword.py
branch0.9.2compat
changeset 370 a8983fed9a9e
parent 366 b1105cc0982f
child 380 0ed26effe190
--- a/hgkw/keyword.py	Thu Jan 31 01:06:49 2008 +0100
+++ b/hgkw/keyword.py	Tue Feb 05 17:23:24 2008 +0100
@@ -85,11 +85,11 @@
         Or, better, use bundle/unbundle to share changes.
 '''
 
-from mercurial import commands, cmdutil, context, filelog
+from mercurial import commands, cmdutil, context
 from mercurial import localrepo, revlog, templater, util
 from mercurial.node import *
 from mercurial.i18n import gettext as _
-import os.path, re, shutil, tempfile, time
+import mimetypes, os.path, re, shutil, tempfile, time
 
 try:
     # avoid spurious rejects if patchfile is available
@@ -109,6 +109,15 @@
     template_filters = templater.common_filters
     template_firstline = templater.firstline
 
+try:
+    # webcommands module introduced in 08887121a652
+    from mercurial.hgweb import webcommands
+    _webcommands = True
+    kwweb_func = webcommands.rawfile
+except ImportError:
+    from mercurial.hgweb import hgweb_mod
+    _webcommands = False
+
 def _normal(repo, files):
     '''Backwards compatible repo.dirstate.normal/update.'''
     # 6fd953d5faea introduced dirstate.normal()
@@ -190,10 +199,6 @@
             except revlog.LookupError:
                 # eg: convert
                 return subfunc == self.re_kw.sub and data or (data, None)
-        elif subfunc == self.re_kw.sub:
-            # hg kwcat using kwfilelog.read
-            c = context.filectx(self.repo, path, fileid=node)
-            node = c.node()
 
         def kwsub(mobj):
             '''Substitutes keyword using corresponding template.'''
@@ -229,19 +234,6 @@
             return data
         return self.re_kw.sub(r'$\1$', data)
 
-class kwfilelog(filelog.filelog):
-    '''
-    Subclass of filelog to hook into its read method for kwcat.
-    '''
-    def __init__(self, opener, path, kwt):
-        super(kwfilelog, self).__init__(opener, path)
-        self._kwt = kwt
-        self._path = path
-
-    def read(self, node):
-        '''Expands keywords when reading filelog.'''
-        data = super(kwfilelog, self).read(node)
-        return self._kwt.expand(self._path, data, node)
 
 
 def _status(ui, repo, *pats, **opts):
@@ -307,11 +299,22 @@
     %d   dirname of file being printed, or '.' if in repo root
     %p   root-relative path name of file being printed
     '''
+    ctx = repo.changectx(opts['rev'])
     try:
-        repo.file = repo._kwfile
+        repo._kwt.ctx = ctx
+        kw = True
     except AttributeError:
-        pass
-    commands.cat(ui, repo, file1, *pats, **opts)
+        kw = False
+    err = 1
+    for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts,
+                                             ctx.node()):
+        fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
+        data = ctx.filectx(abs).data()
+        if kw and repo._kwt.matcher(abs):
+            data = repo._kwt.expand(abs, data, None)
+        fp.write(data)
+        err = 0
+    return err
 
 def demo(ui, repo, *args, **opts):
     '''print [keywordmaps] configuration and an expansion example
@@ -454,14 +457,6 @@
         return
 
     class kwrepo(repo.__class__):
-        def _kwfile(self, f):
-            '''Returns filelog expanding keywords on read (for kwcat).'''
-            if f[0] == '/':
-                f = f[1:]
-            if self._kwt.matcher(f):
-                return kwfilelog(self.sopener, f, self._kwt)
-            return filelog.filelog(self.sopener, f)
-
         def _wreadkwct(self, filename, expand, ctx, node):
             '''Reads filename and returns tuple of data with keywords
             expanded/shrunk and count of keywords (for _overwrite).'''
@@ -578,6 +573,72 @@
 
         patchfile.__init__ = kwpatchfile_init
 
+    if _webcommands:
+        def kwweb_rawfile(web, req, tmpl):
+            '''Monkeypatch webcommands.rawfile so it expands keywords.'''
+            path = web.cleanpath(req.form.get('file', [''])[0])
+            if not path:
+                content = web.manifest(tmpl, web.changectx(req), path)
+                req.respond(webcommands.HTTP_OK, web.ctype)
+                return content
+            try:
+                fctx = web.filectx(req)
+            except revlog.LookupError:
+                content = web.manifest(tmpl, web.changectx(req), path)
+                req.respond(webcommands.HTTP_OK, web.ctype)
+                return content
+            path = fctx.path()
+            text = fctx.data()
+            if kwt.matcher(path):
+                text = kwt.expand(path, text, fctx.node())
+            mt = mimetypes.guess_type(path)[0]
+            if mt is None or util.binary(text):
+                mt = mt or 'application/octet-stream'
+            req.respond(webcommands.HTTP_OK, mt, path, len(text))
+            return [text]
+
+        webcommands.rawfile = kwweb_rawfile
+
+    else:
+        def kwweb_filerevision(self, fctx):
+            '''Monkeypatch hgweb_mod.hgweb.filerevision so keywords are
+            expanded in raw file output.'''
+            f = fctx.path()
+            text = fctx.data()
+            fl = fctx.filelog()
+            n = fctx.filenode()
+            parity = hgweb_mod.paritygen(self.stripecount)
+            mt = mimetypes.guess_type(f)[0]
+            rawtext = text
+            if kwt.matcher(f):
+                rawtext = kwt.expand(f, text, fctx.node())
+            if util.binary(text):
+                mt = mt or 'application/octet-stream'
+                text = "(binary:%s)" % mt
+            mt = mt or 'text/plain'
+            def lines():
+                for l, t in enumerate(text.splitlines(1)):
+                    yield {"line": t,
+                           "linenumber": "% 6d" % (l + 1),
+                           "parity": parity.next()}
+            yield self.t("filerevision",
+                         file=f,
+                         path=hgweb_mod._up(f),
+                         text=lines(),
+                         raw=rawtext,
+                         mimetype=mt,
+                         rev=fctx.rev(),
+                         node=hex(fctx.node()),
+                         author=fctx.user(),
+                         date=fctx.date(),
+                         desc=fctx.description(),
+                         parent=self.siblings(fctx.parents()),
+                         child=self.siblings(fctx.children()),
+                         rename=self.renamelink(fl, n),
+                         permissions=fctx.manifest().flags(f))
+
+        hgweb_mod.hgweb.filerevision = kwweb_filerevision
+
     repo.__class__ = kwrepo