Source code for plugin_collection

"""
This module defines the PluginCollection class, which is responsible for discovering and loading
plugin modules that inherit from a base Plugin class. The PluginCollection class recursively walks
through a specified package to find and instantiate plugin classes.

Plugins are expected to perform specific operations within a larger application framework, ensuring
a consistent interface for interaction.
"""

import inspect
import os
import pkgutil
from base_plugin import Plugin


[docs] class PluginCollection(object): """ Manages the collection of plugins by discovering and loading them from a specified package. Attributes: plugins (list): A list of instantiated plugin objects. name_application (list): A list of plugin class names. seen_paths (list): A list of paths that have already been scanned for plugins. path_folder (list): A list of module paths where plugins were found. plugin_package (str): The name of the package to search for plugins. """ def __init__(self, plugin_package): """ Upon creation, this class will read the plugins package for modules that contains a class definition that is inheriting from the Plugin class. Args: plugin_package (): The folder name of plugins directory. i.e here is "plugins" """ self.plugins = None self.name_application = None self.seen_paths = None self.path_folder = None self.plugin_package = plugin_package self.reload_plugins()
[docs] def reload_plugins(self): """ Reset the list of all plugins and initiate the walk over the main provided plugin package to load all available plugins. Returns: None """ self.plugins = [] self.name_application = [] self.seen_paths = [] self.path_folder = [] self.walk_package(self.plugin_package)
[docs] def application(self, argument, index): """ Apply all of the plugin on the argument supplied to this function. Args: argument (): this is the widget send from main apps(QMainWindow) index (): The index number from the list plugins available Returns: None """ if index != -1: plugin = self.plugins[index] plugin.perform_operation(argument) else: print("No Application available!!")
[docs] def walk_package(self, package): """ Recursively walk the supplied package to retrieve all plugins. Args: package (): The name folder e define. i.e "plugins" Returns: Create list plugins that find from plugin directory. """ imported_package = __import__(package, fromlist=['blah']) for _, pluginname, ispkg in pkgutil.iter_modules( imported_package.__path__, imported_package.__name__ + '.'): if not ispkg: plugin_module = __import__(pluginname, fromlist=['blah']) clsmembers = inspect.getmembers(plugin_module, inspect.isclass) for (_, c) in clsmembers: # only add classes that are a sub class of plugin, but not # plugin it self if issubclass(c, Plugin) & (c is not Plugin): # print(f'Found Plugin class: {c.__module__}') self.path_folder.append(c.__module__) self.name_application.append(c.__name__) self.plugins.append(c()) # Now that we have looked at all the modules in the current package, start looking # recursively for additional modules in sub packages all_curent_paths = [] if isinstance(imported_package.__path__, str): all_curent_paths.append(imported_package.__path__) else: all_curent_paths.extend([x for x in imported_package.__path__]) for pkg_path in all_curent_paths: if pkg_path not in self.seen_paths: self.seen_paths.append(pkg_path) # get sub directory of curent package path directory child_pkgs = [ p for p in os.listdir(pkg_path) if os.path.isdir( os.path.join( pkg_path, p))] # For each sub directory, apply the walk_package method # recursively for child_pkg in child_pkgs: self.walk_package(package + '.' + child_pkg)