diff --git a/first_time_install.sh b/first_time_install.sh index 3da73157..9f98c91e 100644 --- a/first_time_install.sh +++ b/first_time_install.sh @@ -1110,6 +1110,7 @@ $ACTUAL_USER ALL=(ALL) NOPASSWD: $SYSTEMCTL_PATH restart ledmatrix-web.service $ACTUAL_USER ALL=(ALL) NOPASSWD: $PYTHON_PATH $PROJECT_ROOT_DIR/display_controller.py $ACTUAL_USER ALL=(ALL) NOPASSWD: $BASH_PATH $PROJECT_ROOT_DIR/start_display.sh $ACTUAL_USER ALL=(ALL) NOPASSWD: $BASH_PATH $PROJECT_ROOT_DIR/stop_display.sh +$ACTUAL_USER ALL=(ALL) NOPASSWD: $BASH_PATH $PROJECT_ROOT_DIR/scripts/fix_perms/safe_plugin_rm.sh * EOF if [ -n "$JOURNALCTL_PATH" ]; then cat >> /tmp/ledmatrix_web_sudoers << EOF diff --git a/plugin-repos/march-madness/requirements.txt b/plugin-repos/march-madness/requirements.txt index ba79ba59..aa49c296 100644 --- a/plugin-repos/march-madness/requirements.txt +++ b/plugin-repos/march-madness/requirements.txt @@ -1,4 +1,4 @@ requests>=2.28.0 -Pillow>=10.3.0 +Pillow>=12.2.0 pytz>=2022.1 numpy>=1.24.0 diff --git a/scripts/utils/wifi_monitor_daemon.py b/scripts/utils/wifi_monitor_daemon.py index 05ed429c..53f0497c 100755 --- a/scripts/utils/wifi_monitor_daemon.py +++ b/scripts/utils/wifi_monitor_daemon.py @@ -155,7 +155,7 @@ class WiFiMonitorDaemon: logger.error(f"NetworkManager restart failed (rc={e.returncode}); " "resetting failure counter to avoid tight retry loop") self._consecutive_internet_failures = 0 - except Exception as e: + except (subprocess.SubprocessError, OSError) as e: logger.error(f"NetworkManager restart error: {e}; " "resetting failure counter to avoid tight retry loop") self._consecutive_internet_failures = 0 diff --git a/web_interface/blueprints/api_v3.py b/web_interface/blueprints/api_v3.py index aa2c5616..5911fd5a 100644 --- a/web_interface/blueprints/api_v3.py +++ b/web_interface/blueprints/api_v3.py @@ -1840,6 +1840,13 @@ def execute_system_action(): 'stderr': result.stderr }) + except subprocess.TimeoutExpired: + if action == 'start_display' and mode: + msg = f'Failed to start display in {mode} mode: timed out' + else: + msg = f'Action {action} timed out' + logger.warning("[System] execute_system_action timed out: action=%s", action) + return jsonify({'status': 'error', 'message': msg, 'returncode': -1, 'stdout': '', 'stderr': 'timeout'}), 500 except Exception as e: logger.exception("[System] execute_system_action failed") return jsonify({'status': 'error', 'message': 'Failed to execute system action'}), 500 diff --git a/web_interface/static/v3/plugins_manager.js b/web_interface/static/v3/plugins_manager.js index cc3e8b3d..19d25253 100644 --- a/web_interface/static/v3/plugins_manager.js +++ b/web_interface/static/v3/plugins_manager.js @@ -1225,10 +1225,10 @@ function initializePlugins() { window.pluginManager._reswap = false; // Await the installed-plugins fetch so window.installedPlugins is populated before // searchPluginStore renders Installed/Reinstall badges against it. - loadInstalledPlugins().then(() => { - searchPluginStore(!isReswapWarm); - }).catch(err => { + loadInstalledPlugins().catch(err => { console.error('[PluginStore] loadInstalledPlugins failed:', err); + }).finally(() => { + searchPluginStore(!isReswapWarm); }); // Setup search functionality (with guard against duplicate listeners)