680 rev=self.repo.changelog.rev(n), |
680 rev=self.repo.changelog.rev(n), |
681 parent=self.siblings(cl.parents(n), cl.rev), |
681 parent=self.siblings(cl.parents(n), cl.rev), |
682 child=self.siblings(cl.children(n), cl.rev), |
682 child=self.siblings(cl.children(n), cl.rev), |
683 diff=diff) |
683 diff=diff) |
684 |
684 |
|
685 archive_specs = { |
|
686 'bz2': ('application/x-tar', 'tbz2', '.tar.bz2', 'x-bzip2'), |
|
687 'gz': ('application/x-tar', 'tgz', '.tar.gz', 'x-gzip'), |
|
688 'zip': ('application/zip', 'zip', '.zip', None), |
|
689 } |
|
690 |
685 def archive(self, req, cnode, type): |
691 def archive(self, req, cnode, type): |
686 cs = self.repo.changelog.read(cnode) |
692 reponame = re.sub(r"\W+", "-", os.path.basename(self.reponame)) |
687 mnode = cs[0] |
693 name = "%s-%s" % (reponame, short(cnode)) |
688 mf = self.repo.manifest.read(mnode) |
694 mimetype, artype, extension, encoding = self.archive_specs[type] |
689 rev = self.repo.manifest.rev(mnode) |
695 headers = [('Content-type', mimetype), |
690 reponame = re.sub(r"\W+", "-", self.reponame) |
696 ('Content-disposition', 'attachment; filename=%s%s' % |
691 name = "%s-%s/" % (reponame, short(cnode)) |
697 (name, extension))] |
692 |
698 if encoding: |
693 files = mf.keys() |
699 headers.append(('Content-encoding', encoding)) |
694 files.sort() |
700 req.header(headers) |
695 |
701 archival.archive(self.repo, req.out, cnode, artype, prefix=name) |
696 if type == 'zip': |
|
697 tmp = tempfile.mkstemp()[1] |
|
698 try: |
|
699 zf = zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) |
|
700 |
|
701 for f in files: |
|
702 zf.writestr(name + f, self.repo.file(f).read(mf[f])) |
|
703 zf.close() |
|
704 |
|
705 f = open(tmp, 'r') |
|
706 req.httphdr('application/zip', name[:-1] + '.zip', |
|
707 os.path.getsize(tmp)) |
|
708 req.write(f.read()) |
|
709 f.close() |
|
710 finally: |
|
711 os.unlink(tmp) |
|
712 |
|
713 else: |
|
714 tf = tarfile.TarFile.open(mode='w|' + type, fileobj=req.out) |
|
715 mff = self.repo.manifest.readflags(mnode) |
|
716 mtime = int(time.time()) |
|
717 |
|
718 if type == "gz": |
|
719 encoding = "gzip" |
|
720 else: |
|
721 encoding = "x-bzip2" |
|
722 req.header([('Content-type', 'application/x-tar'), |
|
723 ('Content-disposition', 'attachment; filename=%s%s%s' % |
|
724 (name[:-1], '.tar.', type)), |
|
725 ('Content-encoding', encoding)]) |
|
726 for fname in files: |
|
727 rcont = self.repo.file(fname).read(mf[fname]) |
|
728 finfo = tarfile.TarInfo(name + fname) |
|
729 finfo.mtime = mtime |
|
730 finfo.size = len(rcont) |
|
731 finfo.mode = mff[fname] and 0755 or 0644 |
|
732 tf.addfile(finfo, StringIO.StringIO(rcont)) |
|
733 tf.close() |
|
734 |
702 |
735 # add tags to things |
703 # add tags to things |
736 # tags -> list of changesets corresponding to tags |
704 # tags -> list of changesets corresponding to tags |
737 # find tag, changeset, file |
705 # find tag, changeset, file |
738 |
706 |