improved search - separate q=/nick= fields
authorTero Marttila <terom@fixme.fi>
Sun, 13 Sep 2009 18:47:00 +0300
changeset 141 65c98c9e1716
parent 140 6db2527b67cf
child 142 e163794ccf54
improved search - separate q=/nick= fields
qmsk/irclogs/config.py
qmsk/irclogs/handlers.py
qmsk/irclogs/log_search.py
qmsk/irclogs/log_source.py
qmsk/irclogs/urls.py
static/irclogs.css
templates/channel_search.tmpl
--- a/qmsk/irclogs/config.py	Sun Sep 13 01:15:56 2009 +0300
+++ b/qmsk/irclogs/config.py	Sun Sep 13 18:47:00 2009 +0300
@@ -103,7 +103,9 @@
     (50,    50), 
     (100,   100), 
     (200,   200), 
-    (None,  "&#8734;"),
+
+# infinity, not supported
+#    (0,     "&#8734;"),
 )
 
 # search index database path
--- a/qmsk/irclogs/handlers.py	Sun Sep 13 01:15:56 2009 +0300
+++ b/qmsk/irclogs/handlers.py	Sun Sep 13 18:47:00 2009 +0300
@@ -151,7 +151,7 @@
     """
         The main channel view page, displaying the most recent lines
     """
- 
+
     # get latest events
     lines = channel.source.get_latest(count)
    
@@ -231,12 +231,12 @@
     else :
         lines = channel.source.get_date(date)
         max = None
-
+   
     # render channel_date
     return _render_date (request, channel, date, lines, type, count, page, max)
 
 @preferences.handler(prefs.formatter, prefs.count)
-def channel_search (request, channel, formatter, count, q=None, page=1, max=1, type=None, t=None) :
+def channel_search (request, channel, formatter, count, q=None, nick=None, page=1, max=1, type=None) :
     """
         Display the search form for the channel for GET, or do the search for POST.
     """
@@ -244,19 +244,12 @@
     # calculate skip offset from page/count
     skip = (page - 1) * count
 
-    # got a search query?
-    if q :
-        # attribute targets
-        targets = dict(('search_%s' % target, True) for target in t if target in ('msg', 'nick')) if t else {}
 
+    if q or nick :
+        # search
         try :
-            # do search
-            lines = log_search.get_index().search_simple(channel, q, count, skip, **targets)
+            lines = log_search.get_index().search_advanced(channel, q, nick, count, skip)
 
-            # update max?
-            if max and page > max :
-                max = page
-        
         except log_search.NoResultsFound :
             # no results
             lines = None
@@ -264,7 +257,13 @@
     else :
         # just display the search form
         lines = None
- 
+       
+
+    # max?
+    if max and page > max :
+        max = page
+
+
     # type?
     if type and lines :
         # special type
@@ -282,7 +281,8 @@
             prefs           = request.prefs,
             channel         = channel,
             search_query    = q,
-            search_targets  = t,
+            search_nick     = nick,
+            show_results    = (q or nick),
             count           = count,
             page            = page,
             skip            = skip,
--- a/qmsk/irclogs/log_search.py	Sun Sep 13 01:15:56 2009 +0300
+++ b/qmsk/irclogs/log_search.py	Sun Sep 13 18:47:00 2009 +0300
@@ -286,22 +286,17 @@
         # execute
         return self.search_cond(cond)
 
-    def search_simple (self, channel, query, count=None, offset=None, search_msg=True, search_nick=False) :
+    def search_simple (self, channel, query, count=None, offset=None) :
         """
             Search for lines from the given channel for the given simple query.
 
-            The search_* params define which attributes to search for (using fulltext search for the message, STROR for
-            attributes).
+            The given text is searched for in the text of the given channel's entries, and the list of results in
+            reverse time order is returned.
         """
         
         # search attributes
         attrs = []
 
