mercurial/hgweb.py
changeset 142 529bf610092e
parent 138 c77a679e9cfa
child 153 e8a360cd5a9f
child 155 083c38bdfa64
equal deleted inserted replaced
141:5f471a75d607 142:529bf610092e
   120         for f in files[:self.maxfiles]:
   120         for f in files[:self.maxfiles]:
   121             yield self.t("filedifflink", node = hex(changeset), file = f)
   121             yield self.t("filedifflink", node = hex(changeset), file = f)
   122         if len(files) > self.maxfiles:
   122         if len(files) > self.maxfiles:
   123             yield self.t("fileellipses")
   123             yield self.t("fileellipses")
   124 
   124 
       
   125     def parent(self, t1, node, rev):
       
   126         if node != hex(nullid):
       
   127             yield self.t(t1, node = node, rev = rev)
       
   128 
   125     def diff(self, node1, node2, files):
   129     def diff(self, node1, node2, files):
   126         def filterfiles(list, files):
   130         def filterfiles(list, files):
   127             l = [ x for x in list if x in files ]
   131             l = [ x for x in list if x in files ]
   128             
   132             
   129             for f in files:
   133             for f in files:
   167         for f in d:
   171         for f in d:
   168             to = r.file(f).read(mmap1[f])
   172             to = r.file(f).read(mmap1[f])
   169             tn = ""
   173             tn = ""
   170             yield prettyprint(mdiff.unidiff(to, date1, tn, date2, f))
   174             yield prettyprint(mdiff.unidiff(to, date1, tn, date2, f))
   171 
   175 
       
   176     def header(self):
       
   177         yield self.t("header", repo = self.reponame)
       
   178 
       
   179     def footer(self):
       
   180         yield self.t("footer", repo = self.reponame)
       
   181 
   172     def changelog(self, pos=None):
   182     def changelog(self, pos=None):
   173         def changenav():
   183         def changenav():
   174             def seq(factor = 1):
   184             def seq(factor = 1):
   175                 yield 1 * factor
   185                 yield 1 * factor
   176                 yield 2 * factor
   186                 yield 2 * factor
   189                     yield self.t("naventry", rev = s)
   199                     yield self.t("naventry", rev = s)
   190                     
   200                     
   191             yield self.t("naventry", rev = count - 1)
   201             yield self.t("naventry", rev = count - 1)
   192 
   202 
   193         def changelist():
   203         def changelist():
       
   204             parity = (start - end) & 1
   194             cl = self.repo.changelog
   205             cl = self.repo.changelog
   195             l = [] # build a list in forward order for efficiency
   206             l = [] # build a list in forward order for efficiency
   196             for i in range(start, end + 1):
   207             for i in range(start, end + 1):
   197                 n = cl.node(i)
   208                 n = cl.node(i)
   198                 changes = cl.read(n)
   209                 changes = cl.read(n)
   200                 p1, p2 = cl.parents(n)
   211                 p1, p2 = cl.parents(n)
   201                 t = float(changes[2].split(' ')[0])
   212                 t = float(changes[2].split(' ')[0])
   202 
   213 
   203                 l.insert(0, self.t(
   214                 l.insert(0, self.t(
   204                     'changelogentry',
   215                     'changelogentry',
       
   216                     parity = parity,
   205                     author = obfuscate(changes[1]),
   217                     author = obfuscate(changes[1]),
   206                     shortdesc = cgi.escape(changes[4].splitlines()[0]),
   218                     shortdesc = cgi.escape(changes[4].splitlines()[0]),
   207                     age = age(t),
   219                     age = age(t),
       
   220                     parent1 = self.parent("changelogparent",
       
   221                                           hex(p1), cl.rev(p1)),
       
   222                     parent2 = self.parent("changelogparent",
       
   223                                           hex(p2), cl.rev(p2)),
   208                     p1 = hex(p1), p2 = hex(p2),
   224                     p1 = hex(p1), p2 = hex(p2),
   209                     p1rev = cl.rev(p1), p2rev = cl.rev(p2),
   225                     p1rev = cl.rev(p1), p2rev = cl.rev(p2),
   210                     manifest = hex(changes[0]),
   226                     manifest = hex(changes[0]),
   211                     desc = nl2br(cgi.escape(changes[4])),
   227                     desc = nl2br(cgi.escape(changes[4])),
   212                     date = time.asctime(time.gmtime(t)),
   228                     date = time.asctime(time.gmtime(t)),
   213                     files = self.listfilediffs(changes[3], n),
   229                     files = self.listfilediffs(changes[3], n),
   214                     rev = i,
   230                     rev = i,
   215                     node = hn))
   231                     node = hn))
       
   232                 parity = 1 - parity
   216 
   233 
   217             yield l
   234             yield l
   218 
   235 
   219         count = self.repo.changelog.count()
   236         count = self.repo.changelog.count()
   220         pos = pos or count - 1
   237         pos = pos or count - 1
   221         end = min(pos, count - 1)
   238         end = min(pos, count - 1)
   222         start = max(0, pos - self.maxchanges)
   239         start = max(0, pos - self.maxchanges)
   223         end = min(count - 1, start + self.maxchanges)
   240         end = min(count - 1, start + self.maxchanges)
   224 
   241 
   225         yield self.t('changelog', repo = self.reponame, changenav = changenav,
   242         yield self.t('changelog',
   226                      rev = pos, changesets = count, changelist = changelist)
   243                      header = self.header(),
       
   244                      footer = self.footer(),
       
   245                      repo = self.reponame,
       
   246                      changenav = changenav,
       
   247                      rev = pos, changesets = count, entries = changelist)
   227 
   248 
   228     def changeset(self, nodeid):
   249     def changeset(self, nodeid):
   229         n = bin(nodeid)
   250         n = bin(nodeid)
   230         cl = self.repo.changelog
   251         cl = self.repo.changelog
   231         changes = cl.read(n)
   252         changes = cl.read(n)
   241 
   262 
   242         def diff():
   263         def diff():
   243             yield self.diff(p1, n, changes[3])
   264             yield self.diff(p1, n, changes[3])
   244 
   265 
   245         yield self.t('changeset',
   266         yield self.t('changeset',
       
   267                      header = self.header(),
       
   268                      footer = self.footer(),
       
   269                      repo = self.reponame,
   246                      diff = diff,
   270                      diff = diff,
   247                      rev = cl.rev(n),
   271                      rev = cl.rev(n),
   248                      node = nodeid,
   272                      node = nodeid,
   249                      shortdesc = cgi.escape(changes[4].splitlines()[0]),
   273                      shortdesc = cgi.escape(changes[4].splitlines()[0]),
       
   274                      parent1 = self.parent("changesetparent",
       
   275                                            hex(p1), cl.rev(p1)),
       
   276                      parent2 = self.parent("changesetparent",
       
   277                                            hex(p2), cl.rev(p2)),
   250                      p1 = hex(p1), p2 = hex(p2),
   278                      p1 = hex(p1), p2 = hex(p2),
   251                      p1rev = cl.rev(p1), p2rev = cl.rev(p2),
   279                      p1rev = cl.rev(p1), p2rev = cl.rev(p2),
   252                      manifest = hex(changes[0]),
   280                      manifest = hex(changes[0]),
   253                      author = obfuscate(changes[1]),
   281                      author = obfuscate(changes[1]),
   254                      desc = nl2br(cgi.escape(changes[4])),
   282                      desc = nl2br(cgi.escape(changes[4])),
   260         fl = self.repo.file(f)
   288         fl = self.repo.file(f)
   261         count = fl.count()
   289         count = fl.count()
   262 
   290 
   263         def entries():
   291         def entries():
   264             l = []
   292             l = []
       
   293             parity = (count - 1) & 1
       
   294             
   265             for i in range(count):
   295             for i in range(count):
   266 
   296 
   267                 n = fl.node(i)
   297                 n = fl.node(i)
   268                 lr = fl.linkrev(n)
   298                 lr = fl.linkrev(n)
   269                 cn = cl.node(lr)
   299                 cn = cl.node(lr)
   270                 cs = cl.read(cl.node(lr))
   300                 cs = cl.read(cl.node(lr))
   271                 p1, p2 = fl.parents(n)
   301                 p1, p2 = fl.parents(n)
   272                 t = float(cs[2].split(' ')[0])
   302                 t = float(cs[2].split(' ')[0])
   273 
   303 
   274                 l.insert(0, self.t("filelogentry",
   304                 l.insert(0, self.t("filelogentry",
       
   305                                    parity = parity,
   275                                    filenode = hex(n),
   306                                    filenode = hex(n),
   276                                    filerev = i,
   307                                    filerev = i,
   277                                    file = f,
   308                                    file = f,
   278                                    node = hex(cn),
   309                                    node = hex(cn),
   279                                    author = obfuscate(cs[1]),
   310                                    author = obfuscate(cs[1]),
   280                                    age = age(t),
   311                                    age = age(t),
   281                                    date = time.asctime(time.gmtime(t)),
   312                                    date = time.asctime(time.gmtime(t)),
   282                                    shortdesc = cgi.escape(cs[4].splitlines()[0]),
   313                                    shortdesc = cgi.escape(cs[4].splitlines()[0]),
   283                                    p1 = hex(p1), p2 = hex(p2),
   314                                    p1 = hex(p1), p2 = hex(p2),
   284                                    p1rev = fl.rev(p1), p2rev = fl.rev(p2)))
   315                                    p1rev = fl.rev(p1), p2rev = fl.rev(p2)))
       
   316                 parity = 1 - parity
   285 
   317 
   286             yield l
   318             yield l
   287 
   319 
   288         yield self.t("filelog",
   320         yield self.t("filelog",
       
   321                      header = self.header(),
       
   322                      footer = self.footer(),
       
   323                      repo = self.reponame,
   289                      file = f,
   324                      file = f,
   290                      filenode = filenode,
   325                      filenode = filenode,
   291                      entries = entries)
   326                      entries = entries)
   292 
   327 
   293     def filerevision(self, f, node):
   328     def filerevision(self, f, node):
   299         cn = cl.node(changerev)
   334         cn = cl.node(changerev)
   300         cs = cl.read(cn)
   335         cs = cl.read(cn)
   301         p1, p2 = fl.parents(n)
   336         p1, p2 = fl.parents(n)
   302         t = float(cs[2].split(' ')[0])
   337         t = float(cs[2].split(' ')[0])
   303         mfn = cs[0]
   338         mfn = cs[0]
       
   339 
       
   340         def lines():
       
   341             for l, t in enumerate(text.splitlines(1)):
       
   342                 yield self.t("fileline",
       
   343                              line = t,
       
   344                              linenumber = "% 6d" % (l + 1),
       
   345                              parity = l & 1)
   304         
   346         
   305         yield self.t("filerevision", file = f,
   347         yield self.t("filerevision", file = f,
       
   348                      header = self.header(),
       
   349                      footer = self.footer(),
       
   350                      repo = self.reponame,
   306                      filenode = node,
   351                      filenode = node,
   307                      path = up(f),
   352                      path = up(f),
   308                      text = text,
   353                      text = lines(),
   309                      rev = changerev,
   354                      rev = changerev,
   310                      node = hex(cn),
   355                      node = hex(cn),
   311                      manifest = hex(mfn),
   356                      manifest = hex(mfn),
   312                      author = obfuscate(cs[1]),
   357                      author = obfuscate(cs[1]),
   313                      age = age(t),
   358                      age = age(t),
   314                      date = time.asctime(time.gmtime(t)),
   359                      date = time.asctime(time.gmtime(t)),
   315                      shortdesc = cgi.escape(cs[4].splitlines()[0]),
   360                      shortdesc = cgi.escape(cs[4].splitlines()[0]),
       
   361                      parent1 = self.parent("filerevparent",
       
   362                                            hex(p1), fl.rev(p1)),
       
   363                      parent2 = self.parent("filerevparent",
       
   364                                            hex(p2), fl.rev(p2)),
   316                      p1 = hex(p1), p2 = hex(p2),
   365                      p1 = hex(p1), p2 = hex(p2),
   317                      p1rev = fl.rev(p1), p2rev = fl.rev(p2))
   366                      p1rev = fl.rev(p1), p2rev = fl.rev(p2))
   318 
   367 
   319 
   368 
   320     def fileannotate(self, f, node):
   369     def fileannotate(self, f, node):
   330         p1, p2 = fl.parents(n)
   379         p1, p2 = fl.parents(n)
   331         t = float(cs[2].split(' ')[0])
   380         t = float(cs[2].split(' ')[0])
   332         mfn = cs[0]
   381         mfn = cs[0]
   333 
   382 
   334         def annotate():
   383         def annotate():
       
   384             parity = 1
       
   385             last = None
   335             for r, l in fl.annotate(n):
   386             for r, l in fl.annotate(n):
   336                 try:
   387                 try:
   337                     cnode = ncache[r]
   388                     cnode = ncache[r]
   338                 except KeyError:
   389                 except KeyError:
   339                     cnode = ncache[r] = self.repo.changelog.node(r)
   390                     cnode = ncache[r] = self.repo.changelog.node(r)
   346                     f = name.find('@')
   397                     f = name.find('@')
   347                     if f >= 0:
   398                     if f >= 0:
   348                         name = name[:f]
   399                         name = name[:f]
   349                     bcache[r] = name
   400                     bcache[r] = name
   350 
   401 
       
   402                 if last != cnode:
       
   403                     parity = 1 - parity
       
   404                     last = cnode
       
   405 
   351                 yield self.t("annotateline",
   406                 yield self.t("annotateline",
       
   407                              parity = parity,
   352                              node = hex(cnode),
   408                              node = hex(cnode),
   353                              rev = r,
   409                              rev = r,
   354                              author = name,
   410                              author = name,
   355                              file = f,
   411                              file = f,
   356                              line = cgi.escape(l))
   412                              line = cgi.escape(l))
   357 
   413 
   358         yield self.t("fileannotate",
   414         yield self.t("fileannotate",
       
   415                      header = self.header(),
       
   416                      footer = self.footer(),
       
   417                      repo = self.reponame,
   359                      file = f,
   418                      file = f,
   360                      filenode = node,
   419                      filenode = node,
   361                      annotate = annotate,
   420                      annotate = annotate,
   362                      path = up(f),
   421                      path = up(f),
   363                      rev = changerev,
   422                      rev = changerev,
   365                      manifest = hex(mfn),
   424                      manifest = hex(mfn),
   366                      author = obfuscate(cs[1]),
   425                      author = obfuscate(cs[1]),
   367                      age = age(t),
   426                      age = age(t),
   368                      date = time.asctime(time.gmtime(t)),
   427                      date = time.asctime(time.gmtime(t)),
   369                      shortdesc = cgi.escape(cs[4].splitlines()[0]),
   428                      shortdesc = cgi.escape(cs[4].splitlines()[0]),
       
   429                      parent1 = self.parent("filerevparent",
       
   430                                            hex(p1), fl.rev(p1)),
       
   431                      parent2 = self.parent("filerevparent",
       
   432                                            hex(p2), fl.rev(p2)),
   370                      p1 = hex(p1), p2 = hex(p2),
   433                      p1 = hex(p1), p2 = hex(p2),
   371                      p1rev = fl.rev(p1), p2rev = fl.rev(p2))
   434                      p1rev = fl.rev(p1), p2rev = fl.rev(p2))
   372 
   435 
   373     def manifest(self, mnode, path):
   436     def manifest(self, mnode, path):
   374         mf = self.repo.manifest.read(bin(mnode))
   437         mf = self.repo.manifest.read(bin(mnode))
   375         rev = self.repo.manifest.rev(bin(mnode))
   438         rev = self.repo.manifest.rev(bin(mnode))
   376         node = self.repo.changelog.node(rev)
   439         node = self.repo.changelog.node(rev)
   377 
   440 
   378         dirs = {}
       
   379         files = {}
   441         files = {}
   380         short = {}
   442  
   381 
       
   382         p = path[1:]
   443         p = path[1:]
   383         l = len(p)
   444         l = len(p)
   384 
   445 
   385         for f,n in mf.items():
   446         for f,n in mf.items():
   386             if f[:l] != p:
   447             if f[:l] != p:
   387                 continue
   448                 continue
   388             remain = f[l:]
   449             remain = f[l:]
   389             if "/" in remain:
   450             if "/" in remain:
   390                 short = remain[:remain.find("/") + 1] # bleah
   451                 short = remain[:remain.find("/") + 1] # bleah
   391                 dirs[short] = 1
   452                 files[short] = (f, None)
   392             else:
   453             else:
   393                 short = os.path.basename(remain)
   454                 short = os.path.basename(remain)
   394                 files[short] = (f, n)
   455                 files[short] = (f, n)
   395 
   456 
   396         def dirlist():
       
   397             dl = dirs.keys()
       
   398             dl.sort()
       
   399             
       
   400             for d in dl:
       
   401                 yield self.t("manifestdirentry",
       
   402                              path = os.path.join(path, d),
       
   403                              manifest = mnode, basename = d[:-1])
       
   404 
       
   405         def filelist():
   457         def filelist():
       
   458             parity = 0
   406             fl = files.keys()
   459             fl = files.keys()
   407             fl.sort()
   460             fl.sort()
   408             for f in fl:
   461             for f in fl:
   409                 full, fnode = files[f]
   462                 full, fnode = files[f]
   410                 yield self.t("manifestfileentry",
   463                 if fnode:
   411                              file = full, manifest = mnode, filenode = hex(fnode),
   464                     yield self.t("manifestfileentry",
   412                              basename = f)
   465                                  file = full,
       
   466                                  manifest = mnode,
       
   467                                  filenode = hex(fnode),
       
   468                                  parity = parity,
       
   469                                  basename = f)
       
   470                 else:
       
   471                     yield self.t("manifestdirentry",
       
   472                                  parity = parity,
       
   473                                  path = os.path.join(path, f),
       
   474                                  manifest = mnode, basename = f[:-1])
       
   475                 parity = 1 - parity
   413 
   476 
   414         yield self.t("manifest",
   477         yield self.t("manifest",
       
   478                      header = self.header(),
       
   479                      footer = self.footer(),
       
   480                      repo = self.reponame,
   415                      manifest = mnode,
   481                      manifest = mnode,
   416                      rev = rev,
   482                      rev = rev,
   417                      node = hex(node),
   483                      node = hex(node),
   418                      path = path,
   484                      path = path,
   419                      up = up(path),
   485                      up = up(path),
   420                      dirs = dirlist,
   486                      entries = filelist)
   421                      files = filelist)
       
   422 
   487 
   423     def filediff(self, file, changeset):
   488     def filediff(self, file, changeset):
   424         n = bin(changeset)
   489         n = bin(changeset)
   425         cl = self.repo.changelog
   490         cl = self.repo.changelog
   426         p1 = cl.parents(n)[0]
   491         p1 = cl.parents(n)[0]
   429         
   494         
   430         def diff():
   495         def diff():
   431             yield self.diff(p1, n, file)
   496             yield self.diff(p1, n, file)
   432 
   497 
   433         yield self.t("filediff",
   498         yield self.t("filediff",
       
   499                      header = self.header(),
       
   500                      footer = self.footer(),
       
   501                      repo = self.reponame,
   434                      file = file,
   502                      file = file,
   435                      filenode = hex(mf[file]),
   503                      filenode = hex(mf[file]),
   436                      node = changeset,
   504                      node = changeset,
   437                      rev = self.repo.changelog.rev(n),
   505                      rev = self.repo.changelog.rev(n),
   438                      p1 = hex(p1),
   506                      p1 = hex(p1),
   439                      p1rev = self.repo.changelog.rev(p1),
   507                      p1rev = self.repo.changelog.rev(p1),
   440                      diff = diff)
   508                      diff = diff)
   441                      
   509                      
   442     # header and footer, css
       
   443     # add tags to things
   510     # add tags to things
   444     # show parents
       
   445     # diff between rev and parent in changeset and file
       
   446     # manifest links
       
   447     # browse at top
       
   448     # tags -> list of changesets corresponding to tags
   511     # tags -> list of changesets corresponding to tags
   449     # find tag, changeset, file
   512     # find tag, changeset, file
   450 
   513 
   451     def run(self):
   514     def run(self):
   452         args = cgi.parse()
   515         args = cgi.parse()