更新文档,完善插件功能
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -572,4 +572,4 @@ def init_db():
|
||||
print("用户角色数据存入")
|
||||
add_role_power()
|
||||
print("角色权限数据存入")
|
||||
print("数据初始化完成,请使用run脚本运行")
|
||||
print("数据初始化完成,请使用run脚本运行")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
@@ -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')
|
||||
|
||||
@@ -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)
|
||||
@@ -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::
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"plugin_name": "Hello World",
|
||||
"plugin_version": "1.0.0.1",
|
||||
"plugin_description": "一个测试的插件。"
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user