Courmap-Proxy
Docker app from Courmap's Repository
Overview
Readme
View on GitHub
Courmap translates an anime episode between AniDB, AniList, MAL, Kitsu, TVDB, TMDB, IMDb and absolute (fansub) numbering, and resolves release names to the right show and episode, as open data and a library with no server to run.
The same release, counted every way:
| Source | Episode |
|---|---|
Fansub release [SubsPlease] Spy x Family - 17 (1080p) |
17 |
| AniDB, AniList, MAL, Kitsu | Part 2, episode 5 |
| TVDB, TMDB | S01E17 |
Fansub groups count straight through the show. AniDB, AniList, MAL and Kitsu split it into two cours (about 12 episodes each) that restart at 1, and TVDB and TMDB keep one season. Try it in your browser.
Pick your path
Sonarr and self-hosted users
The Courmap proxy sits between Prowlarr and Sonarr and rewrites anime releases into the numbering Sonarr understands; anything it is unsure about passes through untouched.
services:
courmap-proxy:
image: ghcr.io/courmap/proxy:latest
ports:
- "9797:9797"
volumes:
- ./courmap/data:/data
environment:
SONARR_URL: http://sonarr:8989
SONARR_API_KEY: your-sonarr-api-key
INDEXER_NYAA_URL: http://prowlarr:9696/1/api
Finish setup with step 3 of the quickstart, or Prowlarr's copies of your indexers will duplicate anime results.
INDEXER_NYAA_URL makes the proxy serve that Prowlarr feed at /nyaa (the 1 is the indexer's ID in Prowlarr). Then add http://courmap-proxy:9797/nyaa to Sonarr as a Torznab indexer (Newznab for usenet) with your Prowlarr API key. Sonarr quickstart; Unraid, VPN containers, usenet limits and troubleshooting are in the full guide.
Developers
import { createRemoteClient } from '@courmap/client';
const courmap = createRemoteClient(); // fetches small static files on demand, nothing to download
const t = await courmap.translate('anilist:142838', 5, ['tvdb_show', 'absolute']);
console.log(t.results.tvdb_show); // { id: '405920', season: 1, episode: 17 }
const r = await courmap.resolve('[SubsPlease] Sousou no Frieren - 12 (1080p)');
console.log(r.status, r.match?.work, r.match?.episode); // ok sousou-no-frieren 12
Works in Node, browsers and Workers, and fully offline over the weekly SQLite dump. Library quickstart. No code? Ask the HTTP API: curl "https://api.courmap.com/v1/translate?from=anilist:142838&episode=5&to=tvdb_show" (more).
Contributors
Fix a wrong mapping once, for everyone: add a short YAML file that overrides only what is wrong.
# data/works/kusuriya-no-hitorigoto-2nd-season.yaml
id: kusuriya-no-hitorigoto-2nd-season
projections:
tmdb_show:
- { season: 1, episodes: 1-24, start: 25 }
pnpm install
pnpm validate
Fix a mapping, and the full contributing guide.
How it works
Every provider maps to one canonical work (usually one cour, film or OVA), never to each other, so any translation is two hops. About 33,000 works are seeded weekly from anime-offline-database (IDs, titles, synonyms) and Anime-Lists (TVDB and TMDB offsets); hand-written YAML files in data/ correct and extend them. CI checks every mapping (every episode must translate to every provider and back) and compiles it all into a SQLite dump and static JSON files. Bots watch each anime season and open pull requests and issues; a person only reviews where sources disagree.
Courmap never guesses silently: an unsure answer is ambiguous, with its candidates. How it differs from TheXEM, Anime-Lists and anime-offline-database is in the FAQ.
Documentation: courmap.com. Design: docs/SPEC.md.
License and attribution
Code: Apache-2.0 (LICENSE). Data in data/ and every dump: ODbL 1.0 + DbCL 1.0 (DATA_LICENSE). Courmap builds on anime-offline-database (cedya77, continuing manami-project) and Anime-Lists; see ATTRIBUTION.md. Courmap never calls the AniDB API and never redistributes AniDB titles.
Categories
Related apps
Explore more like this
Explore allDetails
ghcr.io/courmap/proxy:latestRuntime arguments
- Web UI
http://[IP]:[PORT:9797]/- Network
bridge- Privileged
- false
- Extra Params
--user 99:100
Template configuration
The proxy's status page, and the address Sonarr uses to reach each indexer (for example http://courmap-proxy:9797/tracker).
- Target
- 9797
- Default
- 9797
- Value
- 9797
Downloaded Courmap data and the unresolved release log. If the status page says the data folder is not writable, run chown -R 99:100 /mnt/user/appdata/courmap-proxy in the Unraid terminal.
- Target
- /data
- Default
- /mnt/user/appdata/courmap-proxy/data
- Value
- /mnt/user/appdata/courmap-proxy/data
Optional courmap-proxy.yaml with the same settings as the variables below. Environment variables win over it.
- Target
- /config
- Default
- /mnt/user/appdata/courmap-proxy/config
- Value
- /mnt/user/appdata/courmap-proxy/config
Address of your Sonarr. Without it and the API key, every release passes through unchanged. Use the host's IP address if the containers are not on one network.
- Target
- SONARR_URL
- Default
- http://sonarr:8989
- Value
- http://sonarr:8989
Your Sonarr API key (Sonarr, Settings, General). The proxy uses it to read your series list.
- Target
- SONARR_API_KEY
One upstream Torznab or Newznab feed, usually a Prowlarr indexer such as http://prowlarr:9696/1/api (the number is the indexer's ID in Prowlarr). The name between INDEXER_ and _URL is a label you choose: TRACKER is served at /tracker, lowercase, with underscores turned into hyphens. Add more indexers as extra variables, for example INDEXER_NYAA_URL.
- Target
- INDEXER_TRACKER_URL
Leave blank for torrents. Set to newznab for a usenet indexer. When blank, the proxy detects the type from the feed's first results. Change TRACKER to match the label of the indexer above.
- Target
- INDEXER_TRACKER_TYPE
How often the Sonarr series list is reloaded.
- Target
- SONARR_REFRESH_MINUTES
- Default
- 60
- Value
- 60
How often the Courmap data release is checked. A new dump is downloaded only when the data version changes.
- Target
- REFRESH_HOURS
- Default
- 24
- Value
- 24
Identical queries to an indexer within this time share one request. 0 turns the cache off.
- Target
- UPSTREAM_CACHE_SECONDS
- Default
- 60
- Value
- 60