From 80f5fad16e830a9fea9e73c0eaa5b36c27566d9c Mon Sep 17 00:00:00 2001 From: Markus Heiser Date: Fri, 28 Feb 2025 11:58:45 +0100 Subject: [PATCH] [fix] add backward compatibility for the "enabled_plugins:" Before #4183 a builtin plugin was *defautlt_on* when it is listed in the "enabled_plugins" settings, this patch restores the previous behavior. Not part of this patch but just to mentioning in context of #4263: In the long term, we will abolish the "enabled_plugins:" setting and combine all options for the plugins in the "plugins:" setting, as is already planned in the PR #4282 Closes: https://github.com/searxng/searxng/issues/4263 Signed-off-by: Markus Heiser --- searx/plugins/_core.py | 45 ++++++++++++++++++++++++---- tests/unit/test_plugin_calculator.py | 2 +- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/searx/plugins/_core.py b/searx/plugins/_core.py index 70e5758ec..7df9772e9 100644 --- a/searx/plugins/_core.py +++ b/searx/plugins/_core.py @@ -72,10 +72,10 @@ class PluginInfo: class Plugin(abc.ABC): """Abstract base class of all Plugins.""" - id: typing.ClassVar[str] + id: str = "" """The ID (suffix) in the HTML form.""" - default_on: typing.ClassVar[bool] + default_on: bool = False """Plugin is enabled/disabled by default.""" keywords: list[str] = [] @@ -91,8 +91,12 @@ class Plugin(abc.ABC): info: PluginInfo """Informations about the *plugin*, see :py:obj:`PluginInfo`.""" + fqn: str = "" + def __init__(self) -> None: super().__init__() + if not self.fqn: + self.fqn = self.__class__.__mro__[0].__module__ for attr in ["id", "default_on"]: if getattr(self, attr, None) is None: @@ -178,10 +182,11 @@ class ModulePlugin(Plugin): _required_attrs = (("name", str), ("description", str), ("default_on", bool)) - def __init__(self, mod: types.ModuleType): + def __init__(self, mod: types.ModuleType, fqn: str): """In case of missing attributes in the module or wrong types are given, a :py:obj:`TypeError` exception is raised.""" + self.fqn = fqn self.module = mod self.id = getattr(self.module, "plugin_id", self.module.__name__) self.log = logging.getLogger(self.module.__name__) @@ -282,7 +287,7 @@ class PluginStorage: # for backward compatibility mod = load_module(f.name, str(f.parent)) - self.register(ModulePlugin(mod)) + self.register(ModulePlugin(mod, f"searx.plugins.{f.stem}")) for fqn in searx.get_setting("plugins"): # type: ignore self.register_by_fqn(fqn) @@ -297,8 +302,35 @@ class PluginStorage: plugin.log.critical(msg) raise KeyError(msg) + if not plugin.fqn.startswith("searx.plugins."): + self.plugin_list.add(plugin) + plugin.log.debug("plugin has been registered") + return + + # backward compatibility for the enabled_plugins setting + # https://docs.searxng.org/admin/settings/settings_plugins.html#enabled-plugins-internal + en_plgs: list[str] | None = searx.get_setting("enabled_plugins") # type:ignore + + if en_plgs is None: + # enabled_plugins not listed in the /etc/searxng/settings.yml: + # check default_on before register .. + if plugin.default_on: + self.plugin_list.add(plugin) + plugin.log.debug("builtin plugin has been registered by SearXNG's defaults") + return + plugin.log.debug("builtin plugin is not registered by SearXNG's defaults") + return + + if plugin.info.name not in en_plgs: + # enabled_plugins listed in the /etc/searxng/settings.yml, + # but this plugin is not listed in: + plugin.log.debug("builtin plugin is not registered by maintainer's settings") + return + + # if the plugin is in enabled_plugins, then it is on by default. + plugin.default_on = True self.plugin_list.add(plugin) - plugin.log.debug("plugin has been loaded") + plugin.log.debug("builtin plugin is registered by maintainer's settings") def register_by_fqn(self, fqn: str): """Register a :py:obj:`Plugin` via its fully qualified class name (FQN). @@ -324,7 +356,8 @@ class PluginStorage: warnings.warn( f"plugin {fqn} is implemented in a legacy module / migrate to searx.plugins.Plugin", DeprecationWarning ) - self.register(ModulePlugin(code_obj)) + + self.register(ModulePlugin(code_obj, fqn)) return self.register(code_obj()) diff --git a/tests/unit/test_plugin_calculator.py b/tests/unit/test_plugin_calculator.py index 2deba35b8..ec0258cab 100644 --- a/tests/unit/test_plugin_calculator.py +++ b/tests/unit/test_plugin_calculator.py @@ -26,7 +26,7 @@ class PluginCalculator(SearxTestCase): engines = {} self.storage = searx.plugins.PluginStorage() - self.storage.register(ModulePlugin(mod)) + self.storage.register(ModulePlugin(mod, "searx.plugins.calculator")) self.storage.init(self.app) self.pref = searx.preferences.Preferences(["simple"], ["general"], engines, self.storage) self.pref.parse_dict({"locale": "en"})