"""Cursor 服务管理类""" import os import json import hashlib from datetime import datetime, timedelta from typing import Dict, Optional, Tuple import urllib3 import requests from cursor_token_refresher import CursorTokenRefresher from machine_resetter import MachineResetter from update_disabler import UpdateDisabler from logger import logger from common_utils import ( get_hardware_id, get_user_state, check_user_state, refresh_user_state, update_user_state, activate_device ) class CursorService: """Cursor 服务管理类""" _instance = None _initialized = False _last_check_time = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def __init__(self): if not self._initialized: # 基础组件初始化 self.token_refresher = CursorTokenRefresher() self.machine_resetter = MachineResetter() self.update_disabler = UpdateDisabler() self.logger = logger.get_logger("CursorService") # 配置文件路径 self.config_dir = os.path.join(os.getenv('APPDATA'), 'TingquanAssistant') self.config_file = os.path.join(self.config_dir, 'config.json') # 确保配置目录存在 os.makedirs(self.config_dir, exist_ok=True) # 初始化配置 self._init_config() # 首次初始化用户状态 self._lazy_init_user_state() self._initialized = True def _init_config(self): """初始化配置文件""" # 默认配置 self.default_config = { "version": "4.0.0.1", "last_check_update": None, "auto_check_update": True, "theme": "light" } # 读取或创建配置文件 if not os.path.exists(self.config_file): with open(self.config_file, 'w', encoding='utf-8') as f: json.dump(self.default_config, f, indent=2, ensure_ascii=False) self.config = self.default_config else: try: with open(self.config_file, 'r', encoding='utf-8') as f: self.config = json.load(f) except Exception as e: self.logger.error(f"读取配置文件失败: {e}") self.config = self.default_config def _lazy_init_user_state(self): """ 懒加载方式初始化用户状态 只在首次使用时初始化,避免频繁刷新 """ try: if not self._last_check_time: machine_id = get_hardware_id() success, msg, state_data = refresh_user_state(machine_id) if success: self._last_check_time = datetime.now() self.logger.info("用户状态初始化成功") else: self.logger.warning(f"用户状态初始化失败: {msg}") except Exception as e: self.logger.error(f"初始化用户状态异常: {e}") def _should_refresh_state(self) -> bool: """ 检查是否需要刷新状态 每5分钟检测一次设备状态 Returns: bool: 是否需要刷新状态 """ try: # 如果没有上次检查时间,需要刷新 if not self._last_check_time: return True # 计算距离上次检查的时间 now = datetime.now() time_diff = now - self._last_check_time # 如果超过5分钟,需要刷新 if time_diff.total_seconds() >= 300: # 5分钟 = 300秒 self.logger.debug("距离上次状态检查已超过5分钟") return True return False except Exception as e: self.logger.error(f"检查状态刷新时间异常: {e}") # 发生异常时返回False,避免频繁刷新 return False def check_activation_status(self) -> Dict: """ 检查当前激活状态 如果需要刷新则自动刷新状态 Returns: Dict: 状态信息字典 """ try: # 检查是否需要刷新状态 if self._should_refresh_state(): machine_id = get_hardware_id() success, msg, state_data = refresh_user_state(machine_id) if success: self._last_check_time = datetime.now() self.logger.info("设备状态检查完成") else: self.logger.warning(f"设备状态检查失败: {msg}") except Exception as e: self.logger.error(f"设备状态检查异常: {e}") # 无论是否刷新成功,都返回当前状态 return get_user_state() def activate_with_code(self, activation_code: str) -> Tuple[bool, str]: """ 使用激活码激活 Args: activation_code: 激活码 Returns: Tuple[bool, str]: (是否成功, 消息) """ try: self.logger.info(f"开始处理激活码: {activation_code}") # 获取机器ID machine_id = get_hardware_id() if not machine_id: self.logger.error("获取机器ID失败") return False, "获取机器ID失败" self.logger.info(f"获取到机器ID: {machine_id}") # 调用激活接口 self.logger.info("正在调用激活接口...") success, msg, data = activate_device(machine_id, activation_code) if success: self.logger.info(f"激活成功: {msg}") else: self.logger.warning(f"激活失败: {msg}") return success, msg except Exception as e: error_msg = f"激活失败: {str(e)}" self.logger.error(error_msg) return False, error_msg def refresh_account(self, machine_id: str) -> Tuple[bool, str, Optional[Dict]]: """刷新账号""" # 检查是否已激活 if not check_user_state(): return False, "请先激活软件", None return self.token_refresher.refresh_token(machine_id) def reset_machine(self) -> Tuple[bool, str, Dict]: """重置机器码""" # 检查是否已激活 if not check_user_state(): return False, "请先激活软件", {} try: new_ids, new_guid = self.machine_resetter.run() return True, "重置成功", { "new_ids": new_ids, "new_guid": new_guid } except Exception as e: return False, f"重置失败: {str(e)}", {} def disable_update(self) -> Tuple[bool, str]: """禁用更新""" # 检查是否已激活 if not check_user_state(): return False, "请先激活软件" success = self.update_disabler.disable() return success, "禁用成功" if success else "禁用失败" def save_config(self, new_config: Dict) -> bool: """ 保存配置 :param new_config: 新的配置信息 :return: 是否成功 """ try: self.config.update(new_config) with open(self.config_file, 'w', encoding='utf-8') as f: json.dump(self.config, f, indent=2, ensure_ascii=False) return True except Exception as e: self.logger.error(f"保存配置失败: {e}") return False def get_config(self) -> Dict: """获取当前配置""" return self.config.copy()