Files
cursorregasscountken/interactive/gui/main_window.py

303 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.

import sys
import tkinter as tk
from tkinter import ttk, messagebox
from pathlib import Path
import logging
import os
from PIL import Image, ImageTk
sys.path.append(str(Path(__file__).parent.parent))
from utils.config import Config
from account_switcher import AccountSwitcher
class MainWindow:
def __init__(self):
self.config = Config()
self.switcher = AccountSwitcher()
self.root = tk.Tk()
self.root.title("听泉Cursor助手 v2.2.2 (本机Cursor版本: 0.45.11)")
self.root.geometry("600x500") # 调整窗口大小
self.root.resizable(True, True) # 允许调整窗口大小
# 设置窗口最小尺寸
self.root.minsize(600, 500)
try:
# 设置图标 - 使用PIL
current_dir = os.path.dirname(os.path.abspath(__file__))
icon_path = os.path.join(os.path.dirname(current_dir), "icon", "th.jpg")
if os.path.exists(icon_path):
# 打开并调整图片大小
img = Image.open(icon_path)
img = img.resize((32, 32), Image.Resampling.LANCZOS)
# 转换为PhotoImage
self.icon = ImageTk.PhotoImage(img)
self.root.iconphoto(True, self.icon)
logging.info(f"成功加载图标: {icon_path}")
else:
logging.error(f"图标文件不存在: {icon_path}")
except Exception as e:
logging.error(f"设置图标失败: {str(e)}")
# 设置关闭窗口处理
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
# 初始化状态变量
self.status_var = tk.StringVar(value="")
# 设置样式
self.style = ttk.Style()
self.style.configure("TButton", padding=5, font=("Microsoft YaHei UI", 9))
self.style.configure("TLabelframe", padding=10, font=("Microsoft YaHei UI", 9))
self.style.configure("TLabel", padding=2, font=("Microsoft YaHei UI", 9))
self.style.configure("Custom.TButton", padding=10, font=("Microsoft YaHei UI", 9))
self.style.configure("Action.TButton", padding=8, font=("Microsoft YaHei UI", 9))
self.setup_ui()
# 启动时检查一次状态
self.check_status()
def setup_ui(self):
"""设置UI界面"""
# 主框架
main_frame = ttk.Frame(self.root, padding=10)
main_frame.pack(fill="both", expand=True)
# 功能菜单
menu_frame = ttk.Frame(main_frame)
menu_frame.pack(fill="x", pady=(0, 10))
ttk.Label(menu_frame, text="功能(F)").pack(side="left")
# 设备ID区域
device_frame = ttk.Frame(main_frame)
device_frame.pack(fill="x", pady=(0, 10))
ttk.Label(device_frame, text="设备识别码(勿动):").pack(side="left")
self.hardware_id_var = tk.StringVar(value=self.switcher.hardware_id)
device_id_entry = ttk.Entry(device_frame, textvariable=self.hardware_id_var, width=35, state="readonly")
device_id_entry.pack(side="left", padx=5)
copy_btn = ttk.Button(device_frame, text="复制ID", command=self.copy_device_id, width=8)
copy_btn.pack(side="left")
# 会员状态区域
status_frame = ttk.LabelFrame(main_frame, text="会员状态")
status_frame.pack(fill="x", pady=(0, 10))
self.status_text = tk.Text(status_frame, height=5, width=40, font=("Microsoft YaHei UI", 9))
self.status_text.pack(fill="both", padx=5, pady=5)
self.status_text.config(state="disabled")
# 激活区域
activation_frame = ttk.LabelFrame(main_frame, text="激活(叠加)会员,多个激活码可叠加整体时长")
activation_frame.pack(fill="x", pady=(0, 10))
input_frame = ttk.Frame(activation_frame)
input_frame.pack(fill="x", padx=5, pady=5)
ttk.Label(input_frame, text="激活码:").pack(side="left")
self.activation_var = tk.StringVar()
activation_entry = ttk.Entry(input_frame, textvariable=self.activation_var, width=35)
activation_entry.pack(side="left", padx=5)
activate_btn = ttk.Button(input_frame, text="激活", command=self.activate_account, width=8)
activate_btn.pack(side="left")
# 操作按钮区域
btn_frame = ttk.Frame(main_frame)
btn_frame.pack(fill="x", pady=5)
self.style.configure("Action.TButton", padding=8)
ttk.Button(btn_frame, text="刷新Cursor授权", command=self.reset_machine_id, style="Action.TButton").pack(fill="x", pady=2)
ttk.Button(btn_frame, text="实现Cursor0.45.x限制", command=self.dummy_function, style="Action.TButton").pack(fill="x", pady=2)
ttk.Button(btn_frame, text="禁用Cursor版本更新", command=self.dummy_function, style="Action.TButton").pack(fill="x", pady=2)
def copy_device_id(self):
"""复制设备ID到剪贴板"""
# 先检查状态
if not self.check_status():
return
self.root.clipboard_clear()
self.root.clipboard_append(self.hardware_id_var.get())
def activate_account(self):
"""激活账号"""
code = self.activation_var.get().strip()
if not code:
messagebox.showwarning("提示", "请输入激活码")
return
self.status_var.set("正在激活...")
self.root.update()
try:
success, message, account_info = self.switcher.check_activation_code(code)
if success:
# 更新会员信息显示
self.update_status_display(account_info)
messagebox.showinfo("激活成功", "激活成功!\n" + message)
self.status_var.set("激活成功")
# 清空激活码输入框
self.activation_var.set("")
else:
messagebox.showerror("激活失败", message)
self.status_var.set("激活失败")
# 激活后检查一次状态
self.check_status()
except Exception as e:
messagebox.showerror("错误", f"激活失败: {str(e)}")
self.status_var.set("发生错误")
# 出错后也检查状态
self.check_status()
def update_status_display(self, status_info: dict):
"""更新状态显示"""
# 打印API返回的原始数据
logging.info("=== API返回数据 ===")
logging.info(f"状态信息: {status_info}")
if 'activation_records' in status_info:
logging.info("激活记录:")
for record in status_info['activation_records']:
logging.info(f"- 记录: {record}")
# 启用文本框编辑
self.status_text.config(state="normal")
# 清空当前内容
self.status_text.delete(1.0, tk.END)
# 更新状态文本
status_map = {
"active": "正常",
"inactive": "未激活",
"expired": "已过期"
}
status_text = status_map.get(status_info.get('status', 'inactive'), "未知")
# 构建状态文本
status_lines = [
f"会员状态:{status_text}",
f"到期时间:{status_info.get('expire_time', '')}",
f"总天数:{status_info.get('total_days', 0)}",
f"剩余天数:{status_info.get('days_left', 0)}"
]
# 如果有激活记录,显示最近一次激活信息
activation_records = status_info.get('activation_records', [])
if activation_records:
latest_record = activation_records[-1] # 获取最新的激活记录
device_info = latest_record.get('device_info', {})
status_lines.extend([
"",
"最近激活信息:",
f"激活码:{latest_record.get('code', '')}",
f"激活时间:{latest_record.get('activation_time', '')}",
f"增加天数:{latest_record.get('days', 0)}",
"",
"设备信息:",
f"系统:{device_info.get('os', '')}",
f"设备名:{device_info.get('device_name', '')}",
f"IP地址{device_info.get('ip', '')}",
f"地区:{device_info.get('location', '--')}"
])
# 写入状态信息
self.status_text.insert(tk.END, "\n".join(status_lines))
# 禁用文本框编辑
self.status_text.config(state="disabled")
def check_status(self):
"""检查会员状态
Returns:
bool: True 表示激活状态正常False 表示未激活或已过期
"""
try:
self.status_var.set("正在检查状态...")
self.root.update()
status = self.switcher.get_member_status()
if status:
self.update_status_display(status)
if status.get('status') == 'inactive':
messagebox.showwarning("警告", "当前设备未激活或激活已失效")
self.status_var.set("未激活")
return False
self.status_var.set("状态检查完成")
return True
else:
# 更新为未激活状态
inactive_status = {
"hardware_id": self.switcher.hardware_id,
"expire_time": "",
"days": 0,
"total_days": 0,
"status": "inactive",
"last_activation": {}
}
self.update_status_display(inactive_status)
self.status_var.set("未激活")
messagebox.showwarning("警告", "当前设备未激活")
return False
except Exception as e:
logging.error(f"检查状态失败: {str(e)}")
self.status_var.set("状态检查失败")
# 显示错误消息
messagebox.showerror("错误", f"检查状态失败: {str(e)}")
return False
def minimize_window(self):
"""最小化窗口"""
self.root.iconify()
def maximize_window(self):
"""最大化/还原窗口"""
if self.root.state() == 'zoomed':
self.root.state('normal')
else:
self.root.state('zoomed')
def on_closing(self):
"""窗口关闭处理"""
try:
logging.info("正在关闭程序...")
self.root.quit()
except Exception as e:
logging.error(f"关闭程序时出错: {str(e)}")
finally:
self.root.destroy()
def run(self):
"""运行程序"""
self.root.mainloop()
def dummy_function(self):
"""占位函数"""
# 先检查状态
if not self.check_status():
return
messagebox.showinfo("提示", "此功能暂未实现")
def reset_machine_id(self):
"""重置机器码"""
# 先检查状态
if not self.check_status():
return
try:
if self.switcher.reset_machine_id():
messagebox.showinfo("成功", "机器码重置成功")
# 重置后检查一次状态
self.check_status()
else:
messagebox.showerror("错误", "机器码重置失败,请查看日志")
# 失败后也检查状态
self.check_status()
except Exception as e:
messagebox.showerror("错误", f"重置失败: {str(e)}")
# 出错后也检查状态
self.check_status()