2012-06-20 20:41:04 +00:00
|
|
|
# -*- coding: iso-8859-1 -*-
|
|
|
|
# Copyright (C) 2004-2005 Tristan Seligmann and Jonathan Jacobs
|
2012-10-11 17:52:52 +00:00
|
|
|
import os
|
2012-06-20 19:58:13 +00:00
|
|
|
import time
|
|
|
|
import urllib
|
2012-10-11 17:52:52 +00:00
|
|
|
from . import rss, util, configuration
|
2012-06-20 19:58:13 +00:00
|
|
|
|
|
|
|
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 RSSEventHandler(EventHandler):
|
2012-09-26 14:47:39 +00:00
|
|
|
"""Output in RSS format."""
|
|
|
|
|
2012-06-20 19:58:13 +00:00
|
|
|
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-10-11 17:52:52 +00:00
|
|
|
link = configuration.Url
|
2012-06-20 19:58:13 +00:00
|
|
|
|
|
|
|
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,
|
2012-12-12 16:41:29 +00:00
|
|
|
'<a href="%s">View Comic</a>' % url,
|
|
|
|
util.rfc822date(time.time())
|
2012-06-20 19:58:13 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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 = {
|
|
|
|
'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
|
|
|
|
2012-10-12 20:07:50 +00:00
|
|
|
_handler = EventHandler(".", None)
|
|
|
|
|
|
|
|
def installHandler(name, basepath=None, baseurl=None):
|
2012-09-26 14:47:39 +00:00
|
|
|
"""Install a global handler with given name."""
|
2012-10-12 20:07:50 +00:00
|
|
|
global _handler
|
2012-06-20 19:58:13 +00:00
|
|
|
if basepath is None:
|
|
|
|
basepath = '.'
|
2012-10-12 20:07:50 +00:00
|
|
|
_handler = handlers[name](basepath, baseurl)
|
2012-06-20 19:58:13 +00:00
|
|
|
|
2012-10-12 20:07:50 +00:00
|
|
|
def getHandler():
|
2012-12-12 16:41:29 +00:00
|
|
|
"""Get installed event handler."""
|
2012-10-12 20:07:50 +00:00
|
|
|
return _handler
|