Files
Curator/docs/modules/core.pool_index.md
T

4.0 KiB

src/core/pool_index.py

Unified metadata index for the Curator pool.

Instead of one sidecar file per movie, the whole pool keeps a single JSON index at <pool>/.Curator.!index. Curator owns the pool (it inserts/removes files itself), so files never move behind its back and a central index is safe.

The index also carries library-level settings (tag_schema, copyasis_folders) under a settings section, so everything describing a particular pool travels with the pool. The global config keeps only app data (window state, MRU) and the pointers to where the pool/output live.

On-disk shape (v2)::

{"version": 2,
 "settings": {...},
 "movies": {"tmdb-603": {"title": …, "media": [{"role", "label", "file"}, …]}}}

Records are keyed by the movie's identity (tmdb-<id>, or a title/year slug when there's no id) and own their files — see src.core.movie. The original v1 shape keyed a record by one file's pool-relative path, which made metadata a passenger on that file; PoolIndex.load migrates such an index in place (backing the old file up first). Migration only rewrites metadata — no file on disk is moved, because a one-video movie is already in its v2 position.

Source: src/core/pool_index.py

Classes

PoolIndex

class · line 35

class PoolIndex:

Single-file JSON metadata store for all files in a pool.

PoolIndex.__init__

method · line 38

__init__(pool_dir: Path) -> None

Open the index of the pool at pool_dir (loads it, migrating an older version if needed).

PoolIndex._key

method · line 45

_key(file_path: Path) -> str

Pool-relative POSIX key for a file path.

PoolIndex.load

method · line 53

load() -> None

Load the index from disk (missing/corrupt index = empty).

A v1 (path-keyed) index is migrated to v2 in place — the old file is copied to .Curator.!index.v1.bak first.

PoolIndex._migrate_v1_to_v2

method · line 76

_migrate_v1_to_v2() -> None

Re-key path-keyed records into identity-keyed movie records.

Each v1 record described one file; several of them can describe one movie (the interim multi-version layout put them in a shared folder), so they are merged by identity. Metadata only — nothing is moved on disk, since a v1 movie's files already sit where v2 wants them.

PoolIndex.save

method · line 139

save() -> None

Persist the index to disk.

PoolIndex.get_setting

method · line 150

get_setting(key: str, default=None)

Return a library-level setting stored in the index.

PoolIndex.set_setting

method · line 154

set_setting(key: str, value) -> None

Upsert a library-level setting and persist the index.

PoolIndex.get_movie

method · line 163

get_movie(key: str) -> dict | None

Return the movie record under key, or None.

PoolIndex.set_movie

method · line 167

set_movie(key: str, data: dict) -> None

Upsert a movie record and persist the index.

PoolIndex.delete_movie

method · line 172

delete_movie(key: str) -> None

Remove a movie record (if present) and persist the index.

PoolIndex.rekey_movie

method · line 177

rekey_movie(old_key: str, new_key: str) -> None

Move a record to a new identity key (e.g. its TMDb id was set/fixed).

PoolIndex.all_movies

method · line 184

all_movies() -> dict[str, dict]

Every movie record, keyed by identity.

PoolIndex.record_for

method · line 188

record_for(file_path: Path) -> dict | None

The movie record that owns file_path, or None if untracked.

PoolIndex.find_movie_by_media

method · line 193

find_movie_by_media(file_path: Path) -> tuple[str, dict] | None

(key, record) of the movie owning file_path, or None.

The reverse lookup a file needs now that records are keyed by identity rather than by path.