# HG changeset patch
# User Tero Marttila
# Date 1234216197 -7200
# Node ID 5a7188bf289438994f7efa828cefb816422d0a06
# Parent 5ade0288f2ec45ad4609e0df986596af5e0c20b3
split defined configuration constants into config, and implement search result pagination
diff -r 5ade0288f2ec -r 5a7188bf2894 channels.py
--- a/channels.py Mon Feb 09 22:17:10 2009 +0200
+++ b/channels.py Mon Feb 09 23:49:57 2009 +0200
@@ -2,65 +2,37 @@
Our list of LogChannels
"""
-import pytz
-
-# for relpath
-import os.path
-
-from log_channel import LogChannel
-from log_source import LogDirectory
-from log_parser import IrssiParser
-
-relpath = lambda path : os.path.join(os.path.dirname(__file__), path)
-
class ChannelList (object) :
"""
The list of channels, and related methods
"""
- # timezone to use
- TIMEZONE = pytz.timezone('Europe/Helsinki')
- # the parser that we use
- PARSER = IrssiParser(TIMEZONE, "%H:%M:%S")
-
- # the statically defined channel list
- CHANNELS = {
- 'tycoon': LogChannel('tycoon', "OFTC", "#tycoon",
- LogDirectory(relpath('logs/tycoon'), TIMEZONE, PARSER)
- ),
- 'openttd': LogChannel('openttd', "OFTC", "#openttd",
- LogDirectory(relpath('logs/openttd'), TIMEZONE, PARSER)
- ),
- }
-
- def __init__ (self, channels) :
+ def __init__ (self, channel_list) :
"""
Initialize with the given channel dict
"""
-
- self.channels = channels
+
+ self.channel_list = channel_list
+ self.channel_dict = dict((channel.id, channel) for channel in channel_list)
def lookup (self, channel_name) :
"""
Looks up the LogChannel for the given name
"""
- return self.channels[channel_name]
+ return self.channel_dict[channel_name]
def dict (self) :
"""
Returns a { name: LogChannel } dict
"""
- return self.channels
+ return self.channel_dict
def __iter__ (self) :
"""
Iterate over our defined LogChannel objects
"""
- return self.channels.itervalues()
+ return iter(self.channel_list)
-# the global singletone ChannelList...
-channel_list = ChannelList(ChannelList.CHANNELS)
-
diff -r 5ade0288f2ec -r 5a7188bf2894 config.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config.py Mon Feb 09 23:49:57 2009 +0200
@@ -0,0 +1,69 @@
+"""
+ Configureable defaults
+"""
+
+import os.path, pytz
+from log_parser import IrssiParser
+from log_channel import LogChannel
+from log_source import LogDirectory
+from log_formatter import IrssiFormatter
+from channels import ChannelList
+import log_formatter
+
+# build relative paths
+relpath = lambda path : os.path.join(os.path.dirname(__file__), path)
+
+# timezone to use for logs
+LOG_TIMEZONE = pytz.timezone('Europe/Helsinki')
+
+# timestamp format for logfiles
+LOG_TIMESTAMP_FMT = '%H:%M:%S'
+
+# character set used for logfiles
+LOG_CHARSET = 'utf-8'
+
+# log filename format
+LOG_FILENAME_FMT = '%Y-%m-%d'
+
+# the log parser that we use
+LOG_PARSER = IrssiParser(LOG_TIMEZONE, LOG_TIMESTAMP_FMT)
+
+# the statically defined channel list
+LOG_CHANNELS = ChannelList([
+ LogChannel('tycoon', "OFTC", "#tycoon",
+ LogDirectory(relpath('logs/tycoon'), LOG_TIMEZONE, LOG_PARSER, LOG_CHARSET, LOG_FILENAME_FMT)
+ ),
+
+ LogChannel('openttd', "OFTC", "#openttd",
+ LogDirectory(relpath('logs/openttd'), LOG_TIMEZONE, LOG_PARSER, LOG_CHARSET, LOG_FILENAME_FMT)
+ ),
+])
+
+# date format for URLs
+URL_DATE_FMT = '%Y-%m-%d'
+
+# month name format
+MONTH_FMT = '%B %Y'
+
+# timezone name format
+TIMEZONE_FMT = '%Z %z'
+
+# available formatters
+LOG_FORMATTERS = log_formatter.FORMATTERS
+
+# default preferences
+PREF_TIME_FMT_DEFAULT = '%H:%M:%S'
+PREF_DATE_FMT_DEFAULT = '%Y-%m-%d'
+PREF_TIMEZONE_DEFAULT = pytz.utc
+PREF_FORMATTER_DEFAULT = IrssiFormatter
+PREF_COUNT_DEFAULT = 200
+PREF_COUNT_MAX = None
+
+# search line count options
+SEARCH_LINE_COUNT_OPTIONS = (
+ (50, 50),
+ (100, 100),
+ (200, 200),
+ (None, "∞"),
+)
+
diff -r 5ade0288f2ec -r 5a7188bf2894 handlers.py
--- a/handlers.py Mon Feb 09 22:17:10 2009 +0200
+++ b/handlers.py Mon Feb 09 23:49:57 2009 +0200
@@ -9,12 +9,14 @@
import urls, channels, helpers
import preferences as prefs
from preferences import preferences
+import config
# load templates from here
templates = template.TemplateLoader("templates",
_helper_class = helpers.Helpers,
urls = urls,
- channel_list = channels.channel_list,
+ channel_list = config.LOG_CHANNELS,
+ config = config,
)
# our LogSearch thing
@@ -162,8 +164,8 @@
lines = lines,
)
-@preferences.handler(prefs.formatter)
-def channel_search (request, channel, formatter, q=None, count=None, skip=None) :
+@preferences.handler(prefs.formatter, prefs.count)
+def channel_search (request, channel, formatter, count, q=None, skip=0, max=None) :
"""
Display the search form for the channel for GET, or do the search for POST
"""
@@ -185,6 +187,9 @@
prefs = request.prefs,
channel = channel,
search_query = q,
+ count = count,
+ skip = skip,
+ max = max,
lines = lines,
)
diff -r 5ade0288f2ec -r 5a7188bf2894 helpers.py
--- a/helpers.py Mon Feb 09 22:17:10 2009 +0200
+++ b/helpers.py Mon Feb 09 23:49:57 2009 +0200
@@ -6,7 +6,7 @@
import qmsk.web.helpers
-import preferences, urls
+import preferences, urls, config
class Helpers (qmsk.web.helpers.Helpers) :
"""
@@ -18,14 +18,14 @@
Returns a string describing the given timezone
"""
- return self.now().strftime("%Z%z")
+ return self.now().strftime(config.TIMEZONE_FMT)
def fmt_month (self, date) :
"""
Formats a month
"""
- return date.strftime('%B %Y')
+ return date.strftime(config.MONTH_FMT)
def fmt_weekday (self, wday) :
"""
@@ -151,4 +151,40 @@
"""
return urls.types['ts'].build(dtz)
+
+ def skip_next (self, count, skip) :
+ """
+ Return skip offset for next page
+ """
+ return count + skip
+
+ def skip_page (self, count, page) :
+ """
+ Skip to page
+ """
+
+ if page :
+ return count * page
+
+ else :
+ return None
+
+ def skip_prev (self, count, skip) :
+ """
+ Return skip offset for previous page, None for first page
+ """
+
+ if skip > count :
+ return skip - count
+
+ else :
+ return None
+
+ def max (self, *values) :
+ """
+ Returns the largest of the given values
+ """
+
+ return max(values)
+
diff -r 5ade0288f2ec -r 5a7188bf2894 log_formatter.py
--- a/log_formatter.py Mon Feb 09 22:17:10 2009 +0200
+++ b/log_formatter.py Mon Feb 09 23:49:57 2009 +0200
@@ -42,7 +42,7 @@
# full timestamps?
if full_timestamp :
- # XXX: ugly
+ # XXX: ugly hack
timestamp_fmt = '%Y-%m-%d ' + self.timestamp_fmt
else :
diff -r 5ade0288f2ec -r 5a7188bf2894 log_source.py
--- a/log_source.py Mon Feb 09 22:17:10 2009 +0200
+++ b/log_source.py Mon Feb 09 23:49:57 2009 +0200
@@ -39,7 +39,7 @@
XXX: modify to implement LogSource?
"""
- def __init__ (self, path, parser, start_date=None, charset='utf-8', sep='\n') :
+ def __init__ (self, path, parser, charset, start_date=None, sep='\n') :
"""
Open the file at the given path, which contains data with the given charset, as lines separated by the
given separator. Lines are parsed using the given parser, using the given date as an initial date, see
@@ -204,7 +204,7 @@
A directory containing a series of timestamped LogFiles
"""
- def __init__ (self, path, tz, parser, charset='utf-8', filename_fmt='%Y-%m-%d') :
+ def __init__ (self, path, tz, parser, charset, filename_fmt) :
"""
Load the logfiles at the given path.
@@ -247,7 +247,7 @@
try :
if load :
# open+return the LogFile
- return LogFile(path, self.parser, d, self.charset)
+ return LogFile(path, self.parser, self.charset, d)
else :
# test
diff -r 5ade0288f2ec -r 5a7188bf2894 preferences.py
--- a/preferences.py Mon Feb 09 22:17:10 2009 +0200
+++ b/preferences.py Mon Feb 09 23:49:57 2009 +0200
@@ -195,6 +195,7 @@
# now for our defined preferences....
import pytz
+import config
class TimeFormat (urltree.URLStringType, Preference) :
"""
@@ -205,7 +206,7 @@
name = 'time_format'
# default value
- default = "%H:%M:%S"
+ default = config.PREF_TIME_FMT_DEFAULT
class DateFormat (urltree.URLStringType, Preference) :
"""
@@ -216,7 +217,7 @@
name = 'date_format'
# default value
- default = "%Y-%m-%d"
+ default = config.PREF_DATE_FMT_DEFAULT
class Timezone (Preference) :
"""
@@ -227,7 +228,7 @@
name = 'timezone'
# default value is UTC...
- default = pytz.utc
+ default = config.PREF_TIMEZONE_DEFAULT
def parse (self, name) :
"""
@@ -280,18 +281,32 @@
return fmt_cls(prefs[timezone], prefs[time_format])
-# and then build the Preferences object
-import log_formatter
+class Count (urltree.URLIntegerType, Preference) :
+ """
+ Number of lines of log data to display per page
+ """
-time_format = TimeFormat()
-date_format = DateFormat()
-timezone = Timezone()
-formatter = Formatter(log_formatter.FORMATTERS, log_formatter.IrssiFormatter)
+ # set name
+ name = "count"
+
+ # default
+ default = config.PREF_COUNT_DEFAULT
+
+ def __init__ (self) :
+ super(Count, self).__init__(allow_negative=False, allow_zero=False, max=config.PREF_COUNT_MAX)
+
+# and then build the Preferences object
+time_format = TimeFormat()
+date_format = DateFormat()
+timezone = Timezone()
+formatter = Formatter(config.LOG_FORMATTERS, config.PREF_FORMATTER_DEFAULT)
+count = Count()
preferences = Preferences([
time_format,
date_format,
timezone,
formatter,
+ count,
])
diff -r 5ade0288f2ec -r 5a7188bf2894 static/irclogs.css
--- a/static/irclogs.css Mon Feb 09 22:17:10 2009 +0200
+++ b/static/irclogs.css Mon Feb 09 23:49:57 2009 +0200
@@ -307,3 +307,45 @@
color: #000000;
}
+/* Pagination */
+div.paginate {
+ height: 50px;
+
+ padding-top: 20px;
+
+ text-align: center;
+}
+
+div.paginate ul {
+ margin: 0px;
+ padding: 0px;
+
+ line-height: 30px;
+
+ border: 1px solid #aaa;
+
+ white-space: nowrap;
+}
+
+div.paginate li {
+ list-style-type: none;
+ display: inline;
+}
+
+div.paginate li * {
+ padding: 7px 10px;
+}
+
+div.paginate li a {
+ color: black;
+ text-decoration: none;
+}
+
+div.paginate li span {
+ color: #d5d5d5;
+}
+
+div.paginate li a:hover {
+ background-color: #d0d0d0;
+}
+
diff -r 5ade0288f2ec -r 5a7188bf2894 templates/channel_search.tmpl
--- a/templates/channel_search.tmpl Mon Feb 09 22:17:10 2009 +0200
+++ b/templates/channel_search.tmpl Mon Feb 09 23:49:57 2009 +0200
@@ -1,5 +1,35 @@
<%inherit file="channel.tmpl" />
+<%def name="paginate(url, count, skip, max, **args)">
+ ## update max?
+ <% max = h.max(max, skip) %>
+ ## number of pages
+ <% page_count = max / count + 1 %>
+
+
+ -
+ % if skip :
+ « Prev
+ % else :
+ « Prev
+ %endif
+
+ % for page in xrange(page_count) :
+ -
+ % if page == skip / count :
+ ${page + 1}
+ % else :
+ ${page + 1}
+ % endif
+
+ % endfor
+ -
+ More »
+
+
+
+%def>
+
% if not search_query :
${channel.title} :: Search
@@ -9,10 +39,9 @@
Results/page:
@@ -32,5 +61,7 @@
% else :
${channel.title} :: Search '${search_query}'
+${paginate(urls.channel_search, count, skip, max, channel=channel, q=search_query)}
<%include file="lines.tmpl" />
+${paginate(urls.channel_search, count, skip, max, channel=channel, q=search_query)}
% endif
diff -r 5ade0288f2ec -r 5a7188bf2894 templates/preferences.tmpl
--- a/templates/preferences.tmpl Mon Feb 09 22:17:10 2009 +0200
+++ b/templates/preferences.tmpl Mon Feb 09 23:49:57 2009 +0200
@@ -41,6 +41,12 @@
% endfor
+
+
+
+
+ (Blank for infinite)
+
diff -r 5ade0288f2ec -r 5a7188bf2894 urls.py
--- a/urls.py Mon Feb 09 22:17:10 2009 +0200
+++ b/urls.py Mon Feb 09 23:49:57 2009 +0200
@@ -13,15 +13,15 @@
import utils
# for configuration
-import channels
+import config
# our URLTypes
types = dict(
# LogChannel
- cid = utils.URLChannelName(channels.channel_list.dict()),
+ cid = utils.URLChannelName(config.LOG_CHANNELS.dict()),
# datetime
- date = utils.URLDateType('%Y-%m-%d'),
+ date = utils.URLDateType(config.URL_DATE_FMT),
# UTC timestamp
ts = utils.URLTimestampType(),
@@ -39,7 +39,7 @@
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=&count:int=&skip:int=', handlers.channel_search )
+channel_search = url('/channels/{channel:cid}/search/?q=&skip:int=0&max:int=', handlers.channel_search )
# mapper
mapper = urltree.URLTree(urls)
diff -r 5ade0288f2ec -r 5a7188bf2894 utils.py
--- a/utils.py Mon Feb 09 22:17:10 2009 +0200
+++ b/utils.py Mon Feb 09 23:49:57 2009 +0200
@@ -37,7 +37,7 @@
Handle dates in URLs as naive datetime objects (with indeterminate time info)
"""
- def __init__ (self, date_fmt="%Y-%m-%d") :
+ def __init__ (self, date_fmt) :
"""
Format/parse dates using the given format
"""