--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/qmsk/irclogs/handlers.py Sun Sep 13 01:15:56 2009 +0300
@@ -0,0 +1,292 @@
+"""
+ 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,
+ )
+