Skip to content

unknown0152/dksubs-proxy-v2

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

104 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DKSubs Proxy

Language-aware Newznab enrichment proxy for the Arr stack, focused on Danish audio and subtitle detection.

DKSubs Proxy sits between Radarr/Sonarr and Prowlarr. It enriches Newznab search results with stable release markers (.DKOK for Danish subs, .DKaudio for Danish audio) so Arr custom formats can correctly prefer Danish releases without relying only on weak indexer titles. Designed for private media-server workflows where Prowlarr indexer metadata is inconsistent and Radarr/Sonarr custom-format matching needs stronger language signals.

What it does

Combines multiple signals to detect Danish content:

  • Title scanning — instantly tags releases with NORDiC, DANISH, DANSK, scene conventions (free, zero I/O)
  • Newznab attribute parsing — reads subs=Danish / language=Danish attrs when indexers expose them (free)
  • Extended-attr enrichment — bypasses Prowlarr's attr-stripping by querying indexers directly with extended=1
  • NFO/MediaInfo deep scan — downloads NFO files for releases that don't advertise Danish in the title; catches multi-language UHD remuxes with hidden Danish tracks
  • v5.6 caching/coordination layers — request dedup with single-flight lock, movie-level "no Danish available" verdicts, cross-indexer release-name dedup, per-indexer hit-rate budget scaling, NFO early-exit, 30-day negative cache. Together: ~86% reduction in indexer API calls vs naive probing.

The proxy does not replace Prowlarr. It wraps Prowlarr and returns enriched Newznab-compatible XML back to Radarr and Sonarr.

Tags added to release titles

Current format (bracketless, scene-style suffix):

Tag Meaning
.DKaudio Danish audio detected (from title, attribute, or NFO)
.DKOK Danish subtitles detected (from title, attribute, or NFO)

Custom-format regexes are backward-compatible with the older bracket forms ([DK:Title], [DKAudio:Title], [DK-NFO], [DKAudio.Title] etc.) so files already on disk continue to score correctly.

Quick Start — single command

sudo git clone https://github.com/unknown0152/dksubs-proxy-v2.git /root/cosmos-deploy/DK
sudo bash /root/cosmos-deploy/DK/setup.sh

That's it. setup.sh detects what's running and does the right things:

  • Fresh box → deploys nzbdav, sets up rclone FUSE mount, wires it into Radarr/Sonarr, configures everything
  • Box on altmount/qBittorrent → offers to migrate (auto-imports Usenet providers from altmount), then wires nzbdav, removes the old containers
  • Already running nzbdav → skips deployment, just refreshes CFs/profiles/indexer cats/timers
  • Out-of-date rclone → upgrades to a version that supports nzbdav's WebDAV symlinks

For updates: cd /root/cosmos-deploy/DK && sudo git pull && sudo bash setup.sh

Optional: NFO media-tag scoring (.NFODV, .NFOAtmos, …)

The proxy can ALSO parse already-fetched NFO text for media properties (Dolby Vision, HDR10/+, Atmos, TrueHD, DTS-HD MA, Remux) and append proxy-owned .NFOxxx tokens to release titles alongside the existing .DKOK / .DKaudio tag. No extra HTTP/API calls — it piggybacks on the same NFO text the proxy already fetches for DK detection. Default OFF.

Enable on the proxy (in /srv/config/dksubs-proxy/.env):

DKSUBS_PROXY_NFO_MEDIA_TAGS=1

Then restart the container.

Apply the matching Custom Formats in Radarr/Sonarr with conservative starter scores:

curl -fsSL https://raw.githubusercontent.com/unknown0152/dksubs-proxy-v2/master/add-nfo-cfs.py | sudo python3 -

Or if you cloned the repo:

sudo python3 /root/cosmos-deploy/DK/add-nfo-cfs.py

This creates 7 Custom Formats (NFO: Dolby Vision, NFO: HDR10+, NFO: HDR10, NFO: Atmos, NFO: TrueHD, NFO: DTS-HD MA, NFO: Remux) in both arrs and assigns them small bonus scores (+75 to +200) to the existing DanishAudio / EnglishSubs profiles. The helper is idempotent — re-running just updates existing scores in place.

Rollback:

sudo python3 /root/cosmos-deploy/DK/add-nfo-cfs.py --rollback   # scores → 0, CFs remain
sudo python3 /root/cosmos-deploy/DK/add-nfo-cfs.py --delete     # remove CFs entirely

See PR #4 for the full scoring rationale.

