.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.plugins._core.PluginStorage Class Reference

Public Member Functions

 __init__ (self)
 
 __iter__ (self)
 
 __len__ (self)
 
list[PluginInfoinfo (self)
 
 load_builtins (self)
 
 register (self, Plugin plugin)
 
 register_by_fqn (self, str fqn)
 
None init (self, flask.Flask app)
 
bool pre_search (self, SXNG_Request request, "SearchWithPlugins" search)
 
bool on_result (self, SXNG_Request request, "SearchWithPlugins" search, Result result)
 
None post_search (self, SXNG_Request request, "SearchWithPlugins" search)
 

Static Public Attributes

set plugin_list [Plugin]
 
list legacy_plugins
 

Detailed Description

A storage for managing the *plugins* of SearXNG.

Definition at line 236 of file _core.py.

Constructor & Destructor Documentation

◆ __init__()

searx.plugins._core.PluginStorage.__init__ ( self)

Definition at line 253 of file _core.py.

253 def __init__(self):
254 self.plugin_list = set()
255

References plugin_list.

Member Function Documentation

◆ __iter__()

searx.plugins._core.PluginStorage.__iter__ ( self)

Definition at line 256 of file _core.py.

256 def __iter__(self):
257
258 yield from self.plugin_list
259

References plugin_list.

◆ __len__()

searx.plugins._core.PluginStorage.__len__ ( self)

Definition at line 260 of file _core.py.

260 def __len__(self):
261 return len(self.plugin_list)
262

References plugin_list.

◆ info()

list[PluginInfo] searx.plugins._core.PluginStorage.info ( self)

Definition at line 264 of file _core.py.

264 def info(self) -> list[PluginInfo]:
265 return [p.info for p in self.plugin_list]
266

References plugin_list.

◆ init()

None searx.plugins._core.PluginStorage.init ( self,
flask.Flask app )
Calls the method :py:obj:`Plugin.init` of each plugin in this
storage.  Depending on its return value, the plugin is removed from
*this* storage or not.

Definition at line 332 of file _core.py.

332 def init(self, app: flask.Flask) -> None:
333 """Calls the method :py:obj:`Plugin.init` of each plugin in this
334 storage. Depending on its return value, the plugin is removed from
335 *this* storage or not."""
336
337 for plg in self.plugin_list.copy():
338 if not plg.init(app):
339 self.plugin_list.remove(plg)
340

References plugin_list.

Referenced by searx.sqlitedb.SQLiteAppl.connect().

+ Here is the caller graph for this function:

◆ load_builtins()

searx.plugins._core.PluginStorage.load_builtins ( self)
Load plugin modules from:

- the python packages in :origin:`searx/plugins` and
- the external plugins from :ref:`settings plugins`.

Definition at line 267 of file _core.py.

267 def load_builtins(self):
268 """Load plugin modules from:
269
270 - the python packages in :origin:`searx/plugins` and
271 - the external plugins from :ref:`settings plugins`.
272 """
273
274 for f in _default.iterdir():
275
276 if f.name.startswith("_"):
277 continue
278
279 if f.stem not in self.legacy_plugins:
280 self.register_by_fqn(f"searx.plugins.{f.stem}.SXNGPlugin")
281 continue
282
283 # for backward compatibility
284 mod = load_module(f.name, str(f.parent))
285 self.register(ModulePlugin(mod))
286
287 for fqn in searx.get_setting("plugins"): # type: ignore
288 self.register_by_fqn(fqn)
289
get_setting(name, default=_unset)
Definition __init__.py:69

References searx.get_setting(), legacy_plugins, searx.answerers._core.AnswerStorage.register(), register(), searx.answerers._core.AnswerStorage.register_by_fqn(), and register_by_fqn().

+ Here is the call graph for this function:

◆ on_result()

bool searx.plugins._core.PluginStorage.on_result ( self,
SXNG_Request request,
"SearchWithPlugins" search,
Result result )

Definition at line 355 of file _core.py.

355 def on_result(self, request: SXNG_Request, search: "SearchWithPlugins", result: Result) -> bool:
356
357 ret = True
358 for plugin in [p for p in self.plugin_list if p.id in search.user_plugins]:
359 try:
360 ret = bool(plugin.on_result(request=request, search=search, result=result))
361 except Exception: # pylint: disable=broad-except
362 plugin.log.exception("Exception while calling on_result")
363 continue
364 if not ret:
365 # ignore this result item on the first False from a plugin
366 break
367
368 return ret
369

References plugin_list.

◆ post_search()

None searx.plugins._core.PluginStorage.post_search ( self,
SXNG_Request request,
"SearchWithPlugins" search )
Extend :py:obj:`search.result_container
<searx.results.ResultContainer`> with result items from plugins listed
in :py:obj:`search.user_plugins <SearchWithPlugins.user_plugins>`.

Definition at line 370 of file _core.py.

370 def post_search(self, request: SXNG_Request, search: "SearchWithPlugins") -> None:
371 """Extend :py:obj:`search.result_container
372 <searx.results.ResultContainer`> with result items from plugins listed
373 in :py:obj:`search.user_plugins <SearchWithPlugins.user_plugins>`.
374 """
375
376 keyword = None
377 for keyword in search.search_query.query.split():
378 if keyword:
379 break
380
381 for plugin in [p for p in self.plugin_list if p.id in search.user_plugins]:
382
383 if plugin.keywords:
384 # plugin with keywords: skip plugin if no keyword match
385 if keyword and keyword not in plugin.keywords:
386 continue
387 try:
388 results = plugin.post_search(request=request, search=search) or []
389 except Exception: # pylint: disable=broad-except
390 plugin.log.exception("Exception while calling post_search")
391 continue
392
393 # In case of *plugins* prefix ``plugin:`` is set, see searx.result_types.Result
394 search.result_container.extend(f"plugin: {plugin.id}", results)

References plugin_list.

◆ pre_search()

bool searx.plugins._core.PluginStorage.pre_search ( self,
SXNG_Request request,
"SearchWithPlugins" search )

Definition at line 341 of file _core.py.

341 def pre_search(self, request: SXNG_Request, search: "SearchWithPlugins") -> bool:
342
343 ret = True
344 for plugin in [p for p in self.plugin_list if p.id in search.user_plugins]:
345 try:
346 ret = bool(plugin.pre_search(request=request, search=search))
347 except Exception: # pylint: disable=broad-except
348 plugin.log.exception("Exception while calling pre_search")
349 continue
350 if not ret:
351 # skip this search on the first False from a plugin
352 break
353 return ret
354

References plugin_list.

◆ register()

searx.plugins._core.PluginStorage.register ( self,
Plugin plugin )
Register a :py:obj:`Plugin`.  In case of name collision (if two
plugins have same ID) a :py:obj:`KeyError` exception is raised.

Definition at line 290 of file _core.py.

290 def register(self, plugin: Plugin):
291 """Register a :py:obj:`Plugin`. In case of name collision (if two
292 plugins have same ID) a :py:obj:`KeyError` exception is raised.
293 """
294
295 if plugin in self.plugin_list:
296 msg = f"name collision '{plugin.id}'"
297 plugin.log.critical(msg)
298 raise KeyError(msg)
299
300 self.plugin_list.add(plugin)
301 plugin.log.debug("plugin has been loaded")
302

References plugin_list.

Referenced by load_builtins(), and register_by_fqn().

+ Here is the caller graph for this function:

◆ register_by_fqn()

searx.plugins._core.PluginStorage.register_by_fqn ( self,
str fqn )
Register a :py:obj:`Plugin` via its fully qualified class name (FQN).
The FQNs of external plugins could be read from a configuration, for
example, and registered using this method

Definition at line 303 of file _core.py.

303 def register_by_fqn(self, fqn: str):
304 """Register a :py:obj:`Plugin` via its fully qualified class name (FQN).
305 The FQNs of external plugins could be read from a configuration, for
306 example, and registered using this method
307 """
308
309 mod_name, _, obj_name = fqn.rpartition('.')
310 if not mod_name:
311 # for backward compatibility
312 code_obj = importlib.import_module(fqn)
313 else:
314 mod = importlib.import_module(mod_name)
315 code_obj = getattr(mod, obj_name, None)
316
317 if code_obj is None:
318 msg = f"plugin {fqn} is not implemented"
319 log.critical(msg)
320 raise ValueError(msg)
321
322 if isinstance(code_obj, types.ModuleType):
323 # for backward compatibility
324 warnings.warn(
325 f"plugin {fqn} is implemented in a legacy module / migrate to searx.plugins.Plugin", DeprecationWarning
326 )
327 self.register(ModulePlugin(code_obj))
328 return
329
330 self.register(code_obj())
331

References searx.answerers._core.AnswerStorage.register(), and register().

Referenced by load_builtins().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ legacy_plugins

list searx.plugins._core.PluginStorage.legacy_plugins
static
Initial value:
= [
"ahmia_filter",
"calculator",
"hostnames",
"oa_doi_rewrite",
"tor_check",
"tracker_url_remover",
"unit_converter",
]

Definition at line 242 of file _core.py.

Referenced by load_builtins().

◆ plugin_list

searx.plugins._core.PluginStorage.plugin_list [Plugin]
static

Definition at line 239 of file _core.py.

Referenced by __init__(), __iter__(), __len__(), info(), init(), on_result(), post_search(), pre_search(), and register().


The documentation for this class was generated from the following file: