"""
Format LogLines into some other representation
"""
import re, xml.sax.saxutils
from log_line import LogTypes
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="%H:%M:%S") :
"""
Initialize to format timestamps with the given timezone and timestamp
"""
self.tz = tz
self.timestamp_fmt = timestamp_fmt
def _format_line_text (self, line, template_dict, full_timestamp=False) :
"""
Format the given line as text, using the given { type: string template } dict
"""
# look up the template
template = template_dict[line.type]
# convert timestamp into display timezone
dtz = line.timestamp.astimezone(self.tz)
# full timestamps?
if full_timestamp :
# XXX: ugly
timestamp_fmt = '%Y-%m-%d ' + self.timestamp_fmt
else :
timestamp_fmt = self.timestamp_fmt
# build timestamp
timestamp = dtz.strftime(timestamp_fmt)
# format with dict
return template % dict(
timestamp = timestamp,
source = line.source,
data = line.data,
)
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
class BaseHTMLFormatter (object) :
"""
Implements some HTML-formatting utils
"""
URL_REGEXP = re.compile(r"http://\S+")
def _process_links (self, line) :
"""
Processed the rendered line, adding in <a href>'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 '<a href="%(url_link)s">%(url_html)s</a>' % dict(url_link=url_link, url_html=url_html)
return self.URL_REGEXP.sub(_encode_url, line)
class IrssiTextFormatter (LogFormatter) :
"""
Implements format_txt for irssi-style output
"""
# format definitions by type
__FMT = {
LogTypes.RAW : "%(timestamp)s %(data)s",
}
def format_txt (self, lines, full_timestamps=False) :
# ...handle each line
for line in lines :
# using __TYPES
yield line, self._format_line_text(line, self.__FMT, full_timestamps)
class IrssiFormatter (IrssiTextFormatter, BaseHTMLFormatter) :
"""
Implements plain black-and-white irssi-style formatting
"""
# name
name = 'irssi'
title = "Irssi (plain)"
# parameters
html_fixedwidth = True
def format_html (self, lines, full_timestamps=False) :
"""
Just uses format_txt, but processes links, etc
"""
# format using IrssiTextFormatter
for line, txt in self.format_txt(lines, full_timestamps) :
# escape HTML
html = xml.sax.saxutils.escape(txt)
# process links
html = self._process_links(html)
# yield
yield line, html
# define formatters by name
FORMATTERS = {
'irssi': IrssiFormatter,
}
def by_name (name) :
"""
Lookup and return a class LogFormatter by name
"""
return FORMATTERS[name]