Files
AUTO-MAS-test/main.py
2025-09-28 20:38:54 +08:00

188 lines
5.5 KiB
Python

# AUTO-MAS: A Multi-Script, Multi-Config Management and Automation Software
# Copyright © 2024-2025 DLmaster361
# Copyright © 2025 MoeSnowyFox
# Copyright © 2025 AUTO-MAS Team
# This file is part of AUTO-MAS.
# AUTO-MAS is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation, either version 3 of the License,
# or (at your option) any later version.
# AUTO-MAS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
# the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with AUTO-MAS. If not, see <https://www.gnu.org/licenses/>.
# Contact: DLmaster_361@163.com
import os
import sys
import ctypes
import logging
from pathlib import Path
current_dir = Path(__file__).resolve().parent
if str(current_dir) not in sys.path:
sys.path.insert(0, str(current_dir))
from app.utils import get_logger
logger = get_logger("主程序")
class InterceptHandler(logging.Handler):
def emit(self, record):
# 获取对应 loguru 的 level
try:
level = logger.level(record.levelname).name
except ValueError:
level = record.levelno
# 转发日志
logger.opt(depth=6, exception=record.exc_info).log(level, record.getMessage())
# 拦截标准 logging
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
for name in ("uvicorn", "uvicorn.error", "uvicorn.access", "fastapi"):
logging.getLogger(name).handlers = [InterceptHandler()]
logging.getLogger(name).propagate = False
def is_admin() -> bool:
"""检查当前程序是否以管理员身份运行"""
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
@logger.catch
def main():
if is_admin():
import asyncio
import uvicorn
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from contextlib import asynccontextmanager
@asynccontextmanager
async def lifespan(app: FastAPI):
from app.core import Config, MainTimer, TaskManager
from app.services import System
from app.models.schema import WebSocketMessage
await Config.init_config()
await Config.get_stage(if_start=True)
await Config.clean_old_history()
second_timer = asyncio.create_task(MainTimer.second_task())
hour_timer = asyncio.create_task(MainTimer.hour_task())
await System.set_Sleep()
await System.set_SelfStart()
yield
await TaskManager.stop_task("ALL")
second_timer.cancel()
hour_timer.cancel()
try:
await second_timer
await hour_timer
except asyncio.CancelledError:
logger.info("主业务定时器已关闭")
from app.services import Matomo
await Matomo.close()
await Config.send_json(
WebSocketMessage(
id="Main", type="Signal", data={"Closed": "后端已安全关闭"}
).model_dump()
)
logger.info("AUTO-MAS 后端程序关闭")
from fastapi.middleware.cors import CORSMiddleware
from app.api import (
core_router,
info_router,
scripts_router,
plan_router,
queue_router,
dispatch_router,
history_router,
setting_router,
update_router,
)
app = FastAPI(
title="AUTO-MAS",
description="API for managing automation scripts, plans, and tasks",
version="1.0.0",
lifespan=lifespan,
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许所有域名跨域访问
allow_credentials=True,
allow_methods=["*"], # 允许所有请求方法, 如 GET、POST、PUT、DELETE
allow_headers=["*"], # 允许所有请求头
)
app.include_router(core_router)
app.include_router(info_router)
app.include_router(scripts_router)
app.include_router(plan_router)
app.include_router(queue_router)
app.include_router(dispatch_router)
app.include_router(history_router)
app.include_router(setting_router)
app.include_router(update_router)
app.mount(
"/api/res/materials",
StaticFiles(directory=str(Path.cwd() / "res/images/materials")),
name="materials",
)
app.mount(
"/api/res/sounds",
StaticFiles(directory=str(Path.cwd() / "res/sounds")),
name="sounds",
)
async def run_server():
config = uvicorn.Config(
app, host="0.0.0.0", port=36163, log_level="info", log_config=None
)
server = uvicorn.Server(config)
from app.core import Config
Config.server = server
await server.serve()
asyncio.run(run_server())
else:
ctypes.windll.shell32.ShellExecuteW(
None, "runas", sys.executable, os.path.realpath(sys.argv[0]), None, 1
)
sys.exit(0)
if __name__ == "__main__":
main()