1#
2# format.py
3#
4# This file contains global functions for formatting and printing data. This
5# file should be imported into individual log-parsing scripts located in
6# logs/*. Data is all formatted in HTML. Writing to disk and/or emailng data
7# is left to __main__.py.
8#
910
import os
11import re
12import locale
1314
#import util
15#import interface
16import logparse
17from . import interface, util, config
1819
import logging
20logger = logging.getLogger(__name__)
2122
locale.setlocale(locale.LC_ALL, '') # inherit system locale
23#DEG = "°".encode('unicode_escape')
24DEG = u'\N{DEGREE SIGN}'
25CEL = "C"
26TIMEFMT = "%X"
27DATEFMT = "%x"
2829
def init_varfilter():
30global varfilter
31global varpattern
32varfilter = {"$title$": config.prefs['title'], "$date$": interface.start.strftime(DATEFMT),"$time$": interface.start.strftime(TIMEFMT), "$hostname$": util.hostname(config.prefs['hostname-path']), "$version$": logparse.__version__, "$css$": os.path.relpath(config.prefs['css'], os.path.dirname(config.prefs['output']))}
33varfilter = dict((re.escape(k), v) for k, v in varfilter.items())
34varpattern = re.compile("|".join(varfilter.keys()))
3536
def writetitle(title): # write title for a section
37if (title == '' or '\n' in title):
38logger.error("Invalid title")
39raise ValueError
40logger.debug("Writing title for " + title)
41return tag('h2', 0, title)
4243
def opentag(tag, block = 0, id = None, cl = None): # write html opening tag
44output = ""
45if (block):
46output += '\n'
47output += '<' + tag
48if (id != None):
49output += " id='" + id + "'"
50if (cl != None):
51output += " class='" + cl + "'"
52output += '>'
53if (block):
54output += '\n'
55return output
5657
def closetag(tag, block = 0): # write html closing tag
58if (block == 0):
59return "</" + tag + ">"
60else:
61return "\n</" + tag + ">\n"
6263
def tag(tag, block = 0, content = ""): # write html opening tag, content, and html closing tag
64o = opentag(tag, block)
65c = closetag(tag, block)
66return o + content + c
6768
def header(template): # return a parsed html header from file
69# try:
70# copyfile(config['css'], config['dest'] + '/' + os.path.basename(config['css']))
71# logger.debug("copied main.css")
72# except Exception as e:
73# logger.warning("could not copy main.css - " + str(e))
74init_varfilter()
75headercontent = open(template, 'r').read()
76headercontent = varpattern.sub(lambda m: varfilter[re.escape(m.group(0))], headercontent)
77return headercontent
7879
def orderbyfreq(l): # order a list by the frequency of its elements and remove duplicates
80temp_l = l[:]
81l = list(set(l))
82l = [[i, temp_l.count(i)] for i in l] # add count of each element
83l.sort(key=lambda x:temp_l.count(x[0])) # sort by count
84l = [i[0] + ' (' + str(i[1]) + ')' for i in l] # put element and count into string
85l = l[::-1] # reverse
86return l
8788
def addtag(l, tag): # add prefix and suffix tags to each item in a list
89l2 = ['<' + tag + '>' + i + '</' + tag + '>' for i in l]
90return l2
9192
def truncl(input, limit): # truncate list
93if (len(input) > limit):
94more = str(len(input) - limit)
95output = input[:limit]
96output.append("+ " + more + " more")
97return(output)
98else:
99return(input)
100101
def plural(noun, quantity): # return "1 noun" or "n nouns"
102if (quantity == 1):
103return(str(quantity) + " " + noun)
104else:
105return(str(quantity) + " " + noun + "s")
106107
def parsesize(num, suffix='B'): # return human-readable size from number of bytes
108for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
109if abs(num) < 1024.0:
110return "%3.1f %s%s" % (num, unit, suffix)
111num /= 1024.0
112return "%.1f%s%s" % (num, 'Yi', suffix)
113114
def fsubject(template): # Replace variables in the title template provided in config
115r = varpattern.sub(lambda m: varfilter[re.escape(m.group(0))], template)
116logger.debug("Returning subject line " + r)
117return r
118119
def writedata(subtitle, data = None): # write title and data
120if (subtitle == ""):
121logger.warning("No subtitle provided.. skipping section")
122return
123124
if (data == None or len(data) == 0):
125logger.debug("No data provided.. just printing subtitle")
126return tag('p', 0, subtitle)
127else:
128logger.debug("Received data " + str(data))
129subtitle += ':'
130if (len(data) == 1):
131return tag('p', 0, subtitle + ' ' + data[0])
132else:
133output = ""
134output += tag('p', 0, subtitle)
135output += opentag('ul', 1)
136for datum in data:
137output += tag('li', 0, datum)
138output += closetag('ul', 1)
139return output
140