88 lines
2.6 KiB
Python
88 lines
2.6 KiB
Python
import json
|
|
import os
|
|
|
|
|
|
class PersistentDict(dict):
|
|
"""Extended dict that writes its content to a file every time a value is changed"""
|
|
|
|
def __init__(self, file_name, *args, **kwargs):
|
|
"""initialization of the dict and of the required files"""
|
|
super().__init__(*args, **kwargs)
|
|
|
|
self.path = file_name
|
|
self.last_action = ""
|
|
try:
|
|
self.read_dict()
|
|
except:
|
|
with open(self.path, "a") as f:
|
|
f.write("{}")
|
|
|
|
|
|
## helper - functions
|
|
def write_dict(self):
|
|
with open(self.path, "w") as f:
|
|
json.dump(self, f)
|
|
self.last_action = "w"
|
|
|
|
def read_dict(self):
|
|
with open(self.path) as f:
|
|
tmp = dict(json.load(f))
|
|
for key in tmp:
|
|
super().__setitem__(key, tmp[key])
|
|
self.last_action = "r"
|
|
|
|
|
|
## extended dictionary - logic
|
|
def __setitem__(self, key, value):
|
|
if self.last_action != "r":
|
|
self.read_dict()
|
|
# not sure if the step to read is necessary, but I'll keep it for safety
|
|
super().__setitem__(key,value)
|
|
self.write_dict() # writes 'self' to a json file.
|
|
|
|
def __getitem__(self, key):
|
|
if self.last_action != "r":
|
|
self.read_dict()
|
|
|
|
ret_val = super().__getitem__(key)
|
|
if type(ret_val) != int and type(ret_val) != str:
|
|
ret_val = create_struct(type(ret_val), key, self, ret_val)
|
|
|
|
return ret_val
|
|
|
|
def clear(self):
|
|
super().clear()
|
|
self.write_dict()
|
|
return {}
|
|
|
|
|
|
|
|
def create_struct(struct_type, own_name, parent_name, *args, **kwargs):
|
|
class HookedStruct(struct_type):
|
|
|
|
def __init__(self, own_name, parent_name, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.name = own_name
|
|
self.parent = parent_name
|
|
|
|
def __setitem__(self, *args, **kwargs):
|
|
super().__setitem__(*args, **kwargs)
|
|
self.parent.__setitem__(self.name, self)
|
|
|
|
def __getitem__(self, *args, **kwargs):
|
|
ret_val = super().__getitem__(*args, **kwargs)
|
|
if type(ret_val) != int and type(ret_val) != str:
|
|
ret_val = create_struct(type(ret_val), args[0], self, ret_val)
|
|
return ret_val
|
|
|
|
def pop(self, *args):
|
|
retvalue = super().pop(*args)
|
|
self.parent.__setitem__(self.name, self)
|
|
return retvalue
|
|
|
|
def append(self, *args):
|
|
super().append(*args)
|
|
self.parent.__setitem__(self.name, self)
|
|
print(*args)
|
|
return HookedStruct(own_name, parent_name, *args, **kwargs)
|