Skip to content
 
 

Repository files navigation

Crunchy Downloader Python Rewrite

This is the Python 3.14 + uv rewrite foundation for Crunchy Downloader. It is intentionally CLI-first and Linux/Docker-first, with the browser UI served by the same Python app so the downloader engine remains the source of truth.

Current Slice

  • crd doctor verifies Python version, app directories, and external tools.
  • crd doctor --json prints the same local diagnostics as stable JSON for scripts.
  • crd version prints the package version and Python runtime target.
  • crd web serve starts the local Python-backed web UI on 127.0.0.1:7860 by default. The Vue 3 + Vite UI is served at /; /vue/ remains a compatibility alias. The UI includes dashboard, add-download preview/queueing, queue inspection/actions, account status/actions including credentials-file login, subscription/profile details, validated settings editing, local history review/marking/queue-missing with saved sort/filter views, and calendar views with week navigation, filtering, visible episode queueing, Sonarr status/search/manual matching/sync controls, release checklist/update-status review, redacted log viewing, and debug summary/bundle support. The web surface has every-page render smoke coverage, redaction-sensitive API smoke coverage, and a local browser smoke checklist in docs/web_browser_smoke.md.
  • crd web desktop and crd web desktop-file --output PATH are deprecated compatibility wrappers around the browser server. They do not create separate queue, history, config, token, or download schemas, and they are no longer the primary UI path.
  • All non-version commands write redacted JSONL lifecycle logs to logs/crd.log.jsonl by default; use global --log-file PATH, --verbose, or --quiet to adjust logging.
  • Known CLI failures include stable CRD-* error codes in stderr and structured logs.
  • crd debug bundle --output PATH writes a redacted diagnostic zip with local settings, queue, token status, doctor output, and optional history.
  • crd config import-legacy <old-config-dir> imports old CRD settings into a v1 schema.
  • crd config import-legacy <old-config-dir> --include-secrets also imports legacy token files into Python-owned tokens.v1.json.
  • crd auth import-legacy-tokens <old-config-dir> imports only old CRD token files when settings import is not desired or a legacy settings value needs manual cleanup first.
  • crd config show|get|set|path inspects and updates validated Python-owned settings.
  • By default, local JSON app files live under ./config/; use --app-dir, CRD_HOME, or the Docker /crd-data mount to redirect the full app data directory.
  • crd history import-legacy <history.json> imports old history JSON without modifying it.
  • crd search <query> lists Crunchyroll series metadata, with --json for scripts.
  • crd download <url-or-id> resolves Crunchyroll episode, season, series, movie, music video, concert, artist, and featured-music metadata and queues normalized item(s). Artist and featured-music sources require --all.
  • crd calendar crunchyroll|anilist|upcoming lists Crunchyroll simulcast calendar entries and Crunchyroll-linked AniList seasonal/upcoming entries with cached mocked-test-friendly HTTP.
  • crd sonarr status|series search|match-series|match-episode|sync checks Sonarr, searches existing Sonarr series, stores Sonarr IDs/file flags in history, and can queue monitored Sonarr-missing Crunchyroll history episodes.
  • crd notify test --event EVENT --provider PROVIDER sends a configured test notification through webhook, execute-command, local-file, or sound providers. Queue runs publish download-finished, download-failed, and queue-finished events as best-effort notifications.
  • crd protected tools status [--json] reports optional Bento4 mp4decrypt and Shaka Packager helper availability for diagnostics.
  • crd protected encrypted plan ITEM_ID --track MEDIA:TRACK_ID:PATH [--json] prepares a protected/encrypted media handoff plan from already-downloaded track files.
  • crd protected encrypted handoff ITEM_ID --track MEDIA:TRACK_ID:PATH [--json] routes that handoff through the protected/encrypted handler shell.
  • Protected-media helper paths are configured with protected_media.mp4decrypt_path, protected_media.shaka_packager_path, and protected_media.widevine_device_path. User-owned device files should live outside version control, for example under the ignored local config/ directory. The default device path is config/widevine/device.wvd.
  • Browser-auth inputs are read from user-provided files under the ignored local config/auth/ directory by default. See config/README.md for the local file layout and config/examples/ for placeholder credentials.json, cookies.json, and browser-token.json formats.
  • HTTP challenge pages can be classified on every shared HTTP path. When network.use_flare_solverr is enabled, the client uses the configured network.flare_solverr_url FlareSolverr-compatible /v1 endpoint to resolve the challenged request and keeps solved cookies/user-agent only in memory.
  • crd queue add|list|remove|clear|run manages a persistent v1 queue; queue run orchestrates planning, segment/sidecar download, muxing, and v1 history marking for pending items. Queue runs can retry failed work, select failed batches with --failed, cap work with --limit, preview with --dry-run, and skip history updates with --no-history. When crunchyroll.mark_as_watched is enabled, queue-run marks the episode watched after a successful local output only; the profile action is best-effort and secret-free in output. Set download.debug_logging=true for append-only queue-run debug lines on stderr and redacted download_debug JSONL events in the active log file.
  • crd queue work list|clean inspects queue-run work directories and cleans selected failed, known, or orphaned work files without touching final output directories.
  • crd queue plan <item-id> [--segments] inspects playback artifacts and transient manifest plans.
  • crd queue download-segments <item-id> --output PATH writes selected manifest track bytes to deterministic per-track files with resume support.
  • crd queue download-artifacts <item-id> --output PATH writes raw subtitles, captions, BIFs, images, and description sidecars without conversion.
  • crd queue convert-subtitles <item-id> --input PATH --output PATH converts raw ASS/VTT/SRT sidecars into mux-ready subtitle files while preserving the raw downloads.
  • crd queue generate-chapters <item-id> --input PATH --output PATH converts raw BIF/storyboard sidecars into mux-ready .ffmetadata chapters while preserving the raw BIF files.
  • crd queue sync-timing-plan <item-id> --output PATH --delay audio:ja-JP=120 builds a dry-run timing sidecar, and crd queue sync-timing writes it for mux planning.
  • crd queue sync-video-plan <item-id> --base-video BASE --compare-video DUB --language ja-JP measures two local video tracks and previews an automatic timing sidecar; crd queue sync-video writes the same sidecar format for mux planning.
  • crd queue mux-plan <item-id> --input PATH --output PATH builds a dry-run ffmpeg/mkvmerge command from downloaded tracks and sidecars, including generated chapters, MKV font attachments, sync timing sidecars, and audio-only MP3 output when configured.
  • crd queue mux <item-id> --input PATH --output PATH executes the planned ffmpeg/mkvmerge command and writes the final container file.
  • crd queue encode-plan <item-id> --input PATH --output PATH builds a dry-run post-mux ffmpeg encode command from the selected preset.
  • crd queue encode <item-id> --input PATH --output PATH executes that post-mux encode; queue run uses the same step when muxing.encode_enabled is set.
  • crd auth status|browser import|device start|device poll|diagnose|login --anonymous|login --credentials-file PATH|refresh|profile|profiles|use-profile|endpoint|logout manages browser-session auth, device-code probing, anonymous/token auth, legacy credentials-file login, and redacted endpoint client-setting overrides.
  • The root Dockerfile builds the Python CLI runtime with Python 3.14, uv, ffmpeg, mkvmerge, non-root UID/GID 10001:10001, /crd-data app storage, and /downloads output mounts.
  • crd version --json reports cli_contract_version=1; script-facing JSON output is documented in docs/v1_cli_json_contracts.md.

Live auth/search/metadata calls are available, but tests use mocked transports by default. The living parity checklist is maintained in docs/python_rewrite_parity_checklist.md. The production beta gate is maintained in docs/beta_release_checklist.md. The current error-code catalog is documented in docs/error_codes.md.

Local Commands

uv run crd doctor
uv run crd --log-file /crd-data/logs/crd.log.jsonl doctor --json
uv run crd version
uv run crd web serve
uv run crd debug bundle --output /crd-data/logs/debug.zip
uv run crd search "Frieren"
uv run crd download EPISODE_ID --dub ja-JP --subs en-US
uv run crd download movie:MOVIE_ID --dub ja-JP --subs none
uv run crd download artist:ARTIST_ID --all --subs none
uv run crd calendar crunchyroll --week 2026-05-18 --json
uv run crd calendar anilist --season SPRING --year 2026
uv run crd calendar upcoming --from 2026-05-18 --days 7
uv run crd sonarr status --json
uv run crd sonarr series search "Frieren"
uv run crd sonarr sync --queue-missing --json
uv run crd notify test --event queue-finished --provider local-file --json
uv run crd protected tools status --json
uv run crd config set protected_media.mp4decrypt_path /opt/homebrew/bin/mp4decrypt
uv run crd auth browser import-token --authorization "Basic paste-browser-client-authorization-header" --user-agent "Mozilla/5.0 ..."
uv run crd protected encrypted plan ITEM_ID --track video:v720:/downloads/ITEM_ID-video-v720.bin --json
uv run crd protected encrypted handoff ITEM_ID --track video:v720:/downloads/ITEM_ID-video-v720.bin --tool shaka-packager --timeout 120 --json
uv run crd config set network.use_flare_solverr true
uv run crd config set network.flare_solverr_url http://localhost:8191
uv run crd auth diagnose --operation credentials --credentials-file credentials.json --endpoint android --json
uv run crd auth browser import --cookies-file crunchyroll-cookies.json --endpoint browser
uv run crd auth browser import-token --token-file browser-token.json --cookies-file crunchyroll-cookies.json --endpoint browser --auth-url https://www.crunchyroll.com/auth/v1/token
uv run crd auth browser import-token --endpoint browser
uv run crd auth refresh --endpoint browser
uv run crd auth device start --endpoint device
uv run crd auth device poll --endpoint device --device-code DEVICE_CODE
uv run crd auth login --credentials-file credentials.json --solve-challenge
uv run crd --app-dir /crd-data queue list
uv run crd --app-dir /crd-data queue run
uv run crd --app-dir /crd-data queue work list
uv run crd --app-dir /crd-data queue work clean --failed
uv run crd --app-dir /crd-data queue download-segments ITEM_ID --output /downloads
uv run crd --app-dir /crd-data queue download-artifacts ITEM_ID --output /downloads
uv run crd --app-dir /crd-data queue convert-subtitles ITEM_ID --input /downloads --output /downloads
uv run crd --app-dir /crd-data queue generate-chapters ITEM_ID --input /downloads --output /downloads
uv run crd --app-dir /crd-data queue sync-timing ITEM_ID --output /downloads --delay audio:ja-JP=120
uv run crd --app-dir /crd-data queue sync-video ITEM_ID --base-video /downloads/base.bin --compare-video /downloads/dub.bin --language ja-JP --output /downloads
uv run crd --app-dir /crd-data queue mux-plan ITEM_ID --input /downloads --output /downloads/out.mkv
uv run crd --app-dir /crd-data queue mux ITEM_ID --input /downloads --output /downloads/out.mkv
uv run crd --app-dir /crd-data queue encode-plan ITEM_ID --input /downloads/out.mkv --output /downloads/out-encoded.mkv
uv run crd --app-dir /crd-data queue encode ITEM_ID --input /downloads/out.mkv --output /downloads/out-encoded.mkv
uv run crd --app-dir /crd-data auth login --credentials-file /run/secrets/crd-credentials.json
uv run pytest
uv run ruff check
uv run ty check

