78 lines
3.4 KiB
Markdown
78 lines
3.4 KiB
Markdown
# Overview
|
|
|
|
[← Documentation index](index.md)
|
|
|
|
Photo Pipeline sorts a photo library. It finds duplicates before anything expensive
|
|
happens to them, asks a human which pictures may leave the machine, describes the
|
|
ones that may, proposes album names from what it found, renames folders under a
|
|
crash-safe journal, uploads through `immich-go`, and can archive a finished album off
|
|
active storage without ever forgetting it existed.
|
|
|
|
It runs locally. It talks to exactly three things outside itself: a vision provider,
|
|
an Immich server, and `exiftool` — and it will tell you before it uses any of them.
|
|
|
|
## The workflow
|
|
|
|
Each stage is a gate, not a tab. A later stage can always be looked at; its actions
|
|
stay disabled until what they depend on is true.
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
I["0 · Inventory<br/>discover, hash, cluster duplicates"] --> S["1 · Safety<br/>score and human decision"]
|
|
S -->|sfw| A["2 · Analysis<br/>vision provider, EXIF checkpoint"]
|
|
S -->|nsfw| U
|
|
A --> B["3 · Albums<br/>proposal, then guarded rename"]
|
|
B --> U["4 · Upload<br/>immich-go, verified bytes"]
|
|
U --> R["5 · Archive<br/>copy, verify, then reclaim space"]
|
|
```
|
|
|
|
| Stage | What it decides | What it changes |
|
|
|---|---|---|
|
|
| Inventory | which file is the canonical copy of a picture | nothing — it only reads |
|
|
| Safety | whether a photo may be sent to a cloud provider | one `sfw`/`nsfw` EXIF keyword |
|
|
| Analysis | what a photo shows | a managed caption segment and additive keywords |
|
|
| Albums | what a folder should be called | folder names, through a journaled rename |
|
|
| Upload | which exact bytes reach Immich | nothing locally; assets appear in Immich |
|
|
| Archive | which album leaves active storage | files move to the archive, after verification |
|
|
|
|
## What it will not do
|
|
|
|
These are enforced in code, not by convention, and each one is why some action you
|
|
expected is sometimes refused.
|
|
|
|
- **Nothing under `_IGNORE/` is ever read.** Not scanned, not counted, not
|
|
thumbnailed, not sent anywhere.
|
|
- **A path is not an identity.** Every picture has a stable id, so moving or renaming
|
|
it loses no history.
|
|
- **Only a confirmed-SFW photo reaches the vision provider.** A photo marked NSFW is
|
|
still uploadable to Immich; it simply never leaves for analysis.
|
|
- **Metadata is verified, not hoped for.** Every stage that writes EXIF reads it back
|
|
and proves that what it did not own is unchanged.
|
|
- **One writer at a time.** A library lock, held by one process, is what makes a
|
|
crash recoverable instead of ambiguous.
|
|
- **Nothing irreversible happens without a preview and an explicit approval** that
|
|
names the exact count.
|
|
|
|
## Where things live
|
|
|
|
| | |
|
|
|---|---|
|
|
| the photo library | wherever you point `PHOTO_PIPELINE_LIBRARY_ROOTS`; mounted read-write |
|
|
| the database, cache, logs, backups | the data directory, never inside the library |
|
|
| secrets | the environment, never the database and never a log line |
|
|
| these documents | `docs/` in the repository, served at `/docs` by the application |
|
|
|
|
## Running it
|
|
|
|
The short version, for a host installation:
|
|
|
|
```bash
|
|
python -m photo_pipeline migrate
|
|
python -m photo_pipeline serve # the API and this browser application
|
|
python -m photo_pipeline worker # the process that does the long work
|
|
```
|
|
|
|
The full procedure, the container path, and every setting are in the
|
|
[installation manual](installation.md); if you would rather start using it, take
|
|
[the guided first pass](first-pass.md).
|