From 618ceb61e57a86504fe0a83e41f0cab659e9688d Mon Sep 17 00:00:00 2001 From: master3395 Date: Mon, 26 Jan 2026 03:09:01 +0100 Subject: [PATCH] fix(plugins): Improve auto-cleanup of incomplete plugin directories - Use pluginInstaller.removeFiles() which handles permissions properly - Add fallback to rm -rf if pluginInstaller method fails - Better error handling and logging - Applied to both install_plugin and install_from_store functions Fixes: Incomplete plugin directory cleanup failures due to permission issues --- pluginHolder/views.py | 48 ++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/pluginHolder/views.py b/pluginHolder/views.py index 4a594de06..a340ef192 100644 --- a/pluginHolder/views.py +++ b/pluginHolder/views.py @@ -474,17 +474,27 @@ def install_plugin(request, plugin_name): }, status=400) else: # Directory exists but no meta.xml - likely incomplete/uninstalled - # Try to clean it up first + # Try to clean it up first using pluginInstaller.removeFiles which handles permissions try: - import shutil - shutil.rmtree(pluginInstalled) + from pluginInstaller.pluginInstaller import pluginInstaller + pluginInstaller.removeFiles(plugin_name) logging.writeToFile(f'Cleaned up incomplete plugin directory: {plugin_name}') except Exception as e: logging.writeToFile(f'Warning: Could not clean up incomplete directory: {str(e)}') - return JsonResponse({ - 'success': False, - 'error': f'Incomplete plugin directory found. Please uninstall first or manually remove: {pluginInstalled}' - }, status=400) + # Try fallback: use system rm -rf + try: + import subprocess + result = subprocess.run(['rm', '-rf', pluginInstalled], capture_output=True, text=True, timeout=30) + if result.returncode == 0: + logging.writeToFile(f'Cleaned up incomplete plugin directory using rm -rf: {plugin_name}') + else: + raise Exception(f"rm -rf failed: {result.stderr}") + except Exception as e2: + logging.writeToFile(f'Error: Both cleanup methods failed: {str(e)}, {str(e2)}') + return JsonResponse({ + 'success': False, + 'error': f'Incomplete plugin directory found. Please uninstall first or manually remove: {pluginInstalled}' + }, status=400) # Create zip file for installation (pluginInstaller expects a zip) import tempfile @@ -1217,17 +1227,27 @@ def install_from_store(request, plugin_name): }, status=400) else: # Directory exists but no meta.xml - likely incomplete/uninstalled - # Try to clean it up first + # Try to clean it up first using pluginInstaller.removeFiles which handles permissions try: - import shutil - shutil.rmtree(pluginInstalled) + from pluginInstaller.pluginInstaller import pluginInstaller + pluginInstaller.removeFiles(plugin_name) logging.writeToFile(f'Cleaned up incomplete plugin directory: {plugin_name}') except Exception as e: logging.writeToFile(f'Warning: Could not clean up incomplete directory: {str(e)}') - return JsonResponse({ - 'success': False, - 'error': f'Incomplete plugin directory found. Please uninstall first or manually remove: {pluginInstalled}' - }, status=400) + # Try fallback: use system rm -rf + try: + import subprocess + result = subprocess.run(['rm', '-rf', pluginInstalled], capture_output=True, text=True, timeout=30) + if result.returncode == 0: + logging.writeToFile(f'Cleaned up incomplete plugin directory using rm -rf: {plugin_name}') + else: + raise Exception(f"rm -rf failed: {result.stderr}") + except Exception as e2: + logging.writeToFile(f'Error: Both cleanup methods failed: {str(e)}, {str(e2)}') + return JsonResponse({ + 'success': False, + 'error': f'Incomplete plugin directory found. Please uninstall first or manually remove: {pluginInstalled}' + }, status=400) # Download plugin from GitHub import tempfile