Add multiple keyword search to hgweb
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Add multiple keyword search to hgweb
People kept pestering me about this one. Now it's done.
If you type a tag/id/rev in the search box, it takes you to that entry
in the changelog.
If you type some other random keywords, it does a case-insensitive
search through the history and returns the most recent N items.
It's not super-fast, but it's serviceable.
manifest hash:
e8fa980dee92cf78c04051d3028da9b07a45f3de
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCxO6JywK+sNU5EO8RArAwAKCq+9qO/OL0mQxa1J7C77Z6AcZoWgCfbiDC
AZ5KllldwBtdRRREn7HH6go=
=sIy0
-----END PGP SIGNATURE-----
--- a/mercurial/hgweb.py Thu Jun 30 21:28:18 2005 -0800
+++ b/mercurial/hgweb.py Thu Jun 30 23:19:37 2005 -0800
@@ -286,6 +286,68 @@
manifest = hex(mf),
rev = pos, changesets = count, entries = changelist)
+ def search(self, query):
+
+ def changelist():
+ cl = self.repo.changelog
+ count = 0
+ qw = query.lower().split()
+
+ def revgen():
+ for i in range(cl.count() - 1, 0, -100):
+ l = []
+ for j in range(max(0, i - 100), i):
+ n = cl.node(j)
+ changes = cl.read(n)
+ l.insert(0, (n, j, changes))
+ for e in l:
+ yield e
+
+ for n, i, changes in revgen():
+ miss = 0
+ for q in qw:
+ if not (q in changes[1].lower() or
+ q in changes[4].lower() or
+ q in " ".join(changes[3][:20]).lower()):
+ miss = 1
+ break
+ if miss: continue
+
+ count += 1
+ hn = hex(n)
+ p1, p2 = cl.parents(n)
+ t = float(changes[2].split(' ')[0])
+
+ yield self.t(
+ 'searchentry',
+ parity = count & 1,
+ author = changes[1],
+ parent1 = self.parent("changelogparent",
+ hex(p1), cl.rev(p1)),
+ parent2 = self.parent("changelogparent",
+ hex(p2), cl.rev(p2)),
+ p1 = hex(p1), p2 = hex(p2),
+ p1rev = cl.rev(p1), p2rev = cl.rev(p2),
+ manifest = hex(changes[0]),
+ desc = changes[4],
+ date = t,
+ files = self.listfilediffs(changes[3], n),
+ rev = i,
+ node = hn)
+
+ if count >= self.maxchanges: break
+
+ cl = self.repo.changelog
+ mf = cl.read(cl.tip())[0]
+
+ yield self.t('search',
+ header = self.header(),
+ footer = self.footer(),
+ query = query,
+ repo = self.reponame,
+ manifest = hex(mf),
+ entries = changelist)
+
def changeset(self, nodeid):
n = bin(nodeid)
cl = self.repo.changelog
@@ -586,13 +648,16 @@
self.t = templater(m, self.filters)
if not args.has_key('cmd') or args['cmd'][0] == 'changelog':
- hi = self.repo.changelog.count() - 1
+ c = self.repo.changelog.count() - 1
+ hi = c
if args.has_key('rev'):
hi = args['rev'][0]
try:
hi = self.repo.changelog.rev(self.repo.lookup(hi))
- except KeyError: pass
-
+ except KeyError:
+ write(self.search(hi))
+ return
+
write(self.changelog(hi))
elif args['cmd'][0] == 'changeset':
--- a/templates/map Thu Jun 30 21:28:18 2005 -0800
+++ b/templates/map Thu Jun 30 23:19:37 2005 -0800
@@ -1,11 +1,13 @@
header = header.tmpl
footer = footer.tmpl
+search = search.tmpl
changelog = changelog.tmpl
naventry = "<a href="?cmd=changelog;rev=#rev#">#label#</a> "
filedifflink = "<a href="?cmd=filediff;node=#node#;file=#file#">#file#</a> "
filenodelink = "<a href="?cmd=file;filenode=#filenode#;file=#file#">#file#</a> "
fileellipses = "..."
changelogentry = changelogentry.tmpl
+searchentry = searchentry.tmpl
changeset = changeset.tmpl
manifest = manifest.tmpl
manifestdirentry = "<tr class="parity#parity#"><td><tt>drwxr-xr-x</tt> <td><a href="?cmd=manifest;manifest=#manifest#;path=#path#">#basename#/</a>"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/search.tmpl Thu Jun 30 23:19:37 2005 -0800
@@ -0,0 +1,28 @@
+#header#
+<title>#repo|escape#: searching for #query|escape#</title>
+</head>
+<body>
+
+<div class="buttons">
+<a href="?cmd=changelog;rev=#rev#">changelog</a>
+<a href="?cmd=tags">tags</a>
+<a href="?cmd=manifest;manifest=#manifest#;path=/">manifest</a>
+</div>
+
+<h2>searching for #query|escape#</h2>
+
+<form>
+search:
+<input type="hidden" name="cmd" value="changelog">
+<input name="rev" type="text" width="30" value="#query|escape#">
+</form>
+
+#entries#
+
+<form>
+search:
+<input type="hidden" name="cmd" value="changelog">
+<input name="rev" type="text" width="30">
+</form>
+
+#footer#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/searchentry.tmpl Thu Jun 30 23:19:37 2005 -0800
@@ -0,0 +1,22 @@
+<div class="parity#parity#">
+<table width="100%" cellpadding="0" cellspacing="0">
+<tr>
+ <td align="right" width="15%"><b>#date|age# ago: </b></td>
+ <td><b>#desc|firstline|escape#</b></td></tr>
+<tr>
+ <td align="right">changeset #rev#: </td>
+ <td><a href="?cmd=changeset;node=#node#">#node|short#</a></td></tr>
+#parent1#
+#parent2#
+<tr>
+ <td align="right">author: </td>
+ <td>#author|obfuscate#</td></tr>
+<tr>
+ <td align="right">date: </td>
+ <td>#date|date#</td></tr>
+<tr>
+ <td align="right" valign="top"><a href="?cmd=manifest;manifest=#manifest#;path=/">files</a>: </td>
+ <td>#files#</td></tr>
+</table>
+</div>
+