NZBGet: import from the final location, not the incomplete '….#NZBID' dir
Swigs: 'No audio files found in /data/usenet/incomplete/….#2141' — SoulSync imported a usenet album from NZBGet's intermediate working dir, which is emptied after the move (files were in /data/soulseek/…). Two causes, both fixed to match the already-correct SAB adapter: - _parse_history mapped save_path=DestDir, but the authoritative final location after a post-processing move is FinalDir. Prefer FinalDir, fall back to DestDir, empty/whitespace -> None. - _parse_group exposed the queue group's DestDir (the in-progress '….#NZBID' dir) as save_path, so a PP_FINISHED group (which maps to 'completed') could finalize on the incomplete folder before the move. A queue group now reports no save_path -> finalisation always comes from the history entry (real FinalDir/DestDir), bridged by the existing 120s completed-no-path window. 6 regression tests (FinalDir preferred, DestDir fallback, empty->None, queue/ PP_FINISHED never offer the incomplete path).
This commit is contained in:
parent
2ecbd8badc
commit
a5267ee8cf
2 changed files with 79 additions and 2 deletions
|
|
@ -198,7 +198,15 @@ class NZBGetAdapter:
|
|||
size=size_bytes,
|
||||
downloaded=downloaded_bytes,
|
||||
download_speed=speed,
|
||||
save_path=group.get('DestDir'),
|
||||
# A QUEUED group's DestDir is the in-progress intermediate dir
|
||||
# (NZBGet names it '<NZBName>.#<NZBID>' and empties/renames it once
|
||||
# the move completes). Never offer it as a final save_path — finalize
|
||||
# only from the HISTORY entry (real FinalDir/DestDir). Otherwise a
|
||||
# PP_FINISHED group (which maps to 'completed') would finalize on the
|
||||
# incomplete '....#2141' dir, which is then gone -> "No audio files
|
||||
# found in /…/incomplete/….#2141" (Swigs). Mirrors the SAB adapter
|
||||
# ignoring its incomplete_path.
|
||||
save_path=None,
|
||||
category=group.get('Category'),
|
||||
)
|
||||
|
||||
|
|
@ -217,7 +225,15 @@ class NZBGetAdapter:
|
|||
size=size_bytes,
|
||||
downloaded=size_bytes if not is_failed else 0,
|
||||
download_speed=0,
|
||||
save_path=entry.get('DestDir'),
|
||||
# Prefer FinalDir — the location after a post-processing script (or
|
||||
# NZBGet's own move) relocated the files; DestDir can still point at
|
||||
# the intermediate '….#NZBID' dir. Swigs: files landed in
|
||||
# /data/soulseek/… (FinalDir) while DestDir stayed /…/incomplete/….#2141.
|
||||
# Fall back to DestDir when FinalDir is empty (no PP move). Empty/
|
||||
# whitespace -> None so the plugin waits for a real path.
|
||||
save_path=(str(entry.get('FinalDir') or '').strip()
|
||||
or str(entry.get('DestDir') or '').strip()
|
||||
or None),
|
||||
category=entry.get('Category'),
|
||||
error=status_field if is_failed else None,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -714,6 +714,67 @@ def test_nzbget_parse_group_computes_progress() -> None:
|
|||
assert status.download_speed == 500_000
|
||||
|
||||
|
||||
def test_nzbget_queue_group_never_offers_a_save_path() -> None:
|
||||
"""A queued group's DestDir is the in-progress '….#NZBID' dir, which is gone
|
||||
after the move — never expose it as a final save_path. Finalisation must come
|
||||
from the HISTORY entry. (Swigs: imported from /…/incomplete/….#2141.)"""
|
||||
adapter = _nzbget_with_config()
|
||||
status = adapter._parse_group({
|
||||
'NZBID': 2141, 'NZBName': 'xRepentancex-The.Sickness.Of.Eden',
|
||||
'Status': 'DOWNLOADING',
|
||||
'DestDir': '/data/usenet/incomplete/xRepentancex-The.Sickness.Of.Eden.#2141',
|
||||
'Category': 'soulsync',
|
||||
})
|
||||
assert status.save_path is None
|
||||
|
||||
|
||||
def test_nzbget_pp_finished_group_is_completed_but_has_no_path() -> None:
|
||||
"""PP_FINISHED maps to 'completed' but is still a QUEUE group on the
|
||||
in-progress dir — it must report no save_path so the plugin waits for the
|
||||
history entry instead of finalising on the incomplete folder."""
|
||||
adapter = _nzbget_with_config()
|
||||
status = adapter._parse_group({
|
||||
'NZBID': 2141, 'NZBName': 'Album', 'Status': 'PP_FINISHED',
|
||||
'DestDir': '/data/usenet/incomplete/Album.#2141', 'Category': 'soulsync',
|
||||
})
|
||||
assert status.state == 'completed'
|
||||
assert status.save_path is None
|
||||
|
||||
|
||||
def test_nzbget_history_prefers_finaldir_over_destdir() -> None:
|
||||
"""After a post-processing move, FinalDir is the real location; DestDir can
|
||||
still be the intermediate dir. Swigs' exact case."""
|
||||
adapter = _nzbget_with_config()
|
||||
status = adapter._parse_history({
|
||||
'NZBID': 2141, 'Name': 'xRepentancex-The.Sickness.Of.Eden',
|
||||
'Status': 'SUCCESS/ALL',
|
||||
'DestDir': '/data/usenet/incomplete/xRepentancex-The.Sickness.Of.Eden.#2141',
|
||||
'FinalDir': '/data/soulseek/xRepentancex-The.Sickness.Of.Eden-CD-FLAC-2015-CATARACT',
|
||||
'Category': 'soulsync',
|
||||
})
|
||||
assert status.state == 'completed'
|
||||
assert status.save_path == '/data/soulseek/xRepentancex-The.Sickness.Of.Eden-CD-FLAC-2015-CATARACT'
|
||||
|
||||
|
||||
def test_nzbget_history_falls_back_to_destdir_when_no_finaldir() -> None:
|
||||
"""No PP move -> FinalDir empty -> use DestDir (the final dest in that case)."""
|
||||
adapter = _nzbget_with_config()
|
||||
status = adapter._parse_history({
|
||||
'NZBID': 7, 'Name': 'Album', 'Status': 'SUCCESS/HEALTH',
|
||||
'DestDir': '/data/usenet/completed/Album', 'FinalDir': '', 'Category': 'c',
|
||||
})
|
||||
assert status.save_path == '/data/usenet/completed/Album'
|
||||
|
||||
|
||||
def test_nzbget_history_empty_dirs_yield_none() -> None:
|
||||
adapter = _nzbget_with_config()
|
||||
status = adapter._parse_history({
|
||||
'NZBID': 7, 'Name': 'Album', 'Status': 'SUCCESS/ALL',
|
||||
'DestDir': ' ', 'FinalDir': '', 'Category': 'c',
|
||||
})
|
||||
assert status.save_path is None
|
||||
|
||||
|
||||
def test_nzbget_remove_rejects_non_numeric_id() -> None:
|
||||
"""NZBGet IDs are ints; passing a string id like 'abc' must
|
||||
fail fast instead of corrupting the editqueue call."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue