dosage/dosagelib/events.py

187 lines
5.6 KiB
Python
Raw Normal View History

# -*- coding: iso-8859-1 -*-
# Copyright (C) 2004-2005 Tristan Seligmann and Jonathan Jacobs
2012-06-20 19:58:13 +00:00
import os.path
import time
import rss
import urllib
import util
class EventHandler(object):
2012-09-26 14:47:39 +00:00
"""Base class for writing events to files. The currently defined events are
start(), comicDownloaded() and end()."""
2012-06-20 19:58:13 +00:00
def __init__(self, basepath, baseurl):
2012-09-26 14:47:39 +00:00
"""Initialize base path and url."""
2012-06-20 19:58:13 +00:00
self.basepath = basepath
self.baseurl = baseurl or self.getBaseUrl()
def getBaseUrl(self):
'''Return a file: URL that probably points to the basedir.
This is used as a halfway sane default when the base URL is not
provided; not perfect, but should work in most cases.'''
components = util.splitpath(os.path.abspath(self.basepath))
url = '/'.join([urllib.quote(component, '') for component in components])
return 'file:///' + url + '/'
def getUrlFromFilename(self, filename):
2012-09-26 14:47:39 +00:00
"""Construct URL from filename."""
2012-06-20 19:58:13 +00:00
components = util.splitpath(util.getRelativePath(self.basepath, filename))
url = '/'.join([urllib.quote(component, '') for component in components])
return self.baseurl + url
def start(self):
2012-09-26 14:47:39 +00:00
"""Emit a start event. Should be overridden in subclass."""
2012-06-20 19:58:13 +00:00
pass
def comicDownloaded(self, comic, filename):
2012-09-26 14:47:39 +00:00
"""Emit a comic downloaded event. Should be overridden in subclass."""
2012-06-20 19:58:13 +00:00
pass
def end(self):
2012-09-26 14:47:39 +00:00
"""Emit an end event. Should be overridden in subclass."""
2012-06-20 19:58:13 +00:00
pass
class TextEventHandler(EventHandler):
2012-09-26 14:47:39 +00:00
"""Output nothing. XXX why?"""
2012-06-20 19:58:13 +00:00
pass
class RSSEventHandler(EventHandler):
2012-09-26 14:47:39 +00:00
"""Output in RSS format."""
2012-06-20 19:58:13 +00:00
def RFC822Date(self, indate):
2012-09-26 14:47:39 +00:00
"""Format date in rfc822 format. XXX move to util module."""
2012-06-20 19:58:13 +00:00
return time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(indate))
def getFilename(self):
2012-09-26 14:47:39 +00:00
"""Return RSS filename."""
2012-06-20 19:58:13 +00:00
return os.path.abspath(os.path.join(self.basepath, 'dailydose.rss'))
def start(self):
2012-09-26 14:47:39 +00:00
"""Log start event."""
2012-06-20 19:58:13 +00:00
today = time.time()
yesterday = today - 86400
today = time.localtime(today)
yesterday = time.localtime(yesterday)
2012-09-26 14:47:39 +00:00
# XXX replace with conf var
2012-06-20 19:58:13 +00:00
link = 'https://github.com/wummel/dosage'
self.rssfn = self.getFilename()
if os.path.exists(self.rssfn):
self.newfile = False
self.rss = rss.parseFeed(self.rssfn, yesterday)
else:
self.newfile = True
self.rss = rss.Feed('Daily Dosage', link, 'Comics for %s' % time.strftime('%Y/%m/%d', today))
def comicDownloaded(self, comic, filename):
2012-09-26 14:47:39 +00:00
"""Write RSS entry for downloaded comic."""
2012-06-20 19:58:13 +00:00
url = self.getUrlFromFilename(filename)
args = (
'%s - %s' % (comic, os.path.basename(filename)),
url,
'<a href="%s">View Comic</a>' % (url,),
self.RFC822Date(time.time())
)
if self.newfile:
self.newfile = False
self.rss.addItem(*args)
else:
self.rss.insertHead(*args)
def end(self):
2012-09-26 14:47:39 +00:00
"""Write RSS data to file."""
2012-06-20 19:58:13 +00:00
self.rss.write(self.rssfn)
2012-09-26 14:47:39 +00:00
2012-06-20 19:58:13 +00:00
class HtmlEventHandler(EventHandler):
2012-09-26 14:47:39 +00:00
"""Output in HTML format."""
2012-06-20 19:58:13 +00:00
def fnFromDate(self, date):
2012-09-26 14:47:39 +00:00
"""Get filename from date."""
2012-06-20 19:58:13 +00:00
fn = time.strftime('comics-%Y%m%d.html', date)
fn = os.path.join(self.basepath, 'html', fn)
fn = os.path.abspath(fn)
return fn
def start(self):
2012-09-26 14:47:39 +00:00
"""Start HTML output."""
2012-06-20 19:58:13 +00:00
today = time.time()
yesterday = today - 86400
tomorrow = today + 86400
today = time.localtime(today)
yesterday = time.localtime(yesterday)
tomorrow = time.localtime(tomorrow)
fn = self.fnFromDate(today)
assert not os.path.exists(fn), 'Comic page for today already exists!'
d = os.path.dirname(fn)
if not os.path.isdir(d):
os.makedirs(d)
yesterdayUrl = self.getUrlFromFilename(self.fnFromDate(yesterday))
tomorrowUrl = self.getUrlFromFilename(self.fnFromDate(tomorrow))
self.html = file(fn, 'w')
self.html.write('''<html>
<head>
<title>Comics for %s</title>
</head>
<body>
<a href="%s">Previous Day</a> | <a href="%s">Next Day</a>
<ul>
''' % (time.strftime('%Y/%m/%d', today), yesterdayUrl, tomorrowUrl))
self.lastComic = None
def comicDownloaded(self, comic, filename):
2012-09-26 14:47:39 +00:00
"""Write HTML entry for downloaded comic."""
2012-06-20 19:58:13 +00:00
if self.lastComic != comic:
self.newComic(comic)
url = self.getUrlFromFilename(filename)
self.html.write(' <li><a href="%s">%s</a></li>\n' % (url, os.path.basename(filename)))
def newComic(self, comic):
2012-09-26 14:47:39 +00:00
"""Start new comic list in HTML."""
2012-06-20 19:58:13 +00:00
if self.lastComic is not None:
self.html.write(' </ul>\n')
self.lastComic = comic
self.html.write(''' <li>%s</li>
<ul>
''' % (comic,))
def end(self):
2012-09-26 14:47:39 +00:00
"""End HTML output."""
2012-06-20 19:58:13 +00:00
if self.lastComic is not None:
self.html.write(' </ul>\n')
self.html.write('''</ul>
</body>
</html>''')
self.html.close()
handlers = {
'text': TextEventHandler,
'html': HtmlEventHandler,
'rss': RSSEventHandler,
}
def getHandlers():
2012-09-26 14:47:39 +00:00
"""Get sorted handler names."""
return sorted(handlers.keys())
2012-06-20 19:58:13 +00:00
def installHandler(name=None, basepath=None, baseurl=None):
2012-09-26 14:47:39 +00:00
"""Install a global handler with given name."""
2012-06-20 19:58:13 +00:00
global handler
if name is None:
name = 'text'
if basepath is None:
basepath = '.'
handler = handlers[name](basepath, baseurl)
installHandler()