From b92c450be4e735a6264dd109b3c2a5b5f801a2eb Mon Sep 17 00:00:00 2001 From: wojiaoyishang <422880152@qq.com> Date: Fri, 10 Feb 2023 23:05:54 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8F=92=E4=BB=B6=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .flaskenv | 2 +- applications/view/plugin/__init__.py | 5 +- pear.sql | 6 +- plugins/helloworld/__init__.py | 10 ++- plugins/helloworld/main.py | 7 -- .../templates/helloworld_index.html | 68 ++++++++++++++++++- plugins/realip/__init__.json | 9 +++ plugins/realip/__init__.py | 66 ++++++++++++++++++ plugins/replacePage/__init__.json | 9 +++ plugins/replacePage/__init__.py | 37 ++++++++++ .../templates/replacePage_index.html | 67 ++++++++++++++++++ 11 files changed, 271 insertions(+), 15 deletions(-) create mode 100644 plugins/realip/__init__.json create mode 100644 plugins/realip/__init__.py create mode 100644 plugins/replacePage/__init__.json create mode 100644 plugins/replacePage/__init__.py create mode 100644 plugins/replacePage/templates/replacePage_index.html diff --git a/.flaskenv b/.flaskenv index f411f0e..c6b022c 100644 --- a/.flaskenv +++ b/.flaskenv @@ -29,4 +29,4 @@ MAIL_USERNAME = '123@qq.com' MAIL_PASSWORD = 'XXXXX' # 生成的授权码 # 插件配置 -PLUGIN_ENABLE_FOLDERS = ["HelloWorld", "helloworld"] \ No newline at end of file +PLUGIN_ENABLE_FOLDERS = ["helloworld"] \ No newline at end of file diff --git a/applications/view/plugin/__init__.py b/applications/view/plugin/__init__.py index d30c947..2aa2d47 100644 --- a/applications/view/plugin/__init__.py +++ b/applications/view/plugin/__init__.py @@ -26,7 +26,6 @@ def register_plugin_views(app: Flask): try: with open("plugins/" + plugin_folder + "/__init__.json", "r", encoding='utf-8') as f: plugin_info = json.loads(f.read()) - print(f"* Plugin: Loading {plugin_info['plugin_name']} ......") # 初始化完成事件 try: getattr(importlib.import_module('plugins.' + plugin_folder), "event_init")(app) @@ -34,9 +33,9 @@ def register_plugin_views(app: Flask): pass except BaseException as error: return fail_api(msg="Crash a error! Info: " + str(error)) - print(f"* Plugin: Loaded {plugin_info['plugin_name']} !") + 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 = 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" diff --git a/pear.sql b/pear.sql index 77972f2..e33d78a 100644 --- a/pear.sql +++ b/pear.sql @@ -212,7 +212,7 @@ INSERT INTO `admin_power` VALUES (57, '邮件管理', '1', 'admin:mail:main', '/ INSERT INTO `admin_power` VALUES (58, '邮件发送', '2', 'admin:mail:add', '', '', '57', 'layui-icon layui-icon-ok-circle', 1, '2022-10-11 11:22:26', '2022-10-11 11:22:26', 1); INSERT INTO `admin_power` VALUES (59, '邮件删除', '2', 'admin:mail:remove', '', '', '57', 'layui-icon layui-icon layui-icon-close', 2, '2022-10-11 11:23:06', '2022-10-11 11:23:18', 1); INSERT INTO `admin_power` VALUES (60, '拓展插件', '0', '', '', '', '0', 'layui-icon layui-icon layui-icon-senior', 2, '2022-12-18 12:28:19', '2022-12-18 12:30:25', 1); -INSERT INTO `admin_power` VALUES (61, '插件管理', '1', 'admin:plugin:main', '/plugin', '_iframe', '57', 'layui-icon layui-icon layui-icon layui-icon ', 1, '2022-12-18 12:30:13', '2022-12-18 13:57:20', 1); +INSERT INTO `admin_power` VALUES (61, '插件管理', '1', 'admin:plugin:main', '/plugin', '_iframe', '60', 'layui-icon layui-icon layui-icon layui-icon ', 1, '2022-12-18 12:30:13', '2022-12-18 13:57:20', 1); INSERT INTO `admin_power` VALUES (62, '启禁插件', '2', 'admin:plugin:enable', '', '', '61', 'layui-icon ', 1, '2022-12-18 13:25:37', '2022-12-18 13:25:37', 1); INSERT INTO `admin_power` VALUES (63, '删除插件', '2', 'admin:plugin:remove', '', '', '61', 'layui-icon layui-icon ', 2, '2022-12-18 13:26:30', '2022-12-18 13:27:17', 1); @@ -303,6 +303,10 @@ INSERT INTO `admin_role_power` VALUES (366, 56, 1); INSERT INTO `admin_role_power` VALUES (367, 57, 1); INSERT INTO `admin_role_power` VALUES (368, 58, 1); INSERT INTO `admin_role_power` VALUES (369, 59, 1); +INSERT INTO `admin_role_power` VALUES (370, 60, 1); +INSERT INTO `admin_role_power` VALUES (371, 61, 1); +INSERT INTO `admin_role_power` VALUES (372, 62, 1); +INSERT INTO `admin_role_power` VALUES (373, 63, 1); -- ---------------------------- -- Table structure for admin_user diff --git a/plugins/helloworld/__init__.py b/plugins/helloworld/__init__.py index 58519af..b972aa9 100644 --- a/plugins/helloworld/__init__.py +++ b/plugins/helloworld/__init__.py @@ -1,17 +1,23 @@ """ 初始化插件 """ +import os + from flask import Flask from .main import helloworld_blueprint +# 获取插件所在的目录(结尾没有分割符号) +dir_path = os.path.dirname(__file__).replace("\\", "/") +folder_name = dir_path[dir_path.rfind("/") + 1:] # 插件文件夹名称 + def event_enable(): """当此插件被启用时会调用此处""" - print("启用插件") + print(f"启用插件,dir_path: {dir_path} ; folder_name: {folder_name}") def event_disable(): """当此插件被禁用时会调用此处""" - print("禁用插件") + print(f"禁用插件,dir_path: {dir_path} ; folder_name: {folder_name}") def event_init(app: Flask): """初始化完成时会调用这里""" diff --git a/plugins/helloworld/main.py b/plugins/helloworld/main.py index 7e535be..0f8f56e 100644 --- a/plugins/helloworld/main.py +++ b/plugins/helloworld/main.py @@ -2,13 +2,6 @@ from applications.dev import * from flask import render_template, Blueprint -import os -import psutil - -# 获取插件所在的目录(结尾没有分割符号) -dir_path = os.path.dirname(__file__).replace("\\", "/") -folder_name = dir_path[dir_path.rfind("/") + 1:] # 插件文件夹名称 - # 创建蓝图 helloworld_blueprint = Blueprint('hello_world', __name__, template_folder='templates', static_folder="static", url_prefix="/hello_world") diff --git a/plugins/helloworld/templates/helloworld_index.html b/plugins/helloworld/templates/helloworld_index.html index c062ec2..0982b24 100644 --- a/plugins/helloworld/templates/helloworld_index.html +++ b/plugins/helloworld/templates/helloworld_index.html @@ -1 +1,67 @@ -

