From f83993ad1d6ebfaba9da1da8aee023fa9c739a32 Mon Sep 17 00:00:00 2001 From: serversdown Date: Mon, 11 May 2026 07:25:04 +0000 Subject: [PATCH] fix(import): pair _ASCII.TXT reports on the SFM server side too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The series3-watcher v1.5.0 fix taught the WATCHER to look for BW ACH's _ASCII.TXT report alongside each binary. But the SFM SERVER's import endpoint only knew about the legacy .TXT naming when building its TXT lookup table. Effect: even though the watcher correctly shipped both files in the multipart POST (and logged "+ _ASCII.TXT attached"), the server's reports dict was keyed on the wrong name, so report_bytes resolved to None for every event. Without the report, save_imported_bw fell back to broken-codec peak values and no project info — exactly the same symptom as before the watcher fix landed, just for a different reason. Fix: when stripping the ".TXT" suffix, also recognise the "_ASCII" trailer and reconstruct the binary's filename by converting the last "_" back to ".". Register the report under BOTH possible binary names so the subsequent lookup matches whichever convention the operator's BW installation uses. ACH convention (Blastware ACH): binary T003L2G6.0E0H + report T003L2G6_0E0H_ASCII.TXT ✅ Manual export (operator clicks Save As Text in BW): binary M529LK44.AB0 + report M529LK44.AB0.TXT ✅ Both for same event (e.g. ACH + operator manual save): register under both names; binary lookup wins ✅ Smoke-tested against the four real fixture filenames in the project archive. Full SFM suite still 62 pass. For the user's situation: pull, restart, and the NEXT re-forward pass (after deleting watcher state file again if needed) will hit this code path, parse the report correctly, apply the overlay onto the Event, and the upsert path will land authoritative peak values + project info in the DB. --- sfm/server.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/sfm/server.py b/sfm/server.py index cd2cf80..a7b8cae 100644 --- a/sfm/server.py +++ b/sfm/server.py @@ -1659,8 +1659,33 @@ async def db_import_blastware_file( continue if name.lower().endswith(".txt"): - # Strip the ".txt" suffix to get the binary's filename. - reports[name[:-4].lower()] = content + # Pair the report back to its binary. BW writes ASCII + # reports under two conventions: + # + # 1. ACH convention (Blastware's official Auto Call Home): + # binary: M529LK44.AB0 + # report: M529LK44_AB0_ASCII.TXT + # (replaces the "." with "_", appends "_ASCII.TXT") + # + # 2. Manual-export convention (operator clicks Save As Text + # in BW's UI): + # binary: M529LK44.AB0 + # report: M529LK44.AB0.TXT + # (literal binary filename + ".TXT" suffix) + # + # We register BOTH possible binary names as keys so the + # subsequent lookup matches whichever convention was used. + stripped = name[:-4] # remove ".TXT" + # ACH convention: strip "_ASCII" and convert the last "_" + # back to "." to recover the binary's filename. + if stripped.lower().endswith("_ascii"): + inner = stripped[:-6] # remove "_ASCII" + under = inner.rfind("_") + if under >= 0: + ach_binary = inner[:under] + "." + inner[under + 1 :] + reports[ach_binary.lower()] = content + # Legacy convention: the stripped name IS the binary's name. + reports[stripped.lower()] = content else: binaries.append((name, content))