Files
gtav-src/tools_ng/script/gen9/rsgdnd/utils.py
T
2025-09-29 00:52:08 +02:00

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