hgweb.py
changeset 61 1215bf60468f
parent 57 115106376f45
child 99 db5eb6a86179
child 102 58039eddbdda
equal deleted inserted replaced
60:e32fdbd97839 61:1215bf60468f
     8 
     8 
     9 # useful for debugging
     9 # useful for debugging
    10 import cgitb
    10 import cgitb
    11 cgitb.enable()
    11 cgitb.enable()
    12 
    12 
    13 import os, cgi, time, re, difflib
    13 import os, cgi, time, re, difflib, sys, zlib
    14 from mercurial import hg, mdiff
    14 from mercurial import hg, mdiff
    15 
    15 
    16 repo_path = "."  # change as needed
    16 repo_path = "."  # change as needed
    17 
    17 
    18 def nl2br(text):
    18 def nl2br(text):
    22     l = []
    22     l = []
    23     for c in text:
    23     for c in text:
    24         l.append('&#%d;' % ord(c))
    24         l.append('&#%d;' % ord(c))
    25     return ''.join(l)
    25     return ''.join(l)
    26 
    26 
    27 def httphdr():
    27 def httphdr(type = "text/html"):
    28     print 'Content-type: text/html\n\n'
    28     print 'Content-type: %s\n' % type
    29 
    29 
    30 def htmldoctype():
    30 def htmldoctype():
    31     print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">'
    31     print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">'
    32 
    32 
    33 def htmlhead(title):
    33 def htmlhead(title):
    42     print '.plusline { color: green; }'
    42     print '.plusline { color: green; }'
    43     print '.minusline { color: red; }'
    43     print '.minusline { color: red; }'
    44     print '.atline { color: purple; }'
    44     print '.atline { color: purple; }'
    45     print '</style>'
    45     print '</style>'
    46 
    46 
       
    47 def startpage(title):
       
    48     httphdr()
       
    49     htmldoctype()
       
    50     htmlhead(title)
       
    51     print '<BODY>'
       
    52 
       
    53 def endpage():
       
    54     print '</BODY>'
       
    55     print '</HTML>'
       
    56 
       
    57 
       
    58 
    47 def ent_change(repo, nodeid):
    59 def ent_change(repo, nodeid):
    48     changes = repo.changelog.read(nodeid)
    60     changes = repo.changelog.read(nodeid)
    49     hn = hg.hex(nodeid)
    61     hn = hg.hex(nodeid)
    50     i = repo.changelog.rev(nodeid)
    62     i = repo.changelog.rev(nodeid)
    51     (h1, h2) = [ hg.hex(x) for x in repo.changelog.parents(nodeid) ]
    63     (h1, h2) = [ hg.hex(x) for x in repo.changelog.parents(nodeid) ]
    52     datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0])))
    64     datestr = time.asctime(time.gmtime(float(changes[2].split(' ')[0])))
    53     mf = repo.manifest.read(changes[0])
       
    54     print '<table width="100%" border="1">'
    65     print '<table width="100%" border="1">'
    55     print '\t<tr><td valign="top" width="10%%">author:</td>' + \
    66     print '\t<tr><td valign="top" width="10%%">author:</td>' + \
    56             '<td valign="top" width="20%%">%s</td>' % (obfuscate(changes[1]), )
    67             '<td valign="top" width="20%%">%s</td>' % (obfuscate(changes[1]), )
    57     print '\t\t<td valign="top" width="10%%">description:</td>' + \
    68     print '\t\t<td valign="top" width="10%%">description:</td>' + \
    58             '<td width="60%%">' + \
    69             '<td width="60%%">' + \
    59             '<a href="?cmd=chkin;nd=%s">%s</a></td></tr>' % \
    70             '<a href="?cmd=chkin;nd=%s">%s</a></td></tr>' % \
    60             (hn, nl2br(changes[4]), )
    71             (hn, nl2br(changes[4]), )
    61     print '\t<tr><td>date:</td><td>%s UTC</td>' % (datestr, )
    72     print '\t<tr><td>date:</td><td>%s UTC</td>' % (datestr, )
    62     print '\t\t<td valign="top">files:</td><td valign="top">'
    73     print '\t\t<td valign="top">files:</td><td valign="top">'
    63     for f in changes[3]:
    74     for f in changes[3]:
    64         print '\t\t<a href="?cmd=file;nd=%s;fn=%s">%s</a>' % \
    75         print '\t\t%s&nbsp;&nbsp;' % f
    65                 (hg.hex(mf[f]), f, f, ),
       
    66         print '&nbsp;&nbsp;'
       
    67     print '\t</td></tr>'
    76     print '\t</td></tr>'
    68 #    print '\t<tr><td>revision:</td><td colspan="3">%d:<a ' % (i, ) + \
    77 #    print '\t<tr><td>revision:</td><td colspan="3">%d:<a ' % (i, ) + \
    69 #            'href="?cmd=rev;nd=%s">%s</a></td></tr>' % (hn, hn, )
    78 #            'href="?cmd=rev;nd=%s">%s</a></td></tr>' % (hn, hn, )
    70     print '</table><br />'
    79     print '</table><br />'
    71 
    80 
    85         else:
    94         else:
    86             print line
    95             print line
    87     print '</pre>'
    96     print '</pre>'
    88 
    97 
    89 def ent_checkin(repo, nodeid):
    98 def ent_checkin(repo, nodeid):
       
    99     startpage("Mercurial Web")
       
   100 
    90     changes = repo.changelog.read(nodeid)
   101     changes = repo.changelog.read(nodeid)
    91     hn = hg.hex(nodeid)
   102     hn = hg.hex(nodeid)
    92     i = repo.changelog.rev(nodeid)
   103     i = repo.changelog.rev(nodeid)
    93     parents = repo.changelog.parents(nodeid)
   104     parents = repo.changelog.parents(nodeid)
    94     (h1, h2) = [ hg.hex(x) for x in parents ]
   105     (h1, h2) = [ hg.hex(x) for x in parents ]
   133     for f in a:
   144     for f in a:
   134         ent_diff('', repo.file(f).read(mf[f]), f)
   145         ent_diff('', repo.file(f).read(mf[f]), f)
   135     for f in d:
   146     for f in d:
   136         ent_diff(repo.file(f).read(mf2[f]), '', f)
   147         ent_diff(repo.file(f).read(mf2[f]), '', f)
   137 
   148 
       
   149     endpage()
       
   150 
       
   151 
   138 def ent_file(repo, nodeid, fn):
   152 def ent_file(repo, nodeid, fn):
   139     print '<div class="filename">%s (%s)</div>' % (fn, hg.hex(nodeid), )
   153     print '<div class="filename">%s (%s)</div>' % (fn, hg.hex(nodeid), )
   140     print '<pre>'
   154     print '<pre>'
   141     print cgi.escape(repo.file(fn).read(nodeid))
   155     print cgi.escape(repo.file(fn).read(nodeid))
   142     print '</pre>'
   156     print '</pre>'
   143 
   157 
   144 httphdr()
   158 def change_page():
   145 htmldoctype()
   159     startpage("Mercurial Web")
   146 htmlhead('Mercurial Web')
       
   147 
       
   148 print '<BODY>'
       
   149 
       
   150 
       
   151 args = cgi.parse()
       
   152 
       
   153 ui = hg.ui()
       
   154 repo = hg.repository(ui, repo_path)
       
   155 
       
   156 if not args.has_key('cmd'):
       
   157     print '<table width="100%" align="center">'
   160     print '<table width="100%" align="center">'
   158     for i in xrange(repo.changelog.count()-1, -1, -1):
   161     for i in xrange(0, repo.changelog.count()):
   159         n = repo.changelog.node(i)
   162         n = repo.changelog.node(i)
   160         print '<tr><td>'
   163         print '<tr><td>'
   161         ent_change(repo, n)
   164         ent_change(repo, n)
   162         print '</td></th>'
   165         print '</td></th>'
   163 
   166 
   164     print '</table>'
   167     print '</table>'
       
   168     endpage()
       
   169 
       
   170 args = cgi.parse()
       
   171 
       
   172 ui = hg.ui()
       
   173 repo = hg.repository(ui, repo_path)
       
   174 
       
   175 if not args.has_key('cmd'):
       
   176     change_page()
       
   177     
   165 elif args['cmd'][0] == 'chkin':
   178 elif args['cmd'][0] == 'chkin':
   166     if not args.has_key('nd'):
   179     if not args.has_key('nd'):
   167         print '<div class="errmsg">No Node!</div>'
   180         print '<div class="errmsg">No Node!</div>'
   168     else:
   181     else:
   169         ent_checkin(repo, hg.bin(args['nd'][0]))
   182         ent_checkin(repo, hg.bin(args['nd'][0]))
       
   183 
   170 elif args['cmd'][0] == 'file':
   184 elif args['cmd'][0] == 'file':
       
   185     startpage("Mercurial Web")
       
   186 
   171     if not args.has_key('nd'):
   187     if not args.has_key('nd'):
   172         print '<div class="errmsg">No Node!</div>'
   188         print '<div class="errmsg">No Node!</div>'
   173     elif not args.has_key('fn'):
   189     elif not args.has_key('fn'):
   174         print '<div class="errmsg">No Filename!</div>'
   190         print '<div class="errmsg">No Filename!</div>'
   175     else:
   191     else:
   176         ent_file(repo, hg.bin(args['nd'][0]), args['fn'][0])
   192         ent_file(repo, hg.bin(args['nd'][0]), args['fn'][0])
       
   193     endpage()
       
   194 
       
   195 elif args['cmd'][0] == 'branches':
       
   196     httphdr("text/plain")
       
   197     nodes = []
       
   198     if args.has_key('nodes'):
       
   199         nodes = map(hg.bin, args['nodes'][0].split(" "))
       
   200     for b in repo.branches(nodes):
       
   201         print " ".join(map(hg.hex, b))
       
   202 
       
   203 elif args['cmd'][0] == 'between':
       
   204     httphdr("text/plain")
       
   205     nodes = []
       
   206     if args.has_key('pairs'):
       
   207         pairs = [ map(hg.bin, p.split("-"))
       
   208                   for p in args['pairs'][0].split(" ") ]
       
   209     for b in repo.between(pairs):
       
   210         print " ".join(map(hg.hex, b))
       
   211 
       
   212 elif args['cmd'][0] == 'changegroup':
       
   213     httphdr("application/hg-changegroup")
       
   214     nodes = []
       
   215     if args.has_key('roots'):
       
   216         nodes = map(hg.bin, args['roots'][0].split(" "))
       
   217 
       
   218     z = zlib.compressobj()
       
   219     for chunk in repo.changegroup(nodes):
       
   220         sys.stdout.write(z.compress(chunk))
       
   221 
       
   222     sys.stdout.write(z.flush())
   177 
   223 
   178 else:
   224 else:
       
   225     startpage("Mercurial Web Error")
   179     print '<div class="errmsg">unknown command: ', args['cmd'][0], '</div>'
   226     print '<div class="errmsg">unknown command: ', args['cmd'][0], '</div>'
   180 
   227     endpage()
   181 print '</BODY>'
       
   182 print '</HTML>'