You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tentest/doc/DjangoBlog/djangoblog/plugin_manage/loader.py

116 lines
4.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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]