fix off-by-one with search paginate, and implement basic pagination for channel_date
authorTero Marttila <terom@fixme.fi>
Tue, 10 Feb 2009 01:02:26 +0200
changeset 76 cc3ab2c39ded
parent 75 c5ce145fdd70
child 77 4287fb77e312
fix off-by-one with search paginate, and implement basic pagination for channel_date
handlers.py
log_source.py
templates/channel_date.tmpl
templates/channel_search.tmpl
templates/inc_paginate.tmpl
urls.py
--- a/handlers.py	Tue Feb 10 00:19:56 2009 +0200
+++ b/handlers.py	Tue Feb 10 01:02:26 2009 +0200
@@ -140,17 +140,22 @@
         days            = days,
     )
 
-@preferences.handler(prefs.formatter, prefs.timezone)
-def channel_date (request, channel, date, formatter, timezone) :
+@preferences.handler(prefs.formatter, prefs.timezone, prefs.count)
+def channel_date (request, channel, date, formatter, timezone, count, page=None) :
     """
         Display all log data for the given date
     """
-    
+
     # fix date timezone
     date = date.replace(tzinfo=timezone)
 
     # get latest events
-    lines = channel.source.get_date(date)
+    if page :
+        page, max, lines = channel.source.get_date_paged(date, count, page)
+        
+    else :
+        lines = channel.source.get_date(date)
+        max = None
 
     # lines
     lines = formatter.format_html(lines)
@@ -161,6 +166,9 @@
         prefs           = request.prefs,
         channel         = channel,
         date            = date,
+        page            = page,
+        count           = count,
+        max             = max,
         lines           = lines,
     )
 
@@ -171,7 +179,7 @@
     """
 
     # calculate skip offset from page/count
-    skip = page * count
+    skip = (page - 1) * count
 
     # got a search query?
     if q :
--- a/log_source.py	Tue Feb 10 00:19:56 2009 +0200
+++ b/log_source.py	Tue Feb 10 01:02:26 2009 +0200
@@ -2,7 +2,7 @@
     A source of IRC log files
 """
 
-import datetime, calendar, itertools
+import datetime, calendar, itertools, functools
 import os, errno
 import pytz
 
@@ -20,18 +20,54 @@
     
     def get_date (self, dt) :
         """
-            Get logs for the given date (as a datetime)
+            Get logs for the given date (as a datetime).
         """
 
         abstract
     
+    def get_date_paged (self, dt, count, page=None) :
+        """
+            Get the logs for a given date (as a datetime), divided into pages of count each. If page is given, the time
+            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.
+
+            The return value is a (page, max, lines) tuple.
+        """
+        
+        # how to act?
+        if page :
+            # constant skip
+            skip = (page - 1) * count
+
+        else :
+            skip = None
+
+        # collect lines
+        lines = []
+
+        # iterate using get_date
+        for line in self.get_date(dt) :
+            # skip?
+            if skip :
+                skip -= 1
+                continue
+            
+            # store line
+            lines.append(line)
+
+            # count?
+            if len(lines) >= count :
+                break
+
+        return (page, 0, lines)
+
     def get_month_days (self, dt) :
         """
             Get a set of dates, telling which days in the given month (as a datetime) have logs available
         """
 
         abstract
-    
+ 
 class LogFile (object) :
     """
         A file containing LogEvents
@@ -69,7 +105,7 @@
     
     def read_full (self) :
         """
