diff --git a/javascript/extensions.js b/javascript/extensions.js index 9f5348a93..cec762f8b 100644 --- a/javascript/extensions.js +++ b/javascript/extensions.js @@ -36,7 +36,7 @@ function install_extension(button, url) { } function uninstall_extension(button, url) { - console.log('Extension uninstall:', url); + console.log('Extension uninstall:', url, decodeURIComponent(url), encodeURI(url)); button.disabled = 'disabled'; button.value = 'Uninstalling...'; button.innerHTML = 'uninstalling'; diff --git a/modules/extensions.py b/modules/extensions.py index 0cd8edacf..c0d9083ef 100644 --- a/modules/extensions.py +++ b/modules/extensions.py @@ -23,7 +23,7 @@ class Extension: def __init__(self, name, path, enabled=True, is_builtin=False): self.name = name self.git_name = '' - self.path = path + self.path = path.replace('\\', '/').rstrip('/') self.enabled = enabled self.status = '' self.can_update = False diff --git a/modules/ui_extensions.py b/modules/ui_extensions.py index b66ea82b1..28c1618dc 100644 --- a/modules/ui_extensions.py +++ b/modules/ui_extensions.py @@ -183,15 +183,26 @@ def install_extension(extension_to_install, search_text, sort_column): def uninstall_extension(extension_path, search_text, sort_column): + def errorRemoveReadonly(func, path, exc): + import stat + excvalue = exc[1] + shared.log.debug(f'Exception during cleanup: {func} {path} {excvalue.strerror}') + if func in (os.rmdir, os.remove, os.unlink) and excvalue.errno == errno.EACCES: + shared.log.debug(f'Retrying cleanup: {path}') + os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) + func(path) + shared.log.info(f'Extension uninstall: {extension_path}') ext = [extension for extension in extensions.extensions if extension.path == extension_path] if len(ext) > 0 and os.path.isdir(extension_path): try: - shutil.rmtree(extension_path, ignore_errors=False) + shutil.rmtree(extension_path, ignore_errors=False, onerror=errorRemoveReadonly) except Exception as e: shared.log.warning(f'Extension uninstall failed: {extension_path} {e}') extensions.extensions = [extension for extension in extensions.extensions if extension.path != extension_path] update_extension_list() + else: + shared.log.warning(f'Extension uninstall cannot find extension: {extension_path}') code = refresh_extensions_list_from_data(search_text, sort_column) # return code, ext_table, message return code, f"Extension uninstalled: {extension_path} | Restart required"