Test!

\ No newline at end of file + + + + + pear-admin-flask + + {% include 'admin/common/header.html' %} + + + + + + + +
+ +
+ + +
+
+ +
+
+
+

你好世界!这是一个测试页面!

+
+
+
+
+
+ + + + + + + + + + + + + diff --git a/plugins/realip/__init__.json b/plugins/realip/__init__.json new file mode 100644 index 0000000..2f7e77f --- /dev/null +++ b/plugins/realip/__init__.json @@ -0,0 +1,9 @@ +{ + "plugin_name": "真实IP插件", + "plugin_version": "1.0.0.1", + "plugin_description": "在上游更改访客IP地址,并采用自定义日志输出。", + "developer_name": "Yishang", + "developer_website": "https://lovepikachu.top", + "developer_email": "422880152@qq.com", + "developer_phone": "-" +} \ No newline at end of file diff --git a/plugins/realip/__init__.py b/plugins/realip/__init__.py new file mode 100644 index 0000000..f1aee91 --- /dev/null +++ b/plugins/realip/__init__.py @@ -0,0 +1,66 @@ +""" +初始化插件 +""" +import os +import logging +from flask import Flask, request +from applications.dev import console + +# 获取插件所在的目录(结尾没有分割符号) +dir_path = os.path.dirname(__file__).replace("\\", "/") +folder_name = dir_path[dir_path.rfind("/") + 1:] # 插件文件夹名称 + +def event_enable(): + """当此插件被启用时会调用此处""" + print(f"启用插件,dir_path: {dir_path} ; folder_name: {folder_name}") + + +def event_disable(): + """当此插件被禁用时会调用此处""" + print(f"禁用插件,dir_path: {dir_path} ; folder_name: {folder_name}") + +def event_init(app: Flask): + """初始化完成时会调用这里""" + # 移除原有的输出日志 + app.logger = None + log = logging.getLogger('werkzeug') + log.setLevel(logging.ERROR) + + # 更改IP地址,只有在最新版的flask中才能生效 + @app.before_request + def before_request(): + request.remote_addr = get_user_ip(request) + + + # 使用自定义的日志输出 + @app.after_request + def after_request(rep): + if rep.status_code == 200: + console.success(f"{request.remote_addr} -- {request.full_path} 200") + elif rep.status_code == 404: + console.error(f"{request.remote_addr} -- {request.full_path} 404") + elif rep.status_code == 500: + console.warning(f"{request.remote_addr} -- {request.full_path} 500") + else: + console.info(f"{request.remote_addr} -- {request.full_path} {rep.status_code}") + return rep + +def get_user_ip(request): + """获取用户真实IP""" + if 'HTTP_X_FORWARDED_FOR' in request.headers: + arr = request.headers['HTTP_X_FORWARDED_FOR'].strip().split(",") + i = 0 + while i < len(arr): + if arr[i].find("unknown") != -1: + del arr[i] + else: + i += 1 + if len(arr) != 0: + return arr[0].strip() + elif 'HTTP_CLIENT_IP' in request.headers: + return request.headers['HTTP_CLIENT_IP'] + elif 'REMOTE_ADDR' in request.headers: + return request.headers['REMOTE_ADDR'] + elif 'X-Forwarded-For' in request.headers: + return request.headers['X-Forwarded-For'] + return request.remote_addr \ No newline at end of file diff --git a/plugins/replacePage/__init__.json b/plugins/replacePage/__init__.json new file mode 100644 index 0000000..d555882 --- /dev/null +++ b/plugins/replacePage/__init__.json @@ -0,0 +1,9 @@ +{ + "plugin_name": "页面替换插件", + "plugin_version": "1.0.0.1", + "plugin_description": "在不更改原有框架视图函数的情况下更改渲染输出页面。", + "developer_name": "Yishang", + "developer_website": "https://lovepikachu.top", + "developer_email": "422880152@qq.com", + "developer_phone": "-" +} \ No newline at end of file diff --git a/plugins/replacePage/__init__.py b/plugins/replacePage/__init__.py new file mode 100644 index 0000000..e973e20 --- /dev/null +++ b/plugins/replacePage/__init__.py @@ -0,0 +1,37 @@ +""" +初始化插件 +""" +import os +import logging +from flask import Flask, render_template_string +from applications.dev import console + +# 获取插件所在的目录(结尾没有分割符号) +dir_path = os.path.dirname(__file__).replace("\\", "/") +folder_name = dir_path[dir_path.rfind("/") + 1:] # 插件文件夹名称 + +def event_enable(): + """当此插件被启用时会调用此处""" + print(f"启用插件,dir_path: {dir_path} ; folder_name: {folder_name}") + + +def event_disable(): + """当此插件被禁用时会调用此处""" + print(f"禁用插件,dir_path: {dir_path} ; folder_name: {folder_name}") + +def event_init(app: Flask): + """初始化完成时会调用这里""" + # 使用下面的代码 查看所有注册的视图函数。对于 Flask app.route 函数的实现,请参考 https://www.jianshu.com/p/dff3bc2f4836 + # print(app.view_functions) + + # 定义新视图函数 + def new_index(): + # 规避 render_template 的做法 + with open(dir_path + "/templates/replacePage_index.html", "r", encoding='utf-8') as f: + return render_template_string(f.read()) + + # Index.index 是主页的视图函数对应的名称,原视图函数位于 applications/view/index/index.py + del app.view_functions['Index.index'] # 释放原视图函数 + app.view_functions['Index.index'] = new_index # 替换原视图函数 + + \ No newline at end of file diff --git a/plugins/replacePage/templates/replacePage_index.html b/plugins/replacePage/templates/replacePage_index.html new file mode 100644 index 0000000..06d8e06 --- /dev/null +++ b/plugins/replacePage/templates/replacePage_index.html @@ -0,0 +1,67 @@ + + + + + pear-admin-flask + + {% include 'admin/common/header.html' %} + + + + + + + +
+ +
+ + +
+
+ +
+
+
+

主页被我替换了哈哈哈!

+
+
+
+
+
+ + + + + + + + + + + + +