feat: MAA调度初步上线
This commit is contained in:
@@ -27,6 +27,7 @@ from .info import router as info_router
|
|||||||
from .scripts import router as scripts_router
|
from .scripts import router as scripts_router
|
||||||
from .plan import router as plan_router
|
from .plan import router as plan_router
|
||||||
from .queue import router as queue_router
|
from .queue import router as queue_router
|
||||||
|
from .dispatch import router as dispatch_router
|
||||||
from .setting import router as setting_router
|
from .setting import router as setting_router
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@@ -34,5 +35,6 @@ __all__ = [
|
|||||||
"scripts_router",
|
"scripts_router",
|
||||||
"plan_router",
|
"plan_router",
|
||||||
"queue_router",
|
"queue_router",
|
||||||
|
"dispatch_router",
|
||||||
"setting_router",
|
"setting_router",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
from fastapi import APIRouter, WebSocket, Body, Path
|
import asyncio
|
||||||
|
from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Body, Path
|
||||||
|
|
||||||
from app.core import Config, TaskManager
|
from app.core import Config, TaskManager
|
||||||
from app.models.schema import *
|
from app.models.schema import *
|
||||||
@@ -55,14 +56,26 @@ async def stop_task(task: DispatchIn = Body(...)) -> OutBase:
|
|||||||
async def websocket_endpoint(
|
async def websocket_endpoint(
|
||||||
websocket: WebSocket, taskId: str = Path(..., description="要连接的任务ID")
|
websocket: WebSocket, taskId: str = Path(..., description="要连接的任务ID")
|
||||||
):
|
):
|
||||||
|
await websocket.accept()
|
||||||
try:
|
try:
|
||||||
uid = uuid.UUID(taskId)
|
uid = uuid.UUID(taskId)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
await websocket.close(code=1008, reason="无效的任务ID")
|
await websocket.close(code=1008, reason="无效的任务ID")
|
||||||
return
|
return
|
||||||
|
|
||||||
if uid in TaskManager.connection_events:
|
if uid in TaskManager.connection_events and uid not in TaskManager.websocket_dict:
|
||||||
TaskManager.websocket_dict[uid] = websocket
|
TaskManager.websocket_dict[uid] = websocket
|
||||||
TaskManager.connection_events[uid].set()
|
TaskManager.connection_events[uid].set()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
data = await asyncio.wait_for(websocket.receive_json(), timeout=30.0)
|
||||||
|
await Config.message_queue.put({"task_id": uid, "message": data})
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await websocket.send_json(
|
||||||
|
TaskMessage(type="Signal", data={"Ping": "无描述"}).model_dump()
|
||||||
|
)
|
||||||
|
except WebSocketDisconnect:
|
||||||
|
TaskManager.websocket_dict.pop(uid, None)
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
await websocket.close(code=1008, reason="任务不存在或已结束")
|
await websocket.close(code=1008, reason="任务不存在或已结束")
|
||||||
|
|||||||
@@ -578,15 +578,6 @@ class AppConfig(GlobalConfig):
|
|||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(if_save_multi_config=False)
|
super().__init__(if_save_multi_config=False)
|
||||||
|
|
||||||
self.log_path = Path.cwd() / "debug/app.log"
|
|
||||||
self.database_path = Path.cwd() / "data/data.db"
|
|
||||||
self.config_path = Path.cwd() / "config"
|
|
||||||
self.key_path = Path.cwd() / "data/key"
|
|
||||||
|
|
||||||
self.silence_dict: Dict[Path, datetime] = {}
|
|
||||||
self.power_sign = "NoAction"
|
|
||||||
self.if_ignore_silence = False
|
|
||||||
|
|
||||||
logger.info("")
|
logger.info("")
|
||||||
logger.info("===================================")
|
logger.info("===================================")
|
||||||
logger.info("AUTO_MAA 后端应用程序")
|
logger.info("AUTO_MAA 后端应用程序")
|
||||||
@@ -594,10 +585,19 @@ class AppConfig(GlobalConfig):
|
|||||||
logger.info(f"工作目录: {Path.cwd()}")
|
logger.info(f"工作目录: {Path.cwd()}")
|
||||||
logger.info("===================================")
|
logger.info("===================================")
|
||||||
|
|
||||||
|
self.log_path = Path.cwd() / "debug/app.log"
|
||||||
|
self.database_path = Path.cwd() / "data/data.db"
|
||||||
|
self.config_path = Path.cwd() / "config"
|
||||||
|
self.key_path = Path.cwd() / "data/key"
|
||||||
# 检查目录
|
# 检查目录
|
||||||
self.log_path.parent.mkdir(parents=True, exist_ok=True)
|
self.log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
self.config_path.mkdir(parents=True, exist_ok=True)
|
self.config_path.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
self.message_queue = asyncio.Queue()
|
||||||
|
self.silence_dict: Dict[Path, datetime] = {}
|
||||||
|
self.power_sign = "NoAction"
|
||||||
|
self.if_ignore_silence = False
|
||||||
|
|
||||||
self.ScriptConfig = MultipleConfig([MaaConfig, GeneralConfig])
|
self.ScriptConfig = MultipleConfig([MaaConfig, GeneralConfig])
|
||||||
self.PlanConfig = MultipleConfig([MaaPlanConfig])
|
self.PlanConfig = MultipleConfig([MaaPlanConfig])
|
||||||
self.QueueConfig = MultipleConfig([QueueConfig])
|
self.QueueConfig = MultipleConfig([QueueConfig])
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
import uuid
|
import uuid
|
||||||
import asyncio
|
import asyncio
|
||||||
from fastapi import WebSocket
|
from fastapi import WebSocket
|
||||||
|
from functools import partial
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
from .config import Config, MaaConfig, GeneralConfig, QueueConfig
|
from .config import Config, MaaConfig, GeneralConfig, QueueConfig
|
||||||
@@ -82,8 +83,21 @@ class _TaskManager:
|
|||||||
raise RuntimeError(f"The task {task_id} is already running.")
|
raise RuntimeError(f"The task {task_id} is already running.")
|
||||||
|
|
||||||
logger.info(f"创建任务:{task_id},模式:{mode}")
|
logger.info(f"创建任务:{task_id},模式:{mode}")
|
||||||
|
self.task_dict[task_id] = asyncio.create_task(
|
||||||
|
self.run_task(mode, task_id, actual_id)
|
||||||
|
)
|
||||||
|
self.task_dict[task_id].add_done_callback(
|
||||||
|
lambda t: asyncio.create_task(self.remove_task(t, mode, task_id))
|
||||||
|
)
|
||||||
|
|
||||||
# 创建任务实例并连接信号
|
return task_id
|
||||||
|
|
||||||
|
# @logger.catch
|
||||||
|
async def run_task(
|
||||||
|
self, mode: str, task_id: uuid.UUID, actual_id: Optional[uuid.UUID]
|
||||||
|
):
|
||||||
|
|
||||||
|
# 等待连接信号
|
||||||
if task_id in self.connection_events:
|
if task_id in self.connection_events:
|
||||||
self.connection_events[task_id].clear()
|
self.connection_events[task_id].clear()
|
||||||
else:
|
else:
|
||||||
@@ -96,20 +110,6 @@ class _TaskManager:
|
|||||||
|
|
||||||
logger.info(f"开始运行任务:{task_id},模式:{mode}")
|
logger.info(f"开始运行任务:{task_id},模式:{mode}")
|
||||||
|
|
||||||
self.task_dict[task_id] = asyncio.create_task(
|
|
||||||
self.run_task(mode, task_id, actual_id)
|
|
||||||
)
|
|
||||||
self.task_dict[task_id].add_done_callback(
|
|
||||||
lambda t: asyncio.create_task(self.remove_task(t, mode, task_id))
|
|
||||||
)
|
|
||||||
|
|
||||||
return task_id
|
|
||||||
|
|
||||||
@logger.catch
|
|
||||||
async def run_task(
|
|
||||||
self, mode: str, task_id: uuid.UUID, actual_id: Optional[uuid.UUID]
|
|
||||||
):
|
|
||||||
|
|
||||||
websocket = self.websocket_dict[task_id]
|
websocket = self.websocket_dict[task_id]
|
||||||
|
|
||||||
if mode == "设置脚本":
|
if mode == "设置脚本":
|
||||||
@@ -129,10 +129,13 @@ class _TaskManager:
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
task = asyncio.create_task(task_item.run())
|
uid = actual_id or uuid.uuid4()
|
||||||
task.add_done_callback(
|
self.task_dict[uid] = asyncio.create_task(task_item.run())
|
||||||
|
self.task_dict[uid].add_done_callback(
|
||||||
lambda t: asyncio.create_task(task_item.final_task(t))
|
lambda t: asyncio.create_task(task_item.final_task(t))
|
||||||
)
|
)
|
||||||
|
self.task_dict[uid].add_done_callback(partial(self.task_dict.pop, uid))
|
||||||
|
await self.task_dict[uid]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
@@ -205,10 +208,14 @@ class _TaskManager:
|
|||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
task = asyncio.create_task(task_item.run())
|
self.task_dict[script_id] = asyncio.create_task(task_item.run())
|
||||||
task.add_done_callback(
|
self.task_dict[script_id].add_done_callback(
|
||||||
lambda t: asyncio.create_task(task_item.final_task(t))
|
lambda t: asyncio.create_task(task_item.final_task(t))
|
||||||
)
|
)
|
||||||
|
self.task_dict[script_id].add_done_callback(
|
||||||
|
partial(self.task_dict.pop, script_id)
|
||||||
|
)
|
||||||
|
await self.task_dict[script_id]
|
||||||
|
|
||||||
async def stop_task(self, task_id: str) -> None:
|
async def stop_task(self, task_id: str) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -249,14 +256,13 @@ class _TaskManager:
|
|||||||
await task
|
await task
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
logger.info(f"任务 {task_id} 已结束")
|
logger.info(f"任务 {task_id} 已结束")
|
||||||
self.task_dict.pop(task_id)
|
self.task_dict.pop(task_id)
|
||||||
|
|
||||||
websocket = self.websocket_dict.pop(task_id, None)
|
websocket = self.websocket_dict.get(task_id, None)
|
||||||
if websocket:
|
if websocket:
|
||||||
await websocket.send_json(
|
await websocket.send_json(
|
||||||
TaskMessage(type="Signal", data={"Accomplish": "无描述"}).model_dump()
|
TaskMessage(type="Signal", data={"Accomplish": "无描述"}).model_dump()
|
||||||
)
|
)
|
||||||
await websocket.close()
|
|
||||||
|
|
||||||
|
|
||||||
TaskManager = _TaskManager()
|
TaskManager = _TaskManager()
|
||||||
|
|||||||
@@ -431,8 +431,10 @@ class ConfigBase:
|
|||||||
|
|
||||||
for name in dir(self):
|
for name in dir(self):
|
||||||
item = getattr(self, name)
|
item = getattr(self, name)
|
||||||
if isinstance(item, ConfigItem | MultipleConfig):
|
if isinstance(item, ConfigItem):
|
||||||
item.lock()
|
item.lock()
|
||||||
|
elif isinstance(item, MultipleConfig):
|
||||||
|
await item.lock()
|
||||||
|
|
||||||
async def unlock(self):
|
async def unlock(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -264,10 +264,7 @@ class _SystemHandler:
|
|||||||
pname = proc.info["name"].lower()
|
pname = proc.info["name"].lower()
|
||||||
if any(keyword.lower() in pname for keyword in keywords):
|
if any(keyword.lower() in pname for keyword in keywords):
|
||||||
proc.kill()
|
proc.kill()
|
||||||
logger.info(
|
logger.info(f"已关闭 MuMu 模拟器进程: {proc.info['name']}")
|
||||||
f"已关闭 MuMu 模拟器进程: {proc.info['name']}",
|
|
||||||
module="系统服务",
|
|
||||||
)
|
|
||||||
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
397
app/task/MAA.py
397
app/task/MAA.py
@@ -105,7 +105,7 @@ class MaaManager:
|
|||||||
if not self.maa_set_path.exists():
|
if not self.maa_set_path.exists():
|
||||||
return "MAA配置文件不存在,请检查MAA路径设置!"
|
return "MAA配置文件不存在,请检查MAA路径设置!"
|
||||||
if (self.mode != "设置脚本" or self.user_id is not None) and not (
|
if (self.mode != "设置脚本" or self.user_id is not None) and not (
|
||||||
Path.cwd() / f"data/{self.script_id}/Default/gui.json"
|
Path.cwd() / f"data/{self.script_id}/Default/ConfigFile/gui.json"
|
||||||
).exists():
|
).exists():
|
||||||
return "未完成 MAA 全局设置,请先设置 MAA!"
|
return "未完成 MAA 全局设置,请先设置 MAA!"
|
||||||
return "Success!"
|
return "Success!"
|
||||||
@@ -118,11 +118,11 @@ class MaaManager:
|
|||||||
self.begin_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
self.begin_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
await self.configure()
|
await self.configure()
|
||||||
check_result = self.check_config()
|
self.check_result = self.check_config()
|
||||||
if check_result != "Success!":
|
if self.check_result != "Success!":
|
||||||
logger.error(f"未通过配置检查:{check_result}")
|
logger.error(f"未通过配置检查:{self.check_result}")
|
||||||
await self.websocket.send_json(
|
await self.websocket.send_json(
|
||||||
TaskMessage(type="Info", data={"Error": check_result}).model_dump()
|
TaskMessage(type="Info", data={"Error": self.check_result}).model_dump()
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ class MaaManager:
|
|||||||
}
|
}
|
||||||
for uid, config in self.user_config.items()
|
for uid, config in self.user_config.items()
|
||||||
if config.get("Info", "Status")
|
if config.get("Info", "Status")
|
||||||
and config.get("Info", "RemainedDay") > 0
|
and config.get("Info", "RemainedDay") != 0
|
||||||
]
|
]
|
||||||
self.user_list = sorted(
|
self.user_list = sorted(
|
||||||
self.user_list,
|
self.user_list,
|
||||||
@@ -184,7 +184,7 @@ class MaaManager:
|
|||||||
if self.script_config.get(
|
if self.script_config.get(
|
||||||
"Run", "ProxyTimesLimit"
|
"Run", "ProxyTimesLimit"
|
||||||
) == 0 or user_data.get("Data", "ProxyTimes") < self.script_config.get(
|
) == 0 or user_data.get("Data", "ProxyTimes") < self.script_config.get(
|
||||||
"RunSet", "ProxyTimesLimit"
|
"Run", "ProxyTimesLimit"
|
||||||
):
|
):
|
||||||
user["status"] = "运行"
|
user["status"] = "运行"
|
||||||
await self.websocket.send_json(
|
await self.websocket.send_json(
|
||||||
@@ -201,9 +201,7 @@ class MaaManager:
|
|||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logger.info(
|
logger.info(f"开始代理用户: {user['user_id']}")
|
||||||
f"开始代理用户: {user['user_id']}",
|
|
||||||
)
|
|
||||||
|
|
||||||
# 详细模式用户首次代理需打开模拟器
|
# 详细模式用户首次代理需打开模拟器
|
||||||
if user_data.get("Info", "Mode") == "详细":
|
if user_data.get("Info", "Mode") == "详细":
|
||||||
@@ -214,8 +212,8 @@ class MaaManager:
|
|||||||
"Annihilation": bool(
|
"Annihilation": bool(
|
||||||
user_data.get("Info", "Annihilation") == "Close"
|
user_data.get("Info", "Annihilation") == "Close"
|
||||||
),
|
),
|
||||||
"Routine": user_data.get("Info", "Mode") == "简洁"
|
"Routine": user_data.get("Info", "Mode") == "复杂"
|
||||||
or not user_data.get("Info", "Routine"),
|
and not user_data.get("Info", "Routine"),
|
||||||
}
|
}
|
||||||
|
|
||||||
user_logs_list = []
|
user_logs_list = []
|
||||||
@@ -380,18 +378,18 @@ class MaaManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 尝试次数循环
|
# 尝试次数循环
|
||||||
for i in range(user_data.get("Run", "RunTimesLimit")):
|
for i in range(self.script_config.get("Run", "RunTimesLimit")):
|
||||||
|
|
||||||
if run_book[mode]:
|
if run_book[mode]:
|
||||||
break
|
break
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"用户 {user['name']} - 模式: {mode} - 尝试次数: {i + 1}/{user_data.get('Run','RunTimesLimit')}",
|
f"用户 {user['name']} - 模式: {mode} - 尝试次数: {i + 1}/{self.script_config.get('Run','RunTimesLimit')}",
|
||||||
)
|
)
|
||||||
|
|
||||||
# 配置MAA
|
# 配置MAA
|
||||||
if isinstance(user_data, MaaUserConfig):
|
if isinstance(user_data, MaaUserConfig):
|
||||||
set = await self.set_maa(mode, index, user_data)
|
set = await self.set_maa(mode, user_data, index)
|
||||||
# 记录当前时间
|
# 记录当前时间
|
||||||
self.log_start_time = datetime.now()
|
self.log_start_time = datetime.now()
|
||||||
|
|
||||||
@@ -681,6 +679,7 @@ class MaaManager:
|
|||||||
},
|
},
|
||||||
).model_dump()
|
).model_dump()
|
||||||
)
|
)
|
||||||
|
await self.set_maa("Update")
|
||||||
subprocess.Popen(
|
subprocess.Popen(
|
||||||
[self.maa_exe_path],
|
[self.maa_exe_path],
|
||||||
creationflags=subprocess.CREATE_NO_WINDOW,
|
creationflags=subprocess.CREATE_NO_WINDOW,
|
||||||
@@ -742,175 +741,165 @@ class MaaManager:
|
|||||||
).model_dump()
|
).model_dump()
|
||||||
)
|
)
|
||||||
|
|
||||||
# # 人工排查模式
|
# # 人工排查模式
|
||||||
# elif self.mode == "人工排查":
|
# elif self.mode == "人工排查":
|
||||||
|
|
||||||
# # 人工排查时,屏蔽静默操作
|
# # 人工排查时,屏蔽静默操作
|
||||||
# logger.info(
|
# logger.info(
|
||||||
# "人工排查任务开始,屏蔽静默操作",
|
# "人工排查任务开始,屏蔽静默操作",
|
||||||
# )
|
# )
|
||||||
# Config.if_ignore_silence = True
|
# Config.if_ignore_silence = True
|
||||||
|
|
||||||
# # 标记是否需要启动模拟器
|
# # 标记是否需要启动模拟器
|
||||||
# self.if_open_emulator = True
|
# self.if_open_emulator = True
|
||||||
# # 标识排查模式
|
# # 标识排查模式
|
||||||
# for _ in self.user_list:
|
# for _ in self.user_list:
|
||||||
# _[0] += "_排查模式"
|
# _[0] += "_排查模式"
|
||||||
|
|
||||||
# # 开始排查
|
# # 开始排查
|
||||||
# for user in self.user_list:
|
# for user in self.user_list:
|
||||||
|
|
||||||
# user_data = self.data[user[2]]["Config"]
|
# user_data = self.data[user[2]]["Config"]
|
||||||
|
|
||||||
# if self.isInterruptionRequested:
|
# if self.isInterruptionRequested:
|
||||||
# break
|
# break
|
||||||
|
|
||||||
# logger.info(f"开始排查用户: {user[0]}", )
|
# logger.info(f"开始排查用户: {user[0]}", )
|
||||||
|
|
||||||
# user[1] = "运行"
|
# user[1] = "运行"
|
||||||
# self.update_user_list.emit(self.user_list)
|
# self.update_user_list.emit(self.user_list)
|
||||||
|
|
||||||
# if user_data["Info"]["Mode"] == "详细":
|
# if user_data["Info"]["Mode"] == "详细":
|
||||||
# self.if_open_emulator = True
|
# self.if_open_emulator = True
|
||||||
|
|
||||||
# run_book = [False for _ in range(2)]
|
# run_book = [False for _ in range(2)]
|
||||||
|
|
||||||
# # 启动重试循环
|
# # 启动重试循环
|
||||||
# while not self.isInterruptionRequested:
|
# while not self.isInterruptionRequested:
|
||||||
|
|
||||||
# # 配置MAA
|
# # 配置MAA
|
||||||
# self.set_maa("人工排查", user[2])
|
# self.set_maa("人工排查", user[2])
|
||||||
|
|
||||||
# # 记录当前时间
|
# # 记录当前时间
|
||||||
# self.log_start_time = datetime.now()
|
# self.log_start_time = datetime.now()
|
||||||
# # 创建MAA任务
|
# # 创建MAA任务
|
||||||
# logger.info(
|
# logger.info(
|
||||||
# f"启动MAA进程:{self.maa_exe_path}",
|
# f"启动MAA进程:{self.maa_exe_path}",
|
||||||
# ,
|
# ,
|
||||||
# )
|
# )
|
||||||
# self.maa_process_manager.open_process(self.maa_exe_path, [], 0)
|
# self.maa_process_manager.open_process(self.maa_exe_path, [], 0)
|
||||||
|
|
||||||
# # 监测MAA运行状态
|
# # 监测MAA运行状态
|
||||||
# self.log_check_mode = "人工排查"
|
# self.log_check_mode = "人工排查"
|
||||||
# self.start_monitor()
|
# self.start_monitor()
|
||||||
|
|
||||||
# if self.maa_result == "Success!":
|
# if self.maa_result == "Success!":
|
||||||
# logger.info(
|
# logger.info(
|
||||||
# f"用户: {user[0]} - MAA进程成功登录PRTS",
|
# f"用户: {user[0]} - MAA进程成功登录PRTS",
|
||||||
# ,
|
# ,
|
||||||
# )
|
# )
|
||||||
# run_book[0] = True
|
# run_book[0] = True
|
||||||
# self.update_log_text.emit("检测到MAA进程成功登录PRTS")
|
# self.update_log_text.emit("检测到MAA进程成功登录PRTS")
|
||||||
# else:
|
# else:
|
||||||
# logger.error(
|
# logger.error(
|
||||||
# f"用户: {user[0]} - MAA未能正确登录到PRTS: {self.maa_result}",
|
# f"用户: {user[0]} - MAA未能正确登录到PRTS: {self.maa_result}",
|
||||||
# ,
|
# ,
|
||||||
# )
|
# )
|
||||||
# self.update_log_text.emit(
|
# self.update_log_text.emit(
|
||||||
# f"{self.maa_result}\n正在中止相关程序\n请等待10s"
|
# f"{self.maa_result}\n正在中止相关程序\n请等待10s"
|
||||||
# )
|
# )
|
||||||
# # 无命令行中止MAA与其子程序
|
# # 无命令行中止MAA与其子程序
|
||||||
# logger.info(
|
# logger.info(
|
||||||
# f"中止MAA进程:{self.maa_exe_path}",
|
# f"中止MAA进程:{self.maa_exe_path}",
|
||||||
# ,
|
# ,
|
||||||
# )
|
# )
|
||||||
# self.maa_process_manager.kill(if_force=True)
|
# self.maa_process_manager.kill(if_force=True)
|
||||||
# System.kill_process(self.maa_exe_path)
|
# System.kill_process(self.maa_exe_path)
|
||||||
# self.if_open_emulator = True
|
# self.if_open_emulator = True
|
||||||
# self.sleep(10)
|
# self.sleep(10)
|
||||||
|
|
||||||
# # 登录成功,结束循环
|
# # 登录成功,结束循环
|
||||||
# if run_book[0]:
|
# if run_book[0]:
|
||||||
# break
|
# break
|
||||||
# # 登录失败,询问是否结束循环
|
# # 登录失败,询问是否结束循环
|
||||||
# elif not self.isInterruptionRequested:
|
# elif not self.isInterruptionRequested:
|
||||||
|
|
||||||
# self.play_sound.emit("排查重试")
|
# self.play_sound.emit("排查重试")
|
||||||
# if not self.push_question(
|
# if not self.push_question(
|
||||||
# "操作提示", "MAA未能正确登录到PRTS,是否重试?"
|
# "操作提示", "MAA未能正确登录到PRTS,是否重试?"
|
||||||
# ):
|
# ):
|
||||||
# break
|
# break
|
||||||
|
|
||||||
# # 登录成功,录入人工排查情况
|
# # 登录成功,录入人工排查情况
|
||||||
# if run_book[0] and not self.isInterruptionRequested:
|
# if run_book[0] and not self.isInterruptionRequested:
|
||||||
|
|
||||||
# self.play_sound.emit("排查录入")
|
# self.play_sound.emit("排查录入")
|
||||||
# if self.push_question(
|
# if self.push_question(
|
||||||
# "操作提示", "请检查用户代理情况,该用户是否正确完成代理任务?"
|
# "操作提示", "请检查用户代理情况,该用户是否正确完成代理任务?"
|
||||||
# ):
|
# ):
|
||||||
# run_book[1] = True
|
# run_book[1] = True
|
||||||
|
|
||||||
# # 结果录入
|
# # 结果录入
|
||||||
# if run_book[0] and run_book[1]:
|
# if run_book[0] and run_book[1]:
|
||||||
# logger.info(
|
# logger.info(
|
||||||
# f"用户 {user[0]} 通过人工排查",
|
# f"用户 {user[0]} 通过人工排查",
|
||||||
# )
|
# )
|
||||||
# user_data["Data"]["IfPassCheck"] = True
|
# user_data["Data"]["IfPassCheck"] = True
|
||||||
# user[1] = "完成"
|
# user[1] = "完成"
|
||||||
# else:
|
# else:
|
||||||
# logger.info(
|
# logger.info(
|
||||||
# f"用户 {user[0]} 未通过人工排查",
|
# f"用户 {user[0]} 未通过人工排查",
|
||||||
# ,
|
# ,
|
||||||
# )
|
# )
|
||||||
# user_data["Data"]["IfPassCheck"] = False
|
# user_data["Data"]["IfPassCheck"] = False
|
||||||
# user[1] = "异常"
|
# user[1] = "异常"
|
||||||
|
|
||||||
# self.update_user_list.emit(self.user_list)
|
# self.update_user_list.emit(self.user_list)
|
||||||
|
|
||||||
# # 解除静默操作屏蔽
|
# # 解除静默操作屏蔽
|
||||||
# logger.info(
|
# logger.info(
|
||||||
# "人工排查任务结束,解除静默操作屏蔽",
|
# "人工排查任务结束,解除静默操作屏蔽",
|
||||||
# )
|
# )
|
||||||
# Config.if_ignore_silence = False
|
# Config.if_ignore_silence = False
|
||||||
|
|
||||||
# # 设置MAA模式
|
# 设置MAA模式
|
||||||
# elif "设置MAA" in self.mode:
|
elif self.mode == "设置脚本":
|
||||||
|
|
||||||
# # 配置MAA
|
# 配置MAA
|
||||||
# self.set_maa(self.mode, "")
|
await self.set_maa(self.mode)
|
||||||
# # 创建MAA任务
|
# 创建MAA任务
|
||||||
# logger.info(
|
logger.info(f"启动MAA进程:{self.maa_exe_path}")
|
||||||
# f"启动MAA进程:{self.maa_exe_path}",
|
await self.maa_process_manager.open_process(self.maa_exe_path, [], 0)
|
||||||
# )
|
# 记录当前时间
|
||||||
# self.maa_process_manager.open_process(self.maa_exe_path, [], 0)
|
self.log_start_time = datetime.now()
|
||||||
# # 记录当前时间
|
|
||||||
# self.log_start_time = datetime.now()
|
|
||||||
|
|
||||||
# # 监测MAA运行状态
|
# 监测MAA运行状态
|
||||||
# self.log_check_mode = "设置MAA"
|
await self.maa_log_monitor.start(self.maa_log_path, self.log_start_time)
|
||||||
# self.start_monitor()
|
self.wait_event.clear()
|
||||||
|
await self.wait_event.wait()
|
||||||
# if "全局" in self.mode:
|
|
||||||
# (self.config_path / "Default").mkdir(parents=True, exist_ok=True)
|
|
||||||
# shutil.copy(self.maa_set_path, self.config_path / "Default")
|
|
||||||
# logger.success(
|
|
||||||
# f"全局MAA配置文件已保存到 {self.config_path / 'Default/gui.json'}",
|
|
||||||
# ,
|
|
||||||
# )
|
|
||||||
|
|
||||||
# elif "用户" in self.mode:
|
|
||||||
# self.user_config_path.mkdir(parents=True, exist_ok=True)
|
|
||||||
# shutil.copy(self.maa_set_path, self.user_config_path)
|
|
||||||
# logger.success(
|
|
||||||
# f"用户MAA配置文件已保存到 {self.user_config_path}",
|
|
||||||
# ,
|
|
||||||
# )
|
|
||||||
|
|
||||||
# result_text = ""
|
|
||||||
|
|
||||||
async def final_task(self, task: asyncio.Task):
|
async def final_task(self, task: asyncio.Task):
|
||||||
|
|
||||||
|
logger.info("MAA 主任务已结束,开始执行后续操作")
|
||||||
|
|
||||||
await Config.ScriptConfig[self.script_id].unlock()
|
await Config.ScriptConfig[self.script_id].unlock()
|
||||||
|
logger.success(f"已解锁脚本配置 {self.script_id}")
|
||||||
|
|
||||||
|
# 结束各子任务
|
||||||
|
await self.maa_process_manager.kill(if_force=True)
|
||||||
|
await System.kill_process(self.maa_exe_path)
|
||||||
|
await self.emulator_process_manager.kill()
|
||||||
|
await self.maa_log_monitor.stop()
|
||||||
|
del self.maa_process_manager
|
||||||
|
del self.emulator_process_manager
|
||||||
|
del self.maa_log_monitor
|
||||||
|
|
||||||
|
if self.check_result != "Success!":
|
||||||
|
return self.check_result
|
||||||
|
|
||||||
# 导出结果
|
# 导出结果
|
||||||
if self.mode in ["自动代理", "人工排查"]:
|
if self.mode in ["自动代理", "人工排查"]:
|
||||||
|
|
||||||
# 结束各子任务
|
|
||||||
await self.maa_process_manager.kill(if_force=True)
|
|
||||||
await System.kill_process(self.maa_exe_path)
|
|
||||||
await self.emulator_process_manager.kill()
|
|
||||||
await self.maa_log_monitor.stop()
|
|
||||||
|
|
||||||
# 更新用户数据
|
# 更新用户数据
|
||||||
sc = Config.ScriptConfig[self.script_id]
|
sc = Config.ScriptConfig[self.script_id]
|
||||||
if isinstance(sc, MaaConfig):
|
if isinstance(sc, MaaConfig):
|
||||||
@@ -960,10 +949,24 @@ class MaaManager:
|
|||||||
10,
|
10,
|
||||||
)
|
)
|
||||||
await self.push_notification("代理结果", title, result)
|
await self.push_notification("代理结果", title, result)
|
||||||
|
elif self.mode == "设置脚本":
|
||||||
|
(
|
||||||
|
Path.cwd()
|
||||||
|
/ f"data/{self.script_id}/{self.user_id if self.user_id else 'Default'}/ConfigFile"
|
||||||
|
).mkdir(parents=True, exist_ok=True)
|
||||||
|
shutil.copy(
|
||||||
|
self.maa_set_path,
|
||||||
|
(
|
||||||
|
Path.cwd()
|
||||||
|
/ f"data/{self.script_id}/{self.user_id if self.user_id else 'Default'}/ConfigFile/gui.json"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
result_text = ""
|
||||||
|
|
||||||
# 复原 MAA 配置文件
|
# 复原 MAA 配置文件
|
||||||
logger.info(f"复原 MAA 配置文件:{Path.cwd() / f'data/{self.script_id}/Temp'}")
|
logger.info(f"复原 MAA 配置文件:{Path.cwd() / f'data/{self.script_id}/Temp'}")
|
||||||
if (Path.cwd() / f"data/{self.script_id}/Temp").exists():
|
if (Path.cwd() / f"data/{self.script_id}/Temp/gui.json").exists():
|
||||||
shutil.copy(
|
shutil.copy(
|
||||||
Path.cwd() / f"data/{self.script_id}/Temp/gui.json", self.maa_set_path
|
Path.cwd() / f"data/{self.script_id}/Temp/gui.json", self.maa_set_path
|
||||||
)
|
)
|
||||||
@@ -981,7 +984,7 @@ class MaaManager:
|
|||||||
data={
|
data={
|
||||||
"log": f"即将搜索ADB实际地址\n正在等待模拟器完成启动\n请等待{self.wait_time}s"
|
"log": f"即将搜索ADB实际地址\n正在等待模拟器完成启动\n请等待{self.wait_time}s"
|
||||||
},
|
},
|
||||||
)
|
).model_dump()
|
||||||
)
|
)
|
||||||
|
|
||||||
await asyncio.sleep(self.wait_time)
|
await asyncio.sleep(self.wait_time)
|
||||||
@@ -1063,7 +1066,7 @@ class MaaManager:
|
|||||||
log = "".join(log_content)
|
log = "".join(log_content)
|
||||||
|
|
||||||
# 更新MAA日志
|
# 更新MAA日志
|
||||||
if self.maa_process_manager.is_running():
|
if await self.maa_process_manager.is_running():
|
||||||
|
|
||||||
await self.websocket.send_json(
|
await self.websocket.send_json(
|
||||||
TaskMessage(type="Update", data={"log": log}).model_dump()
|
TaskMessage(type="Update", data={"log": log}).model_dump()
|
||||||
@@ -1131,14 +1134,12 @@ class MaaManager:
|
|||||||
|
|
||||||
elif (
|
elif (
|
||||||
"MaaAssistantArknights GUI exited" in log
|
"MaaAssistantArknights GUI exited" in log
|
||||||
or not self.maa_process_manager.is_running()
|
or not await self.maa_process_manager.is_running()
|
||||||
):
|
):
|
||||||
self.maa_result = "MAA在完成任务前退出"
|
self.maa_result = "MAA在完成任务前退出"
|
||||||
|
|
||||||
elif datetime.now() - latest_time > timedelta(
|
elif datetime.now() - latest_time > timedelta(
|
||||||
minutes=self.script_config.get(
|
minutes=self.script_config.get("Run", f"{self.log_check_mode}TimeLimit")
|
||||||
"RunSet", f"{self.log_check_mode}TimeLimit"
|
|
||||||
)
|
|
||||||
):
|
):
|
||||||
self.maa_result = "MAA进程超时"
|
self.maa_result = "MAA进程超时"
|
||||||
|
|
||||||
@@ -1156,7 +1157,7 @@ class MaaManager:
|
|||||||
self.maa_result = "MAA在完成任务前中止"
|
self.maa_result = "MAA在完成任务前中止"
|
||||||
elif (
|
elif (
|
||||||
"MaaAssistantArknights GUI exited" in log
|
"MaaAssistantArknights GUI exited" in log
|
||||||
or not self.maa_process_manager.is_running()
|
or not await self.maa_process_manager.is_running()
|
||||||
):
|
):
|
||||||
self.maa_result = "MAA在完成任务前退出"
|
self.maa_result = "MAA在完成任务前退出"
|
||||||
else:
|
else:
|
||||||
@@ -1165,7 +1166,7 @@ class MaaManager:
|
|||||||
elif self.mode == "设置脚本":
|
elif self.mode == "设置脚本":
|
||||||
if (
|
if (
|
||||||
"MaaAssistantArknights GUI exited" in log
|
"MaaAssistantArknights GUI exited" in log
|
||||||
or not self.maa_process_manager.is_running()
|
or not await self.maa_process_manager.is_running()
|
||||||
):
|
):
|
||||||
self.maa_result = "Success!"
|
self.maa_result = "Success!"
|
||||||
else:
|
else:
|
||||||
@@ -1175,50 +1176,21 @@ class MaaManager:
|
|||||||
|
|
||||||
if self.maa_result != "Wait":
|
if self.maa_result != "Wait":
|
||||||
|
|
||||||
|
logger.info(f"MAA 任务结果:{self.maa_result},日志锁已释放")
|
||||||
self.wait_event.set()
|
self.wait_event.set()
|
||||||
|
|
||||||
# def start_monitor(self) -> None:
|
async def set_maa(
|
||||||
# """开始监视MAA日志"""
|
self,
|
||||||
|
mode: str,
|
||||||
# logger.info(
|
user_data: Optional[MaaUserConfig] = None,
|
||||||
# f"开始监视MAA日志,路径:{self.maa_log_path},日志起始时间:{self.log_start_time},模式:{self.log_check_mode}",
|
index: Optional[int] = None,
|
||||||
# ,
|
) -> dict:
|
||||||
# )
|
|
||||||
# self.log_monitor.addPath(str(self.maa_log_path))
|
|
||||||
# self.log_monitor_timer.start(1000)
|
|
||||||
# self.last_check_time = datetime.now()
|
|
||||||
# self.monitor_loop.exec()
|
|
||||||
|
|
||||||
# def quit_monitor(self) -> None:
|
|
||||||
# """退出MAA日志监视进程"""
|
|
||||||
|
|
||||||
# if len(self.log_monitor.files()) != 0:
|
|
||||||
|
|
||||||
# logger.info(
|
|
||||||
# f"MAA日志监视器移除路径:{self.maa_log_path}",
|
|
||||||
# ,
|
|
||||||
# )
|
|
||||||
# self.log_monitor.removePath(str(self.maa_log_path))
|
|
||||||
|
|
||||||
# else:
|
|
||||||
# logger.warning(
|
|
||||||
# f"MAA日志监视器没有正在监看的路径:{self.log_monitor.files()}",
|
|
||||||
# ,
|
|
||||||
# )
|
|
||||||
|
|
||||||
# self.log_monitor_timer.stop()
|
|
||||||
# self.last_check_time = None
|
|
||||||
# self.monitor_loop.quit()
|
|
||||||
|
|
||||||
# logger.info("MAA日志监视锁已释放", )
|
|
||||||
|
|
||||||
async def set_maa(self, mode: str, index: int, user_data: MaaUserConfig) -> dict:
|
|
||||||
"""配置MAA运行参数"""
|
"""配置MAA运行参数"""
|
||||||
logger.info(f"开始配置MAA运行参数: {mode}/{index}")
|
logger.info(f"开始配置MAA运行参数: {mode}/{index}")
|
||||||
|
|
||||||
if "设置脚本" not in self.mode and mode != "Update":
|
if self.mode != "设置脚本" and mode != "Update":
|
||||||
|
|
||||||
if user_data.get("Info", "Server") == "Bilibili":
|
if user_data and user_data.get("Info", "Server") == "Bilibili":
|
||||||
self.agree_bilibili(True)
|
self.agree_bilibili(True)
|
||||||
else:
|
else:
|
||||||
self.agree_bilibili(False)
|
self.agree_bilibili(False)
|
||||||
@@ -1228,7 +1200,7 @@ class MaaManager:
|
|||||||
await System.kill_process(self.maa_exe_path)
|
await System.kill_process(self.maa_exe_path)
|
||||||
|
|
||||||
# 预导入MAA配置文件
|
# 预导入MAA配置文件
|
||||||
if self.mode in ["自动代理", "人工排查"]:
|
if self.mode in ["自动代理", "人工排查"] and user_data is not None:
|
||||||
if user_data.get("Info", "Mode") == "简洁":
|
if user_data.get("Info", "Mode") == "简洁":
|
||||||
shutil.copy(
|
shutil.copy(
|
||||||
(Path.cwd() / f"data/{self.script_id}/Default/ConfigFile/gui.json"),
|
(Path.cwd() / f"data/{self.script_id}/Default/ConfigFile/gui.json"),
|
||||||
@@ -1288,7 +1260,12 @@ class MaaManager:
|
|||||||
data["Global"][f"Timer.Timer{i}"] = "False"
|
data["Global"][f"Timer.Timer{i}"] = "False"
|
||||||
|
|
||||||
# 自动代理配置
|
# 自动代理配置
|
||||||
if self.mode == "自动代理":
|
if (
|
||||||
|
self.mode == "自动代理"
|
||||||
|
and mode in ["Annihilation", "Routine"]
|
||||||
|
and index is not None
|
||||||
|
and user_data is not None
|
||||||
|
):
|
||||||
|
|
||||||
if (index == len(self.user_list) - 1) or (
|
if (index == len(self.user_list) - 1) or (
|
||||||
self.user_config[uuid.UUID(self.user_list[index + 1]["user_id"])].get(
|
self.user_config[uuid.UUID(self.user_list[index + 1]["user_id"])].get(
|
||||||
@@ -1392,7 +1369,7 @@ class MaaManager:
|
|||||||
user_data.get("Info", "SeriesNumb")
|
user_data.get("Info", "SeriesNumb")
|
||||||
) # 连战次数
|
) # 连战次数
|
||||||
|
|
||||||
if "剿灭" in mode:
|
if mode == "Annihilation":
|
||||||
|
|
||||||
data["Configurations"]["Default"][
|
data["Configurations"]["Default"][
|
||||||
"MainFunction.Stage1"
|
"MainFunction.Stage1"
|
||||||
@@ -1434,7 +1411,7 @@ class MaaManager:
|
|||||||
"GUI.HideSeries"
|
"GUI.HideSeries"
|
||||||
] = "False" # 隐藏连战次数
|
] = "False" # 隐藏连战次数
|
||||||
|
|
||||||
elif "日常" in mode:
|
elif mode == "Routine":
|
||||||
|
|
||||||
data["Configurations"]["Default"]["MainFunction.Stage1"] = (
|
data["Configurations"]["Default"]["MainFunction.Stage1"] = (
|
||||||
user_data.get("Info", "Stage")
|
user_data.get("Info", "Stage")
|
||||||
@@ -1541,7 +1518,7 @@ class MaaManager:
|
|||||||
) # 自定义基建配置索引
|
) # 自定义基建配置索引
|
||||||
|
|
||||||
# 人工排查配置
|
# 人工排查配置
|
||||||
elif "人工排查" in mode:
|
elif self.mode == "人工排查" and user_data is not None:
|
||||||
|
|
||||||
data["Configurations"]["Default"][
|
data["Configurations"]["Default"][
|
||||||
"MainFunction.PostActions"
|
"MainFunction.PostActions"
|
||||||
@@ -1607,8 +1584,8 @@ class MaaManager:
|
|||||||
"TaskQueue.Reclamation.IsChecked"
|
"TaskQueue.Reclamation.IsChecked"
|
||||||
] = "False" # 生息演算
|
] = "False" # 生息演算
|
||||||
|
|
||||||
# 设置MAA配置
|
# 设置脚本配置
|
||||||
elif "设置MAA" in mode:
|
elif self.mode == "设置脚本":
|
||||||
|
|
||||||
data["Configurations"]["Default"][
|
data["Configurations"]["Default"][
|
||||||
"MainFunction.PostActions"
|
"MainFunction.PostActions"
|
||||||
@@ -1659,7 +1636,7 @@ class MaaManager:
|
|||||||
"TaskQueue.Reclamation.IsChecked"
|
"TaskQueue.Reclamation.IsChecked"
|
||||||
] = "False" # 生息演算
|
] = "False" # 生息演算
|
||||||
|
|
||||||
elif mode == "更新MAA":
|
elif mode == "Update":
|
||||||
|
|
||||||
data["Configurations"]["Default"][
|
data["Configurations"]["Default"][
|
||||||
"MainFunction.PostActions"
|
"MainFunction.PostActions"
|
||||||
@@ -1712,16 +1689,14 @@ class MaaManager:
|
|||||||
] = "False" # 生息演算
|
] = "False" # 生息演算
|
||||||
|
|
||||||
# 启动模拟器仅生效一次
|
# 启动模拟器仅生效一次
|
||||||
if "设置MAA" not in mode and "更新MAA" not in mode and self.if_open_emulator:
|
if self.mode != "设置脚本" and mode != "Update" and self.if_open_emulator:
|
||||||
self.if_open_emulator = False
|
self.if_open_emulator = False
|
||||||
|
|
||||||
# 覆写配置文件
|
# 覆写配置文件
|
||||||
with self.maa_set_path.open(mode="w", encoding="utf-8") as f:
|
with self.maa_set_path.open(mode="w", encoding="utf-8") as f:
|
||||||
json.dump(data, f, ensure_ascii=False, indent=4)
|
json.dump(data, f, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
logger.success(
|
logger.success(f"MAA运行参数配置完成: {mode}/{index}")
|
||||||
f"MAA运行参数配置完成: {mode}/{index}",
|
|
||||||
)
|
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import aiofiles
|
import aiofiles
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Callable, Optional, List, Awaitable
|
from typing import Callable, Optional, List, Awaitable
|
||||||
|
|
||||||
from loguru import logger
|
from .logger import get_logger
|
||||||
|
|
||||||
|
logger = get_logger("日志监控器")
|
||||||
|
|
||||||
|
|
||||||
class LogMonitor:
|
class LogMonitor:
|
||||||
@@ -22,44 +24,87 @@ class LogMonitor:
|
|||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
self.log_file_path: Optional[Path] = None
|
self.log_file_path: Optional[Path] = None
|
||||||
self.log_start_time: datetime = datetime.now()
|
self.log_start_time: datetime = datetime.now()
|
||||||
|
self.last_callback_time: datetime = datetime.now()
|
||||||
self.log_contents: List[str] = []
|
self.log_contents: List[str] = []
|
||||||
self.task: Optional[asyncio.Task] = None
|
self.task: Optional[asyncio.Task] = None
|
||||||
|
|
||||||
async def monitor_log(self):
|
async def monitor_log(self):
|
||||||
|
"""监控日志文件的主循环"""
|
||||||
if self.log_file_path is None or not self.log_file_path.exists():
|
if self.log_file_path is None or not self.log_file_path.exists():
|
||||||
raise ValueError("Log file path is not set or does not exist.")
|
raise ValueError("Log file path is not set or does not exist.")
|
||||||
|
|
||||||
|
logger.info(f"开始监控日志文件: {self.log_file_path}")
|
||||||
|
|
||||||
|
consecutive_errors = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
try:
|
||||||
|
log_contents = []
|
||||||
|
if_log_start = False
|
||||||
|
|
||||||
log_contents = []
|
# 检查文件是否仍然存在
|
||||||
if_log_start = False
|
if not self.log_file_path.exists():
|
||||||
|
logger.warning(f"日志文件不存在: {self.log_file_path}")
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
continue
|
||||||
|
|
||||||
async with aiofiles.open(
|
# 尝试读取文件
|
||||||
self.log_file_path, "r", encoding=self.encoding
|
try:
|
||||||
) as f:
|
async with aiofiles.open(
|
||||||
|
self.log_file_path, "r", encoding=self.encoding
|
||||||
async for line in f:
|
) as f:
|
||||||
if not if_log_start:
|
async for line in f:
|
||||||
try:
|
if not if_log_start:
|
||||||
entry_time = datetime.strptime(
|
try:
|
||||||
line[
|
entry_time = datetime.strptime(
|
||||||
self.time_stamp_range[0] : self.time_stamp_range[1]
|
line[
|
||||||
],
|
self.time_stamp_range[
|
||||||
self.time_format,
|
0
|
||||||
)
|
] : self.time_stamp_range[1]
|
||||||
if entry_time > self.log_start_time:
|
],
|
||||||
if_log_start = True
|
self.time_format,
|
||||||
|
)
|
||||||
|
if entry_time > self.log_start_time:
|
||||||
|
if_log_start = True
|
||||||
|
log_contents.append(line)
|
||||||
|
except (ValueError, IndexError):
|
||||||
|
continue
|
||||||
|
else:
|
||||||
log_contents.append(line)
|
log_contents.append(line)
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
log_contents.append(line)
|
|
||||||
|
|
||||||
# 调用回调
|
except (FileNotFoundError, PermissionError) as e:
|
||||||
if log_contents != self.log_contents:
|
logger.warning(f"文件访问错误: {e}")
|
||||||
self.log_contents = log_contents
|
await asyncio.sleep(5)
|
||||||
await self.callback(log_contents)
|
continue
|
||||||
|
except UnicodeDecodeError as e:
|
||||||
|
logger.error(f"文件编码错误: {e}")
|
||||||
|
await asyncio.sleep(10)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 调用回调
|
||||||
|
if (
|
||||||
|
log_contents != self.log_contents
|
||||||
|
or datetime.now() - self.last_callback_time > timedelta(minutes=1)
|
||||||
|
):
|
||||||
|
self.log_contents = log_contents
|
||||||
|
self.last_callback_time = datetime.now()
|
||||||
|
|
||||||
|
# 安全调用回调函数
|
||||||
|
try:
|
||||||
|
await self.callback(log_contents)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"回调函数执行失败: {e}")
|
||||||
|
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
logger.info("日志监控任务被取消")
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"监控日志时发生未知错误:{e}")
|
||||||
|
|
||||||
|
consecutive_errors += 1
|
||||||
|
wait_time = min(60, 2**consecutive_errors)
|
||||||
|
await asyncio.sleep(wait_time)
|
||||||
|
continue
|
||||||
|
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
@@ -75,15 +120,19 @@ class LogMonitor:
|
|||||||
self.log_file_path = log_file_path
|
self.log_file_path = log_file_path
|
||||||
self.log_start_time = start_time
|
self.log_start_time = start_time
|
||||||
self.task = asyncio.create_task(self.monitor_log())
|
self.task = asyncio.create_task(self.monitor_log())
|
||||||
|
logger.info(f"日志监控已启动: {self.log_file_path}")
|
||||||
logger.info(f"开始监控文件: {self.log_file_path}")
|
|
||||||
|
|
||||||
async def stop(self):
|
async def stop(self):
|
||||||
"""停止监控"""
|
"""停止监控"""
|
||||||
|
|
||||||
if self.task is not None and not self.task.done():
|
if self.task is not None and not self.task.done():
|
||||||
self.task.cancel()
|
self.task.cancel()
|
||||||
|
try:
|
||||||
|
await self.task
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
pass
|
||||||
|
|
||||||
self.log_contents = []
|
self.log_contents = []
|
||||||
logger.info(f"停止监控文件: {self.log_file_path}")
|
|
||||||
self.log_file_path = None
|
self.log_file_path = None
|
||||||
|
self.task = None
|
||||||
|
logger.info(f"日志监控已停止: {self.log_file_path}")
|
||||||
|
|||||||
2
main.py
2
main.py
@@ -77,6 +77,7 @@ def main():
|
|||||||
scripts_router,
|
scripts_router,
|
||||||
plan_router,
|
plan_router,
|
||||||
queue_router,
|
queue_router,
|
||||||
|
dispatch_router,
|
||||||
setting_router,
|
setting_router,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -99,6 +100,7 @@ def main():
|
|||||||
app.include_router(scripts_router)
|
app.include_router(scripts_router)
|
||||||
app.include_router(plan_router)
|
app.include_router(plan_router)
|
||||||
app.include_router(queue_router)
|
app.include_router(queue_router)
|
||||||
|
app.include_router(dispatch_router)
|
||||||
app.include_router(setting_router)
|
app.include_router(setting_router)
|
||||||
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||||
|
|||||||
Reference in New Issue
Block a user