# HG changeset patch
# User Tero Marttila
- An error occured, which was not logged, and was not reported to anybody. It might be your fault, or it might be mine.
-
- You can try:
- Oops!
-
-
-
-
-
- %(submit_url_short)s -- -
The page you tried to request was:
-- %(url)s -- -
The software version is:
-- %(version_link)s -- -
The error was:
-- %(exception)s -- -
The traceback was:
-%(traceback)s-""" % dict( - url = url if url else 'Unknown', - version_link = version_href if version_href else 'Unknown', - exception = truncate(exception_str, 512), - traceback = cgi.escape(''.join(' ' + line for line in traceback_lines)), - trac_query = trac_query, - trac_query_url = trac_query_url, - trac_query_version = trac_query_version, - trac_query_err = trac_query_err, - submit_url = submit_url, - submit_url_short = truncate(submit_url, 120) - )).encode('utf-8')) - diff -r 9c7769850195 -r 6db2527b67cf handlers.py --- a/handlers.py Sun Sep 13 00:49:55 2009 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,292 +0,0 @@ -""" - Our URL action handlers -""" - -import datetime, calendar, pytz - -from qmsk.web import http, template - -import urls, channels, helpers -import preferences as prefs -from preferences import preferences -import config, log_search - -# load templates from here -templates = template.TemplateLoader("templates", - _helper_class = helpers.Helpers, - urls = urls, - channel_list = config.LOG_CHANNELS, - config = config, -) - -# return a http.Response for the given text in the given format -def _render_type (request, channel, lines, type, full_timestamps=False) : - """ - Render the given LogLines as a http.Response in the given format, which is one of: - html - XXX: not supported - txt - Plaintext - png - PNG image - rss - RSS feed - """ - - # load related preferences - formatter = request.prefs['formatter'] - - kwargs = dict( - full_timestamps = full_timestamps - ) - - # we can render in various modes... - if type in ('html', None) : - xxx - - elif type == 'txt' : - # plaintext - lines = formatter.format_txt(lines, **kwargs) - - # build data - data = '\n'.join(data for line, data in lines) - - return http.Response(data, 'text/plain') - - elif type == 'png' : - # PNG image - png_data = formatter.format_png(lines, **kwargs) - - return http.Response(png_data, 'image/png', charset=None) - - elif type == 'rss' : - # RSS feed - rss_data = formatter.format_rss(lines, **kwargs) - - # XXX: fix to render as unicode? - return http.Response(rss_data, 'application/rss+xml', charset=None) - - 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), - ) - -@preferences.handler() -def index (request) : - """ - The topmost index page, display a list of available channels, perhaps some general stats - """ - - return templates.render_to_response("index", - req = request, - prefs = request.prefs, - ) - -# XXX: fix this namespace crap -@preferences.handler() -def preferences_ (request) : - """ - Preferences editor - """ - - # POST? - if request.is_post() : - # update any modified preferences - for pref in preferences.pref_list : - # get the POST'd value, default = None - post_value = request.get_post(pref.name, None) - - # skip non-specified values - # XXX: this is to not clobber timezone_offset to None - if post_value is None : - continue - - # parse the POST'd value, None -> default - new_value = request.prefs.parse(pref, post_value) - - # update if given and changed - if new_value != request.prefs[pref] : - request.prefs.set(pref.name, new_value) - - # render - return templates.render_to_response("preferences", - req = request, - prefs = request.prefs, - preferences = prefs, - ) - -def channel_select (request, channel) : - """ - Redirect to the appropriate channel_view - """ - - return http.Redirect(urls.channel.build(request, channel=channel)) - -@preferences.handler(prefs.formatter) -def channel_last (request, channel, count, formatter, type=None) : - """ - The main channel view page, displaying the most recent lines - """ - - # get latest events - lines = channel.source.get_latest(count) - - # type? - if type : - # other format - return _render_type(request, channel, lines, type) - - else : - # format HTML - lines = formatter.format_html(lines) - - # render page - return templates.render_to_response("channel_last", - req = request, - prefs = request.prefs, - channel = channel, - count = count, - lines = lines, - ) - -@preferences.handler(prefs.formatter, prefs.timezone, prefs.count) -def channel_link (request, channel, timestamp, formatter, timezone, count, type=None) : - """ - Display channel_date for specific UTC timestamp - """ - - # convert timestamp to user's timezone - timestamp = timestamp.astimezone(timezone) - - # get correct day's correct page of lines - page, max, lines = channel.source.get_date_paged(timestamp, count) - - # 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) : - """ - Display a list of avilable logs for some month - """ - - # current date as default - now = timezone.localize(datetime.datetime.now()) - - # target year/month - target = timezone.localize(datetime.datetime( - year = year if year else now.year, - month = month if month else now.month, - day = 1 - )) - - # display calendar - return templates.render_to_response("channel_calendar", - req = request, - prefs = request.prefs, - channel = channel, - month = target, - ) - -@preferences.handler(prefs.count, prefs.timezone) -def channel_date (request, channel, date, count, timezone, page=1, type=None) : - """ - Display all log data for the given date - """ - - # convert date to user's timezone - date = timezone.localize(date) - -# print -# print "channel_date: date=%s" % date - - # get that day's events, either paged or not - if page : - page, max, lines = channel.source.get_date_paged(date, count, page) - - else : - lines = channel.source.get_date(date) - max = None - - # 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, t=None) : - """ - Display the search form for the channel for GET, or do the search for POST. - """ - - # calculate skip offset from page/count - skip = (page - 1) * count - - # got a search query? - if q : - # attribute targets - targets = dict(('search_%s' % target, True) for target in t if target in ('msg', 'nick')) if t else {} - - try : - # do search - lines = log_search.get_index().search_simple(channel, q, count, skip, **targets) - - # update max? - if max and page > max : - max = page - - except log_search.NoResultsFound : - # no results - lines = None - - else : - # just display the search form - lines = None - - # type? - if type and lines : - # special type - return _render_type(request, channel, lines, type, full_timestamps=True) - - else : - # format lines to HTML if any - if lines : - # format - lines = formatter.format_html(lines, full_timestamps=True) - - # render page - return templates.render_to_response("channel_search", - req = request, - prefs = request.prefs, - channel = channel, - search_query = q, - search_targets = t, - count = count, - page = page, - skip = skip, - max = max, - lines = lines, - ) - diff -r 9c7769850195 -r 6db2527b67cf helpers.py --- a/helpers.py Sun Sep 13 00:49:55 2009 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,243 +0,0 @@ -""" - Some additional helpers -""" - -import datetime -import calendar as _calendar - -import qmsk.web.helpers - -import preferences, urls, config, version - -class Helpers (qmsk.web.helpers.Helpers) : - """ - Our set of helpers, inheriting from base helpers - """ - - # set contructor... - set = set - - # reference to calendar instance - calendar = _calendar.Calendar() - - # list of (month_num, month_name) for the months in the year - months = list(enumerate(_calendar.month_name))[1:] - - def version_link (self) : - """ - Returns a representing this version of the software - """ - - return version.version_link_hg(config.HGWEB_URL, config.HG_WC_PATH) - - def tz_name (self, tz) : - """ - Returns a string describing the given timezone - """ - - return self.now().strftime(config.TIMEZONE_FMT) - - def fmt_month (self, date) : - """ - Formats a month - """ - - return date.strftime(config.MONTH_FMT) - - def fmt_weekday (self, wday) : - """ - Formats an abbreviated weekday name - """ - - return _calendar.day_abbr[wday] - - def build_date (self, month, mday) : - """ - Returns a datetime.datetime for the given (month.year, month.month, mday) - """ - - return self.ctx['prefs'][preferences.timezone].localize(datetime.datetime(month.year, month.month, mday)) - - def now (self) : - """ - Build current time - """ - - return self.ctx['prefs'][preferences.timezone].localize(datetime.datetime.now()) - - def today (self) : - """ - Build today's date - """ - - return self.now().date() - - def is_today (self, dt) : - """ - Checks if the given datetime.datetime is today - """ - - # compare with current date - return dt.date() == self.today() - - def is_this_month (self, month) : - """ - Checks the given month is the current month - """ - - today = self.today() - - return (month.year == today.year and month.month == today.month) - - @staticmethod - def _wrap_year (year, month) : - """ - Wraps month to between [1, 12], spilling overflow/underflow by to year. - - Returns (year, month) - """ - - # underflow? - if month == 0 : - # wrap to previous year - return (year - 1, 12) - - # overflow? - elif month == 13 : - # wrap to next year - return (year + 1, 1) - - # sane value - elif 1 <= month <= 12 : - return (year, month) - - # insane value - else : - assert False, "invalid year/month: %d/%d" % (year, month) - - def prev_month (self, month) : - """ - Returns the month preceding the given one (as a datetime.datetime) - """ - - # previous month - y, m = self._wrap_year(month.year, month.month - 1) - - # build datetime - return datetime.datetime(year=y, month=m, day=1, tzinfo=month.tzinfo) - - def next_month (self, month) : - """ - Returns the month following the given one (as a datetime.datetime) - """ - - # previous month - y, m = self._wrap_year(month.year, month.month + 1) - - # build datetime - return datetime.datetime(year=y, month=m, day=1, tzinfo=month.tzinfo) - - def fmt_time (self, time=None) : - """ - Format given time, or current time - """ - - # defaults - if not time : - time = self.now() - - return time.strftime(self.ctx['prefs'][preferences.time_format]) - - def fmt_date (self, date=None) : - """ - Format given date, or current date - """ - - # defaults - if not date : - date = self.now() - - return date.strftime(self.ctx['prefs'][preferences.date_format]) - - def url (self, url, **params) : - """ - Build URL with our request object - """ - - return url.build(self.ctx['req'], **params) - - # old name - build_url = url - - def utc_timestamp (self, dtz) : - """ - Build an UTC timestamp from the given datetime - """ - - 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) - - def select_options (self, key_values, selected_key=None) : - """ - Render a series of