aa4b71f6d79fe3e6b8170d34d5f278d4977ac339
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
13from string import Template
14
15import logparse
16from . import interface, util, config
17
18import logging
19logger = logging.getLogger(__name__)
20
21locale.setlocale(locale.LC_ALL, '') # inherit system locale
22#DEG = "°".encode('unicode_escape')
23DEG = u'\N{DEGREE SIGN}'
24CEL = "C"
25TIMEFMT = "%X"
26DATEFMT = "%x"
27
28def init_varfilter():
29 global varfilter
30 global varpattern
31 global varsubst
32 varfilter = {"$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']))}
33 varfilter = dict((re.escape(k), v) for k, v in varfilter.items())
34 varpattern = re.compile("|".join(varfilter.keys()))
35 varsubst = dict(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'])))
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 = Template(open(template, 'r').read())
77 return headercontent.safe_substitute(varsubst)
78
79def orderbyfreq(l): # order a list by the frequency of its elements and remove duplicates
80 temp_l = l[:]
81 l = list(set(l))
82 l = [[i, temp_l.count(i)] for i in l] # add count of each element
83 l.sort(key=lambda x:temp_l.count(x[0])) # sort by count
84 l = [i[0] + ' (' + str(i[1]) + ')' for i in l] # put element and count into string
85 l = l[::-1] # reverse
86 return l
87
88def addtag(l, tag): # add prefix and suffix tags to each item in a list
89 l2 = ['<' + tag + '>' + i + '</' + tag + '>' for i in l]
90 return l2
91
92def truncl(input, limit): # truncate list
93 if (len(input) > limit):
94 more = str(len(input) - limit)
95 output = input[:limit]
96 output.append("+ " + more + " more")
97 return(output)
98 else:
99 return(input)
100
101def plural(noun, quantity): # return "1 noun" or "n nouns"
102 if (quantity == 1):
103 return(str(quantity) + " " + noun)
104 else:
105 return(str(quantity) + " " + noun + "s")
106
107def parsesize(num, suffix='B'): # return human-readable size from number of bytes
108 for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
109 if abs(num) < 1024.0:
110 return "%3.1f %s%s" % (num, unit, suffix)
111 num /= 1024.0
112 return "%.1f%s%s" % (num, 'Yi', suffix)
113
114def fsubject(template): # Replace variables in the title template provided in config
115 r = varpattern.sub(lambda m: varfilter[re.escape(m.group(0))], template)
116 logger.debug("Returning subject line " + r)
117 return r
118
119def writedata(subtitle, data = None): # write title and data
120 if (subtitle == ""):
121 logger.warning("No subtitle provided.. skipping section")
122 return
123
124 if (data == None or len(data) == 0):
125 logger.debug("No data provided.. just printing subtitle")
126 return tag('p', 0, subtitle)
127 else:
128 logger.debug("Received data " + str(data))
129 subtitle += ':'
130 if (len(data) == 1):
131 return tag('p', 0, subtitle + ' ' + data[0])
132 else:
133 output = ""
134 output += tag('p', 0, subtitle)
135 output += opentag('ul', 1)
136 for datum in data:
137 output += tag('li', 0, datum)
138 output += closetag('ul', 1)
139 return output
140