mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 17:24:32 +02:00
authentication and locking improvements
This commit is contained in:
+45
-27
@@ -181,51 +181,69 @@ def temp_disable_extensions():
|
||||
return disabled
|
||||
|
||||
|
||||
def readfile(filename, silent=False):
|
||||
def readfile(filename, silent=False, lock=False):
|
||||
data = {}
|
||||
lock_file = None
|
||||
locked = False
|
||||
try:
|
||||
if not os.path.exists(filename):
|
||||
return {}
|
||||
with fasteners.InterProcessLock(f"{filename}.lock"):
|
||||
with open(filename, "r", encoding="utf8") as file:
|
||||
data = json.load(file)
|
||||
if type(data) is str:
|
||||
data = json.loads(data)
|
||||
if not silent:
|
||||
log.debug(f'Read: file="{filename}" len={len(data)}')
|
||||
if lock:
|
||||
lock_file = fasteners.InterProcessReaderWriterLock(f"{filename}.lock", logger=log)
|
||||
locked = lock_file.acquire_read_lock(blocking=True, timeout=3)
|
||||
with open(filename, "r", encoding="utf8") as file:
|
||||
data = json.load(file)
|
||||
if type(data) is str:
|
||||
data = json.loads(data)
|
||||
if not silent:
|
||||
log.debug(f'Read: file="{filename}" json={len(data)} bytes={os.path.getsize(filename)}')
|
||||
except Exception as e:
|
||||
if not silent:
|
||||
log.error(f'Reading failed: {filename} {e}')
|
||||
return {}
|
||||
finally:
|
||||
if lock_file is not None:
|
||||
lock_file.release_read_lock()
|
||||
if locked and os.path.exists(f"{filename}.lock"):
|
||||
os.remove(f"{filename}.lock")
|
||||
return data
|
||||
|
||||
|
||||
def writefile(data, filename, mode='w', silent=False):
|
||||
lock = None
|
||||
locked = False
|
||||
|
||||
def default(obj):
|
||||
log.error(f"Saving: {filename} not a valid object: {obj}")
|
||||
return str(obj)
|
||||
|
||||
try:
|
||||
with fasteners.InterProcessLock(f"{filename}.lock"):
|
||||
# skipkeys=True, ensure_ascii=True, check_circular=True, allow_nan=True
|
||||
if type(data) == dict:
|
||||
output = json.dumps(data, indent=2, default=default)
|
||||
elif type(data) == list:
|
||||
output = json.dumps(data, indent=2, default=default)
|
||||
elif isinstance(data, object):
|
||||
simple = {}
|
||||
for k in data.__dict__:
|
||||
if data.__dict__[k] is not None:
|
||||
simple[k] = data.__dict__[k]
|
||||
output = json.dumps(simple, indent=2, default=default)
|
||||
else:
|
||||
raise ValueError('not a valid object')
|
||||
if not silent:
|
||||
log.debug(f'Save: file="{filename}" len={len(output)}')
|
||||
with open(filename, mode, encoding="utf8") as file:
|
||||
file.write(output)
|
||||
# skipkeys=True, ensure_ascii=True, check_circular=True, allow_nan=True
|
||||
if type(data) == dict:
|
||||
output = json.dumps(data, indent=2, default=default)
|
||||
elif type(data) == list:
|
||||
output = json.dumps(data, indent=2, default=default)
|
||||
elif isinstance(data, object):
|
||||
simple = {}
|
||||
for k in data.__dict__:
|
||||
if data.__dict__[k] is not None:
|
||||
simple[k] = data.__dict__[k]
|
||||
output = json.dumps(simple, indent=2, default=default)
|
||||
else:
|
||||
raise ValueError('not a valid object')
|
||||
lock = fasteners.InterProcessReaderWriterLock(f"{filename}.lock", logger=log)
|
||||
locked = lock.acquire_write_lock(blocking=True, timeout=3)
|
||||
with open(filename, mode, encoding="utf8") as file:
|
||||
file.write(output)
|
||||
if not silent:
|
||||
log.debug(f'Save: file="{filename}" json={len(data)} bytes={len(output)}')
|
||||
except Exception as e:
|
||||
log.error(f'Saving failed: {filename} {e}')
|
||||
finally:
|
||||
if lock is not None:
|
||||
lock.release_read_lock()
|
||||
if locked and os.path.exists(f"{filename}.lock"):
|
||||
os.remove(f"{filename}.lock")
|
||||
|
||||
|
||||
if devices.backend == "cpu":
|
||||
@@ -699,7 +717,7 @@ class Options:
|
||||
log.debug(f'Created default config: {filename}')
|
||||
self.save(filename)
|
||||
return
|
||||
self.data = readfile(filename)
|
||||
self.data = readfile(filename, lock=True)
|
||||
if self.data.get('quicksettings') is not None and self.data.get('quicksettings_list') is None:
|
||||
self.data['quicksettings_list'] = [i.strip() for i in self.data.get('quicksettings').split(',')]
|
||||
unknown_settings = []
|
||||
|
||||
Reference in New Issue
Block a user