From 6ac1294bee04383d04d2cd4119f7bd28d16398b6 Mon Sep 17 00:00:00 2001 From: yeongpin Date: Mon, 24 Feb 2025 11:18:57 +0800 Subject: [PATCH] Add Disable Cursor Auto Update Feature --- .env | 4 +- .github/workflows/build.yml | 2 +- CHANGELOG.md | 4 ++ disable_auto_update.py | 135 ++++++++++++++++++++++++++++++++++++ locales/en.json | 16 ++++- locales/zh_cn.json | 16 ++++- locales/zh_tw.json | 19 ++++- main.py | 10 ++- 8 files changed, 196 insertions(+), 10 deletions(-) create mode 100644 disable_auto_update.py diff --git a/.env b/.env index 37b4d97..d88c350 100644 --- a/.env +++ b/.env @@ -1,2 +1,2 @@ -version=1.3.02 -VERSION=1.3.02 +version=1.4.01 +VERSION=1.4.01 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7277b33..39fe116 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ on: version: description: 'Version number (e.g. 1.0.9)' required: true - default: '1.0.9-dev' + default: '1.4.01' permissions: contents: write diff --git a/CHANGELOG.md b/CHANGELOG.md index 375ff08..805fd55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## v1.4.01 + +1. Add Disable Cursor Auto Upgrade | 增加禁用Cursor自動升級 + ## v1.3.02 1. Add Buy Me a Coffee | 增加請我喝杯咖啡 diff --git a/disable_auto_update.py b/disable_auto_update.py new file mode 100644 index 0000000..7f46ae4 --- /dev/null +++ b/disable_auto_update.py @@ -0,0 +1,135 @@ +import os +import sys +import platform +import shutil +from colorama import Fore, Style, init +import subprocess + +# 初始化 colorama +init() + +# 定义 emoji 常量 +EMOJI = { + "PROCESS": "🔄", + "SUCCESS": "✅", + "ERROR": "❌", + "INFO": "ℹ️", + "FOLDER": "📁", + "FILE": "📄", + "STOP": "🛑", + "CHECK": "✔️" +} + +class AutoUpdateDisabler: + def __init__(self, translator=None): + self.translator = translator + self.system = platform.system() + self.updater_paths = { + "Windows": os.path.join(os.getenv("LOCALAPPDATA", ""), "cursor-updater"), + "Darwin": os.path.expanduser("~/Library/Application Support/cursor-updater"), + "Linux": os.path.expanduser("~/.config/cursor-updater") + } + + def _kill_cursor_processes(self): + """结束所有 Cursor 进程""" + try: + print(f"{Fore.CYAN}{EMOJI['PROCESS']} {self.translator.get('update.killing_processes') if self.translator else '正在结束 Cursor 进程...'}{Style.RESET_ALL}") + + if self.system == "Windows": + subprocess.run(['taskkill', '/F', '/IM', 'Cursor.exe', '/T'], capture_output=True) + else: + subprocess.run(['pkill', '-f', 'Cursor'], capture_output=True) + + print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('update.processes_killed') if self.translator else 'Cursor 进程已结束'}{Style.RESET_ALL}") + return True + + except Exception as e: + print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('update.kill_process_failed', error=str(e)) if self.translator else f'结束进程失败: {e}'}{Style.RESET_ALL}") + return False + + def _remove_updater_directory(self): + """删除更新程序目录""" + try: + updater_path = self.updater_paths.get(self.system) + if not updater_path: + raise OSError(self.translator.get('update.unsupported_os', system=self.system) if self.translator else f"不支持的操作系统: {self.system}") + + print(f"{Fore.CYAN}{EMOJI['FOLDER']} {self.translator.get('update.removing_directory') if self.translator else '正在删除更新程序目录...'}{Style.RESET_ALL}") + + if os.path.exists(updater_path): + if os.path.isdir(updater_path): + shutil.rmtree(updater_path) + else: + os.remove(updater_path) + + print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('update.directory_removed') if self.translator else '更新程序目录已删除'}{Style.RESET_ALL}") + return True + + except Exception as e: + print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('update.remove_directory_failed', error=str(e)) if self.translator else f'删除目录失败: {e}'}{Style.RESET_ALL}") + return False + + def _create_blocking_file(self): + """创建阻止文件""" + try: + updater_path = self.updater_paths.get(self.system) + if not updater_path: + raise OSError(self.translator.get('update.unsupported_os', system=self.system) if self.translator else f"不支持的操作系统: {self.system}") + + print(f"{Fore.CYAN}{EMOJI['FILE']} {self.translator.get('update.creating_block_file') if self.translator else '正在创建阻止文件...'}{Style.RESET_ALL}") + + # 创建空文件 + open(updater_path, 'w').close() + + # 设置只读属性 + if self.system == "Windows": + os.system(f'attrib +r "{updater_path}"') + else: + os.chmod(updater_path, 0o444) # 设置为只读 + + print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('update.block_file_created') if self.translator else '阻止文件已创建'}{Style.RESET_ALL}") + return True + + except Exception as e: + print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('update.create_block_file_failed', error=str(e)) if self.translator else f'创建阻止文件失败: {e}'}{Style.RESET_ALL}") + return False + + def disable_auto_update(self): + """禁用自动更新""" + try: + print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('update.start_disable') if self.translator else '开始禁用自动更新...'}{Style.RESET_ALL}") + + # 1. 结束进程 + if not self._kill_cursor_processes(): + return False + + # 2. 删除目录 + if not self._remove_updater_directory(): + return False + + # 3. 创建阻止文件 + if not self._create_blocking_file(): + return False + + print(f"{Fore.GREEN}{EMOJI['CHECK']} {self.translator.get('update.disable_success') if self.translator else '自动更新已禁用'}{Style.RESET_ALL}") + return True + + except Exception as e: + print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('update.disable_failed', error=str(e)) if self.translator else f'禁用自动更新失败: {e}'}{Style.RESET_ALL}") + return False + +def run(translator=None): + """便捷函数,用于直接调用禁用功能""" + print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}") + print(f"{Fore.CYAN}{EMOJI['STOP']} {translator.get('update.title') if translator else '禁用 Cursor 自动更新'}{Style.RESET_ALL}") + print(f"{Fore.CYAN}{'='*50}{Style.RESET_ALL}") + + disabler = AutoUpdateDisabler(translator) + disabler.disable_auto_update() + + print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}") + input(f"{EMOJI['INFO']} {translator.get('update.press_enter') if translator else '按回车键继续...'}") + +if __name__ == "__main__": + from main import translator as main_translator + run(main_translator) \ No newline at end of file diff --git a/locales/en.json b/locales/en.json index ddc10cf..8b50b00 100644 --- a/locales/en.json +++ b/locales/en.json @@ -11,7 +11,8 @@ "invalid_choice": "Invalid choice. Please try again", "program_terminated": "Program terminated by user", "error_occurred": "An error occurred: {error}", - "press_enter": "Press Enter to Exit" + "press_enter": "Press Enter to Exit", + "disable_auto_update": "Disable Cursor Auto Update" }, "languages": { "en": "English", @@ -196,5 +197,18 @@ "verification_code_not_found": "Verification Code Not Found", "verification_code_error": "Verification Code Error: {error}", "address": "Email Address" + }, + "update": { + "title": "Disable Cursor Auto Update", + "disable_success": "Auto Update Disabled Successfully", + "disable_failed": "Disable Auto Update Failed: {error}", + "press_enter": "Press Enter to Exit", + "start_disable": "Start Disabling Auto Update", + "killing_processes": "Killing Processes", + "processes_killed": "Processes Killed", + "removing_directory": "Removing Directory", + "directory_removed": "Directory Removed", + "creating_block_file": "Creating Block File", + "block_file_created": "Block File Created" } } \ No newline at end of file diff --git a/locales/zh_cn.json b/locales/zh_cn.json index 77af844..0a0d536 100644 --- a/locales/zh_cn.json +++ b/locales/zh_cn.json @@ -11,7 +11,8 @@ "invalid_choice": "无效选择,请重试", "program_terminated": "程序被用户终止", "error_occurred": "发生错误: {error}", - "press_enter": "按回车键退出" + "press_enter": "按回车键退出", + "disable_auto_update": "禁用 Cursor 自动更新" }, "languages": { "en": "English", @@ -193,5 +194,18 @@ "verification_code_not_found": "未找到验证码", "verification_code_error": "验证码错误: {error}", "address": "邮箱地址" + }, + "update": { + "title": "禁用 Cursor 自动更新", + "disable_success": "自动更新禁用成功", + "disable_failed": "禁用自动更新失败: {error}", + "press_enter": "按回车键退出", + "start_disable": "开始禁用自动更新", + "killing_processes": "杀死进程", + "processes_killed": "进程已杀死", + "removing_directory": "删除目录", + "directory_removed": "目录已删除", + "creating_block_file": "创建阻止文件", + "block_file_created": "阻止文件已创建" } } \ No newline at end of file diff --git a/locales/zh_tw.json b/locales/zh_tw.json index cdfa242..cb260aa 100644 --- a/locales/zh_tw.json +++ b/locales/zh_tw.json @@ -11,7 +11,8 @@ "invalid_choice": "無效選擇,請重試", "program_terminated": "程序被用戶終止", "error_occurred": "發生錯誤: {error}", - "press_enter": "按回車鍵退出" + "press_enter": "按回車鍵退出", + "disable_auto_update": "禁用 Cursor 自動更新" }, "languages": { "en": "English", @@ -193,6 +194,18 @@ "verification_code_not_found": "未找到驗證碼", "verification_code_error": "驗證碼錯誤: {error}", "address": "郵箱地址" - } - + }, + "update": { + "title": "禁用 Cursor 自动更新", + "disable_success": "自動更新禁用成功", + "disable_failed": "禁用自動更新失敗: {error}", + "press_enter": "按回車鍵退出", + "start_disable": "開始禁用自動更新", + "killing_processes": "殺死進程", + "processes_killed": "進程已殺死", + "removing_directory": "刪除目錄", + "directory_removed": "目錄已刪除", + "creating_block_file": "創建阻止文件", + "block_file_created": "阻止文件已創建" + } } \ No newline at end of file diff --git a/main.py b/main.py index 0d1f299..05335d9 100644 --- a/main.py +++ b/main.py @@ -19,7 +19,8 @@ EMOJI = { "RESET": "🔄", "MENU": "📋", "ARROW": "➜", - "LANG": "🌐" + "LANG": "🌐", + "UPDATE": "🔄" } class Translator: @@ -74,6 +75,7 @@ def print_menu(): print(f"{Fore.GREEN}3{Style.RESET_ALL}. {EMOJI['SUCCESS']} {translator.get('menu.register_manual')}") print(f"{Fore.GREEN}4{Style.RESET_ALL}. {EMOJI['ERROR']} {translator.get('menu.quit')}") print(f"{Fore.GREEN}5{Style.RESET_ALL}. {EMOJI['LANG']} {translator.get('menu.select_language')}") + print(f"{Fore.GREEN}6{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.disable_auto_update')}") print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}") def select_language(): @@ -103,7 +105,7 @@ def main(): while True: try: - choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices='0-5')}: {Style.RESET_ALL}") + choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices='0-6')}: {Style.RESET_ALL}") if choice == "0": print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.exit')}...{Style.RESET_ALL}") @@ -129,6 +131,10 @@ def main(): if select_language(): print_menu() continue + elif choice == "6": + import disable_auto_update + disable_auto_update.run(translator) + break else: print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}") print_menu()