diff --git a/services/travel-memories/app/routes/albums.py b/services/travel-memories/app/routes/albums.py index 1cdd45c..1119470 100644 --- a/services/travel-memories/app/routes/albums.py +++ b/services/travel-memories/app/routes/albums.py @@ -1,9 +1,76 @@ -from flask import Blueprint, current_app, render_template, request -from app.state import load_state +from pathlib import Path + +from flask import Blueprint, current_app, redirect, render_template, request +from app.immich import ImmichClient +from app.state import TripState, Photo, load_state, save_state bp = Blueprint("albums", __name__) +def _client(): + return ImmichClient(current_app.config["IMMICH_URL"], + current_app.config["IMMICH_API_KEY"]) + + +@bp.get("/") +def index(): + try: + albums = _client().list_albums() + error = None + except ConnectionError as e: + albums = [] + error = str(e) + state_dir = Path(current_app.config["STATE_DIR"]) + for album in albums: + album["has_state"] = (state_dir / f"{album['id']}.json").exists() + return render_template("phase1.html", albums=albums, error=error, + current_phase="", album_id=None, + phase_stale=[], notes_content="") + + +@bp.post("/select") +def select(): + album_ids = request.form.getlist("album_ids[]") + grav_trip_slug = request.form["grav_trip_slug"].strip() + start_over = request.form.get("start_over") == "1" + + if len(album_ids) == 1: + primary_id = album_ids[0] + else: + primary_id = "__merged__" + "_".join(sorted(album_ids)) + + existing = load_state(primary_id, current_app) + if existing and not start_over: + return redirect(f"/{existing.phase}?album_id={primary_id}") + + # Fetch and merge assets, deduplicating by asset ID + all_assets = {} + album_name_parts = [] + for aid in album_ids: + album = _client().get_album(aid) + album_name_parts.append(album["albumName"]) + for asset in album["assets"]: + if asset["id"] not in all_assets: + all_assets[asset["id"]] = asset + + photos = [ + Photo(id=a["id"], original_filename=a["originalFileName"], + local_datetime=a["localDateTime"]) + for a in sorted(all_assets.values(), key=lambda x: x["localDateTime"]) + ] + for i, p in enumerate(photos): + p.order = i + + state = TripState( + album_id=primary_id, + album_name=", ".join(album_name_parts), + grav_trip_slug=grav_trip_slug, + photos=photos, + ) + save_state(state, current_app) + return redirect(f"/triage?album_id={primary_id}") + + # TODO(task-6): replace this stub with the real triage route @bp.get("/triage") def triage(): diff --git a/services/travel-memories/app/templates/phase1.html b/services/travel-memories/app/templates/phase1.html new file mode 100644 index 0000000..41c33fd --- /dev/null +++ b/services/travel-memories/app/templates/phase1.html @@ -0,0 +1,55 @@ +{% extends "base.html" %} +{% block content %} +