soulsync/core
Broque Thomas de2faf290b feat(torrent): add adapter layer for qBittorrent, Transmission, Deluge
Second commit in the torrent + usenet rollout. SoulSync now speaks
three different BitTorrent client APIs through one uniform adapter
contract — picks the active client by config and dispatches the same
verbs to whichever backend the user uses. Each adapter handles its
own auth quirk (qBit cookie + CSRF Referer, Transmission session-id
renegotiation, Deluge JSON-RPC session) and maps native state
strings onto a shared 7-value set so the rest of the app stays
client-agnostic.

- core/torrent_clients/base.py: TorrentClientAdapter Protocol +
  TorrentStatus dataclass. Eight verbs: is_configured, check_connection,
  add_torrent (URL/magnet), add_torrent_file (raw bytes), get_status,
  get_all, remove, pause, resume.
- core/torrent_clients/__init__.py: adapter_for_type factory +
  get_active_adapter that reads torrent_client.type each call so
  settings changes take effect without restart.
- core/torrent_clients/qbittorrent.py: WebUI v2 adapter. Cookie auth
  via /api/v2/auth/login, transparent 403 re-login, Referer header
  to satisfy qBit's CSRF guard. add_torrent returns the just-added
  hash via /torrents/info sort=added_on (qBit's add endpoint doesn't
  echo the hash).
- core/torrent_clients/transmission.py: RPC adapter. Auto-resolves
  bare host URLs to /transmission/rpc, handles the 409 + new
  X-Transmission-Session-Id renegotiation transparently, accepts
  HTTP basic auth. add_torrent_file base64-encodes payload per spec.
- core/torrent_clients/deluge.py: Deluge 2.x JSON-RPC adapter.
  Password-only auth, distinguishes magnet vs HTTP URL at the RPC
  method layer, applies category via Label plugin (best-effort —
  label plugin is optional).
- core/connection_test.py: 'torrent_client' branch picks the right
  adapter, runs check_connection, surfaces a per-client error
  message.
- config/settings.py: torrent_client.{type, url, username, password,
  category, save_path} defaults + torrent_client.password in the
  encrypted-at-rest secrets list.
- web_server.py: 'torrent_client' added to the /api/settings POST
  allow-list so saved config persists.
- webui/index.html: new Torrent Client panel on the Indexers &
  Downloaders tab — client-type dropdown, URL, username, password,
  category, optional save path, Test Connection.
