#!/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())