5350bb6f62705dce07540fe2792f4f53282257e6
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#
9
10import os
11import re
12import locale
13
14from .config import prefs
15#import util
16#import interface
17import logparse
18from . import interface, util
19
20import logging
21logger = logging.getLogger(__name__)
22
23locale.setlocale(locale.LC_ALL, '') # inherit system locale
24#DEG = "°".encode('unicode_escape')
25DEG = u'\N{DEGREE SIGN}'
26CEL = "C"
27TIMEFMT = "%X"
28DATEFMT = "%x"
29
30def init_varfilter():
31 global varfilter
32 global varpattern
33 varfilter = {"$title$": prefs['title'], "$date$": interface.start.strftime(DATEFMT),"$time$": interface.start.strftime(TIMEFMT), "$hostname$": util.hostname(prefs['hostname-path']), "$version$": logparse.__version__, "$css$": os.path.relpath(prefs['css'], os.path.dirname(prefs['output']))}
34 varfilter = dict((re.escape(k), v) for k, v in varfilter.items())
35 varpattern = re.compile("|".join(varfilter.keys()))
36
37def writetitle(title): # write title for a section
38 if (title == '' or '\n' in title):
39 logger.error("Invalid title")
40 raise ValueError
41 logger.debug("Writing title for " + title)
42 return tag('h2', 0, title)
43
44def opentag(tag, block = 0, id = None, cl = None): # write html opening tag
45 output = ""
46 if (block):
47 output += '\n'
48 output += '<' + tag
49 if (id != None):
50 output += " id='" + id + "'"
51 if (cl != None):
52 output += " class='" + cl + "'"
53 output += '>'
54 if (block):
55 output += '\n'
56 return output
57
58def closetag(tag, block = 0): # write html closing tag
59 if (block == 0):
60 return "</" + tag + ">"
61 else:
62 return "\n</" + tag + ">\n"
63
64def tag(tag, block = 0, content = ""): # write html opening tag, content, and html closing tag
65 o = opentag(tag, block)
66 c = closetag(tag, block)
67 return o + content + c
68
69def header(template): # return a parsed html header from file
70# try:
71# copyfile(config['css'], config['dest'] + '/' + os.path.basename(config['css']))
72# logger.debug("copied main.css")
73# except Exception as e:
74# logger.warning("could not copy main.css - " + str(e))
75 init_varfilter()
76 headercontent = open(template, 'r').read()
77 headercontent = varpattern.sub(lambda m: varfilter[re.escape(m.group(0))], headercontent)
78 return headercontent
79
80def orderbyfreq(l): # order a list by the frequency of its elements and remove duplicates
81 temp_l = l[:]
82 l = list(set(l))
83 l = [[i, temp_l.count(i)] for i in l] # add count of each element
84 l.sort(key=lambda x:temp_l.count(x[0])) # sort by count
85 l = [i[0] + ' (' + str(i[1]) + ')' for i in l] # put element and count into string
86 l = l[::-1] # reverse
87 return l
88
89def addtag(l, tag): # add prefix and suffix tags to each item in a list
90 l2 = ['<' + tag + '>' + i + '</' + tag + '>' for i in l]
91 return l2
92
93def truncl(input, limit): # truncate list
94 if (len(input) > limit):
95 more = str(len(input) - limit)
96 output = input[:limit]
97 output.append("+ " + more + " more")
98 return(output)
99 else:
100 return(input)
101
102def plural(noun, quantity): # return "1 noun" or "n nouns"
103 if (quantity == 1):
104 return(str(quantity) + " " + noun)
105 else:
106 return(str(quantity) + " " + noun + "s")
107
108def parsesize(num, suffix='B'): # return human-readable size from number of bytes
109 for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
110 if abs(num) < 1024.0:
111 return "%3.1f %s%s" % (num, unit, suffix)
112 num /= 1024.0
113 return "%.1f%s%s" % (num, 'Yi', suffix)
114
115def fsubject(template): # Replace variables in the title template provided in config
116 r = varpattern.sub(lambda m: varfilter[re.escape(m.group(0))], template)
117 logger.debug("Returning subject line " + r)
118 return r
119
120def writedata(subtitle, data = None): # write title and data
121 if (subtitle == ""):
122 logger.warning("No subtitle provided.. skipping section")
123 return
124
125 if (data == None or len(data) == 0):
126 logger.debug("No data provided.. just printing subtitle")
127 return tag('p', 0, subtitle)
128 else:
129 logger.debug("Received data " + str(data))
130 subtitle += ':'
131 if (len(data) == 1):
132 return tag('p', 0, subtitle + ' ' + data[0])
133 else:
134 output = ""
135 output += tag('p', 0, subtitle)
136 output += opentag('ul', 1)
137 for datum in data:
138 output += tag('li', 0, datum)
139 output += closetag('ul', 1)
140 return output
141