diff --git a/build.py b/build.py index 2bc5e4f..915f51e 100644 --- a/build.py +++ b/build.py @@ -1,9 +1,15 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + import warnings import os import platform import subprocess import time import threading +import json +import sys +from pathlib import Path # Ignore specific SyntaxWarning warnings.filterwarnings("ignore", category=SyntaxWarning, module="DrissionPage") @@ -79,6 +85,169 @@ def filter_output(output): return "\n".join(important_lines) +def increment_version(): + """增加构建版本号""" + version_file = Path("version.json") + if version_file.exists(): + with open(version_file, "r") as f: + version_data = json.load(f) + + # 增加构建号 + version_data["build"] += 1 + + # 更新版本号的最后一位 + version_parts = version_data["version"].split(".") + version_parts[-1] = str(version_data["build"]) + version_data["version"] = ".".join(version_parts) + + # 保存更新后的版本信息 + with open(version_file, "w") as f: + json.dump(version_data, f, indent=4) + + return version_data + else: + print("错误:未找到 version.json 文件") + sys.exit(1) + + +def create_icns(): + """将 SVG 转换为 ICNS 格式""" + if not Path("icons/logo.svg").exists(): + print("错误:未找到 logo.svg 文件") + sys.exit(1) + + # 创建临时目录 + os.makedirs("icons/tmp.iconset", exist_ok=True) + + # 转换 SVG 到 PNG + sizes = [16, 32, 64, 128, 256, 512, 1024] + for size in sizes: + # 普通分辨率 + os.system(f"rsvg-convert -w {size} -h {size} icons/logo.svg > icons/tmp.iconset/icon_{size}x{size}.png") + # 高分辨率(@2x) + if size <= 512: + os.system(f"rsvg-convert -w {size*2} -h {size*2} icons/logo.svg > icons/tmp.iconset/icon_{size}x{size}@2x.png") + + # 生成 icns 文件 + os.system("iconutil -c icns icons/tmp.iconset -o icons/logo.icns") + + # 清理临时文件 + os.system("rm -rf icons/tmp.iconset") + + +def update_spec(version_data): + """更新 spec 文件中的版本信息""" + spec_content = f'''# -*- mode: python ; coding: utf-8 -*- + +block_cipher = None + +a = Analysis( + ['cursor_gui.py'], + pathex=[], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + hooksconfig={{}}, + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False, +) + +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + +exe = EXE( + pyz, + a.scripts, + [], + exclude_binaries=True, + name='听泉Cursor助手', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + console=False, + disable_windowed_traceback=False, + argv_emulation=True, + target_arch=None, + codesign_identity=None, + entitlements_file=None, + icon='icons/logo.icns', +) + +coll = COLLECT( + exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=True, + upx_exclude=[], + name='听泉Cursor助手', +) + +app = BUNDLE( + coll, + name='听泉Cursor助手.app', + icon='icons/logo.icns', + bundle_identifier='com.tingquan.cursor', + info_plist={{ + 'CFBundleShortVersionString': '{version_data["version"]}', + 'CFBundleVersion': '{version_data["build"]}', + 'NSHighResolutionCapable': 'True', + 'LSMinimumSystemVersion': '10.13.0', + 'CFBundleName': '听泉Cursor助手', + 'CFBundleDisplayName': '听泉Cursor助手', + }}, +)''' + + with open("cursor_app.spec", "w") as f: + f.write(spec_content) + + +def build_app(): + """构建应用程序""" + # 增加版本号 + version_data = increment_version() + + # 创建图标 + create_icns() + + # 更新 spec 文件 + update_spec(version_data) + + # 更新主程序中的版本号 + update_main_version(version_data["version"]) + + # 构建应用 + os.system("pyinstaller cursor_app.spec") + + # 创建压缩包 + os.system(f'cd dist && zip -r "听泉Cursor助手_v{version_data["version"]}.zip" "听泉Cursor助手.app"') + + print(f"\n构建完成!版本号:v{version_data['version']}") + print(f"应用程序位置:dist/听泉Cursor助手.app") + print(f"压缩包位置:dist/听泉Cursor助手_v{version_data['version']}.zip") + + +def update_main_version(version): + """更新主程序中的版本号""" + with open("cursor_gui.py", "r") as f: + content = f.read() + + # 替换版本号 + content = content.replace( + 'self.setWindowTitle("Cursor账号管理器 v3.5.3")', + f'self.setWindowTitle("听泉Cursor助手 v{version}")' + ) + + with open("cursor_gui.py", "w") as f: + f.write(content) + + def build(): # Clear screen os.system("cls" if platform.system().lower() == "windows" else "clear") @@ -176,4 +345,4 @@ def build(): if __name__ == "__main__": - build() + build_app() diff --git a/cursor_gui.py b/cursor_gui.py index 909833f..4a08a95 100644 --- a/cursor_gui.py +++ b/cursor_gui.py @@ -7,6 +7,42 @@ from PyQt6.QtCore import Qt, QTimer, QPropertyAnimation from PyQt6.QtGui import QIcon, QPixmap import cursor_account_manager as backend from logger import logging +import traceback + +# 设置日志文件路径 +def setup_logging(): + try: + # 获取应用程序所在目录 + if getattr(sys, 'frozen', False): + # 如果是打包后的应用程序 + app_dir = os.path.dirname(sys.executable) + else: + # 如果是开发环境 + app_dir = os.path.dirname(os.path.abspath(__file__)) + + # 创建日志目录 + log_dir = os.path.join(app_dir, 'logs') + os.makedirs(log_dir, exist_ok=True) + + # 设置日志文件路径 + log_file = os.path.join(log_dir, 'app.log') + + # 配置日志记录 + logging.basicConfig( + level=logging.INFO, + format='%(asctime)s [%(levelname)s] %(message)s', + handlers=[ + logging.FileHandler(log_file, encoding='utf-8'), + logging.StreamHandler() + ] + ) + + logging.info('日志系统初始化成功') + logging.info(f'日志文件路径: {log_file}') + + except Exception as e: + print(f"设置日志系统时出错: {str(e)}") + print(traceback.format_exc()) class SuccessDialog(QDialog): def __init__(self, message, parent=None): @@ -154,7 +190,7 @@ class PasswordDialog(QDialog): class CursorGUI(QMainWindow): def __init__(self): super().__init__() - self.setWindowTitle("Cursor账号管理器 v3.5.3") + self.setWindowTitle("听泉Cursor助手 v3.0.2") self.setFixedSize(600, 600) # 设置整体样式 @@ -488,7 +524,27 @@ class CursorGUI(QMainWindow): QMessageBox.information(self, "提示", "更新功能开发中") if __name__ == "__main__": - app = QApplication(sys.argv) - window = CursorGUI() - window.show() - sys.exit(app.exec()) \ No newline at end of file + try: + # 初始化日志系统 + setup_logging() + + # 记录启动信息 + 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): + logging.error("未捕获的异常:", exc_info=(exc_type, exc_value, exc_traceback)) + + sys.excepthook = handle_exception + + sys.exit(app.exec()) + except Exception as e: + logging.error(f"程序启动失败: {str(e)}") + logging.error(traceback.format_exc()) + raise \ No newline at end of file diff --git a/icons/logo.icns b/icons/logo.icns new file mode 100644 index 0000000..8ebd798 Binary files /dev/null and b/icons/logo.icns differ diff --git a/icons/logo.svg b/icons/logo.svg new file mode 100644 index 0000000..e47998e --- /dev/null +++ b/icons/logo.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + 听泉 + Cursor + \ No newline at end of file diff --git a/logo.ico b/logo.ico new file mode 100644 index 0000000..fcd403e Binary files /dev/null and b/logo.ico differ diff --git a/requirements.txt b/requirements.txt index 863daa6..b8f051b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,9 @@ DrissionPage==4.1.0.9 colorama==0.4.6 python-dotenv==1.0.0 -pyinstaller +pyinstaller==6.3.0 PyQt6==6.6.1 PyQt6-Qt6==6.6.1 -PyQt6-sip==13.6.0 \ No newline at end of file +PyQt6-sip==13.6.0 +requests==2.31.0 +urllib3==2.1.0 \ No newline at end of file diff --git a/version.json b/version.json new file mode 100644 index 0000000..ba6176d --- /dev/null +++ b/version.json @@ -0,0 +1,4 @@ +{ + "version": "3.0.5", + "build": 5 +} \ No newline at end of file