Skip to content

Instantly share code, notes, and snippets.

@RedBlaze42
Last active May 30, 2022 18:12
Show Gist options
  • Save RedBlaze42/6e22dae2cb5bb871167d861eae88dd79 to your computer and use it in GitHub Desktop.
Save RedBlaze42/6e22dae2cb5bb871167d861eae88dd79 to your computer and use it in GitHub Desktop.
My take on a locking json editor for config or state files
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