-            Reads all LogLines. The LogLines will have a valid offset
+            Reads all LogLines. The LogLines will have a valid offset.
         """
         
         # just use our __iter__
@@ -380,7 +416,7 @@
             # open both of them
             f_begin = self._get_logfile_date(d_begin)
             f_end = self._get_logfile_date(d_end)
-
+            
             # chain together the two sources
             return itertools.chain(
                 f_begin.read_from(dtz_begin), 
--- a/templates/channel_date.tmpl	Tue Feb 10 00:19:56 2009 +0200
+++ b/templates/channel_date.tmpl	Tue Feb 10 01:02:26 2009 +0200
@@ -1,5 +1,13 @@
 <%inherit file="channel.tmpl" />
+<%namespace file="inc_paginate.tmpl" import="paginate" />
 
 <div id="title">${channel.title} :: Logs for ${h.fmt_date(date)}</div>
 
+% if page :
+${paginate(urls.channel_date, count, page, max, channel=channel, date=date)}
+% endif
 <%include file="lines.tmpl" />
+% if page :
+${paginate(urls.channel_date, count, page, max, channel=channel, date=date)}
+% endif
+
--- a/templates/channel_search.tmpl	Tue Feb 10 00:19:56 2009 +0200
+++ b/templates/channel_search.tmpl	Tue Feb 10 01:02:26 2009 +0200
@@ -1,43 +1,5 @@
 <%inherit file="channel.tmpl" />
-
-<%def name="paginate(url, count, page_cur, page_max, _more=None, _last=False, **args)">
-    <%doc>
-        Pagination works using page numbers, with a specific number of maximum pages displayed. If _more is True,
-        then instead of a "Next" button, we have a "More" button, which goes to the max+1'th page, unless _last is
-        True, whereupon it's not displayed
-    </%doc>
-    <div class="paginate">
-        <ul>
-            <li>
-            % if page_cur > 1 :
-                <a href="${h.build_url(url, count=count, page=page_cur-1, max=max, **args)}">&laquo; Prev</a>
-            % else :
-                <span>&laquo; Prev</span>
-            %endif
-            </li>
-        % for page in xrange(1, page_max + 1) :
-            <li>
-            % if page == page_cur :
-                <strong>${page}</strong>
-            % else :
-                <a href="${h.build_url(url, count=count, page=page, max=page_max, **args)}">${page}</a>
-            % endif
-            </li>
-        % endfor
-            <li>
-            % if _more and _last :
-                <span>More &raquo;</span>
-            % elif _more : 
-                <a href="${h.build_url(url, count=count, page=page_max+1, **args)}">More &raquo;</a>
-            % elif page_cur == page_max : ## last page
-                <span>Next &raquo;</span>
-            % else : 
-                <a href="${h.build_url(url, count=count, page=page+1, **args)}">Next &raquo;</a>
-            % endif
-            </li>
-        </ul>
-    </div>
-</%def>
+<%namespace file="inc_paginate.tmpl" import="paginate" />
 
 % if not search_query :
 <div id="title">${channel.title} :: Search</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/inc_paginate.tmpl	Tue Feb 10 01:02:26 2009 +0200
@@ -0,0 +1,39 @@
+<%def name="paginate(url, count, page_cur, page_max, _more=None, _last=False, **args)">
+    <%doc>
+        Pagination works using page numbers, with a specific number of maximum pages displayed. If _more is True,
+        then instead of a "Next" button, we have a "More" button, which goes to the max+1'th page, unless _last is
+        True, whereupon it's not displayed
+    </%doc>
+    <div class="paginate">
+        <ul>
+            <li>
+            % if page_cur > 1 :
+                <a href="${h.build_url(url, count=count, page=page_cur-1, max=max, **args)}">&laquo; Prev</a>
+            % else :
+                <span>&laquo; Prev</span>
+            %endif
+            </li>
+        % for page in xrange(1, page_max + 1) :
+            <li>
+            % if page == page_cur :
+                <strong>${page}</strong>
+            % else :
+                <a href="${h.build_url(url, count=count, page=page, max=page_max, **args)}">${page}</a>
+            % endif
+            </li>
+        % endfor
+            <li>
+            % if _more and _last :
+                <span>More &raquo;</span>
+            % elif _more : 
+                <a href="${h.build_url(url, count=count, page=page_max+1, **args)}">More &raquo;</a>
+            % elif page_cur == page_max : ## last page
+                <span>Next &raquo;</span>
+            % else : 
+                <a href="${h.build_url(url, count=count, page=page_cur+1, **args)}">Next &raquo;</a>
+            % endif
+            </li>
+        </ul>
+    </div>
+</%def>
+
--- a/urls.py	Tue Feb 10 00:19:56 2009 +0200
+++ b/urls.py	Tue Feb 10 01:02:26 2009 +0200
@@ -38,8 +38,8 @@
 channel_last        = url('/channels/{channel:cid}/last/{count:int=100}',                   handlers.channel_last                       )
 channel_link        = url('/channels/{channel:cid}/link/{timestamp:ts}',                    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}',                       handlers.channel_date                       )
-channel_search      = url('/channels/{channel:cid}/search/?q=&page:int=0&max:int=1',        handlers.channel_search                     )
+channel_date        = url('/channels/{channel:cid}/date/{date:date}/?page:int=',            handlers.channel_date                       )
+channel_search      = url('/channels/{channel:cid}/search/?q=&page:int=1&max:int=1',        handlers.channel_search                     )
 
 # mapper
 mapper = urltree.URLTree(urls)