mercurial/hgweb.py
changeset 981 4f81068ed8cd
parent 964 3f37720e7dc7
parent 980 5197fb9d65d5
child 982 8d2e24bae760
equal deleted inserted replaced
973:a51991ebf229 981:4f81068ed8cd
    61         if hasattr(thing, "__iter__"):
    61         if hasattr(thing, "__iter__"):
    62             for part in thing:
    62             for part in thing:
    63                 write(part)
    63                 write(part)
    64         else:
    64         else:
    65             sys.stdout.write(str(thing))
    65             sys.stdout.write(str(thing))
    66 
       
    67 def template(tmpl, filters = {}, **map):
       
    68     while tmpl:
       
    69         m = re.search(r"#([a-zA-Z0-9]+)((\|[a-zA-Z0-9]+)*)#", tmpl)
       
    70         if m:
       
    71             yield tmpl[:m.start(0)]
       
    72             v = map.get(m.group(1), "")
       
    73             v = callable(v) and v(**map) or v
       
    74 
       
    75             fl = m.group(2)
       
    76             if fl:
       
    77                 for f in fl.split("|")[1:]:
       
    78                     v = filters[f](v)
       
    79 
       
    80             yield v
       
    81             tmpl = tmpl[m.end(0):]
       
    82         else:
       
    83             yield tmpl
       
    84             return
       
    85 
    66 
    86 class templater:
    67 class templater:
    87     def __init__(self, mapfile, filters = {}, defaults = {}):
    68     def __init__(self, mapfile, filters = {}, defaults = {}):
    88         self.cache = {}
    69         self.cache = {}
    89         self.map = {}
    70         self.map = {}
   107         m.update(map)
    88         m.update(map)
   108         try:
    89         try:
   109             tmpl = self.cache[t]
    90             tmpl = self.cache[t]
   110         except KeyError:
    91         except KeyError:
   111             tmpl = self.cache[t] = file(self.map[t]).read()
    92             tmpl = self.cache[t] = file(self.map[t]).read()
   112         return template(tmpl, self.filters, **m)
    93         return self.template(tmpl, self.filters, **m)
       
    94 
       
    95     def template(self, tmpl, filters = {}, **map):
       
    96         while tmpl:
       
    97             m = re.search(r"#([a-zA-Z0-9]+)((%[a-zA-Z0-9]+)*)((\|[a-zA-Z0-9]+)*)#", tmpl)
       
    98             if m:
       
    99                 yield tmpl[:m.start(0)]
       
   100                 v = map.get(m.group(1), "")
       
   101                 v = callable(v) and v(**map) or v
       
   102 
       
   103                 format = m.group(2)
       
   104                 fl = m.group(4)
       
   105 
       
   106                 if format:
       
   107                     q = v.__iter__
       
   108                     for i in q():
       
   109                         lm = map.copy()
       
   110                         lm.update(i)
       
   111                         yield self(format[1:], **lm)
       
   112 
       
   113                     v = ""
       
   114 
       
   115                 elif fl:
       
   116                     for f in fl.split("|")[1:]:
       
   117                         v = filters[f](v)
       
   118 
       
   119                 yield v
       
   120                 tmpl = tmpl[m.end(0):]
       
   121             else:
       
   122                 yield tmpl
       
   123                 return
   113 
   124 
   114 def rfc822date(x):
   125 def rfc822date(x):
   115     return time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(x))
   126     return time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(x))
   116 
   127 
   117 common_filters = {
   128 common_filters = {
   240                 if f > count: break
   251                 if f > count: break
   241                 r = "%d" % f
   252                 r = "%d" % f
   242                 if pos + f < count: l.append(("+" + r, pos + f))
   253                 if pos + f < count: l.append(("+" + r, pos + f))
   243                 if pos - f >= 0: l.insert(0, ("-" + r, pos - f))
   254                 if pos - f >= 0: l.insert(0, ("-" + r, pos - f))
   244 
   255 
   245             yield self.t("naventry", rev = 0, label="(0)")
   256             yield {"rev": 0, "label": "(0)"}
   246 
   257 
   247             for label, rev in l:
   258             for label, rev in l:
   248                 yield self.t("naventry", label = label, rev = rev)
   259                 yield {"label": label, "rev": rev}
   249 
   260 
   250             yield self.t("naventry", label="tip")
   261             yield {"label": "tip", "rev": ""}
   251 
   262 
   252         def changelist(**map):
   263         def changelist(**map):
   253             parity = (start - end) & 1
   264             parity = (start - end) & 1
   254             cl = self.repo.changelog
   265             cl = self.repo.changelog
   255             l = [] # build a list in forward order for efficiency
   266             l = [] # build a list in forward order for efficiency
   257                 n = cl.node(i)
   268                 n = cl.node(i)
   258                 changes = cl.read(n)
   269                 changes = cl.read(n)
   259                 hn = hex(n)
   270                 hn = hex(n)
   260                 t = float(changes[2].split(' ')[0])
   271                 t = float(changes[2].split(' ')[0])
   261 
   272 
   262                 l.insert(0, self.t(
   273                 l.insert(0, {
   263                     'changelogentry',
   274                     "parity": parity,
   264                     parity = parity,
   275                     "author": changes[1],
   265                     author = changes[1],
   276                     "parent": self.parents("changelogparent",
   266                     parent = self.parents("changelogparent",
       
   267                                           cl.parents(n), cl.rev),
   277                                           cl.parents(n), cl.rev),
   268                     changelogtag = self.showtag("changelogtag",n),
   278                     "changelogtag": self.showtag("changelogtag",n),
   269                     manifest = hex(changes[0]),
   279                     "manifest": hex(changes[0]),
   270                     desc = changes[4],
   280                     "desc": changes[4],
   271                     date = t,
   281                     "date": t,
   272                     files = self.listfilediffs(changes[3], n),
   282                     "files": self.listfilediffs(changes[3], n),
   273                     rev = i,
   283                     "rev": i,
   274                     node = hn))
   284                     "node": hn})
   275                 parity = 1 - parity
   285                 parity = 1 - parity
   276 
   286 
   277             yield l
   287             for e in l: yield e
   278 
   288 
   279         cl = self.repo.changelog
   289         cl = self.repo.changelog
   280         mf = cl.read(cl.tip())[0]
   290         mf = cl.read(cl.tip())[0]
   281         count = cl.count()
   291         count = cl.count()
   282         start = max(0, pos - self.maxchanges + 1)
   292         start = max(0, pos - self.maxchanges + 1)
   387                 lr = fl.linkrev(n)
   397                 lr = fl.linkrev(n)
   388                 cn = cl.node(lr)
   398                 cn = cl.node(lr)
   389                 cs = cl.read(cl.node(lr))
   399                 cs = cl.read(cl.node(lr))
   390                 t = float(cs[2].split(' ')[0])
   400                 t = float(cs[2].split(' ')[0])
   391 
   401 
   392                 l.insert(0, self.t("filelogentry",
   402                 l.insert(0, {"parity": parity,
   393                                    parity = parity,
   403                              "filenode": hex(n),
   394                                    filenode = hex(n),
   404                              "filerev": i,
   395                                    filerev = i,
   405                              "file": f,
   396                                    file = f,
   406                              "node": hex(cn),
   397                                    node = hex(cn),
   407                              "author": cs[1],
   398                                    author = cs[1],
   408                              "date": t,
   399                                    date = t,
   409                              "parent": self.parents("filelogparent",
   400                                    parent = self.parents("filelogparent",
       
   401                                        fl.parents(n), fl.rev, file=f),
   410                                        fl.parents(n), fl.rev, file=f),
   402                                    desc = cs[4]))
   411                              "desc": cs[4]})
   403                 parity = 1 - parity
   412                 parity = 1 - parity
   404 
   413 
   405             yield l
   414             for e in l: yield e
   406 
   415 
   407         yield self.t("filelog",
   416         yield self.t("filelog",
   408                      file = f,
   417                      file = f,
   409                      filenode = filenode,
   418                      filenode = filenode,
   410                      entries = entries)
   419                      entries = entries)
   420         t = float(cs[2].split(' ')[0])
   429         t = float(cs[2].split(' ')[0])
   421         mfn = cs[0]
   430         mfn = cs[0]
   422 
   431 
   423         def lines():
   432         def lines():
   424             for l, t in enumerate(text.splitlines(1)):
   433             for l, t in enumerate(text.splitlines(1)):
   425                 yield self.t("fileline", line = t,
   434                 yield {"line": t,
   426                              linenumber = "% 6d" % (l + 1),
   435                        "linenumber": "% 6d" % (l + 1),
   427                              parity = l & 1)
   436                        "parity": l & 1}
   428 
   437 
   429         yield self.t("filerevision", file = f,
   438         yield self.t("filerevision", file = f,
   430                      filenode = node,
   439                      filenode = node,
   431                      path = up(f),
   440                      path = up(f),
   432                      text = lines(),
   441                      text = lines(),
   476 
   485 
   477                 if last != cnode:
   486                 if last != cnode:
   478                     parity = 1 - parity
   487                     parity = 1 - parity
   479                     last = cnode
   488                     last = cnode
   480 
   489 
   481                 yield self.t("annotateline",
   490                 yield {"parity": parity,
   482                              parity = parity,
   491                        "node": hex(cnode),
   483                              node = hex(cnode),
   492                        "rev": r,
   484                              rev = r,
   493                        "author": name,
   485                              author = name,
   494                        "file": f,
   486                              file = f,
   495                        "line": l}
   487                              line = l)
       
   488 
   496 
   489         yield self.t("fileannotate",
   497         yield self.t("fileannotate",
   490                      file = f,
   498                      file = f,
   491                      filenode = node,
   499                      filenode = node,
   492                      annotate = annotate,
   500                      annotate = annotate,
   526             parity = 0
   534             parity = 0
   527             fl = files.keys()
   535             fl = files.keys()
   528             fl.sort()
   536             fl.sort()
   529             for f in fl:
   537             for f in fl:
   530                 full, fnode = files[f]
   538                 full, fnode = files[f]
       
   539                 if not fnode:
       
   540                     continue
       
   541 
       
   542                 yield {"file": full,
       
   543                        "manifest": mnode,
       
   544                        "filenode": hex(fnode),
       
   545                        "parity": parity,
       
   546                        "basename": f,
       
   547                        "permissions": mff[full]}
       
   548                 parity = 1 - parity
       
   549 
       
   550         def dirlist(**map):
       
   551             parity = 0
       
   552             fl = files.keys()
       
   553             fl.sort()
       
   554             for f in fl:
       
   555                 full, fnode = files[f]
   531                 if fnode:
   556                 if fnode:
   532                     yield self.t("manifestfileentry",
   557                     continue
   533                                  file = full,
   558 
   534                                  manifest = mnode,
   559                 yield {"parity": parity,
   535                                  filenode = hex(fnode),
   560                        "path": os.path.join(path, f),
   536                                  parity = parity,
   561                        "manifest": mnode,
   537                                  basename = f,
   562                        "basename": f[:-1]}
   538                                  permissions = mff[full])
       
   539                 else:
       
   540                     yield self.t("manifestdirentry",
       
   541                                  parity = parity,
       
   542                                  path = os.path.join(path, f),
       
   543                                  manifest = mnode, basename = f[:-1])
       
   544                 parity = 1 - parity
   563                 parity = 1 - parity
   545 
   564         
   546         yield self.t("manifest",
   565         yield self.t("manifest",
   547                      manifest = mnode,
   566                      manifest = mnode,
   548                      rev = rev,
   567                      rev = rev,
   549                      node = hex(node),
   568                      node = hex(node),
   550                      path = path,
   569                      path = path,
   551                      up = up(path),
   570                      up = up(path),
   552                      entries = filelist)
   571                      fentries = filelist,
       
   572                      dentries = dirlist)
   553 
   573 
   554     def tags(self):
   574     def tags(self):
   555         cl = self.repo.changelog
   575         cl = self.repo.changelog
   556         mf = cl.read(cl.tip())[0]
   576         mf = cl.read(cl.tip())[0]
   557 
   577 
   559         i.reverse()
   579         i.reverse()
   560 
   580 
   561         def entries(**map):
   581         def entries(**map):
   562             parity = 0
   582             parity = 0
   563             for k,n in i:
   583             for k,n in i:
   564                 yield self.t("tagentry",
   584                 yield {"parity": parity,
   565                              parity = parity,
   585                        "tag": k,
   566                              tag = k,
   586                        "node": hex(n)}
   567                              node = hex(n))
       
   568                 parity = 1 - parity
   587                 parity = 1 - parity
   569 
   588 
   570         yield self.t("tags",
   589         yield self.t("tags",
   571                      manifest = hex(mf),
   590                      manifest = hex(mf),
   572                      entries = entries)
   591                      entries = entries)