soulsync/core/download_plugins
Tyler Richardson-LaPlume 0b325da3e9 Usenet bundle: writable staging dir + client→local path resolution (#721)
Follow-up to the poll fix, covering the two things that blocked a
successful end-to-end album import once the poll itself stopped
freezing:

1. Staging dir permissions
   The album-bundle private staging path defaults to
   'storage/album_bundle_staging' -> /app/storage, but /app/storage was
   never created or chowned by the image (unlike /app/Staging,
   /app/Transfer, etc.), and /app is root-owned. The copy failed with
   "[Errno 13] Permission denied: 'storage'" under the non-root soulsync
   UID. Added /app/storage to the Dockerfile build-time mkdir+chown and
   the entrypoint PUID/PGID chown, exactly like the sibling runtime dirs.

2. Client->local path resolution
   Usenet/torrent clients report save paths from inside THEIR OWN
   container (e.g. SAB '/data/downloads/music/<album>'); SoulSync often
   mounts the same files at a different point ('/app/downloads/<album>').
   Feeding the client path straight to the audio walker yields
   "No audio files found" though the files are physically present.
   New resolve_reported_save_path():
     a. use the reported path as-is if readable (mirrored mounts),
     b. apply explicit download_source.usenet_path_mappings
        ({from,to}, Sonarr/Radarr-style) for non-shared layouts,
     c. basename fallback under SoulSync's own download roots —
        zero-config for the standard shared-volume arr setup.
   Wired into both call sites in usenet.py AND torrent.py
   (download_album_to_staging + _finalize_download), logging any
   translation and including the resolved path in the no-audio error.

Tests: resolver verbatim / explicit-mapping / basename-fallback /
priority / not-found / empty / mapping-miss-then-basename. ruff +
compileall + pytest green (645 in the download suites).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 02:04:47 -04:00
..
__init__.py Cin-1: Make DownloadSourcePlugin inheritance explicit on every client 2026-05-04 22:19:52 -07:00
album_bundle.py Usenet bundle: writable staging dir + client→local path resolution (#721) 2026-05-29 02:04:47 -04:00
base.py Address Copilot doc-drift review 2026-05-05 15:46:48 -07:00
registry.py feat(downloads): wire torrent + usenet as live download sources 2026-05-20 17:22:19 -07:00
torrent.py Usenet bundle: writable staging dir + client→local path resolution (#721) 2026-05-29 02:04:47 -04:00
types.py Add torrent and usenet release staging support 2026-05-21 14:22:21 -07:00
usenet.py Usenet bundle: writable staging dir + client→local path resolution (#721) 2026-05-29 02:04:47 -04:00