Files
DeletedPosts/Bot/jsonwrapper/autosavedict.py

121 lines
3.4 KiB
Python
Raw Normal View History

2026-02-23 22:48:25 +00:00
from __future__ import annotations
import os
import json
from typing import (
Any,
Dict,
Tuple,
Mapping,
Optional,
Iterable,
MutableMapping,
)
__all__ = (
'AutoSaveDict',
)
class AutoSaveDict(dict[Any, Any]):
def __init__(self,
file_path: Optional[os.PathLike[Any]] = None,
**pairs: Any):
self.file_path = file_path
self.__default = pairs
if self.file_path is None:
self._pairs = pairs
elif not os.path.exists(self.file_path):
self._pairs = pairs
else:
self._pairs = self._read()
super(AutoSaveDict, self).__init__(**self._pairs)
def __setitem__(self, __key: Any, __value: Any) -> None:
data = self._read()
data[__key] = __value
self._write(data)
super().__setitem__(__key, __value)
def __delitem__(self, __key: Any) -> None:
data = self._read()
del data[__key]
self._write(data)
return super().__delitem__(__key)
def __or__(self, __value: Mapping[Any, Any]) -> AutoSaveDict:
data = self._pairs | __value
return AutoSaveDict(None, **data)
def _write(self, content: Dict[Any, Any]) -> None:
with open(self.file_path, mode='w') as f: # type: ignore
json.dump(content, f, indent=4)
self._pairs = content
def _read(self) -> Dict[Any, Any]:
with open(self.file_path, mode='r') as f: # type: ignore
data: Dict[Any, Any] = json.load(f)
return data
@classmethod
def fromkeys(cls, __iterable: Iterable[Any], __value: Any = None,
file_path: Optional[os.PathLike[Any]] = None) -> AutoSaveDict:
data = {}
for key in __iterable:
data[key] = __value
return cls(file_path, **data)
@classmethod
def frommapping(cls, __mapping: Mapping[Any, Any],
file_path: Optional[os.PathLike[Any]] = None)\
-> AutoSaveDict:
data = dict(__mapping)
return cls(file_path, **data)
@classmethod
def fromfile(cls, src: os.PathLike[Any],
dst: Optional[os.PathLike[Any]] = None) -> AutoSaveDict:
with open(src, mode='r') as f:
data = json.load(f)
return AutoSaveDict(dst, **data)
def init(self) -> None:
if not os.path.exists(self.file_path): # type: ignore
self._write(self._pairs)
else:
self._pairs = self._read()
def restore(self) -> None:
self.clear()
self.update(self.__default)
self.init()
def copy(self,
file_path: Optional[os.PathLike[Any]] = None) -> AutoSaveDict:
data = {}
for key, val in self.items():
data[key] = val
return AutoSaveDict(file_path, **data)
def pop(self, __key: Any) -> Any: # type: ignore
data = self._read()
data.pop(__key)
self._write(data)
return super().pop(__key)
def popitem(self) -> Tuple[Any, Any]:
key = tuple(self._read().keys())[-1]
value = self.pop(key)
super().popitem()
return (key, value)
def clear(self) -> None:
self._write({})
super().clear()
def update(self, __m: Mapping[Any, Any]) -> MutableMapping: # type: ignore
for k, v in __m.items():
self[k] = v
super().update(__m)