changeset 2113:633d733e7b11

make hgweb use new archival module. also use "x-gzip" encoding for ".tar.gz" files, so mozilla and firefox will not transparently decompress stream and save with wrong name.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Fri, 21 Apr 2006 15:28:50 -0700
parents 2b03c6733efa
children 98cc126f9f3f
files mercurial/hgweb.py
diffstat 1 files changed, 18 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/hgweb.py	Fri Apr 21 15:27:57 2006 -0700
+++ b/mercurial/hgweb.py	Fri Apr 21 15:28:50 2006 -0700
@@ -10,8 +10,8 @@
 import mimetypes
 from demandload import demandload
 demandload(globals(), "mdiff time re socket zlib errno ui hg ConfigParser")
-demandload(globals(), "zipfile tempfile StringIO tarfile BaseHTTPServer util")
-demandload(globals(), "mimetypes templater")
+demandload(globals(), "tempfile StringIO BaseHTTPServer util")
+demandload(globals(), "archival mimetypes templater")
 from node import *
 from i18n import gettext as _
 
@@ -682,55 +682,23 @@
                      child=self.siblings(cl.children(n), cl.rev),
                      diff=diff)
 
-    def archive(self, req, cnode, type):
-        cs = self.repo.changelog.read(cnode)
-        mnode = cs[0]
-        mf = self.repo.manifest.read(mnode)
-        rev = self.repo.manifest.rev(mnode)
-        reponame = re.sub(r"\W+", "-", self.reponame)
-        name = "%s-%s/" % (reponame, short(cnode))
-
-        files = mf.keys()
-        files.sort()
-
-        if type == 'zip':
-            tmp = tempfile.mkstemp()[1]
-            try:
-                zf = zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED)
-
-                for f in files:
-                    zf.writestr(name + f, self.repo.file(f).read(mf[f]))
-                zf.close()
+    archive_specs = {
+        'bz2': ('application/x-tar', 'tbz2', '.tar.bz2', 'x-bzip2'),
+        'gz': ('application/x-tar', 'tgz', '.tar.gz', 'x-gzip'),
+        'zip': ('application/zip', 'zip', '.zip', None),
+        }
 
-                f = open(tmp, 'r')
-                req.httphdr('application/zip', name[:-1] + '.zip',
-                        os.path.getsize(tmp))
-                req.write(f.read())
-                f.close()
-            finally:
-                os.unlink(tmp)
-
-        else:
-            tf = tarfile.TarFile.open(mode='w|' + type, fileobj=req.out)
-            mff = self.repo.manifest.readflags(mnode)
-            mtime = int(time.time())
-
-            if type == "gz":
-                encoding = "gzip"
-            else:
-                encoding = "x-bzip2"
-            req.header([('Content-type', 'application/x-tar'),
-                    ('Content-disposition', 'attachment; filename=%s%s%s' %
-                        (name[:-1], '.tar.', type)),
-                    ('Content-encoding', encoding)])
-            for fname in files:
-                rcont = self.repo.file(fname).read(mf[fname])
-                finfo = tarfile.TarInfo(name + fname)
-                finfo.mtime = mtime
-                finfo.size = len(rcont)
-                finfo.mode = mff[fname] and 0755 or 0644
-                tf.addfile(finfo, StringIO.StringIO(rcont))
-            tf.close()
+    def archive(self, req, cnode, type):
+        reponame = re.sub(r"\W+", "-", os.path.basename(self.reponame))
+        name = "%s-%s" % (reponame, short(cnode))
+        mimetype, artype, extension, encoding = self.archive_specs[type]
+        headers = [('Content-type', mimetype),
+                   ('Content-disposition', 'attachment; filename=%s%s' %
+                    (name, extension))]
+        if encoding:
+            headers.append(('Content-encoding', encoding))
+        req.header(headers)
+        archival.archive(self.repo, req.out, cnode, artype, prefix=name)
 
     # add tags to things
     # tags -> list of changesets corresponding to tags