comparison mercurial/hgweb.py @ 1078:33f40d0c6124

Various cleanups for tarball support s/tarball/archive/ query config rather than maintaining a list default all archive support to off use changeset nodes rather than manifest nodes use web:name for archive name don't use rev number in filename, it's not portable refactor manifest lookup bits use finally: clause to delete tmpfile
author mpm@selenic.com
date Fri, 26 Aug 2005 20:52:31 -0700
parents b87aeccf73d9
children 3a1a46dcd397
comparison
equal deleted inserted replaced
1077:b87aeccf73d9 1078:33f40d0c6124
156 self.repo = repo 156 self.repo = repo
157 157
158 self.mtime = -1 158 self.mtime = -1
159 self.reponame = name or self.repo.ui.config("web", "name", 159 self.reponame = name or self.repo.ui.config("web", "name",
160 self.repo.root) 160 self.repo.root)
161 self.supportedtarballs = 'zip', 'gz', 'bz2' 161 self.archives = 'zip', 'gz', 'bz2'
162 162
163 def refresh(self): 163 def refresh(self):
164 s = os.stat(os.path.join(self.repo.root, ".hg", "00changelog.i")) 164 s = os.stat(os.path.join(self.repo.root, ".hg", "00changelog.i"))
165 if s.st_mtime != self.mtime: 165 if s.st_mtime != self.mtime:
166 self.mtime = s.st_mtime 166 self.mtime = s.st_mtime
167 self.repo = repository(self.repo.ui, self.repo.root) 167 self.repo = repository(self.repo.ui, self.repo.root)
168 self.maxchanges = self.repo.ui.config("web", "maxchanges", 10) 168 self.maxchanges = self.repo.ui.config("web", "maxchanges", 10)
169 self.maxfiles = self.repo.ui.config("web", "maxchanges", 10) 169 self.maxfiles = self.repo.ui.config("web", "maxchanges", 10)
170 self.allowpull = self.repo.ui.configbool("web", "allowpull", True) 170 self.allowpull = self.repo.ui.configbool("web", "allowpull", True)
171 self.allowedtarballs = []
172 for i in self.supportedtarballs:
173 if self.repo.ui.configbool("web", i, True):
174 self.allowedtarballs.append(i)
175 171
176 def date(self, cs): 172 def date(self, cs):
177 return time.asctime(time.gmtime(float(cs[2].split(' ')[0]))) 173 return time.asctime(time.gmtime(float(cs[2].split(' ')[0])))
178 174
179 def listfiles(self, files, mf): 175 def listfiles(self, files, mf):
393 filenode=hex(mf.get(f, nullid)), file=f)) 389 filenode=hex(mf.get(f, nullid)), file=f))
394 390
395 def diff(**map): 391 def diff(**map):
396 yield self.diff(p1, n, None) 392 yield self.diff(p1, n, None)
397 393
398 def tarballs(): 394 def archivelist():
399 for i in self.allowedtarballs: 395 for i in self.archives:
400 yield {"type" : i, 396 if self.repo.ui.configbool("web", "allow" + i, False):
401 "manifest" : hex(changes[0])} 397 yield {"type" : i, "node" : nodeid}
402 398
403 yield self.t('changeset', 399 yield self.t('changeset',
404 diff=diff, 400 diff=diff,
405 rev=cl.rev(n), 401 rev=cl.rev(n),
406 node=nodeid, 402 node=nodeid,
410 manifest=hex(changes[0]), 406 manifest=hex(changes[0]),
411 author=changes[1], 407 author=changes[1],
412 desc=changes[4], 408 desc=changes[4],
413 date=t, 409 date=t,
414 files=files, 410 files=files,
415 tarballbs = tarballs()) 411 archives=archivelist())
416 412
417 def filelog(self, f, filenode): 413 def filelog(self, f, filenode):
418 cl = self.repo.changelog 414 cl = self.repo.changelog
419 fl = self.repo.file(f) 415 fl = self.repo.file(f)
420 count = fl.count() 416 count = fl.count()
638 rev=self.repo.changelog.rev(n), 634 rev=self.repo.changelog.rev(n),
639 parent=self.parents("filediffparent", 635 parent=self.parents("filediffparent",
640 cl.parents(n), cl.rev), 636 cl.parents(n), cl.rev),
641 diff=diff) 637 diff=diff)
642 638
643 def tarball(self, mnode, type): 639 def archive(self, cnode, type):
640 cs = self.repo.changelog.read(cnode)
641 mnode = cs[0]
642 mf = self.repo.manifest.read(mnode)
643 rev = self.repo.manifest.rev(mnode)
644 reponame = re.sub(r"\W+", "-", self.reponame)
645 name = "%s-%s/" % (reponame, short(cnode))
646
644 if type == 'zip': 647 if type == 'zip':
645 import zipfile 648 import zipfile
646 649
647 tmp = tempfile.mkstemp()[1] 650 try:
648 zf = zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED) 651 tmp = tempfile.mkstemp()[1]
649 mf = self.repo.manifest.read(bin(mnode)) 652 zf = zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED)
650 rev = self.repo.manifest.rev(bin(mnode)) 653
651 cnode = short(self.repo.changelog.node(rev)) 654 for f in mf.keys():
652 name = os.path.basename(self.repo.path[:-4]) # without '/.hg' suffix 655 zf.writestr(name + f, self.repo.file(f).read(mf[f]))
653 name += '-' + str(rev) + '-' + cnode + '/' 656 zf.close()
654 657
655 for fname in mf.keys(): 658 f = open(tmp, 'r')
656 r = self.repo.file(fname) 659 httphdr('application/zip', name[:-1] + '.zip',
657 zf.writestr(name + fname, r.read(mf[fname])) 660 os.path.getsize(tmp))
658 zf.close() 661 sys.stdout.write(f.read())
659 662 f.close()
660 f = open(tmp, 'r') 663 finally:
661 httphdr('application/zip', name[:-1] + '.zip', os.path.getsize(tmp)) 664 os.unlink(tmp)
662 sys.stdout.write(f.read())
663 f.close()
664 os.unlink(tmp)
665 665
666 else: 666 else:
667 import StringIO 667 import StringIO
668 import time 668 import time
669 import tarfile 669 import tarfile
670 670
671 #if type == "gz":
672 # tf = tarfile.TarFile.gzopen('', 'w', sys.stdout, compressionlevel)
673 #else:
674 # tf = tarfile.TarFile.bz2open('', 'w', sys.stdout, compressionlevel)
675 tf = tarfile.TarFile.open(mode='w|' + type, fileobj=sys.stdout) 671 tf = tarfile.TarFile.open(mode='w|' + type, fileobj=sys.stdout)
676 672 mff = self.repo.manifest.readflags(mnode)
677 mf = self.repo.manifest.read(bin(mnode))
678 rev = self.repo.manifest.rev(bin(mnode))
679 cnode = short(self.repo.changelog.node(rev))
680 mff = self.repo.manifest.readflags(bin(mnode))
681 mtime = int(time.time()) 673 mtime = int(time.time())
682 name = os.path.basename(self.repo.path[:-4]) # without '/.hg' suffix
683 name += '-' + str(rev) + '-' + cnode + '/'
684 674
685 httphdr('application/octet-stream', name[:-1] + '.tar.' + type) 675 httphdr('application/octet-stream', name[:-1] + '.tar.' + type)
686 for fname in mf.keys(): 676 for fname in mf.keys():
687 r = self.repo.file(fname) 677 rcont = self.repo.file(fname).read(mf[fname])
688 rcont = r.read(mf[fname])
689 finfo = tarfile.TarInfo(name + fname) 678 finfo = tarfile.TarInfo(name + fname)
690 finfo.mtime = mtime 679 finfo.mtime = mtime
691 finfo.size = len(rcont) 680 finfo.size = len(rcont)
692 finfo.mode = mff[fname] and 0755 or 0644 681 finfo.mode = mff[fname] and 0755 or 0644
693 tf.addfile(finfo, StringIO.StringIO(rcont)) 682 tf.addfile(finfo, StringIO.StringIO(rcont))
808 break 797 break
809 sys.stdout.write(z.compress(chunk)) 798 sys.stdout.write(z.compress(chunk))
810 799
811 sys.stdout.write(z.flush()) 800 sys.stdout.write(z.flush())
812 801
813 elif args['cmd'][0] == 'tarball': 802 elif args['cmd'][0] == 'archive':
814 manifest = args['manifest'][0] 803 changeset = bin(args['node'][0])
815 type = args['type'][0] 804 type = args['type'][0]
816 for i in self.supportedtarballs: 805 if (type in self.archives and
817 if type == i and i in self.allowedtarballs: 806 self.repo.ui.configbool("web", "allow" + type, False)):
818 self.tarball(manifest, type) 807 self.archive(changeset, type)
819 return 808 return
820 809
821 write(self.t("error")) 810 write(self.t("error"))
822 811
823 else: 812 else:
824 write(self.t("error")) 813 write(self.t("error"))