remove debug crap and fix Timezone.is_default to detect config.PREF_TIMEZONE_DEFAULT as well
"""
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),
)
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,
)
# 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,
)