Implement a more robust JSON save-load cycle
This commit is contained in:
1 parent
988889c82e
commit
184abe2cbf
2 files changed
+23
-9
No files matched your search
@@ -9,6 +9,7 @@ __pycache__
|
|||||||
/*.tmp
|
/*.tmp
|
||||||
/Twitch Drops Miner
|
/Twitch Drops Miner
|
||||||
# Dev files
|
# Dev files
|
||||||
|
*.new
|
||||||
/env
|
/env
|
||||||
/cache
|
/cache
|
||||||
/*.jar
|
/*.jar
|
||||||
|
|||||||
@@ -242,20 +242,33 @@ def merge_json(obj: JsonType, template: Mapping[Any, Any]) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def json_load(path: Path, defaults: _JSON_T, *, merge: bool = True) -> _JSON_T:
|
def json_load(path: Path, defaults: _JSON_T, *, merge: bool = True) -> _JSON_T:
|
||||||
defaults_dict: JsonType = dict(defaults)
|
new_path: Path = path.with_name(f"{path.name}.new")
|
||||||
if path.exists():
|
combined: JsonType | None = None
|
||||||
with open(path, 'r', encoding="utf8") as file:
|
# try new file first
|
||||||
combined: JsonType = _remove_missing(json.load(file, object_hook=_deserialize))
|
if new_path.exists():
|
||||||
if merge:
|
try:
|
||||||
merge_json(combined, defaults_dict)
|
with new_path.open('r', encoding="utf8") as file:
|
||||||
else:
|
combined = _remove_missing(json.load(file, object_hook=_deserialize))
|
||||||
combined = defaults_dict
|
except json.JSONDecodeError:
|
||||||
|
# remove invalid file
|
||||||
|
new_path.unlink()
|
||||||
|
# try the old file
|
||||||
|
if combined is None and path.exists():
|
||||||
|
with path.open('r', encoding="utf8") as file:
|
||||||
|
combined = _remove_missing(json.load(file, object_hook=_deserialize))
|
||||||
|
# handle defaults and merging
|
||||||
|
if combined is None:
|
||||||
|
combined = dict(defaults) # always make a copy of defaults
|
||||||
|
elif merge:
|
||||||
|
merge_json(combined, dict(defaults))
|
||||||
return cast(_JSON_T, combined)
|
return cast(_JSON_T, combined)
|
||||||
|
|
||||||
|
|
||||||
def json_save(path: Path, contents: Mapping[Any, Any], *, sort: bool = False) -> None:
|
def json_save(path: Path, contents: Mapping[Any, Any], *, sort: bool = False) -> None:
|
||||||
with open(path, 'w', encoding="utf8") as file:
|
new_path: Path = path.with_name(f"{path.name}.new")
|
||||||
|
with new_path.open('w', encoding="utf8") as file:
|
||||||
json.dump(contents, file, default=_serialize, sort_keys=sort, indent=4)
|
json.dump(contents, file, default=_serialize, sort_keys=sort, indent=4)
|
||||||
|
new_path.replace(path)
|
||||||
|
|
||||||
|
|
||||||
def webopen(url: URL | str):
|
def webopen(url: URL | str):
|
||||||
|
|||||||
Reference in new issue
Block a user