mercurial/hgweb.py
changeset 1076 01db658cc78a
parent 1073 7b35a980b982
child 1077 b87aeccf73d9
equal deleted inserted replaced
1075:e254bcbfe636 1076:01db658cc78a
    56     up = os.path.dirname(p)
    56     up = os.path.dirname(p)
    57     if up == "/":
    57     if up == "/":
    58         return "/"
    58         return "/"
    59     return up + "/"
    59     return up + "/"
    60 
    60 
    61 def httphdr(type):
    61 def httphdr(type, file="", size=0):
    62     sys.stdout.write('Content-type: %s\n\n' % type)
    62     sys.stdout.write('Content-type: %s\n' % type)
       
    63     if file:
       
    64         sys.stdout.write('Content-disposition: attachment; filename=%s\n'
       
    65             % file)
       
    66     if size > 0:
       
    67         sys.stdout.write('Content-length: %d\n' % size)
       
    68     sys.stdout.write('\n')
    63 
    69 
    64 def write(*things):
    70 def write(*things):
    65     for thing in things:
    71     for thing in things:
    66         if hasattr(thing, "__iter__"):
    72         if hasattr(thing, "__iter__"):
    67             for part in thing:
    73             for part in thing:
   159             self.mtime = s.st_mtime
   165             self.mtime = s.st_mtime
   160             self.repo = repository(self.repo.ui, self.repo.root)
   166             self.repo = repository(self.repo.ui, self.repo.root)
   161             self.maxchanges = self.repo.ui.config("web", "maxchanges", 10)
   167             self.maxchanges = self.repo.ui.config("web", "maxchanges", 10)
   162             self.maxfiles = self.repo.ui.config("web", "maxchanges", 10)
   168             self.maxfiles = self.repo.ui.config("web", "maxchanges", 10)
   163             self.allowpull = self.repo.ui.configbool("web", "allowpull", True)
   169             self.allowpull = self.repo.ui.configbool("web", "allowpull", True)
       
   170             self.allowzip = self.repo.ui.configbool("web", "zip", True)
       
   171             self.allowgz = self.repo.ui.configbool("web", "gz", True)
       
   172             self.allowbz2 = self.repo.ui.configbool("web", "bz2", True)
   164 
   173 
   165     def date(self, cs):
   174     def date(self, cs):
   166         return time.asctime(time.gmtime(float(cs[2].split(' ')[0])))
   175         return time.asctime(time.gmtime(float(cs[2].split(' ')[0])))
   167 
   176 
   168     def listfiles(self, files, mf):
   177     def listfiles(self, files, mf):
   185                 yield self.t(t1, node=hex(node), rev=rev(node), **args)
   194                 yield self.t(t1, node=hex(node), rev=rev(node), **args)
   186 
   195 
   187     def showtag(self, t1, node=nullid, **args):
   196     def showtag(self, t1, node=nullid, **args):
   188         for t in self.repo.nodetags(node):
   197         for t in self.repo.nodetags(node):
   189              yield self.t(t1, tag=t, **args)
   198              yield self.t(t1, tag=t, **args)
       
   199 
       
   200     def tarballbuttons(self, m):
       
   201         s = ''
       
   202         if self.allowzip:
       
   203             s += '<a href="?cmd=tarball;manifest=%s;type=zip">zip</a>\n' % m
       
   204         if self.allowgz:
       
   205             s += '<a href="?cmd=tarball;manifest=%s;type=gz">gz</a>\n' % m
       
   206         if self.allowbz2:
       
   207             s += '<a href="?cmd=tarball;manifest=%s;type=bz2">bz2</a>\n' % m
       
   208         return s
   190 
   209 
   191     def diff(self, node1, node2, files):
   210     def diff(self, node1, node2, files):
   192         def filterfiles(list, files):
   211         def filterfiles(list, files):
   193             l = [x for x in list if x in files]
   212             l = [x for x in list if x in files]
   194 
   213 
   393                      changesettag=self.showtag("changesettag",n),
   412                      changesettag=self.showtag("changesettag",n),
   394                      manifest=hex(changes[0]),
   413                      manifest=hex(changes[0]),
   395                      author=changes[1],
   414                      author=changes[1],
   396                      desc=changes[4],
   415                      desc=changes[4],
   397                      date=t,
   416                      date=t,
   398                      files=files)
   417                      files=files,
       
   418                      tarballbuttons=self.tarballbuttons(hex(changes[0])))
   399 
   419 
   400     def filelog(self, f, filenode):
   420     def filelog(self, f, filenode):
   401         cl = self.repo.changelog
   421         cl = self.repo.changelog
   402         fl = self.repo.file(f)
   422         fl = self.repo.file(f)
   403         count = fl.count()
   423         count = fl.count()
   621                      rev=self.repo.changelog.rev(n),
   641                      rev=self.repo.changelog.rev(n),
   622                      parent=self.parents("filediffparent",
   642                      parent=self.parents("filediffparent",
   623                                          cl.parents(n), cl.rev),
   643                                          cl.parents(n), cl.rev),
   624                      diff=diff)
   644                      diff=diff)
   625 
   645 
       
   646     def ziparchive(self, mnode):
       
   647         import zipfile
       
   648 
       
   649         tmp = tempfile.mkstemp()[1]
       
   650         zf = zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED)
       
   651         mf = self.repo.manifest.read(bin(mnode))
       
   652         rev = self.repo.manifest.rev(bin(mnode))
       
   653         cnode = short(self.repo.changelog.node(rev))
       
   654         name = os.path.basename(self.repo.path[:-4]) # without '/.hg' suffix
       
   655         name += '-' + str(rev) + '-' + cnode + '/'
       
   656 
       
   657         for fname in mf.keys():
       
   658             r = self.repo.file(fname)
       
   659             zf.writestr(name + fname, r.read(mf[fname]))
       
   660         zf.close()
       
   661 
       
   662         f = open(tmp, 'r')
       
   663         httphdr('application/zip', name[:-1] + '.zip', os.path.getsize(tmp))
       
   664         sys.stdout.write(f.read())
       
   665         f.close()
       
   666         os.unlink(tmp)
       
   667 
       
   668     def tararchive(self, mnode, type):
       
   669         import StringIO
       
   670         import time
       
   671         import tarfile
       
   672 
       
   673         #if type == "gz":
       
   674         #    tf = tarfile.TarFile.gzopen('', 'w', sys.stdout, compressionlevel)
       
   675         #else:
       
   676         #    tf = tarfile.TarFile.bz2open('', 'w', sys.stdout, compressionlevel)
       
   677         tf = tarfile.TarFile.open(mode='w|' + type, fileobj=sys.stdout)
       
   678 
       
   679         mf = self.repo.manifest.read(bin(mnode))
       
   680         rev = self.repo.manifest.rev(bin(mnode))
       
   681         cnode = short(self.repo.changelog.node(rev))
       
   682         mff = self.repo.manifest.readflags(bin(mnode))
       
   683         mtime = int(time.time())
       
   684         name = os.path.basename(self.repo.path[:-4]) # without '/.hg' suffix
       
   685         name += '-' + str(rev) + '-' + cnode  + '/'
       
   686 
       
   687         httphdr('application/octet-stream', name[:-1] + '.tar.' + type)
       
   688         for fname in mf.keys():
       
   689             r = self.repo.file(fname)
       
   690             rcont = r.read(mf[fname])
       
   691             finfo = tarfile.TarInfo(name + fname)
       
   692             finfo.mtime = mtime
       
   693             finfo.size = len(rcont)
       
   694             finfo.mode = mff[fname] and 0755 or 0644
       
   695             tf.addfile(finfo, StringIO.StringIO(rcont))
       
   696         tf.close()
       
   697 
   626     # add tags to things
   698     # add tags to things
   627     # tags -> list of changesets corresponding to tags
   699     # tags -> list of changesets corresponding to tags
   628     # find tag, changeset, file
   700     # find tag, changeset, file
   629 
   701 
   630     def run(self):
   702     def run(self):
   737                 if not chunk:
   809                 if not chunk:
   738                     break
   810                     break
   739                 sys.stdout.write(z.compress(chunk))
   811                 sys.stdout.write(z.compress(chunk))
   740 
   812 
   741             sys.stdout.write(z.flush())
   813             sys.stdout.write(z.flush())
       
   814 
       
   815         elif args['cmd'][0] == 'tarball':
       
   816             manifest = args['manifest'][0]
       
   817             type = args['type'][0]
       
   818             if type == 'zip' and self.allowzip:
       
   819                 self.ziparchive(manifest)
       
   820             elif type == 'gz' and self.allowgz:
       
   821                 self.tararchive(manifest, 'gz')
       
   822             elif type == 'bz2' and self.allowbz2:
       
   823                 self.tararchive(manifest, 'bz2')
       
   824             else:
       
   825                 write(self.t("error"))
   742 
   826 
   743         else:
   827         else:
   744             write(self.t("error"))
   828             write(self.t("error"))
   745 
   829 
   746 def create_server(repo):
   830 def create_server(repo):