rudimentary search
authorTero Marttila <terom@fixme.fi>
Mon, 09 Feb 2009 07:32:11 +0200
changeset 63 416560b82116
parent 62 e7ca94b94a4e
child 64 cdb6403c2498
rudimentary search
handlers.py
helpers.py
log_source.py
templates/channel_search.tmpl
urls.py
--- a/handlers.py	Mon Feb 09 07:15:19 2009 +0200
+++ b/handlers.py	Mon Feb 09 07:32:11 2009 +0200
@@ -140,6 +140,7 @@
     # lines
     lines = formatter.format_html(lines)
 
+    # render
     return templates.render_to_response("channel_date",
         req             = request,
         prefs           = request.prefs,
@@ -148,10 +149,31 @@
         lines           = lines,
     )
 
-def channel_search (request, channel, q) :
+@preferences.handler(prefs.formatter)
+def channel_search (request, channel, formatter, q=None) :
     """
         Display the search form for the channel for GET, or do the search for POST
     """
 
-    pass
+    # got a search query?
+    if q :
+        # do search
+        lines = channel.source.get_search(q)
 
+        # format
+        lines = formatter.format_html(lines)
+
+    else :
+        lines = None
+    
+    # render
+    return templates.render_to_response("channel_search",
+        req             = request,
+        prefs           = request.prefs,
+        channel         = channel,
+        query           = q,
+        lines           = lines,
+    )
+
+
+
--- a/helpers.py	Mon Feb 09 07:15:19 2009 +0200
+++ b/helpers.py	Mon Feb 09 07:32:11 2009 +0200
@@ -138,3 +138,10 @@
 
         return date.strftime(self.ctx['prefs'][preferences.date_format])
 
+    def build_url (self, url, **params) :
+        """
+            Build URL with our request object
+        """
+
+        return url.build(self.ctx['req'], **params)
+
--- a/log_source.py	Mon Feb 09 07:15:19 2009 +0200
+++ b/log_source.py	Mon Feb 09 07:32:11 2009 +0200
@@ -31,7 +31,14 @@
         """
 
         abstract
-        
+    
+    def get_search (self, query) :
+        """
+            Search the logs for the given query
+        """
+
+        abstract
+
 class LogFile (object) :
     """
         A file containing LogEvents
@@ -286,41 +293,58 @@
             # one day sdrawkcab
             dtz -= ONE_DAY
     
-    def get_latest (self, count) :
+    def _iter_logfile_reverse (self, dt=None, max_files=100) :
         """
-            Uses _iter_backwards + _get_logfile_date to read the yield the given lines from as many logfiles as needed
+            Yields a series of LogFile objects, iterating backwards in time starting at the given datetime, or the
+            current date, if none given.
+
+            Reads/probes at most max_files files.
         """
         
-        # iterate backwards from now
-        day_iter = self._iter_date_reverse()
-
-        # number of files read
-        files = 0
-
-        # only read up to 100 files or so
-        MAX_FILES = 100
+        # start counting at zero...
+        file_count = 0
 
-        # read the events into here
-        lines = []
-        
-        # loop until done
-        while len(lines) < count :
+        # iterate backwards over days
+        for day in self._iter_date_reverse(dt) :
+            # stop if we've handled enough files by now
+            if file_count > max_files :
+                break
+            
+            # try and open the next logfile
             logfile = None
-
-            # get next logfile
-            files += 1
             
-            # open
-            logfile = self._get_logfile_date(day_iter.next())
+            file_count += 1
+            logfile = self._get_logfile_date(day)
             
+            # no logfile there?
             if not logfile :
-                if files > MAX_FILES :
+                # if we didn't find any logfiles at all, terminate rudely
+                if file_count > max_files :
                     raise Exception("No recent logfiles found")
                 
                 else :
                     # skip to next day
                     continue
             
+            # yield it
+            yield logfile
+
+    def get_latest (self, count) :
+        """
+            Uses _iter_backwards + _get_logfile_date to read the yield the given lines from as many logfiles as needed
+        """
+
+        # iterate over logfiles
+        iter = self._iter_logfile_reverse()
+        
+        # read the events into here
+        lines = []
+        
+        # loop until done
+        while len(lines) < count :
+            # next logfile
+            logfile = iter.next()
+
             # read the events
             # XXX: use a queue
             lines = list(logfile.read_latest(count)) + lines
@@ -382,3 +406,18 @@
         # return set
         return days
 
+    def get_search (self, query) :
+        """
+            Just inspect the latest logfile
+        """
+
+        # one logfile
+        logfile = self._iter_logfile_reverse().next()
+
+        # inspect each line
+        for line in logfile.read_full() :
+            # XXX: use proper LogQuery stuff
+            if query in line.data :
+                yield line
+        
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/channel_search.tmpl	Mon Feb 09 07:32:11 2009 +0200
@@ -0,0 +1,21 @@
+<%inherit file="channel.tmpl" />
+
+% if not query :
+<div id="title">${channel.title} :: Search</div>
+
+<form action="${h.build_url(urls.channel_search, channel=channel)}" method="GET">
+    <p>
+        <input type="text" name="q" />
+        <input type="submit" value="Search" />
+    </p>
+</form>
+
+<p>Search for something.</p>
+
+% else :
+<div id="title">${channel.title} :: Search '${query}'</div>
+
+% for line in lines:
+${line}\
+% endfor
+% endif
--- a/urls.py	Mon Feb 09 07:15:19 2009 +0200
+++ b/urls.py	Mon Feb 09 07:32:11 2009 +0200
@@ -34,7 +34,7 @@
 channel_last        = url('/channels/{channel:cid}/last/{count:int=100}/{format=html}',     handlers.channel_last           )
 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}',                       handlers.channel_date           )
-channel_search      = url('/channels/{channel:cid}/search/?q',                              handlers.channel_search         )
+channel_search      = url('/channels/{channel:cid}/search/?q=',                             handlers.channel_search         )
 
 # mapper
 mapper = urltree.URLTree(urls)