import json import os from dataclasses import dataclass, field, asdict from pathlib import Path from typing import Optional from flask import current_app @dataclass class Photo: id: str original_filename: str local_datetime: str tag: str = "untagged" # untagged | journal | story | skip order: int = 0 @dataclass class Group: id: str photo_ids: list = field(default_factory=list) entry_type: str = "journal" # journal | story title: str = "" body: str = "" location_city: str = "" location_country: str = "" date: str = "" hero_photo_id: Optional[str] = None shortcode_hints: str = "" status: str = "draft" # draft | written | skipped | exported @dataclass class TripState: album_id: str album_name: str grav_trip_slug: str phase: str = "triage" phases_completed: list = field(default_factory=list) phase_stale: list = field(default_factory=list) photos: list = field(default_factory=list) groups: list = field(default_factory=list) notes: str = "" def _state_path(album_id: str, app) -> Path: return Path(app.config["STATE_DIR"]) / f"{album_id}.json" def load_state(album_id: str, app) -> Optional[TripState]: path = _state_path(album_id, app) if not path.exists(): return None with open(path) as f: data = json.load(f) photos = [Photo(**p) for p in data.pop("photos", [])] groups = [Group(**g) for g in data.pop("groups", [])] return TripState(photos=photos, groups=groups, **data) def save_state(state: TripState, app) -> None: path = _state_path(state.album_id, app) path.parent.mkdir(parents=True, exist_ok=True) tmp = path.with_suffix(".tmp") with open(tmp, "w") as f: json.dump(asdict(state), f, indent=2) os.rename(tmp, path)