import json import os from pathlib import Path from typing import List, Dict, Any, Optional from libs.app.common.paths import FILES_DIR class DataStore: def __init__(self, path: str = "data/data.json", default_data:Optional[Dict[str, List[Any]]] = None, autosave:bool = True): if default_data is None: default_data = {"data": []} if not os.path.isabs(path): path = os.path.normpath(os.path.join(FILES_DIR, path)) self.file_path = Path(path) self.default_data = default_data self.data = default_data.copy() self.autosave = autosave self.load() def load(self): if self.file_path.exists(): with open(self.file_path, "r", encoding="utf-8") as f: self.data = json.load(f) else: os.makedirs(self.file_path.parent, exist_ok=True) self._save() def save(self): with open(self.file_path, "w", encoding="utf-8") as f: json.dump(self.data, f, indent=2) def _save(self): if not self.autosave: return self.save() def clear(self): self.data = self.default_data.copy() self._save() def add_item(self, parent:str, data: Dict[str, Any], unique: bool = False, id_field:Optional[str]=None, id: Optional[str]=None): if unique and id and id_field: if any(item.get(id_field) == id for item in self.data.get(parent, [])): raise ValueError(f"Item already exists in {parent}. {id_field}:{id}") self.data.setdefault(parent, []).append(data) self._save() def get_item(self, parent:str, id_field:str, id:str) -> Optional[Dict[str, Any]]: for item in self.data.get(parent, []): if item.get(id_field) == id: return item return None def update_item(self, parent: str, id_field: str, id: str, updates: Dict[str, Any]) -> bool: for item in self.data.get(parent, []): if item.get(id_field) == id: item.update(updates) self._save() return True return False def remove_item(self, parent:str, id_field:str, id:str) -> bool: items = self.data.get(parent, []) new_items = [item for item in items if item.get(id_field) != id] if len(new_items) != len(items): self.data[parent] = new_items self._save() return True return False def list_items(self, parent:str) -> List[Dict[str, Any]]: return self.data.get(parent, [])