Docker Runtime

docker build -t crunchy-downloader-python:local .
mkdir -p .crd-data/{config,cache,temp,video,logs} downloads
docker run --rm crunchy-downloader-python:local version
docker run --rm -v "$PWD/.crd-data:/crd-data" -v "$PWD/downloads:/downloads" crunchy-downloader-python:local doctor --json
docker run --rm -v "$PWD/.crd-data:/crd-data" -v "$PWD/downloads:/downloads" crunchy-downloader-python:local queue run --output /downloads

On Linux hosts, make the mounted paths writable by the image user with sudo chown -R 10001:10001 .crd-data downloads. Full Docker notes are in docs/docker.md.

Auth Setup

Live Crunchyroll auth currently works best through a user-owned browser session. Keep real auth material under ignored local paths such as config/auth/ and config/widevine/; do not commit cookies, bearer tokens, Authorization headers, credentials, WVD files, or downloaded media. The expected local layout is documented in config/README.md, and the config/examples/ directory contains placeholder formats:

  • config/examples/cookies.example.json shows the JSON cookie export shape accepted by crd auth browser import and import-token. Netscape cookie exports are also accepted.
  • config/examples/browser-token.example.json shows the browser token response fields expected by crd auth browser import-token.
  • config/examples/credentials.example.json shows the legacy username/password credentials-file shape.

For browser auth, provide:

  • A cookie export from your own logged-in Crunchyroll browser session.
  • A token JSON copied from your own browser token response, containing at least access_token, refresh_token, and expires_in.
  • Optional one-off browser client details, such as the browser request's Authorization header value or user-agent, as crd auth browser import-token flags when needed.
  • mp4decrypt and a user-owned Widevine device file if you plan to process protected media.

Place the user-owned auth files in the ignored local config directory:

mkdir -p config/auth config/widevine
cp config/examples/credentials.example.json config/auth/credentials.json
cp config/examples/cookies.example.json config/auth/cookies.json
cp config/examples/browser-token.example.json config/auth/browser-token.json

uv run crd config set protected_media.mp4decrypt_path /opt/homebrew/bin/mp4decrypt

Then import and refresh with short commands:

uv run crd auth browser import-token --endpoint browser
uv run crd auth profile --endpoint browser
uv run crd auth refresh --endpoint browser

Flags override conventional files. For one-off imports, pass --token-file, --cookies-file, --authorization, --auth-url, --playback-endpoint, and --user-agent directly.

Browser-session import stores cookies in sessions.v1.json with redacted debug-bundle output. Browser token import stores token metadata in tokens.v1.json; refresh uses stored endpoint metadata and browser cookies so the short-lived access token does not need to be pasted repeatedly. Device-code login is probed through standard OAuth device-code endpoints and works only if Crunchyroll exposes a compatible response for the configured endpoint/client.

Credentials-file login expects JSON such as {"username":"name@example.test","password":"account-password"}. The file is read once, not copied into app storage, and credentials are redacted from logs. Crunchyroll may reject this legacy OAuth grant/client combination; prefer browser-session import or device-code login when available. Run live account tests only in a throwaway app directory. Use crd auth endpoint set NAME --authorization "Basic ..." --user-agent "..." only for user-supplied Crunchyroll client settings you are allowed to use; show and list always redact the stored Authorization header.

Release notes and smoke-test prompts live in docs/release_notes_template.md, docs/smoke_checklist.md, docs/web_browser_smoke.md, and docs/desktop_wrapper.md.

Deprecated desktop compatibility commands are documented in docs/desktop_wrapper.md for existing launcher users, but new workflows should use crd web serve and open the browser UI directly.

If Python 3.14 is not installed locally, use python3 -m unittest discover for syntax-level development feedback until the target interpreter is available.

About

My personal python rewrite of the forked Crunchy-Downloader project

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages