From 551df0c3ca175b78d2ce9b4238f0c55f98b3faef Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Sun, 28 Jun 2026 15:10:30 -0700 Subject: [PATCH] downloads: fix file-finder collapsing on an unbalanced bracket (false "not found") MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Discord (Shdjfgatdif): a downloaded .flac sat right there in the download folder but the import flow reported "File not found on disk after 5 search attempts" and failed it. root cause: slskd REPORTS the name as "[34 - You & Me (Flume Remix).flac" but SAVES it as "34 - You & Me (Flume Remix).flac" (it strips the leading '['). The finder's fuzzy-match normaliser used one combined bracket-strip — r'[\[\(].*?[\]\)]' — which allows MISMATCHED delimiters, so the lone '[' matched all the way to the next ')', ate the whole title, and collapsed the search target to just "flac". That scored 0.40 against the real filename (below the 0.85 floor) → "not found", despite the file being on disk. Confirmed by running the real code on his exact filename. fix: strip only BALANCED pairs (\[...\] and (...) separately). A stray unbalanced bracket now survives to the alphanumeric strip instead of devouring the title. '[34 - You & Me (Flume Remix)' → matches at 1.00. Balanced tags like "[FLAC]" / "(Remastered 2016)" are still stripped (no regression). Only used internally by the finder's fuzzy scorer — contained blast radius. 3 tests: his exact unbalanced-'[' filename, a stray-']' variant, and a balanced-tag no-regression guard. 1311 imports/downloads/quality tests green, ruff clean. --- core/downloads/file_finder.py | 11 +++++- tests/downloads/test_file_finder.py | 53 +++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/core/downloads/file_finder.py b/core/downloads/file_finder.py index 0e6e03a7..5ea9a5e5 100644 --- a/core/downloads/file_finder.py +++ b/core/downloads/file_finder.py @@ -77,7 +77,16 @@ def _normalize_for_finding(text: str) -> str: return "" text = unidecode(text).lower() text = re.sub(r'[._/]', ' ', text) - text = re.sub(r'[\[\(].*?[\]\)]', '', text) + # Strip ONLY balanced bracket pairs (tags like "[FLAC]", "(Remastered 2016)"). + # The old combined pattern r'[\[\(].*?[\]\)]' allowed MISMATCHED delimiters, so a + # lone unbalanced '[' — slskd reports "[34 - You & Me (Flume Remix)" but saves the + # file as "34 - You & Me (Flume Remix)" — matched from that '[' all the way to the + # next ')', eating the entire title and collapsing the search target to "flac". The + # file then scored 0.40 against the real on-disk name and was reported "not found" + # despite sitting right there. Per-delimiter pairs can't over-consume; a stray + # unbalanced bracket simply survives to the alphanumeric strip below. + text = re.sub(r'\[[^\]]*\]', '', text) + text = re.sub(r'\([^)]*\)', '', text) text = re.sub(r'[^a-z0-9\s-]', '', text) return ' '.join(text.split()).strip() diff --git a/tests/downloads/test_file_finder.py b/tests/downloads/test_file_finder.py index 5e7d6291..2bd89130 100644 --- a/tests/downloads/test_file_finder.py +++ b/tests/downloads/test_file_finder.py @@ -396,3 +396,56 @@ def test_real_soulseek_path_still_basenamed(tmp_path): str(downloads), r'shared\Billy Ocean\Very Best Of\01 - Suddenly.flac', ) assert found == str(target) + + +# --------------------------------------------------------------------------- +# Unbalanced bracket — slskd REPORTS "[34 - Title.flac" but SAVES the file as +# "34 - Title.flac" (it sanitises the leading '['). The normaliser's old combined +# bracket-strip r'[\[\(].*?[\]\)]' matched from that lone '[' all the way to the +# next ')', eating the whole title and collapsing the search target to just "flac" +# → 0.40 fuzzy score → "File not found on disk" despite the file sitting right +# there. (Discord: Shdjfgatdif — "You & Me (Flume Remix)".) +# --------------------------------------------------------------------------- + + +def test_finds_file_when_slskd_strips_a_leading_bracket(tmp_path): + downloads = tmp_path / 'downloads' + # On disk: no leading '['. API filename (slskd-reported): has the '['. + target = downloads / 'Disclosure' / '34 - You & Me (Flume Remix).flac' + _touch(target) + + found, location = find_completed_audio_file( + str(downloads), r'Music\Disclosure\[34 - You & Me (Flume Remix).flac', + ) + + assert found == str(target), \ + 'the lone "[" used to collapse the target to "flac" and miss the file' + assert location == 'downloads' + + +def test_balanced_bracket_tags_still_stripped(tmp_path): + """No regression: balanced "[FLAC]" / "(Remastered 2016)" tags in a Soulseek + filename must still be stripped so it matches the clean saved file.""" + downloads = tmp_path / 'downloads' + target = downloads / 'Song.mp3' + _touch(target) + + found, _ = find_completed_audio_file( + str(downloads), r'shared\Artist\Album\Song [FLAC] (Remastered 2016).mp3', + ) + + assert found == str(target) + + +def test_stray_closing_bracket_does_not_break_match(tmp_path): + """The other shape in the wild (Discord: "Abort, Retry, Fail_]1-01 …") — a + stray ']' must not wreck the match either.""" + downloads = tmp_path / 'downloads' + target = downloads / 'White Town' / "Fail_]1-01 Your Woman.flac" + _touch(target) + + found, _ = find_completed_audio_file( + str(downloads), r"@@digadom\Music\White Town\Fail_]1-01 Your Woman.flac", + ) + + assert found == str(target)