| import json |
| from pathlib import Path |
|
|
| ROOT = Path(__file__).parent |
| STORE = ROOT / "avatars" |
|
|
|
|
| def avatar_dir(avatar_id: str) -> Path: |
| return STORE / avatar_id |
|
|
|
|
| def avatar_json_path(avatar_id: str) -> Path: |
| |
| nested = avatar_dir(avatar_id) / "avatar.json" |
| legacy = STORE / f"{avatar_id}.json" |
| if nested.exists(): |
| return nested |
| return legacy |
|
|
|
|
| def avatar_portrait_path(avatar_id: str) -> Path: |
| return avatar_dir(avatar_id) / "portrait.png" |
|
|
|
|
| def avatar_generated_dir(avatar_id: str) -> Path: |
| return avatar_dir(avatar_id) / "generated" |
|
|
|
|
| def avatar_generated_path(avatar_id: str, timestamp: str, suffix: str = "png") -> Path: |
| return avatar_generated_dir(avatar_id) / f"{timestamp}.{suffix}" |
|
|
|
|
| def clear_generated_images(avatar_id: str) -> int: |
| dir_path = avatar_generated_dir(avatar_id) |
| if not dir_path.exists(): |
| return 0 |
| removed = 0 |
| for item in dir_path.iterdir(): |
| if item.is_file(): |
| try: |
| item.unlink() |
| removed += 1 |
| except Exception: |
| continue |
| return removed |
|
|
|
|
| def load_avatar(avatar_id: str) -> dict: |
| if not avatar_id: |
| raise ValueError("avatar_id required") |
| path = avatar_json_path(avatar_id) |
| if not path.exists(): |
| raise ValueError("avatar not found") |
| with path.open("r", encoding="utf-8") as handle: |
| return json.load(handle) |
|
|
|
|
| def save_avatar(avatar: dict) -> None: |
| avatar_id = avatar.get("id") |
| if not avatar_id: |
| raise ValueError("avatar missing id") |
| STORE.mkdir(exist_ok=True) |
| dir_path = avatar_dir(avatar_id) |
| dir_path.mkdir(exist_ok=True) |
| path = dir_path / "avatar.json" |
| with path.open("w", encoding="utf-8") as handle: |
| json.dump(avatar, handle, ensure_ascii=False, indent=2) |
|
|