What gets configured

  • Radarr + Sonarr (and their -4k counterparts when present):
    • DKAudio and DKSubs custom formats (scored 10000, regex matches both legacy bracket tags AND new bracketless suffixes)
    • Audio codec CFs as tiebreakers: TrueHD Atmos (+2000), DTS-X (+1800), TrueHD (+1600), DTS-HD MA (+1400), EAC3 Atmos (+1200), EAC3 (+1000), DTS (+500), AAC (+100)
    • DanishAudio and EnglishSubs quality profiles (minFormatScore=10000, cutoff=Remux-2160p, upgrades enabled)
    • Low qualities disabled (CAM/TS/SDTV/DVD/480p/576p/HDTV-720p)
    • Quality Definitions: sane min/preferred/max MB/min for 720p/1080p/2160p
    • Indexer categories trimmed (SD/Other/3D/DVD dropped)
  • Prowlarr:
    • All indexers renamed <name> {DK} and rerouted via http://dksubs-proxy:9699/<id>
    • Application syncCategories trimmed; syncLevel set to addOnly so subsequent syncs don't undo the rewire
  • nzbdav:
    • Container deployed on media-stack network with /srv/config/nzbdav + /mnt + /srv/media (or MEDIA_DIR) mounts
    • Admin account, WebDAV creds, Usenet providers, and api.key written directly to the SQLite DB (no web-UI step)
    • Providers auto-imported from existing /srv/config/altmount/config.yaml if present
  • Host:
    • Latest rclone installed if Debian's apt version (1.60) is too old
    • rclone-nzbdav.service systemd unit mounting nzbdav's WebDAV at /mnt/nzbdav with --links
    • arr-force-import.timer running every 1 min — force-imports any Radarr/Sonarr queue items stuck in importPending/importBlocked (the workaround for nzbdav's obfuscated-NZB hash filenames)
  • dksubs-proxy:
    • Container on media-stack, .env with auto-detected indexer routing + DROP_NON_DK=1 filter mode + per-category min release sizes

How It Works

Radarr/Sonarr → dksubs-proxy:9699/{indexer_id} → Prowlarr → NZB Indexer
                      ↓
              [Scans titles + fetches NFOs]
                      ↓
              Returns tagged RSS to Radarr/Sonarr

NFO fetching uses two stages per release:

  1. Prowlarr's t=getnfo proxy (usually returns error 202 — most indexers don't support it via Prowlarr)
  2. Direct call to the indexer's own API using real API keys extracted from Prowlarr's database

Background model: The proxy returns partial results (title hits + fast NFO fetches) within 5 seconds. Slow NFO fetches continue in the background and populate the cache for the next poll.

Environment Variables

All variables are written to .env by setup-proxy.sh. You can override them manually:

Variable Default Description
PROWLARR_URL http://Prowlarr:9696 Prowlarr internal URL
PROWLARR_API_KEY (required) Prowlarr API key
NFO_INDEXERS auto-detected Comma-separated Prowlarr indexer IDs for NFO scanning
INDEXER_{id}_APIKEY auto Real API key for indexer (from Prowlarr's SQLite DB)
INDEXER_{id}_BASEURL auto Base URL for indexer
NFO_TIMEOUT 5.0 Foreground NFO fetch budget in seconds
NFO_DIRECT_RATE_CALLS 8 Max direct NFO API calls per rate window
NFO_DIRECT_RATE_WINDOW 10 Rate limit window in seconds
CACHE_TTL_NEGATIVE 2592000 Seconds before a "no Danish" result is retried (30d, extended from 6h in v5.6 — NZB IDs are immutable)
DEBUG_LOGGING 0 Set to 1 for verbose logs

Monitoring

# Live logs
docker logs -f dksubs-proxy

# Health check
curl http://dksubs-proxy:9699/health

# Metrics (JSON)
curl http://dksubs-proxy:9699/metrics

Metrics include: requests_total, hunt_total, dk_hits, nfo_fetches, nfo_direct_fetches, nfo_direct_hits, cache_hits, cache_misses.

After Changing Indexers in Prowlarr

bash setup-proxy.sh && docker compose up -d

Rate Limiting

Direct NFO API calls are rate-limited per indexer (default: 8 requests/10s). For indexers with stricter limits, add to .env:

INDEXER_{id}_RATE_CALLS=5
INDEXER_{id}_RATE_WINDOW=10

For indexers with very strict limits (e.g. 300 calls/5 min):

INDEXER_{id}_RATE_CALLS=250
INDEXER_{id}_RATE_WINDOW=300

Compatibility and stability

The .DKOK and .DKaudio release markers are considered stable wire-format markers. They are intentionally kept short and unchanged so existing Radarr/Sonarr custom formats continue to work across releases. The Custom Format regexes Radarr/Sonarr use also remain backward-compatible with legacy bracketed forms ([DK:Title], [DKAudio:Title], [DK-NFO], [DKAudio.Title], etc.) so any files already on disk continue to score correctly.

The project name, Docker image (ghcr.io/unknown0152/dksubs-proxy), environment variables (DKSUBS_PROXY_V56_FEATURES, DKSUBS_REGEX, etc.), Cosmos Market manifest, and container/service names all remain under the dksubs-proxy naming scheme for production compatibility. This is intentional, not legacy debt — renaming would cascade through GHCR, env, Cosmos, and deployed containers on multiple hosts with no functional benefit.

License

MIT — built for the home-lab community.

About

Language-aware Newznab enrichment proxy for the Arr stack with Danish audio/subtitle detection

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors