#!/usr/bin/env python
"""
Convert a directory with IRC logs to HTML.
Usage: logs2html.py pathname
Needs irclog2html.py. Produces an index page and a number of HTML-formatted
log files with navigational links.
Looks for *.log in a given directory. Needs an ISO 8601 date (YYYY-MM-DD) in
the filename.
"""
# Copyright (c) 2005, Marius Gedminas
#
# Released under the terms of the GNU GPL
# http://www.gnu.org/copyleft/gpl.html
import os
import re
import sys
import glob
import urllib
import datetime
import optparse
import irclog2html
VERSION = "0.1"
RELEASE = "2005-01-09"
DATE_REGEXP = re.compile('^.*(\d\d\d\d)-(\d\d)-(\d\d)')
class LogFile:
"""IRC log file."""
def __init__(self, filename):
self.filename = filename
basename = os.path.basename(filename)
m = DATE_REGEXP.match(basename)
self.date = datetime.date(*map(int, m.groups()))
self.link = basename + ".html"
self.title = self.date.strftime('%Y-%m-%d (%A)')
def newfile(self):
"""Check whether the log file is new.
The log file is new iff the corresponding html file does not exist
or was just generated by self.generate. This implies that navigation
links for the previous/next file need to be updated.
"""
if not hasattr(self, '_newfile'):
# Only do this once, so that self.generate() does not change
# newness
self._newfile = not os.path.exists(self.filename + ".html")
return self._newfile
def uptodate(self):
"""Check whether the HTML version of the log is up to date."""
log_mtime = os.stat(self.filename).st_mtime
try:
html_mtime = os.stat(self.filename + ".html").st_mtime
except OSError:
return False
return html_mtime > log_mtime
def generate(self, style, title_prefix='', prev=None, next=None):
"""Generate HTML for this log file."""
self.newfile() # update newness flag and remember it
argv = ['irclog2html.py', '-s', style]
argv += ['-t', title_prefix + self.date.strftime('%A, %Y-%m-%d')]
if prev:
argv += ['--prev-url', prev.link,
'--prev-title',
'« ' + prev.date.strftime('%A, %Y-%m-%d')]
argv += ['--index-url=index.html', '--index-title=Index']
if next:
argv += ['--next-url', next.link,
'--next-title',
next.date.strftime('%A, %Y-%m-%d') + ' »']
argv += [self.filename]
irclog2html.main(argv)
def find_log_files(directory):
"""Find all IRC log files in a given directory.
Returns a sorted list of LogFile objects (oldest first).
"""
logfiles = []
for filename in glob.glob(os.path.join(directory, '*.log')):
logfiles.append((filename, LogFile(filename)))
logfiles.sort() # ISO 8601 dates sort the way we need them
return [log for filename, log in logfiles]
def escape(s):
"""Replace ampersands, pointies, control characters"""
s = s.replace('&', '&').replace('<', '<').replace('>', '>')
return ''.join([c for c in s if ord(c) > 0x1F])
def write_index(outfile, title, logfiles):
"""Write an index with links to all log files."""
print >> outfile, """\
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=%(charset)s" />
<title>%(title)s</title>
<link rel="stylesheet" href="irclog.css" />
<meta name="generator" content="logs2html.py %(VERSION)s by Marius Gedminas" /
>
<meta name="version" content="%(VERSION)s - %(RELEASE)s" />
</head>
<body>""" % {'VERSION': VERSION, 'RELEASE': RELEASE,
'title': escape(title), 'charset': 'UTF-8'}
print >> outfile, '<h1>%s</h1>' % escape(title)
print >> outfile, '<ul>'
for logfile in logfiles:
link = escape(urllib.quote(logfile.link))
title = escape(logfile.title)
print >> outfile, ('<li><a href="%s">%s</a></li>' % (link, title))
print >> outfile, '</ul>'
print >> outfile, """
<div class="generatedby">
<p>Generated by logs2html.py %(VERSION)s by <a href="mailto:marius@pov.lt">Mariu
s Gedminas</a>
- find it at <a href="http://mg.pov.lt/irclog2html/">mg.pov.lt</a>!</p>
</div>
</body>
</html>""" % {'VERSION': VERSION, 'RELEASE': RELEASE}
def main(argv=sys.argv):
progname = os.path.basename(argv[0])
parser = optparse.OptionParser("usage: %prog [options] directory",
prog=progname,
description="Colourises and converts all IRC"
" logs to HTML format for easy"
" web reading.")
parser.add_option('-s', '--style', dest="style", default="xhtmltable",
help="format log according to specific style"
" (default: xhtmltable); passes the style name"
" to irclog2html.py")
parser.add_option('-t', '--title', dest="title", default="IRC logs",
help="title of the index page (default: IRC logs)")
parser.add_option('-p', '--prefix', dest="prefix", default="",
help="prefix for page title (e.g.:"
" 'IRC logs of #channel for ')")
parser.add_option('-f', '--force', action="store_true", dest="force",
default=False,
help="ignore mtime and regenerate all files")
options, args = parser.parse_args(argv[1:])
if len(args) != 1:
parser.error("incorrect number of arguments")
dir = args[0]
logfiles = find_log_files(dir)
logfiles.reverse() # newest first
for n, logfile in enumerate(logfiles):
if n > 0:
next = logfiles[n - 1]
else:
next = None
if n + 1 < len(logfiles):
prev = logfiles[n + 1]
else:
prev = None
if (options.force or not logfile.uptodate()
or prev and prev.newfile() or next and next.newfile()):
logfile.generate(options.style, options.prefix, prev, next)
outfilename = os.path.join(dir, 'index.html')
try:
outfile = open(outfilename, 'w')
except IOError, e:
sys.exit("%s: cannot open %s for writing: %s"
% (progname, outfilename, e))
try:
write_index(outfile, options.title, logfiles)
finally:
outfile.close()
if __name__ == '__main__':
main()