From 7a8cc854db604629285bdb877c6b3acefffb8f25 Mon Sep 17 00:00:00 2001 From: Antti Kettunen Date: Sun, 12 Apr 2026 11:45:53 +0300 Subject: [PATCH 1/3] Setup logging early to prevent initial logs from being swallowed There's a lot side-effects happening at import-time (eg. client initialization etc.), some of which include meaningful logging as well (eg. migration-related logging in MusicDatabase client). If we delay the logging initialization to the __main__ block, we'll lose out on these early logs --- web_server.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/web_server.py b/web_server.py index 08bdcf8e..a11c0ebe 100644 --- a/web_server.py +++ b/web_server.py @@ -21,15 +21,17 @@ from urllib.parse import urljoin from concurrent.futures import ThreadPoolExecutor, as_completed from flask import Flask, render_template, request, jsonify, redirect, send_file, Response, session, g from flask_socketio import SocketIO, emit, join_room, leave_room -from utils.logging_config import get_logger +from utils.logging_config import get_logger, setup_logging from utils.async_helpers import run_async # --- Core Application Imports --- # Import the same core clients and config manager used by the GUI app from config.settings import config_manager -# Initialize logger -logger = get_logger("web_server") +# Setup logging early to avoid any import-time logs from being swallowed +_log_level = config_manager.get('logging.level', 'INFO') +_log_path = config_manager.get('logging.path', 'logs/app.log') +logger = setup_logging(_log_level, _log_path) # App version — single source of truth for backup metadata, version-info endpoint, etc. SOULSYNC_VERSION = "2.2" @@ -52560,12 +52562,6 @@ def _emit_repair_progress_loop(): if __name__ == '__main__': - # Initialize logging for web server - from utils.logging_config import setup_logging - log_level = config_manager.get('logging.level', 'INFO') - log_path = config_manager.get('logging.path', 'logs/app.log') - logger = setup_logging(log_level, log_path) - print("Starting SoulSync Web UI Server...") print("Open your browser and navigate to http://127.0.0.1:8008") From 5a40c185e1984f4d68c307ac77dd3d8db41a3992 Mon Sep 17 00:00:00 2001 From: Antti Kettunen Date: Sun, 12 Apr 2026 11:57:56 +0300 Subject: [PATCH 2/3] Remove lingering local db file --- database/music_library.db | Bin 40960 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 database/music_library.db diff --git a/database/music_library.db b/database/music_library.db deleted file mode 100644 index fc442bc7b77c33b0bbc88df55a491bf3d902fabd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40960 zcmeI(T~E_c7{KvWVPhDL7beTX&AFtBcw@YGj)OtRkgh~D(WcO8l4h#Fr)|4jyM_w?bM-}AKWB+%RG1d%VE9EJlo64xu2D~3_IDMY1G zsjJtrdSzRDypSEJ@5aRbal7@(wflE2s(0(P#mc4N!q<9p>C4jN+PB*0+MYVah5!Nx zAb`NX6WFO&8*5GDc`)?+SAqA+i9+|_`N)ZasPF6j<+deTwiKJ)b-5>IW5jk>=s2;O zTx9Mn&7^eu`{O~HQt#L2QclLiDfMxd(yFPHD-)x1!zdU^XOjhmFtFE&5yoUb*SP2$lcGnK+k$1O=-7ob!1-mWl^vN zp6VD|-j0aA%%g-@TN8tz-w#Iq!Qs#w6;AX?(D$7eZuBe}O>ye|Kn+8E zFirJ}gAPJp#dwbT?-b`4zwmxL$HulLH*a_2 z(u&orjHa;UhEzjn%U*sb2c8+X+q&#X^)P9-dhOP_EFRc&(yZ9iS+je&FzuYZ`Tpo! z($gQelAhK#g8q7bs;Biiu{xI`Zt;l@{c%rcb-YYj9O!5 z#rW`6_nvND{k$EWo9@1>tqW`LGwm1ujyp{^{fS-~jRylaJUXHK{(iORK+Skn`oAQFW|{~ffB*srAb Date: Sun, 12 Apr 2026 12:51:52 +0300 Subject: [PATCH 3/3] Fix db initialization When starting from scratch (no existing .db file), certain db init steps were being skipped. Upon subsequent startup, these remaining 4-5 steps would execute. Up until recently this has not been much of an issue since all the db init steps were run repeatedly throughout the process' lifetime, but after the init was changed to be only done once per startup, this became more problematic --- database/music_database.py | 48 ++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/database/music_database.py b/database/music_database.py index 95b54646..f8271d30 100644 --- a/database/music_database.py +++ b/database/music_database.py @@ -977,12 +977,15 @@ class MusicDatabase: cursor.execute("ALTER TABLE discovery_pool ADD COLUMN artist_genres TEXT") logger.info("Added artist_genres column to discovery_pool table") + if 'source' not in discovery_pool_columns: + cursor.execute("ALTER TABLE discovery_pool ADD COLUMN source TEXT DEFAULT 'spotify'") + logger.info("Added source column to discovery_pool table") + # Migration: Add iTunes columns to discovery_pool for dual-source discovery if 'itunes_track_id' not in discovery_pool_columns: cursor.execute("ALTER TABLE discovery_pool ADD COLUMN itunes_track_id TEXT") cursor.execute("ALTER TABLE discovery_pool ADD COLUMN itunes_album_id TEXT") cursor.execute("ALTER TABLE discovery_pool ADD COLUMN itunes_artist_id TEXT") - cursor.execute("ALTER TABLE discovery_pool ADD COLUMN source TEXT DEFAULT 'spotify'") logger.info("Added iTunes columns to discovery_pool table for dual-source discovery") # Migration: Add Deezer columns to discovery_pool for tri-source discovery @@ -1008,9 +1011,12 @@ class MusicDatabase: cursor.execute("PRAGMA table_info(recent_releases)") recent_releases_columns = [column[1] for column in cursor.fetchall()] + if 'source' not in recent_releases_columns: + cursor.execute("ALTER TABLE recent_releases ADD COLUMN source TEXT DEFAULT 'spotify'") + logger.info("Added source column to recent_releases table") + if 'album_itunes_id' not in recent_releases_columns: cursor.execute("ALTER TABLE recent_releases ADD COLUMN album_itunes_id TEXT") - cursor.execute("ALTER TABLE recent_releases ADD COLUMN source TEXT DEFAULT 'spotify'") logger.info("Added iTunes columns to recent_releases table for dual-source discovery") # Migration: Add Deezer column to recent_releases for tri-source discovery @@ -1022,10 +1028,13 @@ class MusicDatabase: cursor.execute("PRAGMA table_info(discovery_recent_albums)") discovery_recent_albums_columns = [column[1] for column in cursor.fetchall()] + if 'source' not in discovery_recent_albums_columns: + cursor.execute("ALTER TABLE discovery_recent_albums ADD COLUMN source TEXT DEFAULT 'spotify'") + logger.info("Added source column to discovery_recent_albums table") + if 'album_itunes_id' not in discovery_recent_albums_columns: cursor.execute("ALTER TABLE discovery_recent_albums ADD COLUMN album_itunes_id TEXT") cursor.execute("ALTER TABLE discovery_recent_albums ADD COLUMN artist_itunes_id TEXT") - cursor.execute("ALTER TABLE discovery_recent_albums ADD COLUMN source TEXT DEFAULT 'spotify'") logger.info("Added iTunes columns to discovery_recent_albums table for dual-source discovery") # Migration: Add Deezer columns to discovery_recent_albums for tri-source discovery @@ -1284,7 +1293,7 @@ class MusicDatabase: cursor.execute("CREATE INDEX IF NOT EXISTS idx_lap_profile ON liked_artists_pool (profile_id)") cursor.execute("CREATE INDEX IF NOT EXISTS idx_lap_status ON liked_artists_pool (profile_id, match_status)") - logger.info("Discovery tables created successfully") + logger.info("Discovery tables added/verified successfully") except Exception as e: logger.error(f"Error creating discovery tables: {e}") @@ -1450,6 +1459,8 @@ class MusicDatabase: include_remixes INTEGER DEFAULT 0, include_acoustic INTEGER DEFAULT 0, include_compilations INTEGER DEFAULT 0, + include_instrumentals INTEGER DEFAULT 0, + lookback_days INTEGER DEFAULT NULL, itunes_artist_id TEXT, deezer_artist_id TEXT, discogs_artist_id TEXT, @@ -1476,6 +1487,8 @@ class MusicDatabase: include_remixes INTEGER DEFAULT 0, include_acoustic INTEGER DEFAULT 0, include_compilations INTEGER DEFAULT 0, + include_instrumentals INTEGER DEFAULT 0, + lookback_days INTEGER DEFAULT NULL, itunes_artist_id TEXT, deezer_artist_id TEXT, discogs_artist_id TEXT @@ -1489,6 +1502,7 @@ class MusicDatabase: 'last_scan_timestamp', 'created_at', 'updated_at', 'image_url', 'include_albums', 'include_eps', 'include_singles', 'include_live', 'include_remixes', 'include_acoustic', 'include_compilations', + 'include_instrumentals', 'lookback_days', 'itunes_artist_id', 'deezer_artist_id', 'discogs_artist_id', 'profile_id'] shared_cols = [c for c in new_cols if c in old_cols] cols_str = ', '.join(shared_cols) @@ -1749,7 +1763,7 @@ class MusicDatabase: cursor.execute("CREATE INDEX IF NOT EXISTS idx_albums_discogs_id ON albums (discogs_id)") cursor.execute("CREATE INDEX IF NOT EXISTS idx_albums_discogs_status ON albums (discogs_match_status)") - logger.info("Discogs enrichment columns added/verified") + logger.info("Discogs enrichment columns added/verified successfully") except Exception as e: logger.error(f"Error adding Discogs columns: {e}") @@ -2217,6 +2231,8 @@ class MusicDatabase: include_remixes INTEGER DEFAULT 0, include_acoustic INTEGER DEFAULT 0, include_compilations INTEGER DEFAULT 0, + include_instrumentals INTEGER DEFAULT 0, + lookback_days INTEGER DEFAULT NULL, itunes_artist_id TEXT, deezer_artist_id TEXT, discogs_artist_id TEXT, @@ -2231,6 +2247,7 @@ class MusicDatabase: 'last_scan_timestamp', 'created_at', 'updated_at', 'image_url', 'include_albums', 'include_eps', 'include_singles', 'include_live', 'include_remixes', 'include_acoustic', 'include_compilations', + 'include_instrumentals', 'lookback_days', 'itunes_artist_id', 'deezer_artist_id', 'discogs_artist_id', 'profile_id'] shared_cols = [c for c in new_cols if c in col_names] cols_str = ', '.join(shared_cols) @@ -2393,6 +2410,9 @@ class MusicDatabase: itunes_track_id TEXT, itunes_album_id TEXT, itunes_artist_id TEXT, + deezer_track_id TEXT, + deezer_album_id TEXT, + deezer_artist_id TEXT, source TEXT NOT NULL DEFAULT 'spotify', track_name TEXT NOT NULL, artist_name TEXT NOT NULL, @@ -2412,6 +2432,7 @@ class MusicDatabase: new_cols = ['id', 'spotify_track_id', 'spotify_album_id', 'spotify_artist_id', 'itunes_track_id', 'itunes_album_id', 'itunes_artist_id', + 'deezer_track_id', 'deezer_album_id', 'deezer_artist_id', 'source', 'track_name', 'artist_name', 'album_name', 'album_cover_url', 'duration_ms', 'popularity', 'release_date', 'is_new_release', 'track_data_json', 'artist_genres', 'added_date', 'profile_id'] @@ -2486,6 +2507,7 @@ class MusicDatabase: watchlist_artist_id INTEGER NOT NULL, album_spotify_id TEXT, album_itunes_id TEXT, + album_deezer_id TEXT, source TEXT NOT NULL DEFAULT 'spotify', album_name TEXT NOT NULL, release_date TEXT NOT NULL, @@ -2498,8 +2520,8 @@ class MusicDatabase: """) new_cols = ['id', 'watchlist_artist_id', 'album_spotify_id', 'album_itunes_id', - 'source', 'album_name', 'release_date', 'album_cover_url', - 'track_count', 'added_date', 'profile_id'] + 'album_deezer_id', 'source', 'album_name', 'release_date', + 'album_cover_url', 'track_count', 'added_date', 'profile_id'] shared_cols = [c for c in new_cols if c in old_cols] cols_str = ', '.join(shared_cols) @@ -2557,10 +2579,15 @@ class MusicDatabase: source_artist_id TEXT NOT NULL, similar_artist_spotify_id TEXT, similar_artist_itunes_id TEXT, + similar_artist_deezer_id TEXT, similar_artist_name TEXT NOT NULL, similarity_rank INTEGER DEFAULT 1, occurrence_count INTEGER DEFAULT 1, last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + image_url TEXT, + genres TEXT, + popularity INTEGER DEFAULT 0, + metadata_updated_at TIMESTAMP, last_featured TIMESTAMP, profile_id INTEGER DEFAULT 1, UNIQUE(profile_id, source_artist_id, similar_artist_name) @@ -2568,9 +2595,10 @@ class MusicDatabase: """) new_cols = ['id', 'source_artist_id', 'similar_artist_spotify_id', - 'similar_artist_itunes_id', 'similar_artist_name', - 'similarity_rank', 'occurrence_count', 'last_updated', - 'last_featured', 'profile_id'] + 'similar_artist_itunes_id', 'similar_artist_deezer_id', + 'similar_artist_name', 'similarity_rank', 'occurrence_count', + 'last_updated', 'image_url', 'genres', 'popularity', + 'metadata_updated_at', 'last_featured', 'profile_id'] shared_cols = [c for c in new_cols if c in old_cols] cols_str = ', '.join(shared_cols)