bug 437429 - change pushlog hg extension to use new sqlite backend. r=bsmedberg
authorTed Mielczarek <ted.mielczarek@gmail.com>
Fri, 06 Jun 2008 10:09:55 -0400
changeset 25 904ea0ddd0b1475e6a0bbe5707ad5c5e6c4a9666
parent 24 76f6d3a9078a6aaa08d10d0fbf3fd9e0eaba9353
child 26 3e98a662394d9a45a33189604c562c6ec0cc1004
push id3
push usertmielczarek@mozilla.com
push dateFri, 06 Jun 2008 14:10:13 +0000
reviewersbsmedberg
bugs437429
bug 437429 - change pushlog hg extension to use new sqlite backend. r=bsmedberg
pushlog-feed.py
--- a/pushlog-feed.py
+++ b/pushlog-feed.py
@@ -1,99 +1,135 @@
 import mercurial.hgweb.protocol as hgwebprotocol
 from mercurial.templatefilters import xmlescape
 from mercurial.hgweb.common import HTTP_OK, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
+from mercurial.node import short, bin
 import os.path
 import re
 import time
+import sqlite3 as sqlite
 
 def addwebcommand(f, name):
     setattr(hgwebprotocol, name, f)
     hgwebprotocol.__all__.append(name)
 
-datere = re.compile(r'^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d{1,2}) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d{2}):(\d{2}):(\d{2}) -(\d{4})$')
-
-MONTHS = {'Jan': 1,
-          'Feb': 2,
-          'Mar': 3,
-          'Apr': 4,
-          'May': 5,
-          'Jun': 6,
-          'Jul': 7,
-          'Aug': 8,
-          'Sep': 9,
-          'Oct': 10,
-          'Nov': 11,
-          'Dec': 12}
-
-def rfc3339datehack(dstr):
-    wday, d, m, y, h, min, s, tz = datere.match(dstr).groups()
-
-    m = MONTHS[m]
-    d = int(d)
-    
-    return "%s-%02i-%02iT%s:%s:%s-%s:%s" % (
-        y, m, d, h, min, s, tz[:2], tz[2:])
-
 ATOM_MIMETYPE = 'application/atom+xml'
 
-reader = re.compile(r'^"([a-f0-9]{40})"\t"([^\t]*)"\t"([^\t]*)"$')
+def lastNEntries(pushdb, n):
+    conn = sqlite.connect(pushdb)
+    res = conn.execute("SELECT node, user, date FROM pushlog ORDER BY date DESC LIMIT ?", (n,))
+    return res.fetchall()
 
-def readlog(logfile):
-    """Read a pushlog and yield (node, user, date) for each line."""
-    fd = open(logfile)
-    entries = []
-    for line in fd:
-        entries.append(reader.match(line).group(1, 2, 3))
-    entries.reverse()
-    return entries
-
-def pushlog(web, req):
-    plogfile = os.path.join(web.repo.path, "pushlog")
-    e = readlog(plogfile)
-
+def pushlogSetup(web, req):
+    repopath = os.path.dirname(web.repo.path)
+    reponame = os.path.basename(repopath)
+    if reponame == '.hg':
+        reponame = os.path.basename(os.path.dirname(repopath))
+    pushdb = os.path.join(web.repo.path, "pushlog.db")
+    e = lastNEntries(pushdb, 10)
     proto = req.env.get('wsgi.url_scheme')
     if proto == 'https':
         proto = 'https'
         default_port = "443"
     else:
         proto = 'http'
         default_port = "80"
     port = req.env["SERVER_PORT"]
     port = port != default_port and (":" + port) or ""
 
     urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
+    return (e, urlbase, reponame)
+    
+def pushlogFeed(web, req):
+    (e, urlbase, reponame) = pushlogSetup(web, req)
 
     resp = ["""<?xml version="1.0" encoding="UTF-8"?>
 <feed xmlns="http://www.w3.org/2005/Atom">
  <id>%(urlbase)s%(url)spushlog</id>
  <link rel="self" href="%(urlbase)s%(url)spushlog" />
  <updated>%(date)s</updated>
- <title>Pushlog</title>""" % {'urlbase': urlbase,
+ <title>%(reponame)s Pushlog</title>""" % {'urlbase': urlbase,
                               'url': req.url,
-                              'date': rfc3339datehack(e[0][2])}];
+                              'reponame': reponame,
+                              'date': e[0][2]}];
 
-    for node, user, date in e[:10]:
+    for node, user, date in e:
         resp.append("""
  <entry>
   <title>Changeset %(node)s</title>
   <id>http://www.selenic.com/mercurial/#changeset-%(node)s</id>
   <link href="%(urlbase)s%(url)srev/%(node)s" />
   <updated>%(date)s</updated>
   <author>
    <name>%(user)s</name>
   </author>
  </entry>""" % {'node': node,
-                'date': rfc3339datehack(date),
+                'date': date,
                 'user': xmlescape(user),
                 'urlbase': urlbase,
                 'url': req.url})
 
     resp.append("</feed>")
 
     resp = "".join(resp)
 
     req.respond(HTTP_OK, ATOM_MIMETYPE, length=len(resp))
     req.write(resp)
 
-addwebcommand(pushlog, 'pushlog')
+def pushlogHTML(web, req):
+    (e, urlbase, reponame) = pushlogSetup(web, req)
+
+    resp = ["""<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
+<head>
+<link rel="icon" href="%(urlbase)s/static/hgicon.png" type="image/png" />
+<meta name="robots" content="index, nofollow"/>
+<link rel="stylesheet" href="%(urlbase)s/static/style-gitweb.css" type="text/css" />
+<title>%(reponame)s pushlog</title>
+<link rel="alternate" type="application/atom+xml"
+   href="%(urlbase)s/pushlog" title="Atom feed for %(reponame)s pushlog"/>
+</head>
+<body>
+<div class="page_header">
+<a href="http://developer.mozilla.org/en/docs/Mercurial" title="Mercurial" style="float: right;">Mercurial</a>
+<a href="%(urlbase)s%(url)s">%(reponame)s</a>
+</div>
+<div><a  class="title" href="%(urlbase)s/shortlog">pushed changes</a></div>
+<table cellspacing="0">
+<tr><th></th><th>Changeset</th><th>Who</th><th>Files</th><th>Description</th></tr>
+""" % {'urlbase': urlbase,
+       'url': req.url,
+       'reponame': reponame}];
+
+    i = 0
+    for node, user, date in e:
+        ctx = web.repo.changectx(node)
+        resp.append("""<tr class="parity%(i)d"><td class="link"><a href="rev/%(node)s">diff</a><br><a href="file/%(node)s">browse</a></td><td class="age">%(node)s<br/><i>%(date)s</i></td><td><strong>%(user)s</strong></td><td>%(files)s</td><td>%(description)s</td></tr>
+""" % {'node': short(bin(node)),
+       'date': date,
+       'user': xmlescape(user),
+       'files': '<br/>'.join(ctx.files()),
+       'description': xmlescape(ctx.description()),
+       'urlbase': urlbase,
+       'url': req.url,
+       'i': i})
+        i += 1
+        i %= 2
+
+    resp.append("""</table>
+<div class="page_footer">
+<div class="page_footer_text">%(reponame)s</div>
+<br />
+</div>
+</body>
+</html>
+""" % {'reponame': reponame})
+
+    resp = "".join(resp)
+
+    req.respond(HTTP_OK, "text/html", length=len(resp))
+    req.write(resp)
+
+addwebcommand(pushlogFeed, 'pushlog')
+addwebcommand(pushlogHTML, 'pushloghtml')
 
 cmdtable = {}