Name anime creditless openings/endings (NCOP/NCED) using AnimeThemes
Find a file
xenarathon fb608478ec harden: anime-only default roots + stricter confidence guard
Drop /media/TV Library from NCOP_ROOTS (NCOP/NCED are anime-only) and remove the loose '>=2 shared words = confident' branch that could mis-download an OP/ED into a wrong show.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 12:42:37 -04:00
.dockerignore ncop-themes: anime NCOP/NCED namer + AnimeThemes downloader 2026-06-13 15:52:51 -04:00
.gitignore ncop-themes: anime NCOP/NCED namer + AnimeThemes downloader 2026-06-13 15:52:51 -04:00
docker-compose.yml Point watcher at Anime Library only 2026-06-15 22:10:46 -04:00
Dockerfile ncop-themes: anime NCOP/NCED namer + AnimeThemes downloader 2026-06-13 15:52:51 -04:00
LICENSE Relicense from MIT to GPL-3.0-or-later 2026-06-13 18:57:48 -04:00
ncop-themes.py harden: anime-only default roots + stricter confidence guard 2026-06-24 12:42:37 -04:00
README.md README: drop redundant bullet from collapsible summaries 2026-06-15 22:22:43 -04:00

ncop-themes

Automatically name your anime creditless openings/endings (NCOP/NCED) and download the ones you're missing from AnimeThemes.moe, laid out as Plex / Jellyfin / Emby local extras.

For every show in your library it will:

  1. find any creditless opening/ending video files you already have,
  2. match the show to AnimeThemes — fuzzy search disambiguated by the folder year, so Trigun (1998) is never confused with Trigun Stampede (2023),
  3. rename them tidily into the show's Scenes/ folder, and
  4. download any creditless OP/ED the show is missing.

It's safe to re-run (it never touches a file twice), skips uncertain matches instead of guessing, only ever writes inside each show's Scenes/ folder, and has no dependencies — just Python.

New to all this? No problem. The Quick start below is five copy-paste steps, and every step has a ▸ click-to-expand explainer telling you what the command does and why.


Quick start

The safest way to try it: run once in preview mode (changes nothing, just shows what it would do), check the output, then run it for real.

First time using a terminal? Start here

A "terminal" is a window where you type commands instead of clicking buttons.

  • Windows: install Docker Desktop, then open PowerShell (search for it in the Start menu).
  • macOS: install Docker Desktop, then open Terminal (in Applications → Utilities).
  • Linux: you likely already have a terminal and may already have Docker.

To run a command, copy it, paste it into the terminal window, and press Enter. That's it. "Docker" is just a tool that runs this program in a tidy box so you don't have to install Python or anything else yourself.

1. Get the code

git clone https://github.com/you/ncop-themes.git
cd ncop-themes
What did that do?

git clone downloads a copy of this project to your computer. cd ncop-themes ("change directory") moves you into the folder it created, so the next commands run in the right place. Replace the URL with wherever you got this from (e.g. your own Forgejo/GitHub address).

2. Preview what it would do (changes nothing)

docker run --rm \
  -e NCOP_DRY_RUN=1 \
  -e NCOP_ROOTS="/media/Anime Library" \
  -v "/path/to/your/anime:/media/Anime Library" \
  ncop-themes:latest
What does this command do, piece by piece?
  • docker run — start the program in its tidy box, then throw the box away when done (--rm).
  • -e NCOP_DRY_RUN=1dry run: log every rename/download it would do, but change nothing. This is your safety net — always do this first.
  • -e NCOP_ROOTS="/media/Anime Library" — tells the program where your anime lives inside the box.
  • -v "/path/to/your/anime:/media/Anime Library" — connects a folder on your computer (the part before the :) to that location inside the box (the part after). Change /path/to/your/anime to where your anime actually is. See Personalize it to your setup for how to find that path.
  • ncop-themes:latest — the name of the program to run.

Read the output. Lines like MOVE … and DL … are what it would do. If it looks right, move on.

3. Run it for real

Same command, just remove the -e NCOP_DRY_RUN=1 line:

docker run --rm \
  -e NCOP_ROOTS="/media/Anime Library" \
  -v "/path/to/your/anime:/media/Anime Library" \
  ncop-themes:latest

4. (Optional) Keep it running on a schedule

To have it re-check your library automatically (e.g. weekly), use Docker Compose instead — see Run it automatically below.


Personalize it to your setup

You only ever need to change a couple of things. Here's what and how.

Your media path — wherever your anime folders live. In every command above, replace /path/to/your/anime with that path.

How do I find my media path?

