Files
auto_cursor/start.py
huangzhenpc 6dad187156 xx
2025-04-01 17:58:08 +08:00

311 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Cursor自动化服务统一启动脚本
- 检查数据库标记
- 启动自动化服务或独立功能
- 集中管理各项服务功能
"""
import asyncio
import sys
import os
import argparse
import subprocess
import time
from typing import Optional, List
from loguru import logger
# Windows平台特殊处理强制使用SelectorEventLoop
if sys.platform.startswith("win"):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
from core.config import Config
from core.database import DatabaseManager
# 配置日志
logger.remove()
logger.add(sys.stderr, level="INFO")
logger.add(
"start.log",
rotation="10 MB",
retention="10 days",
level="DEBUG",
compression="zip"
)
class CursorServiceManager:
def __init__(self):
self.config = Config.from_yaml()
self.db_manager = DatabaseManager(self.config)
self.service_process = None
self.upload_process = None
async def initialize(self):
"""初始化数据库连接"""
logger.info("初始化数据库连接")
await self.db_manager.initialize()
async def cleanup(self):
"""清理资源"""
logger.info("清理资源")
if self.service_process and self.service_process.poll() is None:
logger.info("终止自动化服务进程")
try:
if sys.platform.startswith("win"):
subprocess.run(["taskkill", "/F", "/T", "/PID", str(self.service_process.pid)])
else:
self.service_process.terminate()
self.service_process.wait(timeout=5)
except Exception as e:
logger.error(f"终止进程时出错: {e}")
if self.upload_process and self.upload_process.poll() is None:
logger.info("终止上传进程")
try:
if sys.platform.startswith("win"):
subprocess.run(["taskkill", "/F", "/T", "/PID", str(self.upload_process.pid)])
else:
self.upload_process.terminate()
self.upload_process.wait(timeout=5)
except Exception as e:
logger.error(f"终止进程时出错: {e}")
await self.db_manager.cleanup()
async def check_service_flag(self) -> bool:
"""检查数据库中是否存在启动标记"""
try:
# 创建系统设置表(如果不存在)
await self.db_manager.execute("""
CREATE TABLE IF NOT EXISTS system_settings (
id INT AUTO_INCREMENT PRIMARY KEY,
key_name VARCHAR(50) UNIQUE NOT NULL,
value TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
""")
# 检查是否存在自动服务启动标记
result = await self.db_manager.fetch_one(
"SELECT value FROM system_settings WHERE key_name = 'auto_service_enabled'"
)
if result:
return result['value'] == '1'
else:
# 如果不存在记录,创建默认记录(不启用)
await self.db_manager.execute(
"INSERT INTO system_settings (key_name, value) VALUES ('auto_service_enabled', '0')"
)
return False
except Exception as e:
logger.error(f"检查服务标记时出错: {e}")
return False
async def set_service_flag(self, enabled: bool):
"""设置服务启动标记"""
try:
value = '1' if enabled else '0'
await self.db_manager.execute(
"INSERT INTO system_settings (key_name, value) VALUES ('auto_service_enabled', %s) "
"ON DUPLICATE KEY UPDATE value = %s",
(value, value)
)
logger.success(f"自动服务标记已{'启用' if enabled else '禁用'}")
except Exception as e:
logger.error(f"设置服务标记时出错: {e}")
def start_auto_service(self):
"""启动自动化服务"""
if self.service_process and self.service_process.poll() is None:
logger.info("自动化服务已在运行中")
return
logger.info("启动自动化服务")
try:
if sys.platform.startswith("win"):
self.service_process = subprocess.Popen(
["python", "auto_cursor_service.py"],
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)
else:
self.service_process = subprocess.Popen(
["python3", "auto_cursor_service.py"]
)
logger.info(f"自动化服务已启动PID: {self.service_process.pid}")
except Exception as e:
logger.error(f"启动自动化服务时出错: {e}")
self.service_process = None
def stop_auto_service(self):
"""停止自动化服务"""
if not self.service_process or self.service_process.poll() is not None:
logger.info("自动化服务未在运行")
self.service_process = None
return
logger.info("停止自动化服务")
try:
if sys.platform.startswith("win"):
subprocess.run(["taskkill", "/F", "/T", "/PID", str(self.service_process.pid)])
else:
self.service_process.terminate()
self.service_process.wait(timeout=5)
logger.info("自动化服务已停止")
except Exception as e:
logger.error(f"停止自动化服务时出错: {e}")
self.service_process = None
def start_upload(self):
"""启动账号上传"""
logger.info("开始上传账号")
try:
if sys.platform.startswith("win"):
self.upload_process = subprocess.Popen(
["python", "upload_account.py"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NO_WINDOW
)
else:
self.upload_process = subprocess.Popen(
["python3", "upload_account.py"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# 等待进程完成
stdout, stderr = self.upload_process.communicate()
if self.upload_process.returncode != 0:
logger.error(f"上传账号进程异常终止,退出码: {self.upload_process.returncode}")
if stderr:
logger.error(f"错误输出: {stderr.decode('utf-8', errors='ignore')}")
else:
logger.info("账号上传完成")
if stdout:
# 只记录最后几行输出
output_lines = stdout.decode('utf-8', errors='ignore').strip().split('\n')
for line in output_lines[-5:]:
logger.info(f"Upload: {line}")
except Exception as e:
logger.error(f"执行账号上传脚本时出错: {e}")
self.upload_process = None
def start_register(self):
"""启动注册进程"""
logger.info("启动注册进程")
try:
# 使用subprocess启动main.py
if sys.platform.startswith("win"):
register_process = subprocess.Popen(
["python", "main.py"],
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)
else:
register_process = subprocess.Popen(
["python3", "main.py"]
)
logger.info(f"注册进程已启动PID: {register_process.pid}")
return register_process
except Exception as e:
logger.error(f"启动注册进程时出错: {e}")
return None
async def run_service_check(self):
"""检查并启动/停止自动服务"""
enabled = await self.check_service_flag()
if enabled:
if not self.service_process or self.service_process.poll() is not None:
logger.info("自动服务标记已启用,但服务未运行,现在启动")
self.start_auto_service()
else:
if self.service_process and self.service_process.poll() is None:
logger.info("自动服务标记已禁用,但服务仍在运行,现在停止")
self.stop_auto_service()
return enabled
async def main():
"""主函数"""
parser = argparse.ArgumentParser(description="Cursor自动化服务管理工具")
group = parser.add_mutually_exclusive_group()
group.add_argument("--enable", action="store_true", help="启用自动服务")
group.add_argument("--disable", action="store_true", help="禁用自动服务")
group.add_argument("--status", action="store_true", help="查看自动服务状态")
group.add_argument("--upload", action="store_true", help="手动上传账号")
group.add_argument("--register", action="store_true", help="仅运行注册进程")
args = parser.parse_args()
manager = CursorServiceManager()
await manager.initialize()
try:
if args.enable:
await manager.set_service_flag(True)
manager.start_auto_service()
elif args.disable:
await manager.set_service_flag(False)
manager.stop_auto_service()
elif args.status:
enabled = await manager.check_service_flag()
print(f"自动服务状态: {'已启用' if enabled else '已禁用'}")
# 检查进程是否在运行
if manager.service_process and manager.service_process.poll() is None:
print(f"自动服务进程: 运行中 (PID: {manager.service_process.pid})")
else:
print("自动服务进程: 未运行")
elif args.upload:
manager.start_upload()
elif args.register:
register_process = manager.start_register()
if register_process:
print(f"注册进程已启动PID: {register_process.pid}")
print("按Ctrl+C结束...")
try:
# 等待进程结束
register_process.wait()
except KeyboardInterrupt:
print("正在终止注册进程...")
if sys.platform.startswith("win"):
subprocess.run(["taskkill", "/F", "/T", "/PID", str(register_process.pid)])
else:
register_process.terminate()
else:
# 默认行为:检查并根据标记启动/停止服务
enabled = await manager.run_service_check()
print(f"自动服务状态: {'已启用' if enabled else '已禁用'}")
if enabled:
print("自动服务已启动按Ctrl+C停止...")
try:
# 保持进程运行,等待用户中断
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
print("正在停止...")
finally:
await manager.cleanup()
if __name__ == "__main__":
asyncio.run(main())