#!/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, """\ %(title)s """ % {'VERSION': VERSION, 'RELEASE': RELEASE, 'title': escape(title), 'charset': 'UTF-8'} print >> outfile, '

%s

' % escape(title) print >> outfile, '' print >> outfile, """

Generated by logs2html.py %(VERSION)s by Mariu s Gedminas - find it at mg.pov.lt!

""" % {'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()