It's the folder that contains your show folders (the ones named like Cowboy Bebop (1998)). Examples:

  • Windows: D:\Media\Anime → write it as D:/Media/Anime (forward slashes) or //d/Media/Anime.
  • macOS/Linux: something like /Volumes/media/Anime or /srv/media/Anime.
  • A NAS/server: the path as that machine sees it, e.g. /srv/media/Anime Library.

Tip: open the folder in your file manager and copy it from the address bar.

The settings (environment variables) — all optional; the defaults are sensible.

Variable Default What it does
NCOP_ROOTS /media/Anime Library,/media/TV Library Which library folders to scan. Comma-separated if you have more than one.
NCOP_DRY_RUN (off) Set to 1 to preview only — log what it would do, change nothing.
NCOP_ONLY_EXISTING (off) Set to 1 for conservative mode: only tidy shows that already have some theme files, never download new ones. Default: scan everything and fetch what's missing.
NCOP_RUN_EVERY 0 Seconds to wait between runs. 0 = run once and stop. 604800 = weekly.
NCOP_USER_AGENT a browser UA Advanced — only change if AnimeThemes starts blocking requests.
Why does scanning "everything" matter, and when would I use conservative mode?

By default the tool looks at every show and downloads any creditless OP/ED it's missing — great for filling out a whole library at once. If instead you only want it to neatly rename files you've already collected yourself (and never download anything), set NCOP_ONLY_EXISTING=1.

One side effect of the default: it does one AnimeThemes lookup per show, so it's worth pointing NCOP_ROOTS only at folders that actually contain anime (non-anime shows just return "no match" and are skipped harmlessly, but it's wasted effort).


Run it automatically

The included docker-compose.yml runs the tool on a schedule and keeps it running.

docker compose up -d --build
docker compose logs -f ncop-themes
What do these two commands do — and what should I edit first?
  • docker compose up -d --build — builds the program and starts it in the background (-d).
  • docker compose logs -f ncop-themes — shows its live output so you can watch what it's doing (press Ctrl+C to stop watching; the program keeps running).

Before running, open docker-compose.yml in a text editor and set:

  1. volumes: — change ./media to your real media path (same idea as the -v above), e.g. - "/srv/media/Anime Library:/media/Anime Library".
  2. user: — change 1000:1000 to the user/group that owns your media, so downloaded files have the right ownership. On macOS/Linux run id in a terminal to see your numbers; on a NAS it's usually shown in the user settings. If unsure, 1000:1000 is the common default.
  3. NCOP_ROOTS — make sure it matches the folder name you mounted in step 1.

It's set to run weekly by default. To preview first here too, uncomment the NCOP_DRY_RUN line.

I'd rather not use Docker at all

You don't have to — it's plain Python (version 3.8+), no extra packages:

NCOP_ROOTS="/path/to/your/anime" python3 ncop-themes.py

How matching & naming works

A show folder like Frieren Beyond Journey's End (2023) {tvdb-424536} is reduced to its title and year, searched on AnimeThemes, and the best result is chosen by year match + title similarity — only used if it's a confident match. Each opening/ending becomes a slot (OP1, ED2, …) and files are named from those slots:

Cowboy Bebop (1998) {tvdb-76885}/
└── Scenes/
    ├── NCOP 01 Tank! -scene.webm
    ├── NCED 01 The Real Folk Blues -scene.mkv
    ├── NCED 02 Space Lion -scene.mkv
    └── NCED 03 Blue -scene.mkv

The -scene suffix is what makes Plex/Jellyfin/Emby file them as Scenes extras. Files you've already named correctly are left untouched; a stray release-named file that fills a gap is renamed in; a clear duplicate sitting in an Other/ or Featurettes/ folder is removed.


Building & publishing your own copy

For maintainers — build the image and push it to a registry
docker build -t ncop-themes:latest .
# then tag/push to your registry, e.g. a self-hosted Forgejo:
docker tag ncop-themes:latest your.forgejo.host/you/ncop-themes:latest
docker push your.forgejo.host/you/ncop-themes:latest

Good to know

  • Matching isn't perfect. AnimeThemes can return the wrong entry for ambiguous titles; the year guard catches most remakes/sequels, and uncertain matches are skipped and logged. Skim docker compose logs ncop-themes after the first run.
  • Versions you've already placed yourself (e.g. NCOP 01v2) are preserved.
  • Data and creditless videos are courtesy of the AnimeThemes.moe community. Please be a good citizen — the tool paces its requests; don't hammer the API.

License

GNU GPL v3 (or later) — see LICENSE. Copyleft, so derivatives stay free software.