from flask import Flask, request, jsonify from module import module, F6_Plugin_module from urllib.parse import unquote from config import Config import queue import threading import logging import os from logging.handlers import RotatingFileHandler from apscheduler.schedulers.background import BackgroundScheduler import requests import atexit app = Flask(__name__) app.config.from_object(Config) f6_module = module.F6Module() f6_plugin_module = F6_Plugin_module.F6PluginModule() # 定义一个映射表,将操作与处理函数关联起来 action_map = { 'login_in': f6_module.accept_login_message, 'get_company_information': f6_module.get_company_information, 'get_store_information': f6_module.get_store_information, "keep_alive": f6_module.get_keep_heart, 'check_file': f6_plugin_module.check_file, 'create_brand': f6_plugin_module.create_brand, 'delete_history': f6_plugin_module.delete_history, # 'delete_customer': f6_plugin_module.delete_customer, # 'delete_cars': f6_plugin_module.delete_cars, } # 创建一个消息队列 task_queue = queue.Queue() # 创建一个线程来处理队列中的任务 def process_tasks(): while True: task = task_queue.get() if task is None: logger.error("任务处理线程已终止") break # 停止处理任务 try: result = task['handler'](task['data']) task['response'].put(result) except Exception as e: logger.error(f"任务执行失败: {str(e)}") task['response'].put({'msg': f'任务执行失败: {str(e)}'}) finally: task_queue.task_done() logger.info("任务处理完成") # 启动任务处理线程 task_thread = threading.Thread(target=process_tasks, daemon=True) task_thread.start() # 配置日志记录器 log_dir = './日志' # 日志文件夹路径 if not os.path.exists(log_dir): os.makedirs(log_dir) # 如果日志文件夹不存在,则创建它 log_file = os.path.join(log_dir, '简道云日志.log') # 设置日志格式和级别 logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # 创建RotatingFileHandler,支持日志文件滚动 file_handler = RotatingFileHandler(log_file, maxBytes=1024 * 1024 * 5, backupCount=5) file_handler.setLevel(logging.INFO) # 定义日志格式 formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s:%(message)s') file_handler.setFormatter(formatter) # 将处理器添加到记录器 logger.addHandler(file_handler) # 将Flask的默认日志记录器也配置为使用相同的处理器 app.logger.addHandler(file_handler) # 创建一个后台调度器 scheduler = BackgroundScheduler() # 定义一个定时任务,定期发送心跳请求以保持服务活跃 def keep_alive(): try: data = { 'Action': 'keep_alive' } header = { 'Action': 'keep_alive' } # 发送一个GET请求到自己的API端点,模拟活动 response = requests.post(url='http://192.168.10.86:5000/webhook', data=data, headers=header, timeout=5) if response.status_code == 200: logger.info("Heartbeat sent successfully") else: logger.warning(f"Heartbeat failed with status code: {response.status_code}") except requests.RequestException as e: logger.error(f"Failed to send heartbeat: {e}") # 添加定时任务,每隔1分钟执行一次 scheduler.add_job(keep_alive, 'interval', minutes=1) # 启动调度器 scheduler.start() # 确保在应用退出时关闭调度器 atexit.register(lambda: scheduler.shutdown()) @app.route('/webhook', methods=['POST']) def webhook(): logging.info('Received POST request to /webhook') """ 接受前端请求后将任务放入消息队列 Returns: any: 返回任务处理的结果 """ # 获取请求体中的 JSON 数据 data = request.json header = request.headers header = decode_headers(header) action = header.get('Action') if action == 'F6_Plugin': check = header.get('Check') if check == '否': handler = f6_plugin_module.check_file elif check == '是': sub_action = data.get('Action') handler = action_map.get(sub_action, lambda x: {'msg': '未执行'}) else: return jsonify({'msg': '未知的操作'}) else: handler = action_map.get(action, lambda x: {'msg': '未知的操作'}) # 创建一个队列用于存储任务处理结果 response_queue = queue.Queue() # 将任务放入消息队列 task_queue.put({ 'handler': handler, 'data': data, 'response': response_queue }) # 等待任务处理结果 result = response_queue.get() return jsonify(result) def decode_headers(headers): """ 解码包含中文字符的 HTTP 请求头。 :param headers: 包含编码后头部字段的字典 :return: 解码后的头部字段字典 """ return {key: unquote(value, encoding='utf-8') for key, value in headers.items()} if __name__ == '__main__': # from waitress import serve # serve(app, host='192.168.10.86', port=5000) app.run(debug=True, port=5000)