diff --git a/services/travel-memories/app/__init__.py b/services/travel-memories/app/__init__.py index 99e6bd5..0e22d9b 100644 --- a/services/travel-memories/app/__init__.py +++ b/services/travel-memories/app/__init__.py @@ -8,7 +8,7 @@ def create_app(state_dir=None, pages_dir=None): app.config["IMMICH_URL"] = os.environ.get("IMMICH_URL", "") app.config["IMMICH_API_KEY"] = os.environ.get("IMMICH_API_KEY", "") - from .routes import albums, triage, proxy, notes, nav, curate, group + from .routes import albums, triage, proxy, notes, nav, curate, group, write app.register_blueprint(albums.bp) app.register_blueprint(triage.bp) app.register_blueprint(proxy.bp) @@ -16,6 +16,7 @@ def create_app(state_dir=None, pages_dir=None): app.register_blueprint(nav.bp) app.register_blueprint(curate.bp) app.register_blueprint(group.bp) + app.register_blueprint(write.bp) @app.get("/health") def health(): diff --git a/services/travel-memories/app/routes/write.py b/services/travel-memories/app/routes/write.py new file mode 100644 index 0000000..c074c5f --- /dev/null +++ b/services/travel-memories/app/routes/write.py @@ -0,0 +1,97 @@ +from flask import Blueprint, current_app, jsonify, redirect, render_template, request, url_for +from app.state import load_state, save_state + +bp = Blueprint("write", __name__) + + +@bp.get("/write") +def write(): + album_id = request.args["album_id"] + group_idx = int(request.args.get("group_idx", 0)) + state = load_state(album_id, current_app) + active_groups = [g for g in state.groups if g.status != "exported"] + total = len(active_groups) + group = active_groups[group_idx] if group_idx < total else None + done_count = sum(1 for g in active_groups if g.status in ("written", "skipped")) + photos = [] + if group: + by_id = {p.id: p for p in state.photos} + photos = [by_id[pid] for pid in group.photo_ids if pid in by_id] + return render_template( + "phase5.html", + state=state, + group=group, + photos=photos, + group_idx=group_idx, + total=total, + done_count=done_count, + current_phase="write", + album_id=album_id, + phase_stale=state.phase_stale, + notes_content=state.notes, + ) + + +@bp.post("/write/autosave") +def autosave(): + body = request.get_json() + state = load_state(body["album_id"], current_app) + for g in state.groups: + if g.id == body["group_id"] and g.status != "exported": + g.title = body.get("title", g.title) + g.body = body.get("body", g.body) + g.location_city = body.get("location_city", g.location_city) + g.location_country = body.get("location_country", g.location_country) + g.date = body.get("date", g.date) + g.hero_photo_id = body.get("hero_photo_id", g.hero_photo_id) + g.shortcode_hints = body.get("shortcode_hints", g.shortcode_hints) + if body.get("entry_type"): + g.entry_type = body["entry_type"] + break + save_state(state, current_app) + return jsonify({"ok": True}) + + +@bp.post("/write/save") +def save(): + body = request.get_json() + state = load_state(body["album_id"], current_app) + for g in state.groups: + if g.id == body["group_id"] and g.status != "exported": + g.title = body.get("title", g.title) + g.body = body.get("body", g.body) + g.location_city = body.get("location_city", g.location_city) + g.location_country = body.get("location_country", g.location_country) + g.date = body.get("date", g.date) + g.hero_photo_id = body.get("hero_photo_id", g.hero_photo_id) + g.shortcode_hints = body.get("shortcode_hints", g.shortcode_hints) + if body.get("entry_type"): + g.entry_type = body["entry_type"] + g.status = "written" + break + save_state(state, current_app) + return jsonify({"ok": True}) + + +@bp.post("/write/skip") +def skip(): + body = request.get_json() + state = load_state(body["album_id"], current_app) + for g in state.groups: + if g.id == body["group_id"] and g.status != "exported": + g.status = "skipped" + break + save_state(state, current_app) + return jsonify({"ok": True}) + + +@bp.post("/write/done") +def done(): + body = request.get_json() + album_id = body["album_id"] + state = load_state(album_id, current_app) + if "write" not in state.phases_completed: + state.phases_completed.append("write") + state.phase = "export" + save_state(state, current_app) + return jsonify({"ok": True, "redirect": f"/export?album_id={album_id}"}) diff --git a/services/travel-memories/app/templates/phase5.html b/services/travel-memories/app/templates/phase5.html new file mode 100644 index 0000000..441d4a7 --- /dev/null +++ b/services/travel-memories/app/templates/phase5.html @@ -0,0 +1,196 @@ +{% extends "base.html" %} +{% block content %} +
Click a photo on the left to set it as the hero.
+{{ state.notes or 'No notes yet.' }}
+