Mercurial > p > roundup > code
diff roundup/cgi_client.py @ 681:1b2d0e702ca8 search_indexing-0-4-2-branch
Added feature [SF#526730] - search for messages capability
| author | Roche Compaan <rochecompaan@users.sourceforge.net> |
|---|---|
| date | Wed, 03 Apr 2002 11:55:57 +0000 |
| parents | 9667625a5695 |
| children | 0521ddc7bb31 |
line wrap: on
line diff
--- a/roundup/cgi_client.py Wed Apr 03 11:55:57 2002 +0000 +++ b/roundup/cgi_client.py Wed Apr 03 11:55:57 2002 +0000 @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: cgi_client.py,v 1.114 2002-03-17 23:06:05 richard Exp $ +# $Id: cgi_client.py,v 1.114.2.1 2002-04-03 11:55:57 rochecompaan Exp $ __doc__ = """ WWW request handler (also used in the stand-alone server). @@ -26,6 +26,7 @@ import roundupdb, htmltemplate, date, hyperdb, password from roundup.i18n import _ +from roundup_indexer import RoundupIndexer class Unauthorised(ValueError): pass @@ -45,6 +46,7 @@ there is no cookie). This allows them to modify the database, and all modifications are attributed to the 'anonymous' user. ''' + classes_to_search = ['issue'] def __init__(self, instance, request, env, form=None): self.instance = instance @@ -70,6 +72,7 @@ except ValueError: # someone gave us a non-int debug level, turn it off self.debug = 0 + self.indexer = RoundupIndexer('%s/db'%instance.INSTANCE_HOME) def getuid(self): return self.db.user.lookup(self.user) @@ -208,6 +211,9 @@ links.append(_('<a href="user">User List</a>')) links.append(_('<a href="newuser">Add User</a>')) + # add the search link + links.append(_('<a href="search">Search</a>')) + # now we have all the links, join 'em links = '\n | '.join(links) @@ -557,6 +563,129 @@ showissue = shownode showmsg = shownode + def search(self): + ''' display search form + ''' + self.pagehead(_('Search')) + self.write(_(''' +<form action="searchresults" method="post"> +<table border=0 cellspacing=0 cellpadding=2> +<tr> +<th>Search terms</th> +<td><input name="search_terms" size="50"></td> +</tr> +<tr> +<td> </td> +<td><input type="submit" value=" Search "></td> +</tr> +</table> +</form> +''')) + self.pagefoot() + + def searchresults(self): + ''' display search results + ''' + search_terms = self.form['search_terms'].value + hits = self.indexer.find(search_terms.split(' ')) + links = [] + nodeids = {} + designator_propname = {'msg': 'messages', + 'file': 'files'} + if hits: + hitcount = len(hits) + instance_url = '%s/%s'%(self.env['SCRIPT_NAME'], + self.instance_path_name) + # build a dictionary of nodes and their associated messages + # and files + for hit in hits.keys(): + filename = hits[hit].split('/')[-1] + for designator, propname in designator_propname.items(): + if filename.find(designator) == -1: continue + nodeid = filename[len(designator):] + for classname in self.classes_to_search: + if not classname in self.db.getclasses(): continue + cl = self.db.getclass(classname) + result = apply(cl.find, (), {propname:nodeid}) + if not result: continue + + if not nodeids.has_key(classname): + nodeids[classname] = {} + + id = int(result[0]) + class_dict = nodeids[classname] + if not class_dict.has_key(id): + class_dict[id] = {} + + node_dict = class_dict[id] + if not node_dict.has_key(propname): + node_dict[propname] = [nodeid] + elif class_dict.has_key(propname): + node_dict[propname].append(nodeid) + + for classname in self.classes_to_search: + if not nodeids.has_key(classname): continue + ids = nodeids[classname].keys() + # TODO: sort hits on relevance, not on ids + ids.sort() + # generate hyperlinks for nodes + for id in ids: + nodepath = '%s/%s%s'%(instance_url, classname, id) + title = self.db.issue.get(`id`, 'title') + node_link = _(''' +<a href="%(nodepath)s">%(classname)s%(id)s: %(title)s</a> +''')%locals() + + node_dict = nodeids[classname][id] + # hyperlinks for messages + message_links = [] + if node_dict.has_key('messages'): + for msgid in node_dict['messages']: + k = self.db.msg.labelprop() + lab = self.db.msg.get(msgid, k) + msgpath = '%s/msg%s'%(instance_url, msgid) + message_links.append(_(''' +<a href="%(msgpath)s">%(lab)s</a>''')%locals()) + message_links = _('<li>Messages: %s</li>')%( + ', '.join(message_links)) + else: + message_links = '' + + # hyperlinks for files + file_links = [] + if node_dict.has_key('files'): + for fileid in node_dict['files']: + filename = self.db.file.get(fileid, 'name') + filepath = '%s/file%s/%s'%(instance_url, + fileid, filename) + file_links.append(_(''' +<a href="%(filepath)s">%(filename)s</a>''')%locals()) + file_links = _('<li>Files: %s</li>')%( + ', '.join(file_links)) + else: + file_links = '' + + links.append(_('''%(node_link)s +<ul> +%(message_links)s +%(file_links)s +</ul>''')%locals()) + else: + hitcount = 0 + + self.pagehead(_('Search Results')) + if links: + links = '<li>'.join(links) + self.write(_('''<p>Searching for "%(search_terms)s" returned +%(hitcount)s results:</p> +<ol> +<li>%(links)s +</ol>''')%locals()) + else: + self.write(_('''<p>Searching for "%(search_terms)s" returned +no results.</p>''')%locals()) + self.pagefoot() + def _add_assignedto_to_nosy(self, props): ''' add the assignedto value from the props to the nosy list ''' @@ -1220,6 +1349,12 @@ if action == 'logout': self.logout() return + if action == 'search': + self.search() + return + if action == 'searchresults': + self.searchresults() + return # see if we're to display an existing node m = dre.match(action) @@ -1269,6 +1404,7 @@ showtimelog = Client.shownode newsupport = Client.newnode newtimelog = Client.newnode + classes_to_search = ['issue', 'support'] default_index_sort = ['-activity'] default_index_group = ['priority'] @@ -1357,6 +1493,9 @@ # # $Log: not supported by cvs2svn $ +# Revision 1.114 2002/03/17 23:06:05 richard +# oops +# # Revision 1.113 2002/03/14 23:59:24 richard # . #517734 ] web header customisation is obscure #
