logparse / formatting.pyon commit fix bugs in interface & module loading (b34181e)
   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
  14#import util
  15#import interface
  16import logparse
  17from . import interface, util, config
  18
  19import logging
  20logger = logging.getLogger(__name__)
  21
  22locale.setlocale(locale.LC_ALL, '') # inherit system locale
  23#DEG = "°".encode('unicode_escape')
  24DEG = u'\N{DEGREE SIGN}'
  25CEL = "C"
  26TIMEFMT = "%X"
  27DATEFMT = "%x"
  28
  29def init_varfilter():
  30    global varfilter
  31    global varpattern
  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
  36def writetitle(title):  # write title for a section
  37    if (title == '' or '\n' in title):
  38        logger.error("Invalid title")
  39        raise ValueError 
  40    logger.debug("Writing title for " + title)
  41    return tag('h2', 0, title)
  42
  43def opentag(tag, block = 0, id = None, cl = None):   # write html opening tag
  44    output = ""
  45    if (block):
  46        output += '\n'
  47    output += '<' + tag
  48    if (id != None):
  49        output += " id='" + id + "'"
  50    if (cl != None):
  51        output += " class='" + cl + "'"
  52    output += '>'
  53    if (block):
  54        output += '\n'
  55    return output
  56
  57def closetag(tag, block = 0):  # write html closing tag
  58    if (block == 0):
  59        return "</" + tag + ">"
  60    else:
  61        return "\n</" + tag + ">\n"
  62
  63def tag(tag, block = 0, content = ""):  # write html opening tag, content, and html closing tag
  64    o = opentag(tag, block)
  65    c = closetag(tag, block)
  66    return o + content + c
  67
  68def 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))
  74    init_varfilter()
  75    headercontent = open(template, 'r').read()
  76    headercontent = varpattern.sub(lambda m: varfilter[re.escape(m.group(0))], headercontent)
  77    return headercontent
  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