[38ba34]: / Body / AAUHuman / BodyModels / GenericBodyModel / ammr-checks.py

Download this file

164 lines (127 with data), 4.4 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import os
import json
import logging
import hashlib
import inspect
import functools
from contextlib import contextmanager
from glob import iglob
from pathlib import Path
import dataclasses
from typing import Tuple
import functools
def create_logger(filename):
"""
Creates a logging object and returns it
"""
logger = logging.getLogger("ams_python_logger")
logger.setLevel(logging.INFO)
# create the logging file handler
fh = logging.FileHandler(filename)
fmt = "\n%(asctime)s - %(name)s - %(levelname)s - %(message)s"
formatter = logging.Formatter(fmt)
fh.setFormatter(formatter)
logger.handlers = []
# add handler to logger object
logger.addHandler(fh)
return logger
# logger = create_logger(Path(__file__).with_suffix(".log"))
def log_exception(logger):
"""
A decorator that wraps the passed in function and logs
exceptions should one occur
@param logger: The logging object
"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except:
logger.exception(f"There was an exception in {func.__name__}")
raise
return wrapper
return decorator
@dataclasses.dataclass(frozen=True)
class AMSContext:
""" Helper class for easy acces to members in the context variable """
py_file: str
fun_name: str
anyfun_full_name: str
anyfunex_file: str
anyfunex_line: int
call_location_file: str
def __iter__(self):
yield from dataclasses.astuple(self)
def save_arguments(func):
""" Helper decorator for saving arguments from for later debugging"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
global __name__
if __name__ == "__main__":
# Disable save not called externally.
return func(*args, **kwargs)
curent_file = Path(__file__)
filename = curent_file.parent / f"{curent_file.stem}_{func.__name__}.json"
with open(filename, "w+") as fh:
fh.write(json.dumps({"args": args, "cwd": os.getcwd()}, indent=4))
return func(*args, **kwargs)
return wrapper
@contextmanager
def debug_context(fun):
context_file = Path(__file__).parent / f"{Path(__file__).stem}_{fun.__name__}.json"
if not context_file.exists():
raise FileNotFoundError("No file saved data for debugging")
with open(context_file, "r+") as fh:
data = json.load(fh)
olddir = Path.cwd()
os.chdir(data["cwd"])
yield data["args"]
os.chdir(olddir)
# @log_exception(logger)
# @save_arguments
def is_file_writeable(context, fpath):
""" Check if fpath is a writeable file """
is_writeable = True
try:
with open(fpath, "r+"):
pass
except PermissionError:
is_writeable = False
finally:
return is_writeable
def endswith(context, string: str, arg: str):
return int(string.endswith(arg))
# @save_arguments
def hash_directory(context, dirpath, subsearch="**/*.any"):
""" Compute an md5 hash of all files matching a `subsearch` globbing expression
defaults is recursive search for anyscript files (**/*.any").
"""
hashval = ""
try:
digest = hashlib.md5()
dirpath = Path(dirpath)
for fpath in sorted(dirpath.glob(subsearch)):
# Hash relative path of file. To handle empty files and renames
digest.update(
hashlib.md5(
str(fpath.relative_to(dirpath)).upper().encode("utf-8")
).digest()
)
with open(fpath, "rb") as fh:
while True:
buf = fh.read(2 ** 16)
if not buf:
break
digest.update(buf)
hashval = digest.hexdigest()
except Exception:
# Errors must not prevent AnyBody from loading.
hashval = ""
finally:
return hashval
if __name__ == "__main__":
with debug_context(hash_directory) as args:
print(AMSContext(*args[0]))
hashcode = hash_directory(*args)
print(hashcode)