"""
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,
)
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+parse new POST'd value
# XXX: this doesn't postprocess
new_value = pref.parse(request.get_post(pref.name))
# update if 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,
timezones = pytz.common_timezones,
)
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)
# we can render in various modes...
if not type :
# normal HTML
lines = formatter.format_html(lines)
return templates.render_to_response("channel_last",
req = request,
prefs = request.prefs,
channel = channel,
count = count,
lines = lines,
)
elif type == 'txt' :
# plaintext
lines = formatter.format_txt(lines)
# 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)
return http.Response(png_data, 'image/png', charset=None)
elif type == 'rss' :
# RSS feed
rss_data = formatter.format_rss(lines)
return http.Response(rss_data, 'application/rss+xml')
else :
raise http.ResponseError("Unrecognized type: %r" % (type, ))
@preferences.handler(prefs.formatter, prefs.timezone, prefs.count)
def channel_link (request, channel, timestamp, formatter, timezone, count) :
"""
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)
# lines
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,
)
@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
))
# get set of days available
days = set(channel.source.get_month_days(target))
# display calendar
return templates.render_to_response("channel_calendar",
req = request,
prefs = request.prefs,
channel = channel,
calendar = calendar.Calendar(),
month = target.date(),
days = days,
)
@preferences.handler(prefs.formatter, prefs.timezone, prefs.count)
def channel_date (request, channel, date, formatter, timezone, count, page=1) :
"""
Display all log data for the given date
"""
# fix date timezone
date = date.replace(tzinfo=timezone)
# 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
# lines
lines = formatter.format_html(lines)
# render
return templates.render_to_response("channel_date",
req = request,
prefs = request.prefs,
channel = channel,
date = date,
page = page,
count = count,
max = max,
lines = lines,
)
@preferences.handler(prefs.formatter, prefs.count)
def channel_search (request, channel, formatter, count, q=None, page=1, max=1) :
"""
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 :
try :
# do search
lines = log_search.get_index().search_simple(channel, q, count, skip)
# update max?
if max and page > max :
max = page
except log_search.NoResultsFound :
# no lines
lines = None
else :
# format
lines = formatter.format_html(lines, full_timestamps=True)
else :
lines = None
# render
return templates.render_to_response("channel_search",
req = request,
prefs = request.prefs,
channel = channel,
search_query = q,
count = count,
page = page,
skip = skip,
max = max,
lines = lines,
)