diff --git a/beats_check.py b/beats_check.py index efe6135..11e0841 100644 --- a/beats_check.py +++ b/beats_check.py @@ -441,7 +441,8 @@ def collect_audio_files(input_folder, min_age_minutes=30): age_threshold = time.time() - (min_age_minutes * 60) files = [] skipped_young = 0 - for root, _, filenames in os.walk(input_folder, followlinks=False): + for root, dirs, filenames in os.walk(input_folder, followlinks=False): + dirs.sort() for f in sorted(filenames): file_path = os.path.join(root, f) real_path = os.path.realpath(file_path) @@ -573,6 +574,13 @@ def _run_scan_inner(input_folder, output_folder, log_file, log_dir, all_files = collect_audio_files(input_folder, min_age_minutes) total_library_size = _total_file_size(all_files) + # Push library size to WebUI immediately so the dashboard shows it + if _webui_app_state is not None: + _webui_app_state.update( + library_size_human=format_size(total_library_size), + library_files=len(all_files), + ) + files_to_check = [f for f in all_files if f not in already_processed] skipped = len(all_files) - len(files_to_check) total = len(files_to_check) @@ -2754,4 +2762,9 @@ def main(): if __name__ == "__main__": + import sys + # Register as 'beats_check' so that ``from beats_check import …`` + # in webui.py finds THIS running instance instead of re-importing + # the file as a second module with separate global state. + sys.modules.setdefault("beats_check", sys.modules[__name__]) main() diff --git a/static/app.js b/static/app.js index 193aa62..1a2273c 100644 --- a/static/app.js +++ b/static/app.js @@ -354,6 +354,8 @@ async function refreshDashboard() { const summary = data.summary || {}; setCardValue('dash-status', status.charAt(0).toUpperCase() + status.slice(1)); + const dashStatusEl = document.getElementById('dash-status'); + if (dashStatusEl) dashStatusEl.className = 'card-value status-' + status; setCardValue('dash-mode', (data.mode || '--').toUpperCase()); setCardValue('dash-uptime', formatUptime(data.uptime)); setCardValue('dash-corrupt', summary.corrupted != null ? summary.corrupted : '--'); diff --git a/static/style.css b/static/style.css index dd041c2..11969d7 100644 --- a/static/style.css +++ b/static/style.css @@ -210,6 +210,10 @@ header h1 { font-size: 1.15rem; font-weight: 700; letter-spacing: -.01em; } .status-dot.setup { background: #b080e8; box-shadow: 0 0 6px rgba(176,128,232,.4); } .status-dot.error { background: #e0506a; box-shadow: 0 0 8px rgba(224,80,106,.5); } #status-text { font-size: .82rem; color: var(--text-muted); } +.card-value.status-idle { color: #3ecfa0; } +.card-value.status-scanning { color: #e8b84a; } +.card-value.status-setup { color: #b080e8; } +.card-value.status-error { color: #e0506a; } @keyframes pulse-scan { 0%, 100% { box-shadow: 0 0 4px rgba(232,184,74,.3); } diff --git a/webui.py b/webui.py index f2d7bba..fcd2780 100644 --- a/webui.py +++ b/webui.py @@ -551,6 +551,12 @@ def do_GET(self): if self.path == '/api/status': state = app_state.snapshot() summary = _read_summary(config_dir) + # Merge live library size from scan into summary so the + # dashboard shows it immediately, not only after scan ends + for key in ('library_size_human', 'library_files'): + val = state.get(key) + if val is not None: + summary[key] = val state["summary"] = summary self._json_response(state)