Last active
May 30, 2022 18:12
-
-
Save RedBlaze42/6e22dae2cb5bb871167d861eae88dd79 to your computer and use it in GitHub Desktop.
My take on a locking json editor for config or state files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class JsonConfig(): | |
def __init__(self, filepath): | |
self.last_timestamp_loaded = None | |
self.file = None | |
if not os.path.exists(filepath): | |
with open(filepath, "w") as f: json.dump({}, f) | |
print(filepath, os.path.exists(filepath)) | |
self.filepath = filepath | |
self.lockpath = f"{filepath}.lock" | |
self.storage = self.read() | |
def open(self): | |
if self.file is not None and not self.file.closed: return self.file | |
while True: | |
while os.path.exists(self.lockpath): | |
time.sleep(0.01) | |
try: | |
Path(self.lockpath).touch() | |
except FileExistsError: | |
continue | |
else: | |
break | |
if not os.path.exists(self.filepath): | |
with open(self.filepath, "w") as temp_file: | |
temp_file.write('{}') | |
self.file = open(self.filepath, "r+") | |
return self.file | |
def close(self): | |
self.file.close() | |
self.file = None | |
os.remove(self.lockpath) | |
def write(self, data = None): | |
if data is None: data = self.storage | |
if self.file is None: self.file = self.open() | |
self.file.seek(0) # Vérifie que le curseur est bien au début du fichier | |
self.file.truncate(0) # écrase le fichier | |
json.dump(data, self.file) | |
self.close() | |
return data | |
def read(self): | |
self.last_timestamp_loaded = os.path.getmtime(self.filepath) | |
self.storage = json.load(self.open()) | |
self.close() | |
return self.storage | |
@property | |
def is_open(self): | |
return self.file is not None and not self.file.closed | |
@property | |
def data(self): | |
if self.is_open: # Si le fichier est ouvert on renvoie les données stockées | |
return self.storage | |
elif self.last_timestamp_loaded == os.path.getmtime(self.filepath): # Si le fichier n'a pas été modifié depuis la dernière lecture, on renvoie les données stockées | |
return self.storage | |
else: # Sinon on lit le fichier | |
return self.read() | |
def __getitem__(self, key): | |
return self.data[key] | |
def __setitem__(self, key, value): | |
self.data[key] = value | |
def edit(self): #À utiliser un context manager | |
return JsonEditor(self) | |
class JsonEditor(): | |
def __init__(self, config): | |
self.config = config | |
def __enter__(self): | |
self.config.open() | |
self.config.storage = json.load(self.config.file) | |
def __exit__(self, exc_type, exc_value, trace): | |
self.config.write() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment