# HG changeset patch # User Tero Marttila # Date 1234390612 -7200 # Node ID 751e3fcd11d2855ec1f0860b970286efe12bfbe6 # Parent d4848d807fd1ff63b18edbbe8e028c906bef1dcc have dates in URLs be partial timestamps - fix datetime-timezone-comparison mess diff -r d4848d807fd1 -r 751e3fcd11d2 handlers.py --- a/handlers.py Wed Feb 11 23:38:05 2009 +0200 +++ b/handlers.py Thu Feb 12 00:16:52 2009 +0200 @@ -61,6 +61,35 @@ else : raise http.ResponseError("Unrecognized type: %r" % (type, )) +def _render_date (request, channel, date, lines, type, count, page, max) : + """ + Render the given LogLines as a http.Response for channel_date + """ + + # type? + if type : + # special type + return _render_type(request, channel, lines, type) + + else : + # format HTML + lines = request.prefs['formatter'].format_html(lines) + + # render + return templates.render_to_response("channel_date", + req = request, + prefs = request.prefs, + channel = channel, + date = date, + count = count, + page = page, + max = max, + lines = lines, + + # for prev/next date + date_next = channel.source.get_next_date(date), + date_prev = channel.source.get_prev_date(date), + ) def index (request) : """ @@ -143,31 +172,9 @@ # get correct day's correct page of lines page, max, lines = channel.source.get_date_paged(timestamp, count) - - # type? - if type : - # special type - return _render_type(request, channel, lines, type) - else : - # format HTML - lines = formatter.format_html(lines) - - # render - return templates.render_to_response("channel_date", - req = request, - prefs = request.prefs, - channel = channel, - date = timestamp, - page = page, - count = count, - max = max, - lines = lines, - - # for prev/next date - date_next = channel.source.get_next_date(timestamp), - date_prev = channel.source.get_prev_date(timestamp), - ) + # render channel_date + return _render_date (request, channel, timestamp, lines, type, count, page, max) @preferences.handler(prefs.timezone) def channel_calendar (request, channel, year, month, timezone) : @@ -193,14 +200,14 @@ month = target, ) -@preferences.handler(prefs.formatter, prefs.timezone, prefs.count) -def channel_date (request, channel, date, formatter, timezone, count, page=1, type=None) : +@preferences.handler(prefs.count) +def channel_date (request, channel, date, count, page=1, type=None) : """ Display all log data for the given date """ - # fix date timezone - date = timezone.localize(date) +# print +# print "channel_date: date=%s" % date # get that day's events, either paged or not if page : @@ -210,30 +217,8 @@ lines = channel.source.get_date(date) max = None - # type? - if type : - # special type - return _render_type(request, channel, lines, type) - - else : - # lines - lines = formatter.format_html(lines) - - # render page - return templates.render_to_response("channel_date", - req = request, - prefs = request.prefs, - channel = channel, - date = date, - page = page, - count = count, - max = max, - lines = lines, - - # for prev/next date - date_next = channel.source.get_next_date(date), - date_prev = channel.source.get_prev_date(date), - ) + # 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) : diff -r d4848d807fd1 -r 751e3fcd11d2 helpers.py --- a/helpers.py Wed Feb 11 23:38:05 2009 +0200 +++ b/helpers.py Thu Feb 12 00:16:52 2009 +0200 @@ -46,10 +46,10 @@ def build_date (self, month, mday) : """ - Returns a datetime.date for the given (month.year, month.month, mday) + Returns a datetime.datetime for the given (month.year, month.month, mday) """ - return datetime.date(month.year, month.month, mday) + return self.ctx['prefs'][preferences.timezone].localize(datetime.datetime(month.year, month.month, mday)) def now (self) : """ @@ -65,13 +65,13 @@ return self.now().date() - def is_today (self, date) : + def is_today (self, dt) : """ - Checks if the given date is today + Checks if the given datetime.datetime is today """ - # construct current date - return date == self.today() + # compare with current date + return dt.date() == self.today() def is_this_month (self, month) : """ diff -r d4848d807fd1 -r 751e3fcd11d2 log_source.py --- a/log_source.py Wed Feb 11 23:38:05 2009 +0200 +++ b/log_source.py Thu Feb 12 00:16:52 2009 +0200 @@ -384,18 +384,7 @@ self.decoder = decoder self.filename_fmt = filename_fmt - def _get_logfile_datetime (self, dt) : - """ - Get the logfile corresponding to the given datetime - """ - - # convert to target timezone - dtz = dt.astimezone(self.tz) - - # convert to date and use that - return self._get_logfile_date(dtz.date()) - - def _get_logfile_date (self, d, load=True, mtime=False, ignore_missing=True) : + def _get_logfile_date (self, d, load=True, mtime=False, ignore_missing=False) : """ Get the logfile corresponding to the given naive date in our timezone. @@ -443,6 +432,13 @@ reverse the dates are returned in reverse order instead. Note that the meaning of after/until doesn't change """ + # convert timestamps to our timezone's dates + if after : + after = after.astimezone(self.tz).date() + + if until : + until = until.astimezone(self.tz).date() + # listdir filenames = os.listdir(self.path) @@ -453,7 +449,8 @@ for filename in filenames : try : # parse date - date = self.tz.localize(datetime.datetime.strptime(filename, self.filename_fmt)) + dt = self.tz.localize(datetime.datetime.strptime(filename, self.filename_fmt)) + date = dt.date() except : # ignore @@ -465,11 +462,8 @@ continue else : -# print -# print "iter_logfile_dates: after=%s, until=%s, reverse=%s -> %s" % (after, until, reverse, date) - # yield - yield date + yield dt def _iter_date_reverse (self, dt=None) : """ @@ -517,7 +511,7 @@ logfile = None file_count += 1 - logfile = self._get_logfile_date(day) + logfile = self._get_logfile_date(day, ignore_missing=True) # no logfile there? if not logfile : @@ -586,18 +580,15 @@ # open that log logfile = self._get_logfile_date(d_begin) - if not logfile : - raise Exception("No logfile for date=%r" % (dt, )) - # return the full data return logfile.read_full() # otherwise, we need to pull two partial logs else : - # open both of them + # open both of them, but it's okay if we don't have the second one f_begin = self._get_logfile_date(d_begin) - f_end = self._get_logfile_date(d_end) - + f_end = self._get_logfile_date(d_end, ignore_missing=True) + # chain together the two sources return itertools.chain( f_begin.read_from(dtz_begin), @@ -634,7 +625,7 @@ log_date = dt.astimezone(self.tz).date() # test for it - if self._get_logfile_date(log_date, load=False) : + if self._get_logfile_date(log_date, load=False, ignore_missing=True) : # valid yield dt.date() @@ -648,7 +639,7 @@ # compare against dt? if dt : # stat - mtime = self._get_logfile_date(log_date, load=False, mtime=True) + mtime = self._get_logfile_date(log_date, load=False, mtime=True, ignore_missing=True) # not modified? if mtime < dt : @@ -656,7 +647,7 @@ continue # open - logfile = self._get_logfile_date(log_date, ignore_missing=False) + logfile = self._get_logfile_date(log_date) # yield all lines for line in logfile.read_full() : diff -r d4848d807fd1 -r 751e3fcd11d2 templates/channel_calendar.tmpl --- a/templates/channel_calendar.tmpl Wed Feb 11 23:38:05 2009 +0200 +++ b/templates/channel_calendar.tmpl Thu Feb 12 00:16:52 2009 +0200 @@ -44,9 +44,9 @@ ## build date <% date = h.build_date(month, day) %>\ ## render cell - \ + \ ## link to logs for this day? - % if date in log_dates : + % if date.date() in log_dates : ${day}\ % else : ${day}\ diff -r d4848d807fd1 -r 751e3fcd11d2 utils.py --- a/utils.py Wed Feb 11 23:38:05 2009 +0200 +++ b/utils.py Thu Feb 12 00:16:52 2009 +0200 @@ -35,9 +35,12 @@ class URLDateType (URLType) : """ - Handle dates in URLs as naive datetime objects (with indeterminate time info) + Handle dates in URLs as shortened UTC datetime timestamps """ + # percision = hour + SCALE = 60 * 60 + def __init__ (self, date_fmt) : """ Format/parse dates using the given format @@ -45,19 +48,27 @@ self.date_fmt = date_fmt - def parse (self, date_str) : + def parse (self, sts_str) : """ - date_str -> naive datetime.datetime + short_timestamp_str -> datetime.datetime """ - return datetime.datetime.strptime(date_str, self.date_fmt) + # scale -> from_utc + return + return from_utc_timestamp(int(sts_str) * self.SCALE) - def build (self, date) : + def build (self, dtz) : """ - datetime.date -> date_str + datetime.datetime -> short_timestamp_str """ - return date.strftime(self.date_fmt) + # force it to be interpreted as UTC + dt_utc = dtz.replace(tzinfo=pytz.utc) + + # scale the UTC timestamp + sts = to_utc_timestamp(dt_utc) / self.SCALE + + # str + return str(sts) class URLTimestampType (URLType) : """