Mercurial > hg
changeset 1076:01db658cc78a
tarball support v0.3
Hello,
I'm slowly improving support for tarballs in Mercurial. Attached patch
is made against current tip in Matt's repository - f859e9cba1b9, and
contains everything done so far.
Changes:
- gzip and bzip2 tarballs are sent immediately without writing to
temporary files (I was wrong Matt, it can be done very easy)
- hgrc customization, you can choose which type (if any) you will support
There's no easy way to support compression levels, since TarFile open()
assume that it is 9. I tried to use gzopen(), and bz2open() methods
instead, but it seems that headers of generated archives, are missing or
wrong. We could eventually try to rewrite tarfile.py and include our own
version into Mercurial, but I don't know if it's good idea...
Wojtek
author | Wojciech Milkowski <wmilkowski@interia.pl> |
---|---|
date | Fri, 26 Aug 2005 20:51:34 -0700 |
parents | e254bcbfe636 |
children | b87aeccf73d9 |
files | mercurial/hgweb.py templates/changeset.tmpl |
diffstat | 2 files changed, 88 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/hgweb.py Fri Aug 26 19:20:04 2005 -0700 +++ b/mercurial/hgweb.py Fri Aug 26 20:51:34 2005 -0700 @@ -58,8 +58,14 @@ return "/" return up + "/" -def httphdr(type): - sys.stdout.write('Content-type: %s\n\n' % type) +def httphdr(type, file="", size=0): + sys.stdout.write('Content-type: %s\n' % type) + if file: + sys.stdout.write('Content-disposition: attachment; filename=%s\n' + % file) + if size > 0: + sys.stdout.write('Content-length: %d\n' % size) + sys.stdout.write('\n') def write(*things): for thing in things: @@ -161,6 +167,9 @@ self.maxchanges = self.repo.ui.config("web", "maxchanges", 10) self.maxfiles = self.repo.ui.config("web", "maxchanges", 10) self.allowpull = self.repo.ui.configbool("web", "allowpull", True) + self.allowzip = self.repo.ui.configbool("web", "zip", True) + self.allowgz = self.repo.ui.configbool("web", "gz", True) + self.allowbz2 = self.repo.ui.configbool("web", "bz2", True) def date(self, cs): return time.asctime(time.gmtime(float(cs[2].split(' ')[0]))) @@ -188,6 +197,16 @@ for t in self.repo.nodetags(node): yield self.t(t1, tag=t, **args) + def tarballbuttons(self, m): + s = '' + if self.allowzip: + s += '<a href="?cmd=tarball;manifest=%s;type=zip">zip</a>\n' % m + if self.allowgz: + s += '<a href="?cmd=tarball;manifest=%s;type=gz">gz</a>\n' % m + if self.allowbz2: + s += '<a href="?cmd=tarball;manifest=%s;type=bz2">bz2</a>\n' % m + return s + def diff(self, node1, node2, files): def filterfiles(list, files): l = [x for x in list if x in files] @@ -395,7 +414,8 @@ author=changes[1], desc=changes[4], date=t, - files=files) + files=files, + tarballbuttons=self.tarballbuttons(hex(changes[0]))) def filelog(self, f, filenode): cl = self.repo.changelog @@ -623,6 +643,58 @@ cl.parents(n), cl.rev), diff=diff) + def ziparchive(self, mnode): + import zipfile + + tmp = tempfile.mkstemp()[1] + zf = zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) + mf = self.repo.manifest.read(bin(mnode)) + rev = self.repo.manifest.rev(bin(mnode)) + cnode = short(self.repo.changelog.node(rev)) + name = os.path.basename(self.repo.path[:-4]) # without '/.hg' suffix + name += '-' + str(rev) + '-' + cnode + '/' + + for fname in mf.keys(): + r = self.repo.file(fname) + zf.writestr(name + fname, r.read(mf[fname])) + zf.close() + + f = open(tmp, 'r') + httphdr('application/zip', name[:-1] + '.zip', os.path.getsize(tmp)) + sys.stdout.write(f.read()) + f.close() + os.unlink(tmp) + + def tararchive(self, mnode, type): + import StringIO + import time + import tarfile + + #if type == "gz": + # tf = tarfile.TarFile.gzopen('', 'w', sys.stdout, compressionlevel) + #else: + # tf = tarfile.TarFile.bz2open('', 'w', sys.stdout, compressionlevel) + tf = tarfile.TarFile.open(mode='w|' + type, fileobj=sys.stdout) + + mf = self.repo.manifest.read(bin(mnode)) + rev = self.repo.manifest.rev(bin(mnode)) + cnode = short(self.repo.changelog.node(rev)) + mff = self.repo.manifest.readflags(bin(mnode)) + mtime = int(time.time()) + name = os.path.basename(self.repo.path[:-4]) # without '/.hg' suffix + name += '-' + str(rev) + '-' + cnode + '/' + + httphdr('application/octet-stream', name[:-1] + '.tar.' + type) + for fname in mf.keys(): + r = self.repo.file(fname) + rcont = r.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() + # add tags to things # tags -> list of changesets corresponding to tags # find tag, changeset, file @@ -740,6 +812,18 @@ sys.stdout.write(z.flush()) + elif args['cmd'][0] == 'tarball': + manifest = args['manifest'][0] + type = args['type'][0] + if type == 'zip' and self.allowzip: + self.ziparchive(manifest) + elif type == 'gz' and self.allowgz: + self.tararchive(manifest, 'gz') + elif type == 'bz2' and self.allowbz2: + self.tararchive(manifest, 'bz2') + else: + write(self.t("error")) + else: write(self.t("error"))
--- a/templates/changeset.tmpl Fri Aug 26 19:20:04 2005 -0700 +++ b/templates/changeset.tmpl Fri Aug 26 20:51:34 2005 -0700 @@ -8,6 +8,7 @@ <a href="?cmd=tags">tags</a> <a href="?cmd=manifest;manifest=#manifest#;path=/">manifest</a> <a href="?cmd=changeset;node=#node#;style=raw">raw</a> +#tarballbuttons# </div> <h2>changeset: #desc|escape|firstline#</h2>