-        # nickname target query
-        if search_nick :
-            attrs.append("source_nickname STRINC %s" % query)
-#            attrs.append("target_nickname STRINC %s" % query)
-        
         # use search(), backwards
         results = list(self.search(
             # simplified phrase
@@ -311,7 +306,43 @@
             channel     = channel,
 
             # given phrase
-            phrase      = query if search_msg else None,
+            phrase      = query,
+
+            # attributes defined above
+            attrs       = attrs,
+
+            # order by timestamp, descending (backwards)
+            order       = "timestamp NUMD",
+
+            # count/offset
+            max         = count,
+            skip        = offset,
+        ))
+        
+        # reverse
+        return reversed(results)
+
+    def search_advanced (self, channel, phrase=None, nick_query=None, count=None, offset=None) :
+        """
+            Search for lines from the given channel for the given full-featured query.
+
+            The given phrase is used to build the condition, or alternatively, the given extra *_query parameters can
+            be used to specific additional attributes to search.
+        """
+
+        attrs = []
+
+        if nick_query :
+            # search for messages from specific nickname
+            attrs.append("source_nickname STRINC %s" % nick_query)
+
+        # use search(), backwards
+        results = list(self.search(
+            # specific channel
+            channel     = channel,
+
+            # given phrase
+            phrase      = phrase,
 
             # attributes defined above
             attrs       = attrs,
--- a/qmsk/irclogs/log_source.py	Sun Sep 13 01:15:56 2009 +0300
+++ b/qmsk/irclogs/log_source.py	Sun Sep 13 18:47:00 2009 +0300
@@ -89,7 +89,15 @@
             portion of the dt is ignored, and the lines for the given page are returned. Otherwise, if page is None,
             then the lines for the page containing the given timestamp is returned.
 
+                dt          - the date to get logs for. If page is None, this is also the specific timestamp to page to
+                count       - number of lines per page to return
+                page        - specific page to return, or None to pick the right page for the given datetime
+
             The return value is a (page, max, lines) tuple.
+                page        - the selected page
+                max         - total number of pages
+                lines       - the sequence of lines for the selected page
+
         """
         
         # how to act?
--- a/qmsk/irclogs/urls.py	Sun Sep 13 01:15:56 2009 +0300
+++ b/qmsk/irclogs/urls.py	Sun Sep 13 18:47:00 2009 +0300
@@ -39,7 +39,7 @@
 channel_link        = url('/channels/{channel:cid}/link/{timestamp:ts}/?type=',             handlers.channel_link                       )
 channel_calendar    = url('/channels/{channel:cid}/calendar/{year:int=0}/{month:int=0}',    handlers.channel_calendar                   )
 channel_date        = url('/channels/{channel:cid}/date/{date:date}/?page:int=1&type=',     handlers.channel_date                       )
-channel_search      = url('/channels/{channel:cid}/search/?q=&page:int=1&max:int=1&type=&t:list=',  handlers.channel_search                     )
+channel_search      = url('/channels/{channel:cid}/search/?q=&nick=&page:int=1&max:int=1&type=',  handlers.channel_search                     )
 
 # mapper
 mapper = urltree.URLTree(urls)
--- a/static/irclogs.css	Sun Sep 13 01:15:56 2009 +0300
+++ b/static/irclogs.css	Sun Sep 13 18:47:00 2009 +0300
@@ -271,6 +271,10 @@
     width: 8em;
 }
 
+fieldset input.wide {
+    width: 30em;
+}
+
 fieldset span.example {
     font-size: x-small;
 
@@ -284,19 +288,21 @@
     text-align: center;
 }
 
+/*
 div#search input[type=text] {
     display: block;
 
     width: 40%;
     margin: 0px auto 5px auto;
-
 }
 
 div#search div.indent {
     margin-left: 8.5em;
 }
+*/
 
 div#search-help {
+
 }
 
 div#search-error {
--- a/templates/channel_search.tmpl	Sun Sep 13 01:15:56 2009 +0300
+++ b/templates/channel_search.tmpl	Sun Sep 13 18:47:00 2009 +0300
@@ -1,26 +1,32 @@
 <%inherit file="channel.tmpl" />
 <%namespace file="inc_paginate.tmpl" import="paginate" />
 
-% if not search_query :
+% if not show_results :
 <div id="title">${channel.title} :: Search</div>
 
 <div id="search">
     <form action="${h.build_url(urls.channel_search, channel=channel)}" method="GET">
+        <fieldset>
+            <p>
+                <label for="q">Message:</label>
+                <input type="text" name="q" class="wide" />
+            </p>
+            
+            <p>
+                <label for="nick">By nickname:</label>
+                <input type="text" name="nick" />
+                <span>(optional)</span>
+            </p>
 
-        <div id="search-form">    
-            <input type="text" name="q" />
+            <p>
+                <label for="count">Results/page:</label>
+                <select name="count">
+                    ${h.select_options(((cc, cc_label) for cc, cc_label in config.SEARCH_LINE_COUNT_OPTIONS), count)}
+                </select>
+            </p>
+            
             <input type="submit" value="Search" />
-        </div>
-        
-<p>        
-        <label for="count">Results/page:</label>
-        <select name="count">
-        ${h.select_options(((cc, cc_label) for cc, cc_label in config.SEARCH_LINE_COUNT_OPTIONS), count)}
-        </select>
-</p>
-        <label for="t">Search in:</label><br/>
-            <div class="indent"><input type="radio" name="t" value="msg" checked="checked" /> Messages</div>
-            <div class="indent"><input type="radio" name="t" value="nick" /> Nicknames</div>
+        </fieldset>        
     </form>
     
     <div id="search-help">
@@ -37,7 +43,14 @@
 </div>
 
 % else :
-<div id="title">${channel.title} :: Search '${search_query}'</div>
+<div id="title">${channel.title} :: Results\
+%   if search_query :
+ With '${search_query}'\
+%   endif
+%   if search_nick :
+ By ${search_nick}\
+%   endif
+</div>
 
 ${paginate(urls.channel_search, count, page, max, channel=channel, q=search_query, t=search_targets, _more=True, _last=not(bool(lines)))}
 % if lines :