-
-
Notifications
You must be signed in to change notification settings - Fork 144
Description
Summary
This PR adds an Immich plugin to Elodie that enables albums and favorites to be managed through Immich’s UI while ensuring:
- All metadata is persisted in the photo itself
- Elodie remains the canonical organizer
- File moves do not break album or favorite state
Immich is treated as both:
- an intent source (albums, favorites)
- a materialized view target (albums rebuilt from metadata)
The plugin uses Elodie’s plugin database to track state and perform incremental syncs, avoiding full rescans on each run.
Metadata Contracts (Authoritative)
Album Metadata (Existing Elodie Behavior)
Elodie already supports album metadata using the following fields (checked in order):
XMP-xmpDM:AlbumXMP:Album
The plugin must use these fields when writing album metadata.
Exactly one album per photo is supported.
Favorites Metadata
Immich does not support ratings; it supports favorites.
Mapping rules:
-
Immich
isFavorite = true
→ writeXMP:Rating = 5 -
Immich
isFavorite = false
→ removeXMP:Ratingif present
Immich favorites are treated as the intent source, while XMP:Rating is the durable, file-backed representation.
This mapping must be enforced during Immich → Elodie sync.
Immich API Requirements
The plugin must use Immich’s API to retrieve:
-
Albums
- Album ID
- Album name
- Asset membership
updatedAt
-
Assets
- Asset ID
- File path
isFavoriteupdatedAt
A required endpoint is one that can retrieve all assets (or assets updated since a timestamp) so favorite changes can be detected incrementally.
The plugin must not assume Immich asset IDs are stable across file moves.
Plugin Database Usage (Required)
The plugin must use Elodie’s plugin database (see googlephotos plugin) to store:
- Last successful sync timestamp
- Asset ID → file path mapping
- Last known album per asset
- Last known favorite state
- Last processed
updatedAtper asset
This enables:
- Incremental Immich API calls
- Avoiding full library scans
- Avoiding rereading metadata for all files on each run
Album Conflict Resolution
If an asset is in Album A and is added to Album B in Immich:
- Log the conflict
- Treat Album B as authoritative
- Update the photo’s album metadata
- Allow Elodie to move the photo into the new album
This preserves the “single album per photo” constraint while respecting user intent.
Supported User Actions
1. ./elodie.py batch
This command performs a one-time bootstrap sync from Elodie to Immich for albums and favorites. Once completed, this should be stored so that future calls to batch perform Immich to Elodie syncs only.
Elodie → Immich
Use Elodie's filesystem.get_all_files() generator to get all files and map to Immich asset by using originalFileName and originalPath from the POST /search/metadata API (here).
-
For photos with album metadata:
- Ensure Immich album exists
- Ensure photo is added to that album
-
For photos with
XMP:Rating = 5:- Ensure Immich favorite is set
-
For photos without
XMP:Rating:- Ensure Immich favorite is cleared
Immich → Elodie
-
Fetch only assets where:
updatedAt > last_sync_time
-
For changed assets:
-
If album membership changed:
- Update photo album metadata
-
If
isFavoritechanged:- Write or remove
XMP:Rating = 5
- Write or remove
-
Optimization Requirements
-
Do not scan all Immich assets on each run
-
Do not reread metadata from all photos
- Immich
updatedAt - Plugin DB state
- Immich
-
Full scan should only be required on first run when the plugin database does not have record that it's been completed.
Execution Order
For batch runs:
- If bootstrap has not run then perform Elodie to Immich sync.
- If bootstrap has run then fetch incremental changes from Immich
2.1. Update photo metadata (albums, favorites) using.set_album()and a new.set_favorite()methods
2.2. Run existing Elodie organization logic by callingfilesystem.process_file()and making any updates to the plugin database to store the new path
Error Handling & Logging
-
Log (do not crash) on:
- Missing files
- Assets no longer managed by Elodie
- Album conflicts
- API failures
-
Provide summary output including:
- Metadata updates
- Album moves
- Favorites set and cleared
Non-Goals
- Preserving Immich asset IDs across file moves
- Supporting multiple albums per photo
- Real-time or webhook-based sync
- Immich being a source of truth for metadata
Expected Outcome
After this PR:
- Immich can be used safely as a UI for viewing and modifying albums and favorites
- Favorites can be both set and cleared reliably
- Elodie remains deterministic and metadata-driven
- Album and favorite state survives file moves
- Sync operations scale to very large libraries
- Immich becomes a replaceable, reconstructible view layer