import string from json import dumps as json_dumps from json import loads as json_loads from random import choice from subprocess import Popen, PIPE from app.core.logger import make_log class ConfigFile: def __init__(self, filepath: str): self.filepath = filepath self.values @property def values(self): with open(self.filepath, 'r') as file: return json_loads(file.read()) assert isinstance(self.values, dict) def get(self, key, default=None): return self.values.get(key, default) def set(self, key, value): random_part = choice(string.ascii_lowercase) app_cached_values = self.values app_cached_values[key] = value with open(f"{'/'.join(self.filepath.split('/')[:-1])}/.backup_{self.filepath.split('/')[-1]}_{random_part}", 'w') as file: file.write( json_dumps( app_cached_values, indent=4, sort_keys=True ) ) with open(self.filepath, 'w') as file: file.write( json_dumps( app_cached_values, indent=4, sort_keys=True ) ) make_log("ConfigFile", f"Edited {key}", level="debug") p1 = Popen(["md5sum", self.filepath], stdout=PIPE, stderr=PIPE) p1.wait() out1, err1 = p1.communicate() p2 = Popen(["md5sum", f"{'/'.join(self.filepath.split('/')[:-1])}/.backup_{self.filepath.split('/')[-1]}_{random_part}"], stdout=PIPE, stderr=PIPE) p2.wait() out2, err2 = p2.communicate() if err1 or err2: make_log("ConfigFile", f"Error when editing {key} (check md5sum): {err1} {err2}", level="error") return self.set(key, value) fingerprint1 = out1.split()[0].strip() fingerprint2 = out2.split()[0].strip() if fingerprint1 != fingerprint2: make_log("ConfigFile", f"Error when editing {key} (check md5sum): {fingerprint1} {fingerprint2}", level="error") return self.set(key, value)