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 28definit_varfilter(): 29global varfilter 30global varpattern 31global 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 37defwritetitle(title):# write title for a section 38if(title ==''or'\n'in title): 39 logger.error("Invalid title") 40raiseValueError 41 logger.debug("Writing title for "+ title) 42returntag('h2',0, title) 43 44defopentag(tag, block =0,id=None, cl =None):# write html opening tag 45 output ="" 46if(block): 47 output +='\n' 48 output +='<'+ tag 49if(id!=None): 50 output +=" id='"+id+"'" 51if(cl !=None): 52 output +=" class='"+ cl +"'" 53 output +='>' 54if(block): 55 output +='\n' 56return output 57 58defclosetag(tag, block =0):# write html closing tag 59if(block ==0): 60return"</"+ tag +">" 61else: 62return"\n</"+ tag +">\n" 63 64deftag(tag, block =0, content =""):# write html opening tag, content, and html closing tag 65 o =opentag(tag, block) 66 c =closetag(tag, block) 67return o + content + c 68 69defheader(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)) 75init_varfilter() 76 headercontent =Template(open(template,'r').read()) 77return headercontent.safe_substitute(varsubst) 78 79deforderbyfreq(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 86return l 87 88defaddtag(l, tag):# add prefix and suffix tags to each item in a list 89 l2 = ['<'+ tag +'>'+ i +'</'+ tag +'>'for i in l] 90return l2 91 92deftruncl(input, limit):# truncate list 93if(len(input) > limit): 94 more =str(len(input) - limit) 95 output =input[:limit] 96 output.append("+ "+ more +" more") 97return(output) 98else: 99return(input) 100 101defplural(noun, quantity):# return "1 noun" or "n nouns" 102if(quantity ==1): 103return(str(quantity) +" "+ noun) 104else: 105return(str(quantity) +" "+ noun +"s") 106 107defparsesize(num, suffix='B'):# return human-readable size from number of bytes 108for unit in['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']: 109ifabs(num) <1024.0: 110return"%3.1f%s%s"% (num, unit, suffix) 111 num /=1024.0 112return"%.1f%s%s"% (num,'Yi', suffix) 113 114deffsubject(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) 117return r 118 119defwritedata(subtitle, data =None):# write title and data 120if(subtitle ==""): 121 logger.warning("No subtitle provided.. skipping section") 122return 123 124if(data ==None orlen(data) ==0): 125 logger.debug("No data provided.. just printing subtitle") 126returntag('p',0, subtitle) 127else: 128 logger.debug("Received data "+str(data)) 129 subtitle +=':' 130if(len(data) ==1): 131returntag('p',0, subtitle +' '+ data[0]) 132else: 133 output ="" 134 output +=tag('p',0, subtitle) 135 output +=opentag('ul',1) 136for datum in data: 137 output +=tag('li',0, datum) 138 output +=closetag('ul',1) 139return output 140