From 739d2f67c1631571fa058f5404a6158bdc5052df Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Tue, 21 Apr 2026 08:59:16 -0700 Subject: [PATCH] Fix Reorganize All sending every album to Albums folder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reorganize endpoints built a template context without albumtype, so ${albumtype} silently fell through to the engine's hardcoded "Album" default — EPs, singles, and compilations all landed in Albums/. Wires albumtype through from the albums table's record_type column (populated by Spotify/Deezer/iTunes enrichment workers) with track-count fallback when record_type is missing. New helper mirrors the download pipeline's classification logic so reorganize produces the same folders as initial placement. Also handles Deezer's raw 'compile' value which the Deezer worker writes directly without mapping. --- web_server.py | 49 ++++++++++++++++++++++++++++++++++++++++++ webui/static/helper.js | 4 ++++ 2 files changed, 53 insertions(+) diff --git a/web_server.py b/web_server.py index 410d4f39..218a42e4 100644 --- a/web_server.py +++ b/web_server.py @@ -13272,6 +13272,10 @@ def reorganize_album_preview(album_id): 'disc_number': disc_number, 'year': year_val, 'quality': quality, + 'albumtype': _get_album_type_display( + album_data.get('record_type'), + album_data.get('track_count') or len(tracks) + ), } # Build new path using the template @@ -13426,6 +13430,10 @@ def reorganize_album_files(album_id): 'disc_number': disc_number, 'year': year_val, 'quality': quality, + 'albumtype': _get_album_type_display( + album_data.get('record_type'), + album_data.get('track_count') or len(tracks) + ), } folder_path, filename = _get_file_path_from_template_raw(template, context) @@ -18472,6 +18480,47 @@ def _create_lossy_copy(final_path): print(f"[Lossy Copy] Conversion error: {e}") return None +def _get_album_type_display(raw_type, track_count) -> str: + """ + Return the display form of an album's type for the $albumtype template variable. + + Mirrors the inference used in the download pipeline so reorganize output + matches initial placement. Values: 'Album', 'Single', 'EP', 'Compilation'. + """ + raw = (raw_type or '').strip().lower() + try: + tc = int(track_count or 0) + except (TypeError, ValueError): + tc = 0 + + # Deezer's raw API returns 'compile' (only mapped to 'compilation' in the + # Album dataclass path); the Deezer enrichment worker writes the raw value, + # so both need to match here. + if raw in ('compilation', 'compile'): + return 'Compilation' + if raw == 'album': + return 'Album' + if raw in ('single', 'ep'): + # Match download-pipeline logic: Spotify labels both singles and EPs + # as 'single', so final classification is by track count. Applying the + # same rule to explicit 'ep' keeps reorganize consistent with where + # the files were first placed. + if tc <= 3: + return 'Single' + if tc <= 6: + return 'EP' + return 'Album' + + # Unknown/missing — infer from track count + if tc <= 0: + return 'Album' + if tc <= 3: + return 'Single' + if tc <= 6: + return 'EP' + return 'Album' + + def _apply_path_template(template: str, context: dict) -> str: """ Apply template to build file path. diff --git a/webui/static/helper.js b/webui/static/helper.js index 4b8d5415..1464c6b8 100644 --- a/webui/static/helper.js +++ b/webui/static/helper.js @@ -3600,6 +3600,10 @@ function closeHelperSearch() { const WHATS_NEW = { '2.35': [ + // --- April 21, 2026 --- + { date: 'April 21, 2026' }, + { title: 'Fix Reorganize All Ignoring Album Type', desc: 'Reorganize All was sending every album — EPs, singles, and compilations — into the "Albums" folder because the $albumtype template variable silently defaulted to "Album". The variable is now resolved from the album\'s record_type (with track-count fallback) so ${albumtype}s produces the expected Albums/Singles/EPs/Compilations split', page: 'library' }, + // --- April 20, 2026 --- { date: 'April 20, 2026' }, { title: 'Discography Backfill Maintenance Job', desc: 'New library maintenance job that scans each artist in your library, fetches their full discography from metadata sources, and creates findings for any missing tracks. Review findings and click "Add to Wishlist" to queue them for download. Respects content filters (live/remix/acoustic/compilation) and release type filters. Opt-in, disabled by default', page: 'library' },