149 lines
4.6 KiB
Python
Executable File
149 lines
4.6 KiB
Python
Executable File
from xml.etree import ElementTree
|
|
from xml.dom import minidom
|
|
import re
|
|
import sys
|
|
import pathlib
|
|
import datetime
|
|
import pickle
|
|
import time
|
|
import os
|
|
|
|
def log(*args, **kwargs):
|
|
# make it so this goes to a file
|
|
print( " ".join(map(str,args)), **kwargs)
|
|
|
|
class Bunch(object):
|
|
def __init__(self, adict):
|
|
self.__dict__.update(adict)
|
|
|
|
def write_xml_file(filename, element):
|
|
"""write an element to an xml file"""
|
|
try:
|
|
xmlstr = ElementTree.tostring(element)
|
|
dom = minidom.parseString(xmlstr)
|
|
xmlstr = dom.toprettyxml()
|
|
with open(filename, "w") as outbug:
|
|
outbug.write(xmlstr)
|
|
except Exception:
|
|
log("invalid filename or xml.")
|
|
|
|
def print_xml(element):
|
|
"""print an xml element to the terminal"""
|
|
try:
|
|
xmlstr = ElementTree.tostring(element)
|
|
dom = minidom.parseString(xmlstr)
|
|
log(dom.toprettyxml())
|
|
except Exception:
|
|
log("invalid filename or xml.")
|
|
|
|
def sanatise_path(path):
|
|
return "".join([x for x in path if x not in "<>:\"|?*"])
|
|
|
|
def is_debugging():
|
|
"""Return if the debugger is currently active"""
|
|
gettrace = getattr(sys, 'gettrace', lambda : None)
|
|
return gettrace() is not None
|
|
|
|
def trywrap():
|
|
"""wrap function in a debugger friendly try block"""
|
|
def decorator(wrapped_function):
|
|
def wrapper(*args, **kwargs):
|
|
if not is_debugging():
|
|
try:
|
|
return wrapped_function(*args, **kwargs)
|
|
except Exception as e:
|
|
log("exception: "+str(repr(e)))
|
|
else:
|
|
return wrapped_function(*args, **kwargs)
|
|
return wrapper
|
|
return decorator
|
|
|
|
file_cache_hits = 0
|
|
file_cache_refresh = 0
|
|
file_cache_misses = 0
|
|
|
|
def file_cache(basedir, refresh=900):
|
|
"""wrap function in a file based cache"""
|
|
_basedir = str(pathlib.Path.home())
|
|
basedir = os.path.join(_basedir, basedir)
|
|
def decorator(wrapped_function):
|
|
def wrapper(*args):
|
|
global file_cache_hits
|
|
global file_cache_misses
|
|
global file_cache_refresh
|
|
filename = map(sanatise_path, map(str, args))
|
|
filename = map(lambda x: x.replace("//", ""), filename) # to deal with network drive paths, not sure it's a good thing.
|
|
filename = os.path.join(basedir, wrapped_function.__name__, *filename)
|
|
try:
|
|
filecache = pickle.load(open(filename, 'rb'))
|
|
file_cache_hits += 1
|
|
except Exception:
|
|
filecache = None
|
|
|
|
if not filecache:
|
|
file_cache_misses += 1
|
|
filecache = [wrapped_function(*args), time.time()]
|
|
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
|
if filecache[0]:
|
|
try:
|
|
pickle.dump(filecache, open(filename, 'wb'))
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
elif time.time() - filecache[1] > refresh and refresh != False:
|
|
file_cache_refresh += 1
|
|
filecache = [wrapped_function(*args), time.time()]
|
|
if filecache[0]:
|
|
try:
|
|
pickle.dump(filecache, open(filename, 'wb'))
|
|
except Exception:
|
|
pass
|
|
return filecache[0]
|
|
return wrapper
|
|
return decorator
|
|
|
|
|
|
def re_unescape(pattern):
|
|
unescape = re.compile(r'\\(.)')
|
|
return unescape.sub(r'\1', pattern)
|
|
|
|
def str_insert(line, ins, pos):
|
|
return ''.join(line[:pos]+ins+line[pos:])
|
|
|
|
|
|
def file_mtime(path):
|
|
t = datetime.datetime.fromtimestamp(os.stat(path).st_mtime,
|
|
datetime.timezone.utc)
|
|
return t.astimezone().isoformat()
|
|
|
|
def confirm_prompt(question, default=None):
|
|
answer = False
|
|
while(True):
|
|
try:
|
|
answer = input(question+" (y/n): ")
|
|
answer = answer.upper()
|
|
if (answer in ["YES", "Y"]):
|
|
answer = True
|
|
break
|
|
elif (answer in ["NO", "N"]):
|
|
answer = False
|
|
break
|
|
elif not answer and default is not None:
|
|
answer = default
|
|
break
|
|
except Exception:
|
|
break
|
|
return answer
|
|
|
|
def ip_to_user(address):
|
|
import socket
|
|
import ipaddress
|
|
user = ipaddress.ip_address(address)
|
|
try:
|
|
host = socket.gethostbyaddr(user.ipv4_mapped)
|
|
user = host[0].split(".")[0]
|
|
except Exception:
|
|
user = str(int(user))
|
|
return user
|