diff -r 9c7769850195 -r 6db2527b67cf log_formatter.py
--- a/log_formatter.py Sun Sep 13 00:49:55 2009 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-"""
- Format LogLines into some other representation
-"""
-
-import re, xml.sax.saxutils
-
-from log_line import LogTypes
-from log_formatter_pil import PILImageFormatter
-from log_formatter_rss import RSSFormatter
-
-class LogFormatter (object) :
- """
- Provides a method to format series of LogLines into various output formats, with varying themes.
- """
-
- # machine-readable name
- name = None
-
- # human-readable name
- title = None
-
- ## parameters
- # use a fixed-width font for HTML output
- html_fixedwidth = True
-
- def __init__ (self, tz, timestamp_fmt, img_ttf_path, img_font_size) :
- """
- Initialize to format timestamps with the given timezone and timestamp.
-
- Use the given TTF font to render image text with the given size, if given, otherwise, a default one.
- """
-
- # store
- self.tz = tz
- self.timestamp_fmt = timestamp_fmt
- self.img_ttf_path = img_ttf_path
- self.img_font_size = img_font_size
-
- # XXX: harcoded
- self.date_fmt = '%Y-%m-%d'
-
- def _format_line_text (self, line, template_dict, type=None, full_timestamp=False, **extra) :
- """
- Format the given line as text, using the given { type: string template } dict.
-
- If type is given, then it overrides line.type
-
- Any additional keyword args will also be available for the template to use
- """
-
- # default type?
- if type is None :
- type = line.type
-
- # look up the template
- if type in template_dict :
- template = template_dict[type]
-
- else :
- raise Exception("Format template not defined for type: %s" % LogTypes.name_from_code(type))
-
- # convert timestamp into display timezone
- dtz = line.timestamp.astimezone(self.tz)
-
- # full timestamps?
- if full_timestamp :
- # XXX: let the user define a 'datetime' format instead?
- timestamp_fmt = self.date_fmt + ' ' + self.timestamp_fmt
-
- else :
- timestamp_fmt = self.timestamp_fmt
-
- # breakdown source
- source_nickname, source_username, source_hostname, source_chanflag = line.source
- target_nickname = line.target
-
- # format with dict
- return template % dict(
- channel_name = line.channel.name,
- datetime = dtz.strftime('%a %b %d %H:%M:%S %Y'),
- date = dtz.strftime(self.date_fmt),
- timestamp = dtz.strftime(timestamp_fmt),
- source_nickname = source_nickname,
- source_username = source_username,
- source_hostname = source_hostname,
- source_chanflag = source_chanflag,
- target_nickname = target_nickname,
- message = line.data,
- **extra
- )
-
- def format_txt (self, lines, full_timestamps=False) :
- """
- Format given lines as plaintext.
-
- If full_timestamps is given, the output will contain full timestamps with both date and time.
-
- No trailing newlines.
- """
-
- abstract
-
- def format_html (self, lines, full_timestamps=False) :
- """
- Format as HTML.
-
- See format_txt for information about arguments
- """
-
- abstract
-
- def format_png (self, lines, full_timestamps=False) :
- """
- Format as a PNG image, returning the binary PNG data
- """
-
- abstract
-
- def format_rss (self, lines, full_timestamps=False) :
- """
- Format as an XML RSS document
- """
-
- abstract
-
-class BaseHTMLFormatter (LogFormatter) :
- """
- Implements some HTML-formatting utils
- """
-
- # parameters
- html_fixedwidth = True
-
- # regexp to match URLs
- URL_REGEXP = re.compile(r"http://\S+")
-
- def _process_links (self, line) :
- """
- Processed the rendered line, adding in 's for things that look like URLs, returning the new line.
-
- The line should already be escaped
- """
-
- def _encode_url (match) :
- # encode URL
- url_html = match.group(0)
- url_link = xml.sax.saxutils.unescape(url_html)
-
- return '%(url_html)s' % dict(url_link=url_link, url_html=url_html)
-
- return self.URL_REGEXP.sub(_encode_url, line)
-
- def format_html (self, lines, **kwargs) :
- """
- Just uses format_txt, but processes links, etc
- """
-
- # format using IrssiTextFormatter
- for line, txt in self.format_txt(lines, **kwargs) :
- # escape HTML
- html = xml.sax.saxutils.escape(txt)
-
- # process links
- html = self._process_links(html)
-
- # yield
- yield line, html
-
-
-class IrssiTextFormatter (RSSFormatter, PILImageFormatter, LogFormatter) :
- """
- Implements format_txt for irssi-style output
- """
-
- # format definitions by type
- __FMT = {
- LogTypes.RAW : "%(timestamp)s %(data)s",
- LogTypes.LOG_OPEN : "--- Log opened %(datetime)s",
- LogTypes.LOG_CLOSE : "--- Log closed %(datetime)s",
- 'DAY_CHANGED' : "--- Day changed %(date)s",
-
- LogTypes.MSG : "%(timestamp)s <%(source_chanflag)s%(source_nickname)s> %(message)s",
- LogTypes.NOTICE : "%(timestamp)s -%(source_nickname)s- %(message)s",
- LogTypes.ACTION : "%(timestamp)s * %(source_nickname)s %(message)s",
-
- LogTypes.JOIN : "%(timestamp)s -!- %(source_nickname)s [%(source_username)s@%(source_hostname)s] has joined %(channel_name)s",
- LogTypes.PART : "%(timestamp)s -!- %(source_nickname)s [%(source_username)s@%(source_hostname)s] has left %(channel_name)s [%(message)s]",
- LogTypes.KICK : "%(timestamp)s -!- %(target_nickname)s was kicked from %(channel_name)s by %(source_nickname)s [%(message)s]",
- LogTypes.MODE : "%(timestamp)s -!- mode/%(channel_name)s [%(message)s] by %(source_nickname)s",
-
- LogTypes.NICK : "%(timestamp)s -!- %(source_nickname)s is now known as %(target_nickname)s",
- LogTypes.QUIT : "%(timestamp)s -!- %(source_nickname)s [%(source_username)s@%(source_hostname)s] has quit [%(message)s]",
-
- LogTypes.TOPIC : "%(timestamp)s -!- %(source_nickname)s changed the topic of %(channel_name)s to: %(message)s",
- 'TOPIC_UNSET' : "%(timestamp)s -!- Topic unset by %(source_nickname)s on %(channel_name)s",
-
- LogTypes.SELF_NOTICE: "%(timestamp)s -%(source_nickname)s- %(message)s",
- LogTypes.SELF_NICK : "%(timestamp)s -!- %(source_nickname)s is now known as %(target_nickname)s",
-
- LogTypes.NETSPLIT_START :
- "%(timestamp)s -!- Netsplit %(source_hostname)s <-> %(target_nickname)s quits: %(_netsplit_targets)s",
- LogTypes.NETSPLIT_END :
- "%(timestamp)s -!- Netsplit over, joins: %(_netsplit_targets)s",
- }
-
- def format_txt (self, lines, full_timestamps=False) :
- # ...handle each line
- for line in lines :
- # extra args
- extra = {}
-
- # default to line.type
- type = line.type
-
- # special formatting for unset-Topic
- if line.type == LogTypes.TOPIC and line.data is None :
- type = 'TOPIC_UNSET'
-
- # format netsplit stuff
- elif line.type & LogTypes._NETSPLIT_MASK :
- # format the netsplit-targets stuff
- extra['_netsplit_targets'] = line.data
-
- # using __TYPES
- yield line, self._format_line_text(line, self.__FMT, type, full_timestamps, **extra)
-
-class IrssiFormatter (BaseHTMLFormatter, IrssiTextFormatter) :
- """
- Implements plain black-and-white irssi-style formatting
- """
-
- # name
- name = 'irssi'
- title = "Irssi (plain)"
-
-class DebugFormatter (BaseHTMLFormatter) :
- """
- Implements a raw debug-style formatting of LogLines
- """
-
- # name
- name = 'debug'
- title = "Raw debugging format"
-
- def format_txt (self, lines, full_timestamps=False) :
- # iterate
- for line in lines :
- # just dump
- yield line, unicode(line)
-
-def by_name (name) :
- """
- Lookup and return a class LogFormatter by name
- """
-
- return FORMATTERS[name]
-