feedBack/lib
=Scr4tch= 196008a98e fix(sloppak/ws_highway): drums stay in picker and show correct hit count
Problem:
The editor strips drum arrangements from the sloppak manifest, converting
them to a drum_tab sidecar.  This left two visible bugs:

1. "Drums (0)" — drum-only packs showed zero notes in the arrangement
   picker even though the drum highway displayed thousands of hits.  The
   sloppak loader synthesized a placeholder Arrangement(name="Drums")
   with no notes whenever the arrangements list was empty, and the
   WebSocket highway always reported that placeholder's note count (0).

2. Drums disappear alongside other arrangements — when a drum+bass or
   drum+guitar pack was loaded, the placeholder was never created because
   the arrangements list was not empty (the other instrument was present).
   The drum arrangement had been removed by the editor during drum_tab
   conversion, so drums vanished entirely from the arrangement picker.

Fix (sloppak.py):
Replaced the "arrangements list is empty" trigger with "no drum
arrangement exists".  The loader now checks whether any arrangement name
contains 'drum' or 'percussion' (case-insensitive substring match using
_DRUM_KEYWORDS) and synthesizes the placeholder when a drum_tab is
present but no matching arrangement is found.  This ensures drums appear
in the picker even alongside bass, guitar, or other pitched instruments.

Fix (ws_highway.py):
When building the arrangement list for the song_info WebSocket message,
the highway now reads the drum_tab hit count from the loaded sloppak and
substitutes it for any empty arrangement whose name matches the drum
keywords.  The placeholder has no notes of its own (it exists only to
carry the drum_tab through to the drum highway), so the real hit count
from drum_tab is surfaced instead — e.g. "Drums (1922)" instead of
"Drums (0)".

Guard against false positives:
The hit-count override is scoped to drum/percussion arrangements only.
Without this guard, an empty "Vocals" or "Keys" track in the same
pack would incorrectly inherit the drum hit count.  The same keyword set
_DRUM_KEYWORDS = ('drum', 'percussion') is used in both sloppak.py and
ws_highway.py to keep the detection consistent.

Signed-off-by: =Scr4tch= <305609711+0-Scr4tch-0@users.noreply.github.com>
2026-07-20 12:05:37 -04:00
..
routers fix(sloppak/ws_highway): drums stay in picker and show correct hit count 2026-07-20 12:05:37 -04:00
acoustid_match.py feat(enrichment): AcoustID audio-fingerprint identification (opt-in) (#759) 2026-07-05 00:17:43 +02:00
appconfig.py refactor(server): extract /api/tunings into routers/tunings.py + lib/appconfig.py (R3) (#858) 2026-07-11 01:43:19 +02:00
appstate.py refactor(server): carve the library scanner into lib/scan.py (R3b) (#901) 2026-07-12 01:26:02 +02:00
audio_effects_db.py refactor(server): extract AudioEffectsMappingDB into lib/audio_effects_db.py (R3) (#831) 2026-07-10 14:30:05 +02:00
audio.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
builtin_content.py refactor(server): carve builtin-content seeding into lib/builtin_content.py (R3b) (#900) 2026-07-12 00:50:50 +02:00
demo_mode.py fix(demo): the janitor re-entry guard actually works now (#902) (#909) 2026-07-12 11:30:53 +02:00
diagnostics_bundle.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
diagnostics_hardware.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
diagnostics_redact.py fix(tests): isolate plugin routes modules + redact .feedpak filenames (#736) 2026-07-03 13:01:07 +02:00
dlc_paths.py perf(paths): resolve the library root once, not on every path check (#966) 2026-07-14 19:48:39 +02:00
drums.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
enrichment.py fix(sloppak): the full mix is a stem — drop the invented original_audio key (#946) 2026-07-13 12:22:42 -04:00
env_compat.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
gp2midi.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
gp2notation.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
gp2rs_gpx.py fix(gp2rs): write arrangement XML as UTF-8 so GP import survives non-ASCII metadata (#984) 2026-07-19 00:56:32 -05:00
gp2rs.py fix(gp2rs): write arrangement XML as UTF-8 so GP import survives non-ASCII metadata (#984) 2026-07-19 00:56:32 -05:00
gp8_audio_sync.py fix(gp8): confine registry asset matching to the declared directory (#1011) 2026-07-19 01:36:28 -05:00
gp_autosync.py fix(gp_autosync): slope-constrained DTW steps — stop path collapse on riff-based songs (#791) 2026-07-05 23:12:31 +02:00
jsonc.py feat(core): read .jsonc data files (strip C-style comments) (feedpak-spec §8) 2026-06-20 14:10:04 -07:00
library_registry.py fix(library): tuning filter answers for your instrument, not always guitar (#1003) 2026-07-19 00:04:30 -05:00
logging_setup.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
loosefolder.py fix(library): tuning filter answers for your instrument, not always guitar (#1003) 2026-07-19 00:04:30 -05:00
lyrics_transcribe.py fix: remote transcription posts to /transcribe, not /align (stem-splitter#17) (#959) 2026-07-14 01:58:24 -04:00
mb_match.py feat(enrichment): alias-aware scoring — auto-confirm non-Latin-primary artists (#772) 2026-07-05 01:11:38 +02:00
metadata_db.py feat(playlists): flag songs that are not in your current tuning (#1009) 2026-07-19 00:10:53 -05:00
midi_import.py feat(drums): capture velocities alongside times in unmapped-percussion reporting (#808) 2026-07-07 23:58:49 +02:00
notation_lift.py feat(notation_lift): authored per-note hands steer the split — heuristic only guesses the rest (#992) 2026-07-19 00:40:08 -05:00
notation.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
progression.py Improve wording in terminology cleanup 2026-06-16 19:43:45 +01:00
reqfields.py refactor(server): extract the playlists routes into routers/playlists.py (R3) (#841) 2026-07-10 19:58:09 +02:00
safepath.py perf(paths): resolve the library root once, not on every path check (#966) 2026-07-14 19:48:39 +02:00
scan_worker.py fix(library): tuning filter answers for your instrument, not always guitar (#1003) 2026-07-19 00:04:30 -05:00
scan.py fix(library): tuning filter answers for your instrument, not always guitar (#1003) 2026-07-19 00:04:30 -05:00
sloppak.py fix(sloppak/ws_highway): drums stay in picker and show correct hit count 2026-07-20 12:05:37 -04:00
song_score.py Clean release snapshot 2026-06-16 18:47:13 +02:00
song.py feat(song): per-note keys hand assignment (hand) on the Note wire (#990) 2026-07-19 00:39:27 -05:00
songmeta.py library: opt-in gap-fill — write confirmed missing metadata into the pack (R4a) (#724) 2026-07-02 20:52:11 +02:00
tailwind_rebuild.py fix(tailwind): stop the dev server rewriting a tracked file (#911) (#918) 2026-07-12 13:25:16 +02:00
tones.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
tunings.py fix(library): tuning filter answers for your instrument, not always guitar (#1003) 2026-07-19 00:04:30 -05:00
vocal_pitch.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
wem_decode.py rename: slopsmith → feedBack, byron → got-feedBack (#537) 2026-06-23 11:03:01 +02:00
xp.py Clean release snapshot 2026-06-16 18:47:13 +02:00