142 # return |
142 # return |
143 return (page, max_pages, lines) |
143 return (page, max_pages, lines) |
144 |
144 |
145 def get_month_days (self, dt) : |
145 def get_month_days (self, dt) : |
146 """ |
146 """ |
147 Get a set of dates, telling which days in the given month (as a datetime) have logs available |
147 Return a sequence of dates, telling which days in the given month (as a datetime) have logs available |
148 """ |
148 """ |
149 |
149 |
150 abstract |
150 abstract |
151 |
151 |
152 class LogFile (object) : |
152 class LogFile (object) : |
292 buf = lines[0] |
292 buf = lines[0] |
293 |
293 |
294 # yield the rest a line at a time in reverse order... this looks weird, but that's how slicing works :) |
294 # yield the rest a line at a time in reverse order... this looks weird, but that's how slicing works :) |
295 # XXX: use something like islice, this has to build a slice object |
295 # XXX: use something like islice, this has to build a slice object |
296 for line in lines[:0:-1] : |
296 for line in lines[:0:-1] : |
297 yield line.decode(self.charset) |
297 yield self.decoder.decode(line) |
298 |
298 |
299 def read_latest (self, count) : |
299 def read_latest (self, count) : |
300 """ |
300 """ |
301 Returns up to count events, from the end of the file, or less, if the file doesn't contain that many lines. |
301 Returns up to count events, from the end of the file, or less, if the file doesn't contain that many lines. |
302 """ |
302 """ |
514 # chain together the two sources |
514 # chain together the two sources |
515 return itertools.chain( |
515 return itertools.chain( |
516 f_begin.read_from(dtz_begin), |
516 f_begin.read_from(dtz_begin), |
517 f_end.read_until(dtz_end) if f_end else [] |
517 f_end.read_until(dtz_end) if f_end else [] |
518 ) |
518 ) |
|
519 |
|
520 def _iter_month_days (self, month) : |
|
521 """ |
|
522 Iterates over the days of a month as dt objects with time=0 |
|
523 """ |
|
524 |
|
525 # there's at most 31 days in a month... |
|
526 for day in xrange(1, 32) : |
|
527 try : |
|
528 # try and build the datetime |
|
529 dt = datetime.datetime(month.year, month.month, day) |
|
530 |
|
531 except : |
|
532 # stop |
|
533 return |
|
534 |
|
535 else : |
|
536 # fix timezones + yield |
|
537 yield month.tzinfo.localize(dt) |
519 |
538 |
520 def get_month_days (self, month) : |
539 def get_month_days (self, month) : |
521 """ |
540 """ |
522 Returns a set of dates for which logfiles are available in the given datetime's month |
541 Returns a set of dates for which logfiles are available in the given datetime's month |
523 """ |
542 """ |
524 |
543 |
525 # the set of days |
544 # iterate over month's days |
526 days = set() |
545 for dt in self._iter_month_days(month) : |
527 |
|
528 # iterate over month's days using Calendar |
|
529 for date in calendar.Calendar().itermonthdates(month.year, month.month) : |
|
530 # convert date to target datetime |
|
531 dtz = month.tzinfo.localize(datetime.datetime.combine(date, datetime.time(0))).astimezone(self.tz) |
|
532 |
|
533 # date in our target timezone |
546 # date in our target timezone |
534 log_date = dtz.date() |
547 log_date = dt.astimezone(self.tz).date() |
535 |
548 |
536 # test for it |
549 # test for it |
537 if self._get_logfile_date(log_date, load=False) : |
550 if self._get_logfile_date(log_date, load=False) : |
538 # add to set |
551 # valid |
539 days.add(date) |
552 yield dt.date() |
540 |
553 |
541 # return set |
|
542 return days |
|
543 |
|