Commit Graph

21 Commits

Author SHA1 Message Date
140bfef7c9 feat: yt-dlp cookie support + surface real failure reason; default workers 4
Bulk --repair on unauthenticated YouTube trips the bot-check (HTTP 429 "Sign
in to confirm you're not a bot"), after which every call fails until the IP
flag clears. Add cookie support so authenticated requests bypass it:

- --cookies FILE / --cookies-from-browser BROWSER (and $YTDLP_COOKIES /
  $YTDLP_COOKIES_FROM_BROWSER for the API container), threaded into every
  yt-dlp invocation (search, probe, download, repair metadata fetch).
- run_yt_dlp_get_metadata now logs yt-dlp's last stderr line (the actual 429 /
  bot-check / network reason) instead of a bare exit code.
- Default --repair workers lowered 8 -> 4 (safe without cookies; raise with).
- compose: optional YTDLP_COOKIES env + commented cookies mount.
- README: how to obtain cookies (Chrome/Firefox, browser-read vs cookies.txt
  export); gitignore cookies.txt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 11:25:39 -07:00
0347a638cf fix: reliable YouTube tagging, loud Lidarr failures, deno runtime, repair recovery
Root cause of bad album/title tags: yt-dlp's --parse-metadata reads a
single-word FROM (matching field_to_template's ^[a-zA-Z_]+$) as a *field
name*, so literal one-word titles/albums like "Cochise" became "NA". Inject
literals via seed-then-replace into meta_<tag> instead (--parse-metadata to
create the field, --replace-in-metadata with literal args to set it), which
is immune to template parsing and also creates tags the source lacks.

- yt_download: literal-safe meta_artist/title/album; hit album no longer
  clobbered by the Unknown-Album default; artist tag now created when missing.
- lidarr_search: connection/timeout errors surface via err() ("Lidarr
  unreachable … falling back to YouTube") instead of silent dbg(), so the
  YouTube fallback isn't mistaken for "no Lidarr match".
- Dockerfile: install deno (arch-aware) — the JS runtime yt-dlp needs for
  YouTube; without it: "No supported JavaScript runtime" / HTTP 403.
- repair: treat NA/Unknown placeholders as bogus and overwrite title/artist
  from source (was fill-missing-only); normalise literal "NA" album to
  "Unknown Album"; rename bogus "NA [<id>]" filenames to the recovered title.
- README updated; .gitignore excludes server/log.txt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 11:09:27 -07:00
33ca743a34 removed useless portion of compose 2026-06-11 22:02:51 -07:00
530b5b0406 typo in mutagen. fixed 2026-06-11 21:51:16 -07:00
0a4e6d474a added mutagen to requirements.txt 2026-06-11 21:48:33 -07:00
f103b6c253 feat: multi-platform URL & playlist support via yt-dlp probe
Generalize URL handling beyond YouTube to any yt-dlp-supported site
(SoundCloud, Bandcamp, etc), single tracks and playlists/sets/albums.

- probe_url(): one yt-dlp --flat-playlist probe classifies playlist vs track
  and returns per-entry Hits; YouTube playlists still use ytmusicapi.
- _track_url(): YouTube tracks keep the music.youtube album-art URL; other
  platforms download via their native entry URL (no more videoId reconstruction).
- Per-source folders: <root>/<artist>/<extractor>/ (soundcloud/bandcamp/youtube)
  instead of hardcoded youtube; download_single derives source from metadata.
- download_hits() downloads pre-probed Hits; API probes once and passes hits
  into the job closure. Replaces YouTube-only is_playlist_url/expand_playlist.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 00:25:58 -07:00
90b9a01872 fix(server): use .get() for title/artist in perform_url_fetch result
Defensive access guards against download_single returning ok=True
without title/artist keys, avoiding a KeyError in the job worker.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 00:00:45 -07:00
0f7ddd7697 feat(server): route URL/playlist /fetch to download jobs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 23:58:37 -07:00
ca36d2bb27 feat(server): re-export URL helpers; callable job done_message
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 23:54:49 -07:00
425a973d85 fix: write single first-artist tag, not doubled/multi-artist
Live end-to-end test surfaced two bugs in youtube tagging:
- `--replace-in-metadata artist .* NAME` matched twice and doubled the
  artist tag (e.g. "SLVMLORDSLVMLORD"). Anchor with ^.*$ to match once.
- Use only the first artist when several are present (SLVMLORD, not
  "SLVMLORD, Travis Bradley, ...") for both the embedded tag and the
  spoken/echoed API messages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 20:39:03 -07:00
9984c162c6 fix(server): return {message} body for request validation errors
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 20:27:00 -07:00
eecf0836f7 fix(server): make .dockerignore effective at repo root, pin yt-dlp in requirements
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 20:23:37 -07:00
809de44e2e feat(server): Dockerfile and compose for the Lidarr stack
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 20:21:14 -07:00
d4c1b18e58 feat(server): /fetch and /jobs endpoints with async download jobs
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 20:15:28 -07:00
49a45e6270 feat(server): FastAPI app with API-key auth and health check
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 20:09:50 -07:00
257ed5e0a5 fix(server): announce track title not album in messages; cover error paths
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 20:07:09 -07:00
9912eb48a4 feat(server): action dispatch with structured result and messages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 20:02:18 -07:00
09a0d7e682 fix(server): harden job eviction and worker against missing job id
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 19:59:31 -07:00
35df01f08e feat(server): in-memory async job store with thread-pool worker
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 19:55:57 -07:00
c46ff2ff1a refactor(server): register loaded module in sys.modules, add __all__
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 19:54:37 -07:00
ad660afae3 feat(server): load musicfetch binary as importable module
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-08 19:49:18 -07:00