import os import logging from django.conf import settings # wr导入Django配置,用于获取插件相关设置 # wr创建当前模块的日志记录器,用于记录插件加载过程中的日志信息 logger = logging.getLogger(__name__) # wr全局插件注册表:存储所有已成功加载的插件实例 _loaded_plugins = [] def load_plugins(): """ wr动态加载并初始化'plugins'目录中的插件。 此函数应在Django应用注册表就绪时调用(确保Django环境已初始化)。 """ global _loaded_plugins # wr声明使用全局变量_loaded_plugins _loaded_plugins = [] # wr清空现有插件列表,重新加载 # wr遍历配置中激活的插件列表(settings.ACTIVE_PLUGINS定义了需要加载的插件名) for plugin_name in settings.ACTIVE_PLUGINS: # wr构建插件目录的绝对路径:PLUGINS_DIR(插件根目录) + 插件名 plugin_path = os.path.join(settings.PLUGINS_DIR, plugin_name) # wr检查插件目录是否存在,且目录下是否有必要的'plugin.py'文件(插件入口) if os.path.isdir(plugin_path) and os.path.exists(os.path.join(plugin_path, 'plugin.py')): try: # wr导入插件模块:格式为'plugins.插件名.plugin'(对应plugin.py文件) plugin_module = __import__(f'plugins.{plugin_name}.plugin', fromlist=['plugin']) # wr检查插件模块中是否有'plugin'属性(通常是插件类的实例) if hasattr(plugin_module, 'plugin'): plugin_instance = plugin_module.plugin # wr获取插件实例 _loaded_plugins.append(plugin_instance) # wr添加到全局注册表 # wr记录成功加载的日志,包含插件名和插件元数据中的名称 logger.info(f"Successfully loaded plugin: {plugin_name} - {plugin_instance.PLUGIN_NAME}") else: # wr插件模块中没有'plugin'实例时记录警告 logger.warning(f"Plugin {plugin_name} does not have 'plugin' instance") except ImportError as e: # wr导入插件模块失败时记录错误(如文件缺失、语法错误等) logger.error(f"Failed to import plugin: {plugin_name}", exc_info=e) except AttributeError as e: # wr获取插件实例时发生属性错误(如缺少必要属性) logger.error(f"Failed to get plugin instance: {plugin_name}", exc_info=e) except Exception as e: # wr其他未预料的错误 logger.error(f"Unexpected error loading plugin: {plugin_name}", exc_info=e) def get_loaded_plugins(): """ wr获取所有已加载的插件实例列表。 Returns: list: 已初始化的插件实例集合 """ return _loaded_plugins def get_plugin_by_name(plugin_name): """ wr根据插件名称(slug)查找插件实例。 注:实际通过插件的plugin_slug属性匹配(与函数名对应,可能存在命名统一设计)。 Args: plugin_name: 插件的slug名称(通常为插件目录名) Returns: 匹配的插件实例,若未找到则返回None """ for plugin in _loaded_plugins: if plugin.plugin_slug == plugin_name: return plugin return None def get_plugin_by_slug(plugin_slug): """ wr根据插件slug查找插件实例(与get_plugin_by_name功能一致,可能为兼容保留)。 Args: plugin_slug: 插件的唯一标识符(slug) Returns: 匹配的插件实例,若未找到则返回None """ for plugin in _loaded_plugins: if plugin.plugin_slug == plugin_slug: return plugin return None def get_plugins_info(): """ wr获取所有已加载插件的信息字典列表。 信息由插件的get_plugin_info()方法提供(包含元数据和配置)。 Returns: list: 每个元素为一个插件的信息字典 """ return [plugin.get_plugin_info() for plugin in _loaded_plugins] def get_plugins_by_position(position): """ wr筛选出支持指定显示位置的插件实例。 Args: position: 位置标识(如'sidebar'、'article_bottom'等) Returns: list: 所有支持该位置的插件实例 """ return [plugin for plugin in _loaded_plugins if position in plugin.SUPPORTED_POSITIONS]