This repository holds the metadata and collection files that Kometa uses to curate a large personal Plex library: about 8,400 movies and 350 TV shows. Every collection, sort title, content-rating fix and summary in the library is defined here as YAML, so the whole setup can be rebuilt from scratch and every change is tracked in git.
Built and tested against Kometa 2.5.1.
| Folder | Files | Entries | What it does |
|---|---|---|---|
01-Metadata-Feature Films/ |
31 | ~3,400 | Per-movie fixes: sort titles, summaries, content ratings, labels, title corrections |
01-Metadata-TV Shows/ |
2 | 7 | Show and episode fixes: artwork, episode titles, episode ordering |
02-Collections-Feature Films/ |
48 | ~435 | Every movie collection: series, directors, people, studios, holidays, awards |
02-Collections-TV Shows/ |
1 | 7 | TV collections |
_GitHub Archive/ |
Earlier versions of collection files, kept for reference |
Not in this repo (kept local and git-ignored on purpose): config.yml (API keys and Plex token), templates.yml, the assets/ artwork folders, the cache, logs and reports.
Kometa processes folders in the order the config lists them, and the config's run_order is operations → metadata → collections. The prefixes simply mirror that: 01 folders fix the items themselves, 02 folders group them into collections. By the time a collection is built, the titles, sort titles and ratings it depends on are already correct.
Each file name encodes its purpose so that alphabetical order is also processing order:
02-C-DR10 Director's.yml
│ │ │ │ └─ human-readable description
│ │ │ └──── sequence number within the category (01, 02, …)
│ │ └────── category code
│ └──────── M = metadata file, C = collection file
└─────────── processing group (00 runs first, 99 runs last)
| Code | Category | Code | Category |
|---|---|---|---|
FF |
Fix First: must run before anything else | DR |
Director collections |
CT |
Change sort Titles | PC |
People collections (actors, comedy teams) |
CS |
Change Summaries / Create Separators | SS |
Special series (Star Wars, Star Trek, Oscars) |
CR |
Change Ratings (and other per-item fixes) | TC |
Timed collections (holidays, "Best of") |
MS |
Movie Series | SC |
Special collections |
AF |
"A Few …" rotating picks | ST |
Studio collections |
PA |
plex_all filepath collections |
CC |
Cinephile (hand-curated) collections |
Large categories are split into numbered files of roughly 15-20 entries (01-C-MS01 … 01-C-MS19, 02-C-DR01 … 02-C-DR10). That keeps each file easy to review in a diff, and a mistake in one file can't take down a whole category.
config.yml points two Kometa library entries at the same Plex library:
libraries:
Feature Films (Metadata Only-No Assets):
library_name: Feature Films
settings:
asset_folders: false # never touch artwork here
metadata_files:
- folder: config/01-Metadata-Feature Films/
Feature Films (Collections-With Assets):
library_name: Feature Films
settings:
asset_folders: true # collection posters come from assets/
create_asset_folders: true
collection_files:
- folder: config/02-Collections-Feature Films/This separates the ~3,400 per-movie metadata edits, which should never go looking for artwork, from the collections, which should. Each half gets its own asset settings and its own report.
Plex sorts collections by sort title, so every collection gets a deliberate sort_title prefix. Empty separator collections (00-C-CS01 Create Seperators.yml) act as section headings:
A Few:
sort_title: +_02 00
blank_collection: true # a heading with no items
Director's Collections:
sort_title: zzz_01 00
blank_collection: trueThe result is a Collections tab laid out in sections:
| Prefix | Section |
|---|---|
+_01 |
Just added |
+_02 |
A Few … |
+_03 |
Best of the Past |
+_04 |
Special collections |
+_04.5 |
Cinephile |
+_05 |
Oscars |
+_06 |
People |
zzz_01 |
Directors, sorted by surname |
zzz_02 |
Film formats (IMAX, 3D) |
Repetitive collections are built from a handful of templates in templates.yml. The optional: list means one template handles many variations: any variable you don't pass is removed entirely rather than left blank.
templates:
Director:
optional: [writer, actor, producer, title]
sort_title: zzz_01 <<sort_name>>
collection_order: release
plex_search:
any:
director: <<director>>
writer: <<writer>>Each of the ~150 director collections is then just four lines:
Terence Fisher (Director):
template:
name: Director
sort_name: Fisher, Terence
director: Terence FisherHand-picked collections list their films inline, with the title as a comment on each line, and collection_order: custom shows them exactly as written. The Alien Anthology is in in-world chronological order rather than release order:
Alien Anthology:
template:
name: MovieSeriesID
sort_title: Alien 00
collection_order: custom
text: |-
tt1446714 # Prometheus (set 2093)
tt2316204 # Alien: Covenant (set 2104)
tt0078748 # Alien (set 2122)
tt18412256 # Alien: Romulus (set 2142)
tt0090605 # Aliens (set 2179)
...The same approach puts Hannibal Lecter in story order, groups Anne of Green Gables by adaptation (the 1930s RKO films, then the Kevin Sullivan films), and lists the Cars shorts by original air date. IMDb and TMDb IDs can be mixed freely (tmdb:27266). The 15 Cinephile collections in 10-C-CC01 use it for curated film programs.
Holiday collections have a date schedule and delete_not_scheduled: true, so they appear on the Home screen only in season and delete themselves afterwards:
Christmas Movies:
schedule: range(12/10-12/27)
template: {name: Holiday} # visible on Home, random order, auto-deleteSome movies can only be identified by their folder name. A helper collection with build_collection: false scans every file path, applies a label, and creates nothing. Real collections then just search on that label:
Christmas Filename Marker:
build_collection: false
plex_all: true
filters:
filepath: "Christmas"
item_label: Christmas
non_item_remove_label: Christmas # keeps the label in sync if a file movesThe same approach powers the Star Wars path marker, and plex_all with filepath filters builds Great Commentaries, Isolated Score and The Criterion Collection straight from the folder names in the media library.
The "A Few …" row uses Plex smart filters. They're evaluated live, so each visit shows a different random 100 unwatched films in a genre:
A Few Dramas:
smart_filter:
all:
genre: Drama
unplayed: true
sort_by: random
limit: 100A collection can combine builders, and Kometa includes any item found by any of them:
- Apple and Illumination combine an IMDb company search with a Letterboxd studio page (
letterboxd_studio: apple-studios). - Monty Python combines an IMDb list with Letterboxd's Monty Python collection.
- Aardman combines a Plex studio and director search with Letterboxd.
- The Oscars collections use
imdb_awardto pull each year's nominees directly:
98th Annual Oscar Nominations:
imdb_award:
event_id: ev0000003 # Academy Awards
event_year: 2026
winning: false # all nominees, not just winnersThe 01-Metadata files fix what Plex's agents get wrong, and they're applied again on every run so the fixes stick:
Alien 3:
match:
title: ["Alien 3", "Alien³"] # match either spelling
year: 1992
sort_title: Alien 03 # keeps the series in order in the library view
The Rescuers Down Under (1990):
match:
mapping_id: tt0100477
studio: Walt Disney StudiosContent ratings are normalized in two layers. A library operation (content_rating_mapper) maps TV-style and foreign ratings (TV-14, GP, M/PG, …) to MPAA equivalents. The 03-M-CR files then set individual ratings where the mapping isn't enough.
- Backups on every run:
metadata_backupwrites a full YAML backup of every item's locked metadata, so any change can be rolled back. - Episode ordering: set in the TV metadata files (
episode_ordering: tvdb_dvd), so a Plex refresh can't reset it.
Collection posters live outside this repo in assets/, grouped by section (_Movie Series/, _Directors/, _Holidays/, …). With asset_depth: 3, Kometa finds each collection's folder by name anywhere in that tree:
assets/
_Movie Series/
Predator Collection/poster.jpg
_Directors/
Terence Fisher (Director)/poster.png
# full run inside the container
docker exec -it kometa python3 /kometa.py --run
# only one file
docker exec -it kometa python3 /kometa.py --run --run-files "01-C-MS19 Movie Series.yml"
# validate config.yml and every linked YAML file without touching Plex
docker exec -it kometa python3 /kometa.py --validate-config --validate-schemasScheduled runs happen twice a day through the container's KOMETA_TIMES setting.
- Movie series: named
<Name> Collection. Director collections are named<Name> (Director), withsort_nameasSurname, First. - IDs: IMDb IDs are preferred. A TMDb ID (
tmdb:) is used when Plex has no IMDb match for an item. - Comments: every ID has a comment with the film's title (and year where it helps).
- Retired and one-off files: these live in local-only folders (
Feature Film Configs-Retired,-Run Once,-Inactive). Superseded versions of tracked files are in_GitHub Archive/.