- webui/static/settings.js: load/save wiring + testTorrentClientConnection.
- webui/static/helper.js: WHATS_NEW + VERSION_MODAL_SECTIONS entry.
2026-05-20 15:10:30 -07:00
..
artists Complete MusicBrainz watchlist source parity 2026-05-18 19:19:25 -07:00
automation Preserve personalized playlist metadata for wishlist 2026-05-15 21:50:32 -07:00
discovery Add MusicBrainz as a metadata source 2026-05-18 18:47:13 -07:00
download_engine Add module logger + surface silent exceptions in 7 logger-less files — 12 sites 2026-05-07 10:27:04 -07:00
download_plugins Wire Amazon Music as a first-class download source 2026-05-16 09:40:50 -07:00
downloads Enforce duration tolerance for strict sources 2026-05-20 11:24:57 -07:00
enrichment Surface silent exceptions across remaining modules — ~70 sites 2026-05-07 10:28:58 -07:00
imports fix(quarantine): drop already-quarantined sources from candidate picker (#652) 2026-05-19 21:19:50 -07:00
library fix(musicbrainz): user-facing search recall + album-detail 404 2026-05-19 15:38:24 -07:00
matching AcoustID + quarantine modal: three bug fixes (closes #607, closes #608) 2026-05-15 08:55:06 -07:00
media_server Server playlist sync: append mode (preserve user-added tracks) 2026-05-10 22:52:11 -07:00
metadata feat(webui): cache artwork images on disk 2026-05-20 10:43:47 -07:00
personalized Personalized pipeline: auto-refresh stale snapshots after watchlist scan 2026-05-15 20:53:03 -07:00
playlists Final silent-exception sweep + ruff S110 lint guardrail — ~45 sites 2026-05-07 11:16:06 -07:00
repair_jobs fix(repair): rewire Unknown Artist Fixer deferred imports (#646) 2026-05-19 22:09:15 -07:00
search Wire Amazon Music into enhanced search and global search source picker 2026-05-16 14:18:18 -07:00
stats Surface silent exceptions across remaining modules — ~70 sites 2026-05-07 10:28:58 -07:00
streaming Cin-6: Rename soulseek_client global → download_orchestrator 2026-05-04 23:23:32 -07:00
sync Persist Find & Add selections as permanent server-playlist match overrides 2026-05-14 09:39:24 -07:00
torrent_clients feat(torrent): add adapter layer for qBittorrent, Transmission, Deluge 2026-05-20 15:10:30 -07:00
watchlist Complete MusicBrainz watchlist source parity 2026-05-18 19:19:25 -07:00
webui Extract WebUI asset helpers 2026-05-13 22:26:25 +03:00
wishlist Honor manual library matches across source labels 2026-05-18 16:32:38 -07:00
workers Final silent-exception sweep + ruff S110 lint guardrail — ~45 sites 2026-05-07 11:16:06 -07:00
acoustid_client.py Clean up 286 ruff lint errors to unblock CI and fix 10 latent bugs 2026-04-21 13:30:52 -07:00
acoustid_verification.py AcoustID + quarantine modal: three bug fixes (closes #607, closes #608) 2026-05-15 08:55:06 -07:00
album_consistency.py Surface silent exceptions across remaining modules — ~70 sites 2026-05-07 10:28:58 -07:00
amazon_client.py fix(amazon): search albums/artists and track numbers for t2tunes 2026-05-19 14:04:26 -07:00
amazon_download_client.py Amazon download client: write final size==transferred before returning file path 2026-05-16 11:09:04 -07:00
amazon_worker.py Harden Amazon worker schema migration 2026-05-18 15:47:04 -07:00
api_call_tracker.py Wire Amazon Music as a first-class download source 2026-05-16 09:40:50 -07:00
artist_source_detail.py Fix MusicBrainz artist detail showing MBID as name 2026-05-19 12:34:35 -07:00
artist_source_lookup.py Add amazon_id column to artists table for full source parity 2026-05-16 17:06:54 -07:00
audiodb_client.py Add API Rate Monitor dashboard with real-time speedometer gauges 2026-04-02 10:46:43 -07:00
audiodb_worker.py AudioDB worker: stop infinite loop on direct-ID lookup failure (#553) 2026-05-11 14:18:55 -07:00
auto_import_worker.py Auto-import: fall through to other metadata sources when primary returns no match 2026-05-12 12:32:18 -07:00
automation_engine.py Final silent-exception sweep + ruff S110 lint guardrail — ~45 sites 2026-05-07 11:16:06 -07:00
connection_detect.py Final silent-exception sweep + ruff S110 lint guardrail — ~45 sites 2026-05-07 11:16:06 -07:00
connection_test.py feat(torrent): add adapter layer for qBittorrent, Transmission, Deluge 2026-05-20 15:10:30 -07:00
database_update_worker.py Final silent-exception sweep + ruff S110 lint guardrail — ~45 sites 2026-05-07 11:16:06 -07:00
debug_info.py Fix Copy Debug Info music_source + surface missing services 2026-05-12 16:47:55 -07:00
deezer_client.py Fix Deezer contributors tagging silently dropping for cache-polluted tracks 2026-05-14 11:10:51 -07:00
deezer_download_client.py Surface silent exceptions in metadata clients — 37 sites 2026-05-07 09:33:38 -07:00
deezer_worker.py Surface silent exceptions in workers + repair jobs — ~30 sites 2026-05-07 10:27:24 -07:00
discogs_client.py Surface silent exceptions in metadata clients — 37 sites 2026-05-07 09:33:38 -07:00
discogs_worker.py Surface silent exceptions in workers + repair jobs — ~30 sites 2026-05-07 10:27:24 -07:00
download_orchestrator.py Wire Amazon Music as a first-class download source 2026-05-16 09:40:50 -07:00
genius_client.py Add API Rate Monitor dashboard with real-time speedometer gauges 2026-04-02 10:46:43 -07:00
genius_worker.py Surface silent exceptions in workers + repair jobs — ~30 sites 2026-05-07 10:27:24 -07:00
genre_filter.py Expand default genre whitelist from 223 to 272 genres 2026-04-18 20:32:49 -07:00
hifi_client.py Surface engine-not-wired errors + exclude soulseek from monitor aggregation 2026-05-05 12:20:51 -07:00
hydrabase_client.py feat: add explicit badges to discography modal and artist-detail cards 2026-05-12 23:35:08 -04:00
hydrabase_worker.py Improve graceful shutdown and rollback safety 2026-04-12 15:17:18 +03:00
image_cache.py feat(webui): cache artwork images on disk 2026-05-20 10:43:47 -07:00
itunes_client.py feat: add explicit badges to discography modal and artist-detail cards 2026-05-12 23:35:08 -04:00
itunes_worker.py Surface silent exceptions in workers + repair jobs — ~30 sites 2026-05-07 10:27:24 -07:00
jellyfin_client.py Server playlist sync: append mode (preserve user-added tracks) 2026-05-10 22:52:11 -07:00
lastfm_client.py Add Last.fm Track Radio to Discover page 2026-04-14 23:41:36 -07:00
lastfm_worker.py Surface silent exceptions in workers + repair jobs — ~30 sites 2026-05-07 10:27:24 -07:00
library_reorganize.py Reorganize: optional embedded-tag mode (closes #592) 2026-05-15 07:56:18 -07:00
lidarr_download_client.py Surface silent exceptions across remaining modules — ~70 sites 2026-05-07 10:28:58 -07:00
listenbrainz_client.py Remove emojis from all Python log and print statements 2026-04-11 21:11:02 -07:00
listenbrainz_manager.py Final silent-exception sweep + ruff S110 lint guardrail — ~45 sites 2026-05-07 11:16:06 -07:00
listening_stats_worker.py Final silent-exception sweep + ruff S110 lint guardrail — ~45 sites 2026-05-07 11:16:06 -07:00
lyrics_client.py Retag now re-embeds LYRICS tag instead of leaving it empty 2026-05-14 15:52:05 -07:00
matching_engine.py Merge remote-tracking branch 'origin/dev' into refactor/media-server-engine 2026-05-05 20:36:31 -07:00
metadata_service.py Add MusicBrainz as a metadata source 2026-05-18 18:47:13 -07:00
musicbrainz_client.py fix(musicbrainz): user-facing search recall + album-detail 404 2026-05-19 15:38:24 -07:00
musicbrainz_search.py fix(metadata): surface MusicBrainz 'Other' release-groups in discography (#650) 2026-05-19 20:20:28 -07:00
musicbrainz_service.py Cross-script artist aliases: include canonical name + non-strict fallback 2026-05-14 13:07:15 -07:00
musicbrainz_worker.py Alias resolution polish: lazy-fire on direct-match failure + worker backfill 2026-05-10 17:02:02 -07:00
navidrome_client.py Server playlist sync: append mode (preserve user-added tracks) 2026-05-10 22:52:11 -07:00
personalized_playlists.py Add MusicBrainz as a metadata source 2026-05-18 18:47:13 -07:00
plex_client.py Server playlist sync: append mode (preserve user-added tracks) 2026-05-10 22:52:11 -07:00
prowlarr_client.py feat(settings): add Prowlarr integration as indexer aggregator 2026-05-20 14:41:54 -07:00
qobuz_client.py Address Copilot doc-drift review 2026-05-05 15:46:48 -07:00
qobuz_worker.py Surface silent exceptions in workers + repair jobs — ~30 sites 2026-05-07 10:27:24 -07:00
reorganize_queue.py Reorganize: optional embedded-tag mode (closes #592) 2026-05-15 07:56:18 -07:00
reorganize_runner.py Reorganize: optional embedded-tag mode (closes #592) 2026-05-15 07:56:18 -07:00
repair_worker.py AcoustID scanner: multi-candidate match + duration guard + multi-value retag 2026-05-14 14:09:38 -07:00
replaygain.py Add module logger + surface silent exceptions in 7 logger-less files — 12 sites 2026-05-07 10:27:04 -07:00
runtime_state.py Add module logger + surface silent exceptions in 7 logger-less files — 12 sites 2026-05-07 10:27:04 -07:00
seasonal_discovery.py Fix source artist detail navigation from discover modals 2026-05-18 13:50:10 -07:00
socketio_cors.py Socket.IO CORS: handle self-review nits 2026-04-26 19:24:43 -07:00
soulid_worker.py Surface silent exceptions in workers + repair jobs — ~30 sites 2026-05-07 10:27:24 -07:00
soulseek_client.py fix(quarantine): drop already-quarantined sources from candidate picker (#652) 2026-05-19 21:19:50 -07:00
soulsync_client.py Surface silent exceptions across remaining modules — ~70 sites 2026-05-07 10:28:58 -07:00
soundcloud_client.py Surface engine-not-wired errors + exclude soulseek from monitor aggregation 2026-05-05 12:20:51 -07:00
spotify_client.py Add download buttons + bulk action to artist top-tracks sidebar 2026-05-07 15:44:47 -07:00
spotify_public_scraper.py Add Spotify Link tab for public playlist/album scraping without API credentials 2026-03-15 21:25:05 -07:00
spotify_worker.py Surface silent exceptions in workers + repair jobs — ~30 sites 2026-05-07 10:27:24 -07:00
tag_writer.py AcoustID scanner: multi-candidate match + duration guard + multi-value retag 2026-05-14 14:09:38 -07:00
tidal_client.py Your Albums: selectable wishlist modal + Tidal album resolution 2026-05-11 12:36:16 -07:00
tidal_download_client.py Handle non-JSON Tidal auth responses 2026-05-20 14:04:45 -07:00
tidal_worker.py Surface silent exceptions in workers + repair jobs — ~30 sites 2026-05-07 10:27:24 -07:00
watchlist_scanner.py Fix missing album art for non-Spotify sources + animate Downloads nav icon 2026-05-18 20:24:13 -07:00
web_scan_manager.py MS Cin-5: Drop per-server globals — engine owns the clients 2026-05-05 18:05:45 -07:00
wishlist_service.py Extract wishlist logic into dedicated package 2026-04-28 21:17:24 +03:00
worker_utils.py Fix Album Completeness job reporting zero findings for every album 2026-04-24 12:39:41 -07:00
youtube_client.py Drop redundant import sys inside _auto_download_disabled 2026-05-08 15:51:16 -07:00