Files
macm1new/cursor_gui.py

528 lines
19 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.

import sys
import os
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
QLabel, QLineEdit, QPushButton, QTextEdit, QMessageBox,
QHBoxLayout, QDialog)
from PyQt6.QtCore import Qt, QTimer, QPropertyAnimation
from PyQt6.QtGui import QIcon, QPixmap
import traceback
import tempfile
# 创建临时日志文件
temp_log_file = os.path.join(tempfile.gettempdir(), 'cursor_helper_error.log')
def log_error(error_msg):
with open(temp_log_file, 'a', encoding='utf-8') as f:
f.write(f"{error_msg}\n")
try:
from logger import logging
import cursor_account_manager as backend
except Exception as e:
log_error(f"导入模块错误: {str(e)}\n{traceback.format_exc()}")
raise
class SuccessDialog(QDialog):
def __init__(self, message, parent=None):
super().__init__(parent)
self.setWindowTitle("激活成功")
self.setFixedSize(400, 300) # 增加窗口大小
self.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint | Qt.WindowType.FramelessWindowHint)
# 设置样式
self.setStyleSheet("""
QDialog {
background-color: #ffffff;
border: 1px solid #cccccc;
border-radius: 10px;
}
QLabel {
color: #333333;
font-size: 14px;
padding: 10px;
}
QLabel#titleLabel {
font-size: 24px;
font-weight: bold;
color: #0078d4;
}
QLabel#messageLabel {
font-size: 16px;
padding: 20px;
background-color: #f8f8f8;
border-radius: 8px;
}
QPushButton {
background-color: #0078d4;
color: white;
border: none;
padding: 12px 24px;
border-radius: 6px;
font-size: 16px;
min-width: 120px;
}
QPushButton:hover {
background-color: #006cbd;
}
QPushButton:pressed {
background-color: #005ba1;
}
""")
layout = QVBoxLayout()
layout.setSpacing(20)
layout.setContentsMargins(30, 30, 30, 30)
# 标题
title_label = QLabel("🎉 激活成功")
title_label.setObjectName("titleLabel")
title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(title_label)
# 消息内容
message_label = QLabel(message)
message_label.setObjectName("messageLabel")
message_label.setAlignment(Qt.AlignmentFlag.AlignLeft)
message_label.setWordWrap(True)
layout.addWidget(message_label)
# 确定按钮
ok_button = QPushButton("确定")
ok_button.clicked.connect(self.accept)
ok_button.setCursor(Qt.CursorShape.PointingHandCursor)
# 按钮容器
button_container = QWidget()
button_layout = QHBoxLayout()
button_layout.addStretch()
button_layout.addWidget(ok_button)
button_layout.addStretch()
button_container.setLayout(button_layout)
layout.addWidget(button_container)
self.setLayout(layout)
# 5秒后自动关闭
QTimer.singleShot(5000, self.accept)
# 设置窗口位置为父窗口中心
if parent:
self.move(
parent.x() + (parent.width() - self.width()) // 2,
parent.y() + (parent.height() - self.height()) // 2
)
def showEvent(self, event):
"""窗口显示时的动画效果"""
self.setWindowOpacity(0.0)
self.animation = QPropertyAnimation(self, b"windowOpacity")
self.animation.setDuration(300) # 300ms
self.animation.setStartValue(0.0)
self.animation.setEndValue(1.0)
self.animation.start()
super().showEvent(event)
def closeEvent(self, event):
"""窗口关闭时的动画效果"""
self.animation = QPropertyAnimation(self, b"windowOpacity")
self.animation.setDuration(200) # 200ms
self.animation.setStartValue(1.0)
self.animation.setEndValue(0.0)
self.animation.finished.connect(self.close)
self.animation.start()
event.ignore()
class PasswordDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("输入系统密码")
self.setFixedSize(400, 150)
layout = QVBoxLayout()
layout.setSpacing(15)
layout.setContentsMargins(20, 20, 20, 20)
# 密码输入框
self.password_input = QLineEdit()
self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
self.password_input.setPlaceholderText("请输入系统密码")
layout.addWidget(self.password_input)
# 按钮区域
button_layout = QHBoxLayout()
ok_button = QPushButton("确定")
cancel_button = QPushButton("取消")
ok_button.clicked.connect(self.accept)
cancel_button.clicked.connect(self.reject)
button_layout.addWidget(ok_button)
button_layout.addWidget(cancel_button)
layout.addLayout(button_layout)
self.setLayout(layout)
def get_password(self):
return self.password_input.text()
class CursorGUI(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("听泉Cursor助手 v3.0.2")
self.setFixedSize(600, 600)
# 设置整体样式
self.setStyleSheet("""
QMainWindow {
background-color: #f5f5f5;
}
QWidget {
background-color: #f5f5f5;
color: #333333;
}
QLabel {
color: #333333;
font-size: 14px;
font-weight: bold;
}
QLineEdit {
padding: 8px;
border: 1px solid #cccccc;
border-radius: 4px;
background-color: white;
selection-background-color: #0078d4;
}
QTextEdit {
padding: 8px;
border: 1px solid #cccccc;
border-radius: 4px;
background-color: white;
selection-background-color: #0078d4;
}
QScrollBar:vertical {
border: none;
background: #f0f0f0;
width: 10px;
margin: 0px;
}
QScrollBar::handle:vertical {
background: #c0c0c0;
min-height: 30px;
border-radius: 5px;
}
QScrollBar::handle:vertical:hover {
background: #a0a0a0;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
height: 0px;
}
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
background: none;
}
QPushButton {
background-color: #0078d4;
color: white;
padding: 8px;
border: none;
border-radius: 4px;
font-size: 14px;
}
QPushButton:hover {
background-color: #006cbd;
}
QPushButton:pressed {
background-color: #005ba1;
}
""")
# 创建主窗口部件
main_widget = QWidget()
self.setCentralWidget(main_widget)
layout = QVBoxLayout()
layout.setSpacing(15) # 增加垂直间距
layout.setContentsMargins(20, 20, 20, 20) # 设置边距
main_widget.setLayout(layout)
# 设备ID显示区域
id_label = QLabel("设备识别码(勿动):")
id_layout = QHBoxLayout()
id_layout.setSpacing(10) # 设置水平间距
self.id_text = QLineEdit()
self.id_text.setReadOnly(True)
id_copy_btn = QPushButton("复制ID")
id_copy_btn.setFixedWidth(100)
id_copy_btn.clicked.connect(self.copy_device_id)
id_layout.addWidget(self.id_text)
id_layout.addWidget(id_copy_btn)
layout.addWidget(id_label)
layout.addLayout(id_layout)
# 会员状态显示区域
status_label = QLabel("会员状态")
self.status_text = QTextEdit()
self.status_text.setReadOnly(True)
self.status_text.setFixedHeight(150)
layout.addWidget(status_label)
layout.addWidget(self.status_text)
# 激活区域
activate_label = QLabel("激活(盈加)会员,多个激活的可盈加整体时长")
activate_layout = QHBoxLayout()
activate_layout.setSpacing(10) # 设置水平间距
self.activate_input = QLineEdit()
self.activate_input.setPlaceholderText("请输入激活码")
self.activate_btn = QPushButton("激活")
self.activate_btn.setFixedWidth(100)
self.activate_btn.clicked.connect(self.activate_account)
activate_layout.addWidget(self.activate_input)
activate_layout.addWidget(self.activate_btn)
layout.addWidget(activate_label)
layout.addLayout(activate_layout)
# 添加一些间距
layout.addSpacing(20)
# 功能按钮区域
button_style = """
QPushButton {
background-color: #0078d4;
color: white;
padding: 12px;
border: none;
border-radius: 6px;
font-size: 15px;
font-weight: bold;
margin: 5px 0;
}
QPushButton:hover {
background-color: #006cbd;
}
QPushButton:pressed {
background-color: #005ba1;
}
QPushButton:disabled {
background-color: #cccccc;
color: #666666;
}
"""
# 一键重置按钮
self.refresh_btn = QPushButton("刷新Cursor授权 (对话次数用完了提示limit时点一次)")
self.refresh_btn.setStyleSheet(button_style)
self.refresh_btn.setCursor(Qt.CursorShape.PointingHandCursor)
self.refresh_btn.clicked.connect(self.refresh_auth)
layout.addWidget(self.refresh_btn)
# 代用2按钮
self.patch_btn = QPushButton("突破0.45.x限制 (Too many free trials问题点这里)")
self.patch_btn.setStyleSheet(button_style)
self.patch_btn.setCursor(Qt.CursorShape.PointingHandCursor)
self.patch_btn.clicked.connect(self.install_patch)
layout.addWidget(self.patch_btn)
# 代用3按钮
self.update_btn = QPushButton("代用 3")
self.update_btn.setStyleSheet(button_style)
self.update_btn.setCursor(Qt.CursorShape.PointingHandCursor)
self.update_btn.clicked.connect(self.update_cursor)
layout.addWidget(self.update_btn)
# 初始化设备ID和状态
self.update_device_id()
self.update_status()
def update_device_id(self):
"""更新设备ID显示"""
try:
device_id = backend.get_mac_unique_id()
self.id_text.setText(device_id)
except Exception as e:
QMessageBox.warning(self, "错误", f"获取设备ID失败: {str(e)}")
def update_status(self):
"""更新会员状态显示"""
try:
account_manager = backend.CursorAccountManager()
success, status_data = account_manager.check_member_status()
# 获取设备信息
device_info = status_data.get("device_info", {}) if success else {}
# 设置状态文本
if success and status_data.get("is_active"):
status_emoji = ""
status_text = "正常"
else:
status_emoji = ""
status_text = "未激活"
# 格式化显示文本
display_text = f"会员状态:{status_text} {status_emoji}\n"
display_text += f"到期时间:{status_data.get('expire_time', '--') if success else '--'}\n"
display_text += f"总天数:{status_data.get('total_days', 0) if success else 0}\n"
display_text += f"剩余天数:{status_data.get('days_left', 0) if success else 0}\n\n"
# 设备信息部分
display_text += "设备信息:\n"
display_text += f"系统:{device_info.get('system', sys.platform)}\n"
display_text += f"设备名:{device_info.get('device_name', '未知')}\n"
display_text += f"IP地址{device_info.get('ip', '--')}\n"
display_text += f"地理位置:{device_info.get('location', '--')}"
self.status_text.setText(display_text)
except Exception as e:
error_text = "会员状态:未激活 ❌\n"
error_text += "到期时间:--\n"
error_text += "总天数0天\n"
error_text += "剩余天数0天\n\n"
error_text += "设备信息:\n"
error_text += f"系统:{sys.platform}\n"
error_text += f"设备名:{backend.platform.node()}\n"
error_text += "IP地址--\n"
error_text += "地理位置:--"
self.status_text.setText(error_text)
def copy_device_id(self):
"""复制设备ID到剪贴板"""
clipboard = QApplication.clipboard()
clipboard.setText(self.id_text.text())
QMessageBox.information(self, "提示", "设备ID已复制到剪贴板")
def activate_account(self):
"""激活账号"""
code = self.activate_input.text().strip()
if not code:
QMessageBox.warning(self, "警告", "请输入激活码")
return
# 禁用激活按钮,显示加载状态
self.activate_btn.setEnabled(False)
self.activate_btn.setText("激活中...")
QApplication.processEvents()
try:
account_manager = backend.CursorAccountManager()
success, message, account_info = account_manager.check_activation_code(code)
if success:
# 更新状态显示
self.update_status()
# 构建成功消息
success_message = (
f"🎉 激活成功!\n\n"
f"激活码:{code}\n"
f"到期时间:{account_info.get('expire_time', '--')}\n"
f"总天数:{account_info.get('total_days', 0)}\n"
f"剩余天数:{account_info.get('days_left', 0)}"
)
# 显示成功弹窗
dialog = SuccessDialog(success_message, self)
dialog.exec()
# 清空输入框
self.activate_input.clear()
else:
QMessageBox.warning(self, "错误", message)
except Exception as e:
QMessageBox.warning(self, "错误", f"激活过程出错: {str(e)}")
finally:
# 恢复激活按钮状态
self.activate_btn.setEnabled(True)
self.activate_btn.setText("激活")
def refresh_auth(self):
"""刷新授权"""
# 显示密码输入对话框
dialog = PasswordDialog(self)
if dialog.exec() == QDialog.DialogCode.Accepted:
password = dialog.get_password()
# 显示加载状态
self.refresh_btn.setEnabled(False)
self.refresh_btn.setText("重置中...")
QApplication.processEvents()
try:
success, message = backend.reset_auth_with_password(password)
if success:
QMessageBox.information(self, "成功", "重置成功")
self.update_status()
else:
QMessageBox.warning(self, "错误", message)
except Exception as e:
QMessageBox.warning(self, "错误", f"重置失败: {str(e)}")
finally:
# 恢复按钮状态
self.refresh_btn.setEnabled(True)
self.refresh_btn.setText("刷新Cursor授权 (对话次数用完了提示limit时点一次)")
else:
QMessageBox.warning(self, "取消", "重置操作已取消")
def install_patch(self):
"""安装补丁"""
try:
# 检查版本
greater_than_0_45 = backend.check_cursor_version()
# 显示密码输入对话框
dialog = PasswordDialog(self)
if dialog.exec() == QDialog.DialogCode.Accepted:
password = dialog.get_password()
# 显示加载状态
self.patch_btn.setEnabled(False)
self.patch_btn.setText("安装中...")
QApplication.processEvents()
try:
# 设置环境变量
os.environ['SUDO_PASSWORD'] = password
# 执行重置
backend.reset_machine_id(greater_than_0_45)
QMessageBox.information(self, "成功", "补丁安装成功")
self.update_status()
except Exception as e:
QMessageBox.warning(self, "错误", f"安装失败: {str(e)}")
finally:
# 恢复按钮状态
self.patch_btn.setEnabled(True)
self.patch_btn.setText("突破0.45.x限制 (Too many free trials问题点这里)")
else:
QMessageBox.warning(self, "取消", "安装操作已取消")
except Exception as e:
QMessageBox.warning(self, "错误", f"安装补丁失败: {str(e)}")
def update_cursor(self):
"""更新Cursor版本"""
# TODO: 实现版本更新逻辑
QMessageBox.information(self, "提示", "更新功能开发中")
if __name__ == "__main__":
try:
# 记录启动信息
logging.info("=== 应用程序启动 ===")
logging.info(f"Python 版本: {sys.version}")
logging.info(f"操作系统: {sys.platform}")
app = QApplication(sys.argv)
window = CursorGUI()
window.show()
# 捕获未处理的异常
def handle_exception(exc_type, exc_value, exc_traceback):
error_msg = f"未捕获的异常:\n{traceback.format_exception(exc_type, exc_value, exc_traceback)}"
log_error(error_msg)
logging.error("未捕获的异常:", exc_info=(exc_type, exc_value, exc_traceback))
sys.excepthook = handle_exception
sys.exit(app.exec())
except Exception as e:
error_msg = f"程序启动失败: {str(e)}\n{traceback.format_exc()}"
log_error(error_msg)
logging.error(error_msg)
raise