#857: custom in-container completed-downloads path for Torrent/Usenet sources (settings + UI; resolver already consumed the keys)
This commit is contained in:
parent
15067b63ca
commit
2428df1144
4 changed files with 58 additions and 0 deletions
|
|
@ -508,6 +508,22 @@ class ConfigManager:
|
|||
# its partial data, fail the download so the next source can
|
||||
# try) or "pause" (pause in the client, leave for the user).
|
||||
"torrent_stall_action": "abandon",
|
||||
# Where THIS container can read completed torrent/usenet
|
||||
# downloads (#857). The downloader (qBit/SAB) reports a save
|
||||
# path from inside ITS OWN container — often a category folder
|
||||
# like /data/downloads/music — which may be mounted at a
|
||||
# different point here. Set these to the in-container path(s)
|
||||
# where SoulSync sees those finished downloads; the resolver
|
||||
# then finds the release by name under them. Empty = fall back
|
||||
# to the soulseek download/transfer dirs (the shared-volume
|
||||
# default). See core.download_plugins.album_bundle.resolve_reported_save_path.
|
||||
"torrent_download_path": "",
|
||||
"usenet_download_path": "",
|
||||
# Explicit remote→local prefix mappings for non-shared / oddly
|
||||
# mounted layouts (Sonarr/Radarr "Remote Path Mapping" style):
|
||||
# a list of {"from": "<client path>", "to": "<soulsync path>"}.
|
||||
# Tried before the basename fallback above.
|
||||
"usenet_path_mappings": [],
|
||||
},
|
||||
"post_processing": {
|
||||
# When a download is quarantined (AcoustID mismatch, integrity /
|
||||
|
|
|
|||
|
|
@ -551,6 +551,26 @@ def test_resolve_skips_mapping_when_target_missing_then_tries_basename(tmp_path:
|
|||
assert resolved == str(tmp_path / "MyAlbum")
|
||||
|
||||
|
||||
def test_resolve_uses_custom_torrent_download_path(tmp_path: Path) -> None:
|
||||
"""#857: the user's torrent client saves to a category folder (e.g. a
|
||||
'Music' category) mounted here at a custom in-container path. Setting
|
||||
download_source.torrent_download_path lets SoulSync find the release there."""
|
||||
music_mount = tmp_path / "downloads" / "music"
|
||||
(music_mount / "MyAlbum").mkdir(parents=True)
|
||||
cfg = _cfg({'download_source.torrent_download_path': str(music_mount)})
|
||||
resolved = resolve_reported_save_path('/data/Downloads/Music/MyAlbum', config_get=cfg)
|
||||
assert resolved == str(music_mount / "MyAlbum")
|
||||
|
||||
|
||||
def test_resolve_uses_custom_usenet_download_path(tmp_path: Path) -> None:
|
||||
"""#857: same for the usenet source's custom completed-downloads path."""
|
||||
nzb_mount = tmp_path / "nzb" / "music"
|
||||
(nzb_mount / "MyAlbum").mkdir(parents=True)
|
||||
cfg = _cfg({'download_source.usenet_download_path': str(nzb_mount)})
|
||||
resolved = resolve_reported_save_path('/config/Downloads/complete/MyAlbum', config_get=cfg)
|
||||
assert resolved == str(nzb_mount / "MyAlbum")
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# poll_album_download — lifted poll loop for both torrent + usenet plugins.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -5431,6 +5431,13 @@
|
|||
Override where the torrent client writes downloads. This path is on the <strong>torrent client's</strong> machine, not SoulSync's.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Completed Downloads Path — in SoulSync (optional):</label>
|
||||
<input type="text" id="torrent-download-path" placeholder="leave blank for the shared-volume default">
|
||||
<div class="setting-help-text">
|
||||
Where <strong>SoulSync</strong> can read finished torrents — its own in-container path. Set this when your client saves to a category folder (e.g. a "Music" category at <code>/data/downloads/music</code>) that's mounted here at a different path. SoulSync finds the release by name under this folder. Blank = use the Soulseek download/transfer folders.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Stalled torrent timeout (minutes):</label>
|
||||
<input type="number" id="torrent-stall-timeout" min="0" step="1" placeholder="10">
|
||||
|
|
@ -5511,6 +5518,13 @@
|
|||
SoulSync tags every NZB with this category so it ends up in a predictable post-processing folder.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Completed Downloads Path — in SoulSync (optional):</label>
|
||||
<input type="text" id="usenet-download-path" placeholder="leave blank for the shared-volume default">
|
||||
<div class="setting-help-text">
|
||||
Where <strong>SoulSync</strong> can read finished NZB downloads — its own in-container path. Set this when SABnzbd/NZBGet writes that category to a folder (e.g. <code>/data/downloads/music</code>) mounted here at a different path. SoulSync finds the release by name under this folder. Blank = use the Soulseek download/transfer folders.
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Status:</label>
|
||||
<div class="form-actions" style="margin-top: 4px;">
|
||||
|
|
|
|||
|
|
@ -1179,6 +1179,8 @@ async function loadSettingsData() {
|
|||
_tcStall.value = (secs === undefined || secs === null) ? 10 : Math.round(Number(secs) / 60);
|
||||
}
|
||||
if (_tcStallAct) _tcStallAct.value = settings.download_source?.torrent_stall_action || 'abandon';
|
||||
const _tcDlPath = document.getElementById('torrent-download-path');
|
||||
if (_tcDlPath) _tcDlPath.value = settings.download_source?.torrent_download_path || '';
|
||||
const _ucType = document.getElementById('usenet-client-type');
|
||||
const _ucUrl = document.getElementById('usenet-client-url');
|
||||
const _ucKey = document.getElementById('usenet-client-api-key');
|
||||
|
|
@ -1191,6 +1193,8 @@ async function loadSettingsData() {
|
|||
if (_ucUser) _ucUser.value = settings.usenet_client?.username || '';
|
||||
if (_ucPass) _ucPass.value = settings.usenet_client?.password || '';
|
||||
if (_ucCat) _ucCat.value = settings.usenet_client?.category || 'soulsync';
|
||||
const _ucDlPath = document.getElementById('usenet-download-path');
|
||||
if (_ucDlPath) _ucDlPath.value = settings.download_source?.usenet_download_path || '';
|
||||
if (typeof updateUsenetClientUI === 'function') updateUsenetClientUI();
|
||||
// Sync ARL to connections tab field + bidirectional listeners
|
||||
const _connArl = document.getElementById('deezer-connection-arl');
|
||||
|
|
@ -3001,6 +3005,10 @@ async function saveSettings(quiet = false) {
|
|||
return (Number.isFinite(m) && m >= 0 ? m : 10) * 60;
|
||||
})(),
|
||||
torrent_stall_action: document.getElementById('torrent-stall-action')?.value || 'abandon',
|
||||
// In-container path(s) where SoulSync reads finished torrent/usenet
|
||||
// downloads (#857). Rendered in the torrent/usenet client sections.
|
||||
torrent_download_path: document.getElementById('torrent-download-path')?.value || '',
|
||||
usenet_download_path: document.getElementById('usenet-download-path')?.value || '',
|
||||
},
|
||||
tidal_download: {
|
||||
quality: document.getElementById('tidal-download-quality').value || 'lossless',
|
||||
|
|
|
|||
Loading…
Reference in a new issue