|
|
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] |