Mon Jan 9 05:24:26 UTC 2006 Alberto Bertogli <albertogli@telpin.com.ar>
* Implement a search box.
This implements a small search box that appears on the right top besides the
logo (which will be changed to a small version in a following patch).
diff -rN -u old-darcsweb/config.py.sample new-darcsweb/config.py.sample
--- old-darcsweb/config.py.sample 2013-06-28 02:14:48.000000000 +0000
+++ new-darcsweb/config.py.sample 2013-06-28 02:14:48.000000000 +0000
@@ -40,6 +40,12 @@
# otherwise the directory is assumed to exist and be writeable.
#cachedir = '/tmp/darcsweb-cache'
+ # By default, darcsweb's search looks in the last 100 commits; you can
+ # change that number by specifying it here.
+ # Note that search are not cached, so if you have tons of commits and
+ # set the limit to a very high number, they will take time.
+ #searchlimit = 100
+
#
# From now on, every class is a repo configuration, with the same format
diff -rN -u old-darcsweb/darcsweb.cgi new-darcsweb/darcsweb.cgi
--- old-darcsweb/darcsweb.cgi 2013-06-28 02:14:48.000000000 +0000
+++ new-darcsweb/darcsweb.cgi 2013-06-28 02:14:48.000000000 +0000
@@ -163,6 +163,22 @@
pos = s.find("\t")
return s
+def highlight(s, l):
+ "Highlights appearences of s in l"
+ import re
+ # build the regexp by leaving "(s)", replacing '(' and ') first
+ s = s.replace('\\', '\\\\')
+ s = s.replace('(', '\\(')
+ s = s.replace(')', '\\)')
+ s = '(' + escape(s) + ')'
+ try:
+ pat = re.compile(s, re.I)
+ repl = '<span style="color:#e00000">\\1</span>'
+ l = re.sub(pat, repl, l)
+ except:
+ pass
+ return l
+
def fperms(fname):
m = os.stat(fname)[stat.ST_MODE]
m = m & 0777
@@ -242,21 +258,31 @@
<body>
<div class="page_header">
-<a href="http://darcs.net" title="darcs">
-<img src="%(logo)s" alt="darcs logo" style="float:right; border-width:0px;"/>
-</a>
+ <div class="search_box">
+ <form action="%(myname)s" method="get"><div>
+ <input type="hidden" name="r" value="%(reponame)s"/>
+ <input type="hidden" name="a" value="search"/>
+ <input type="text" name="s" size="20" class="search_text"/>
+ <input type="submit" value="search" class="search_button"/>
+ <a href="http://darcs.net" title="darcs">
+ <img src="%(logo)s" alt="darcs logo" class="logo"/>
+ </a>
+ </div></form>
+ </div>
+ <a href="%(myname)s">repos</a> /
+ <a href="%(myreponame)s;a=summary">%(reponame)s</a> /
+ %(action)s
+</div>
""" % {
'reponame': config.reponame,
'css': config.cssfile,
'url': config.myurl + '/' + config.myreponame,
'fav': config.darcsfav,
'logo': config.darcslogo,
+ 'myname': config.myname,
+ 'myreponame': config.myreponame,
+ 'action': action
}
- print '<a href="%s">repos</a> /' % config.myname
- print '<a href="%s;a=summary">%s</a>' % (config.myreponame,
- config.reponame),
- print '/ ' + action
- print "</div>"
def print_footer(put_rss = 1):
@@ -546,6 +572,27 @@
f = run_darcs(params)
return f.readlines()
+ def matches(self, s):
+ "Defines if the patch matches a given string"
+ if s.lower() in self.comment.lower():
+ return self.comment
+ elif s.lower() in self.name.lower():
+ return self.name
+ elif s.lower() in self.author.lower():
+ return self.author
+ elif s == self.hash:
+ return self.hash
+
+ s = s.lower()
+ for l in (self.adds, self.removes, self.modifies,
+ self.diradds, self.dirremoves,
+ self.replaces.keys(), self.moves.keys(),
+ self.moves.keys() ):
+ for i in l:
+ if s in i.lower():
+ return i
+ return ''
+
# patch parsing, we get them through "darcs changes --xml-output"
class BuildPatchList(xml.sax.handler.ContentHandler):
@@ -1893,6 +1940,55 @@
print '</channel></rss>'
+def do_search(s):
+ print_header()
+ print_navbar()
+ ps = get_last_patches(config.searchlimit)
+
+ print '<div class="title">Search last %d commits for "%s"</div>' \
+ % (config.searchlimit, escape(s))
+ print '<table cellspacing="0">'
+
+ alt = False
+ for p in ps:
+ match = p.matches(s)
+ if not match:
+ continue
+
+ if alt:
+ print '<tr class="dark">'
+ else:
+ print '<tr class="light">'
+ alt = not alt
+
+ print """
+ <td><i>%(age)s</i></td>
+ <td>%(author)s</td>
+ <td>
+ <a class="list" title="%(fullname)s" href="%(myrname)s;a=commit;h=%(hash)s">
+ <b>%(name)s</b>
+ </a><br/>
+ %(match)s
+ </td>
+ <td class="link">
+ <a href="%(myrname)s;a=commit;h=%(hash)s">commit</a> |
+ <a href="%(myrname)s;a=commitdiff;h=%(hash)s">commitdiff</a>
+ </td>
+ """ % {
+ 'age': how_old(p.local_date),
+ 'author': shorten_str(p.shortauthor, 26),
+ 'myrname': config.myreponame,
+ 'hash': p.hash,
+ 'name': escape(shorten_str(p.name)),
+ 'fullname': escape(p.name),
+ 'match': highlight(s, shorten_str(match)),
+ }
+ print "</tr>"
+
+ print '</table>'
+ print_footer()
+
+
def do_die():
print_header()
print "<p><font color=red>Error! Malformed query</font></p>"
@@ -2095,6 +2191,11 @@
else:
config.cachedir = None
+ if "searchlimit" in dir(base):
+ config.searchlimit = base.searchlimit
+ else:
+ config.searchlimit = 100
+
if name and "footer" in dir(c):
config.footer = c.footer
elif "footer" in dir(base):
@@ -2269,6 +2370,15 @@
elif action == 'atom':
do_atom()
+elif action == 'search':
+ if form.has_key('s'):
+ s = form["s"].value
+ else:
+ s = ''
+ do_search(s)
+ if config.cachedir:
+ cache.cancel()
+
else:
action = "invalid query"
do_die()
diff -rN -u old-darcsweb/style.css new-darcsweb/style.css
--- old-darcsweb/style.css 2013-06-28 02:14:48.000000000 +0000
+++ new-darcsweb/style.css 2013-06-28 02:14:48.000000000 +0000
@@ -69,6 +69,22 @@
padding:8px;
}
+div.search_box {
+ float:right;
+ text-align:right;
+}
+
+input.search_text {
+ font-size:xx-small;
+ background-color: #edece6;
+ vertical-align: top;
+}
+
+input.search_button {
+ font-size:xx-small;
+ vertical-align: top;
+}
+
div.title, a.title {
display:block; padding:6px 8px;
font-weight:bold;
@@ -136,7 +152,7 @@
}
table {
- clear:both;
+ /*clear:both;*/
padding:8px 4px;
}
@@ -239,3 +255,10 @@
background-color:#ee5500;
}
+img.logo {
+ border-width:0px;
+ vertical-align:top;
+ margin-left:12pt;
+ margin-right:5pt;
+}
+