更新文档,完善插件功能

This commit is contained in:
wojiaoyishang
2025-01-27 21:34:42 +08:00
parent feed91dcd0
commit da5917344e
10 changed files with 119 additions and 41 deletions
+1
View File
@@ -8,6 +8,7 @@ from applications.view import init_bps
def create_app():
app = Flask(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
# 引入配置
app.config.from_object(BaseConfig)
+2
View File
@@ -1,7 +1,9 @@
from flask import Flask
from .admin import admin_cli
from applications.extensions.init_plugins import broadcast_execute
def init_script(app: Flask):
app.cli.add_command(admin_cli)
broadcast_execute(app, 'event_finish')
+1 -1
View File
@@ -572,4 +572,4 @@ def init_db():
print("用户角色数据存入")
add_role_power()
print("角色权限数据存入")
print("数据初始化完成,请使用run脚本运行")
print("数据初始化完成请使用run脚本运行")
+7 -1
View File
@@ -7,9 +7,15 @@ from .init_mail import init_mail, mail as flask_mail
from .init_upload import init_upload
from .init_migrate import init_migrate
from .init_session import init_session
from .init_plugins import register_plugin, broadcast_execute
def init_plugs(app: Flask) -> None:
# 注册插件
register_plugin(app)
broadcast_execute(app, 'event_begin')
# 注册 Flask 功能
init_login_manager(app)
init_databases(app)
init_template_directives(app)
@@ -17,4 +23,4 @@ def init_plugs(app: Flask) -> None:
init_mail(app)
init_upload(app)
init_migrate(app)
init_session(app)
init_session(app)
+61
View File
@@ -0,0 +1,61 @@
import os
from flask import Flask
from flask import Blueprint
import json
import importlib
plugin_bp = Blueprint('plugin', __name__, url_prefix='/plugin')
PLUGIN_ENABLE_FOLDERS = []
PLUGIN_IMPORTLIB = []
def register_plugin(app: Flask):
"""
获取所有插件并加载
"""
global PLUGIN_ENABLE_FOLDERS
app.register_blueprint(plugin_bp)
# 载入插件过程
# plugin_folder 配置的是插件的文件夹名
PLUGIN_ENABLE_FOLDERS = app.config['PLUGIN_ENABLE_FOLDERS']
for plugin_folder in PLUGIN_ENABLE_FOLDERS:
plugin_info = {
'plugin_name': plugin_folder
}
try:
if os.path.exists("plugins/" + plugin_folder + "/__init__.json"):
with open("plugins/" + plugin_folder + "/__init__.json", "r", encoding='utf-8') as f:
plugin_info = json.loads(f.read())
# 将插件全部载入
PLUGIN_IMPORTLIB.append(importlib.import_module('plugins.' + plugin_folder))
print(f" * Plugin: Loaded plugin: {plugin_info['plugin_name']} .")
except BaseException as e:
info = f" * Plugin: Crash a error when loading {plugin_info['plugin_name'] if len(plugin_info) != 0 else 'plugin'} :" + "\n"
app.logger.error(info)
app.logger.exception(e)
def broadcast_execute(app: Flask, function_name):
for plugin in PLUGIN_IMPORTLIB:
try:
# 初始化完成事件
try:
getattr(plugin, function_name)(app)
except AttributeError: # 没有插件启用事件就不调用
pass
except BaseException as e:
app.logger.exception(e)
if function_name == 'event_finish':
with app.app_context():
broadcast_execute(app, 'event_context')
+4 -2
View File
@@ -1,7 +1,9 @@
from applications.view.system import register_system_bps
from applications.view.plugin import register_plugin_views
from applications.extensions.init_plugins import broadcast_execute
def init_bps(app):
register_system_bps(app)
register_plugin_views(app)
# 插件初始化函数
broadcast_execute(app, 'event_init')
-34
View File
@@ -1,34 +0,0 @@
from flask import Flask
from flask import Blueprint
import json
import traceback
import importlib
plugin_bp = Blueprint('plugin', __name__, url_prefix='/plugin')
PLUGIN_ENABLE_FOLDERS = []
def register_plugin_views(app: Flask):
global PLUGIN_ENABLE_FOLDERS
app.register_blueprint(plugin_bp)
# 载入插件过程
# plugin_folder 配置的是插件的文件夹名
PLUGIN_ENABLE_FOLDERS = app.config['PLUGIN_ENABLE_FOLDERS']
for plugin_folder in PLUGIN_ENABLE_FOLDERS:
plugin_info = {}
try:
with open("plugins/" + plugin_folder + "/__init__.json", "r", encoding='utf-8') as f:
plugin_info = json.loads(f.read())
# 初始化完成事件
try:
getattr(importlib.import_module('plugins.' + plugin_folder), "event_init")(app)
except AttributeError: # 没有插件启用事件就不调用
pass
print(f" * Plugin: Loaded plugin: {plugin_info['plugin_name']} .")
except BaseException as e:
info = f" * Plugin: Crash a error when loading {plugin_info['plugin_name'] if len(plugin_info) != 0 else 'plugin'} :" + "\n"
info += 'str(Exception):\t' + str(Exception) + "\n"
info += 'str(e):\t\t' + str(e) + "\n"
info += 'repr(e):\t' + repr(e) + "\n"
info += 'traceback.format_exc():\n%s' + traceback.format_exc()
print(info)
+16 -3
View File
@@ -71,10 +71,10 @@
这个 JSON 文件中,记录了基本的插件名称与插件版本,以及插件的介绍。**在更新之后,此文件可以不存在,插件的名称默认为文件夹名。**
编写插件入口
编写插件事件
-------------------
插件入口位于 `__init__.py` 中,请确保 `__init__.py` 文件一定包含 `event_init(app: Flask)` 函数,如下:
插件入口位于 `__init__.py` 中,一般来说请确保 `__init__.py` 文件包含 `event_init(app: Flask)` 函数,如下:
.. code-block:: python
@@ -122,9 +122,22 @@
这样可以使目录架构更加清晰。
另外,插件还有其他三个事件:
.. code-block:: python
def event_begin(app: Flask): # 在项目所有功能注册之前调用
pass
def event_finish(app: Flask): # 在项目所有功能注册之后调用(插件已经加载完毕)
pass
def event_context(app: Flask): # Flask 初始化完成,等待第一个请求之前,等同于 with app.app_context():
pass
.. important::
注意不要直接在 `__init__.py` `event_init` 函数外直接写存在阻塞的代码,不然项目 Flask 将不能初始化完成。
注意不要直接在 `__init__.py` 的函数外直接写存在阻塞的代码,不然项目 Flask 将不能初始化完成。
.. note::
+5
View File
@@ -0,0 +1,5 @@
{
"plugin_name": "Hello World",
"plugin_version": "1.0.0.1",
"plugin_description": "一个测试的插件。"
}
+22
View File
@@ -6,11 +6,33 @@ import os
from flask import Flask
from .main import helloworld_blueprint
from applications.models import Dept
from applications.common import curd
from applications.schemas import DeptSchema
# 获取插件所在的目录(结尾没有分割符号)
dir_path = os.path.dirname(__file__).replace("\\", "/")
folder_name = dir_path[dir_path.rfind("/") + 1:] # 插件文件夹名称
def event_begin(app: Flask): # 在项目所有功能注册之前调用
print("所有功能初始化之前加载")
def event_init(app: Flask):
"""初始化完成时会调用这里"""
print("初始插件初始化视图")
app.register_blueprint(helloworld_blueprint)
def event_finish(app: Flask): # 在项目所有功能注册之后调用(插件已经加载完毕)
print("所有初始化完毕")
def event_context(app: Flask): # Flask 初始化完成,等待第一个请求之前,等同于 with app.app_context():
print("第一个请求来之前加载")
dept = Dept.query.order_by(Dept.sort).all()
power_data = curd.model_to_dicts(schema=DeptSchema, data=dept)
print(power_data)