David Prince
production: clean source snapshot — no history bloat
71b4454
Raw
History Blame Contribute Delete
1.71 kB
import json
from pathlib import Path
from typing import Any, Dict, Optional
from .models import CMSProject
class CMSManager:
def __init__(self, root: Optional[str] = None):
self.root = Path(
root or Path.cwd() / "storage" / "cms"
)
self.root.mkdir(parents=True, exist_ok=True)
def _path(self, project_id: str) -> Path:
safe = "".join(
c if c.isalnum() or c in "-_" else "_"
for c in project_id
)
if not safe:
raise ValueError("project_id is required")
return self.root / f"{safe}.json"
def get(self, project_id: str) -> Optional[Dict[str, Any]]:
path = self._path(project_id)
if not path.exists():
return None
return json.loads(path.read_text())
def save(
self,
project_id: str,
data: Dict[str, Any]
) -> Dict[str, Any]:
project = CMSProject.create(
project_id,
**data
)
path = self._path(project_id)
temporary = path.with_suffix(".tmp")
temporary.write_text(
json.dumps(
project.to_dict(),
indent=2,
ensure_ascii=False
)
)
temporary.replace(path)
return project.to_dict()
def delete(self, project_id: str) -> bool:
path = self._path(project_id)
if not path.exists():
return False
path.unlink()
return True
_cms_manager: Optional[CMSManager] = None
def get_cms_manager() -> CMSManager:
global _cms_manager
if _cms_manager is None:
_cms_manager = CMSManager()
return _cms_manager