Summary
Ships SoulSync 2.5.9.
This release adds the first production-ready torrent/usenet download path, fixes several user-reported reliability issues, and updates the in-app release notes so the version modal and What's New panel describe the actual 2.5.9 changes.
Highlights
- Adds torrent and usenet as Prowlarr-backed download sources.
- Uses release staging for torrent/usenet album downloads so SoulSync downloads one release, watches progress, and imports the matching tracks from the staged files.
- Keeps torrent/usenet gated: they only run when selected as the primary source, or in hybrid mode for non-album downloads.
- Fixes HiFi instance detection for public hifi-api instances that expose playable manifests through the legacy
/track/flow. - Repairs older Jellyfin media databases before full refresh so missing
tracks.file_sizeandalbums.api_track_countcolumns do not block track imports. - Retries transient SQLite disk I/O failures during cache maintenance and the Tools page full-refresh job.
- Prevents Album Completeness from filling missing tracks with same-title releases from the wrong artist.
- Bumps app and Docker release defaults to
2.5.9.
Torrent / Usenet Behavior
- Single-source torrent/usenet album downloads use the release-bundle staging flow.
- Hybrid album downloads skip torrent/usenet and continue through normal per-track-capable sources.
- Hybrid playlist, wishlist, and other non-album downloads may use torrent/usenet when those sources are included in the hybrid order.
- SoulSync must be able to read the downloader save path after the torrent/usenet client finishes.
- Library history records the real source label for new torrent/usenet imports.
Fixes Included
- HiFi instances are no longer marked
Search onlyjust because they use the public hifi-api manifest shape. - Full Jellyfin refresh no longer imports artists/albums while failing all track inserts on stale schemas.
- Cache maintenance and full refresh are more resilient to short-lived SQLite
disk I/O errorfailures. - Album Completeness now prioritizes artist identity over same-title album/single matches.
- The recent updates modal and What's New panel now lead with 2.5.9 release notes.
Testing
Automated checks run during development:
.venv/bin/python -m pytest \
tests/downloads/test_downloads_status.py \
tests/test_album_bundle_dispatch.py \
tests/downloads/test_downloads_staging.py \
tests/test_torrent_usenet_plugins.py.venv/bin/python -m pytest \
tests/downloads/test_downloads_validation.py \
tests/test_manual_pick_no_auto_retry.py \
tests/downloads/test_downloads_post_processing.py \
tests/downloads/test_downloads_task_worker.py \
tests/imports/test_import_side_effects.py.venv/bin/python -m pytest tests/test_repair_worker_album_fill.py -k "artist_mismatch or wrong_artist_candidate".venv/bin/python -m pytest tests/test_library_disk_usage.py tests/test_worker_utils_album_track_count.py -k "legacy_media_schema or file_size_column or insert_or_update_media_track_persists or api_track_count".venv/bin/python -m pytest tests/test_database_io_resilience.py tests/metadata/test_cache_maintenance_retry.py.venv/bin/python -m pytest tests/downloads/test_hifi_pinning.py -k "instance_capability_probe or get_hls_manifest or download_"Manual checks:
- Torrent-only album download flow.
- Torrent playlist/single-track flow.
- Album-bundle progress in the download modal and Downloads page.
- Torrent source labels in library history for new imports.
- Staging match behavior for featured-artist filenames, bonus-track labels, and wrong-version separation.
- HiFi settings probe against public instances that were previously shown as
Search only.
Reviewer Notes
- Torrent/usenet support is intentionally gated behind source selection, but it is still a new release-oriented download path and should be treated as beta for this first release.
- Remote downloader setups need path mapping or shared storage so SoulSync can read completed files.
- Existing library history rows previously recorded with the wrong source label are not backfilled.
- The HiFi settings page can still show an instance as offline when the upstream API is genuinely returning 502/offline, even if the browser landing page loads.