From a42868d7ebf47d9dc26f0900462900e591ad5506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Fri, 29 May 2015 16:25:18 +0200 Subject: [PATCH] Allow marking plugins as uninstalled Sometimes they will still get discovered by python even though their packages have since been uninstalled. This will also lead to them being reloaded after an uninstall and a subsequent plugin reload. Marking them as uninstalled and not handing out uninstalled plugins when collecting them solves this. --- src/octoprint/plugin/core.py | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/octoprint/plugin/core.py b/src/octoprint/plugin/core.py index d66972dd..3ed3ca8d 100644 --- a/src/octoprint/plugin/core.py +++ b/src/octoprint/plugin/core.py @@ -452,6 +452,8 @@ class PluginManager(object): self.registered_clients = [] + self.marked_plugins = defaultdict(list) + self.reload_plugins(startup=True, initialize_implementations=False) @property @@ -460,18 +462,18 @@ class PluginManager(object): plugins.update(self.disabled_plugins) return plugins - def find_plugins(self, existing=None): + def find_plugins(self, existing=None, ignore_uninstalled=True): if existing is None: existing = self.plugins result = dict() if self.plugin_folders: - result.update(self._find_plugins_from_folders(self.plugin_folders, existing)) + result.update(self._find_plugins_from_folders(self.plugin_folders, existing, ignored_uninstalled=ignore_uninstalled)) if self.plugin_entry_points: - result.update(self._find_plugins_from_entry_points(self.plugin_entry_points, existing)) + result.update(self._find_plugins_from_entry_points(self.plugin_entry_points, existing, ignore_uninstalled=ignore_uninstalled)) return result - def _find_plugins_from_folders(self, folders, existing): + def _find_plugins_from_folders(self, folders, existing, ignored_uninstalled=True): result = dict() for folder in folders: @@ -496,7 +498,7 @@ class PluginManager(object): else: continue - if key in existing or key in result: + if key in existing or key in result or (ignored_uninstalled and key in self.marked_plugins["uninstalled"]): # plugin is already defined, ignore it continue @@ -512,7 +514,7 @@ class PluginManager(object): return result - def _find_plugins_from_entry_points(self, groups, existing): + def _find_plugins_from_entry_points(self, groups, existing, ignore_uninstalled=True): result = dict() # let's make sure we have a current working set @@ -527,11 +529,12 @@ class PluginManager(object): module_name = entry_point.module_name version = entry_point.dist.version - if key in existing or key in result: - # plugin is already defined, ignore it + if key in existing or key in result or (ignore_uninstalled and key in self.marked_plugins["uninstalled"]): + # plugin is already defined or marked as uninstalled, ignore it continue kwargs = dict(module_name=module_name, version=version) + package_name = None try: module_pkginfo = InstalledEntryPoint(entry_point) except: @@ -589,12 +592,15 @@ class PluginManager(object): def _is_plugin_disabled(self, key): return key in self.plugin_disabled_list or key.endswith('disabled') - def reload_plugins(self, startup=False, initialize_implementations=True): + def reload_plugins(self, startup=False, initialize_implementations=True, force_reload=None): self.logger.info("Loading plugins from {folders} and installed plugin packages...".format( folders=", ".join(map(lambda x: x[0] if isinstance(x, tuple) else str(x), self.plugin_folders)) )) - plugins = self.find_plugins() + if force_reload is None: + force_reload = [] + + plugins = self.find_plugins(existing=dict((k, v) for k, v in self.plugins.items() if not k in force_reload)) self.disabled_plugins.update(plugins) for name, plugin in plugins.items(): @@ -616,6 +622,16 @@ class PluginManager(object): hooks=sum(map(lambda x: len(x), self.plugin_hooks.values())) )) + def mark_plugin(self, name, uninstalled=None): + if not name in self.plugins: + self.logger.warn("Trying to mark an unknown plugin {name}".format(**locals())) + + if uninstalled is not None: + if uninstalled and not name in self.marked_plugins["uninstalled"]: + self.marked_plugins["uninstalled"].append(name) + elif not uninstalled and name in self.marked_plugins["uninstalled"]: + self.marked_plugins["uninstalled"].remove(name) + def load_plugin(self, name, plugin=None, startup=False, initialize_implementation=True): if not name in self.plugins: self.logger.warn("Trying to load an unknown plugin {name}".format(**locals()))