Skip to content

Commit 6ac1294

Browse files
committed
Add Disable Cursor Auto Update Feature
1 parent fb44359 commit 6ac1294

File tree

8 files changed

+196
-10
lines changed

8 files changed

+196
-10
lines changed

.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version=1.3.02
2-
VERSION=1.3.02
1+
version=1.4.01
2+
VERSION=1.4.01

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
version:
77
description: 'Version number (e.g. 1.0.9)'
88
required: true
9-
default: '1.0.9-dev'
9+
default: '1.4.01'
1010

1111
permissions:
1212
contents: write

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Change Log
22

3+
## v1.4.01
4+
5+
1. Add Disable Cursor Auto Upgrade | 增加禁用Cursor自動升級
6+
37
## v1.3.02
48

59
1. Add Buy Me a Coffee | 增加請我喝杯咖啡

disable_auto_update.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import os
2+
import sys
3+
import platform
4+
import shutil
5+
from colorama import Fore, Style, init
6+
import subprocess
7+
8+
# 初始化 colorama
9+
init()
10+
11+
# 定义 emoji 常量
12+
EMOJI = {
13+
"PROCESS": "🔄",
14+
"SUCCESS": "✅",
15+
"ERROR": "❌",
16+
"INFO": "ℹ️",
17+
"FOLDER": "📁",
18+
"FILE": "📄",
19+
"STOP": "🛑",
20+
"CHECK": "✔️"
21+
}
22+
23+
class AutoUpdateDisabler:
24+
def __init__(self, translator=None):
25+
self.translator = translator
26+
self.system = platform.system()
27+
self.updater_paths = {
28+
"Windows": os.path.join(os.getenv("LOCALAPPDATA", ""), "cursor-updater"),
29+
"Darwin": os.path.expanduser("~/Library/Application Support/cursor-updater"),
30+
"Linux": os.path.expanduser("~/.config/cursor-updater")
31+
}
32+
33+
def _kill_cursor_processes(self):
34+
"""结束所有 Cursor 进程"""
35+
try:
36+
print(f"{Fore.CYAN}{EMOJI['PROCESS']} {self.translator.get('update.killing_processes') if self.translator else '正在结束 Cursor 进程...'}{Style.RESET_ALL}")
37+
38+
if self.system == "Windows":
39+
subprocess.run(['taskkill', '/F', '/IM', 'Cursor.exe', '/T'], capture_output=True)
40+
else:
41+
subprocess.run(['pkill', '-f', 'Cursor'], capture_output=True)
42+
43+
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('update.processes_killed') if self.translator else 'Cursor 进程已结束'}{Style.RESET_ALL}")
44+
return True
45+
46+
except Exception as e:
47+
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}")
48+
return False
49+
50+
def _remove_updater_directory(self):
51+
"""删除更新程序目录"""
52+
try:
53+
updater_path = self.updater_paths.get(self.system)
54+
if not updater_path:
55+
raise OSError(self.translator.get('update.unsupported_os', system=self.system) if self.translator else f"不支持的操作系统: {self.system}")
56+
57+
print(f"{Fore.CYAN}{EMOJI['FOLDER']} {self.translator.get('update.removing_directory') if self.translator else '正在删除更新程序目录...'}{Style.RESET_ALL}")
58+
59+
if os.path.exists(updater_path):
60+
if os.path.isdir(updater_path):
61+
shutil.rmtree(updater_path)
62+
else:
63+
os.remove(updater_path)
64+
65+
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('update.directory_removed') if self.translator else '更新程序目录已删除'}{Style.RESET_ALL}")
66+
return True
67+
68+
except Exception as e:
69+
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}")
70+
return False
71+
72+
def _create_blocking_file(self):
73+
"""创建阻止文件"""
74+
try:
75+
updater_path = self.updater_paths.get(self.system)
76+
if not updater_path:
77+
raise OSError(self.translator.get('update.unsupported_os', system=self.system) if self.translator else f"不支持的操作系统: {self.system}")
78+
79+
print(f"{Fore.CYAN}{EMOJI['FILE']} {self.translator.get('update.creating_block_file') if self.translator else '正在创建阻止文件...'}{Style.RESET_ALL}")
80+
81+
# 创建空文件
82+
open(updater_path, 'w').close()
83+
84+
# 设置只读属性
85+
if self.system == "Windows":
86+
os.system(f'attrib +r "{updater_path}"')
87+
else:
88+
os.chmod(updater_path, 0o444) # 设置为只读
89+
90+
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('update.block_file_created') if self.translator else '阻止文件已创建'}{Style.RESET_ALL}")
91+
return True
92+
93+
except Exception as e:
94+
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}")
95+
return False
96+
97+
def disable_auto_update(self):
98+
"""禁用自动更新"""
99+
try:
100+
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('update.start_disable') if self.translator else '开始禁用自动更新...'}{Style.RESET_ALL}")
101+
102+
# 1. 结束进程
103+
if not self._kill_cursor_processes():
104+
return False
105+
106+
# 2. 删除目录
107+
if not self._remove_updater_directory():
108+
return False
109+
110+
# 3. 创建阻止文件
111+
if not self._create_blocking_file():
112+
return False
113+
114+
print(f"{Fore.GREEN}{EMOJI['CHECK']} {self.translator.get('update.disable_success') if self.translator else '自动更新已禁用'}{Style.RESET_ALL}")
115+
return True
116+
117+
except Exception as e:
118+
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('update.disable_failed', error=str(e)) if self.translator else f'禁用自动更新失败: {e}'}{Style.RESET_ALL}")
119+
return False
120+
121+
def run(translator=None):
122+
"""便捷函数,用于直接调用禁用功能"""
123+
print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
124+
print(f"{Fore.CYAN}{EMOJI['STOP']} {translator.get('update.title') if translator else '禁用 Cursor 自动更新'}{Style.RESET_ALL}")
125+
print(f"{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
126+
127+
disabler = AutoUpdateDisabler(translator)
128+
disabler.disable_auto_update()
129+
130+
print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
131+
input(f"{EMOJI['INFO']} {translator.get('update.press_enter') if translator else '按回车键继续...'}")
132+
133+
if __name__ == "__main__":
134+
from main import translator as main_translator
135+
run(main_translator)

locales/en.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"invalid_choice": "Invalid choice. Please try again",
1212
"program_terminated": "Program terminated by user",
1313
"error_occurred": "An error occurred: {error}",
14-
"press_enter": "Press Enter to Exit"
14+
"press_enter": "Press Enter to Exit",
15+
"disable_auto_update": "Disable Cursor Auto Update"
1516
},
1617
"languages": {
1718
"en": "English",
@@ -196,5 +197,18 @@
196197
"verification_code_not_found": "Verification Code Not Found",
197198
"verification_code_error": "Verification Code Error: {error}",
198199
"address": "Email Address"
200+
},
201+
"update": {
202+
"title": "Disable Cursor Auto Update",
203+
"disable_success": "Auto Update Disabled Successfully",
204+
"disable_failed": "Disable Auto Update Failed: {error}",
205+
"press_enter": "Press Enter to Exit",
206+
"start_disable": "Start Disabling Auto Update",
207+
"killing_processes": "Killing Processes",
208+
"processes_killed": "Processes Killed",
209+
"removing_directory": "Removing Directory",
210+
"directory_removed": "Directory Removed",
211+
"creating_block_file": "Creating Block File",
212+
"block_file_created": "Block File Created"
199213
}
200214
}

locales/zh_cn.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"invalid_choice": "无效选择,请重试",
1212
"program_terminated": "程序被用户终止",
1313
"error_occurred": "发生错误: {error}",
14-
"press_enter": "按回车键退出"
14+
"press_enter": "按回车键退出",
15+
"disable_auto_update": "禁用 Cursor 自动更新"
1516
},
1617
"languages": {
1718
"en": "English",
@@ -193,5 +194,18 @@
193194
"verification_code_not_found": "未找到验证码",
194195
"verification_code_error": "验证码错误: {error}",
195196
"address": "邮箱地址"
197+
},
198+
"update": {
199+
"title": "禁用 Cursor 自动更新",
200+
"disable_success": "自动更新禁用成功",
201+
"disable_failed": "禁用自动更新失败: {error}",
202+
"press_enter": "按回车键退出",
203+
"start_disable": "开始禁用自动更新",
204+
"killing_processes": "杀死进程",
205+
"processes_killed": "进程已杀死",
206+
"removing_directory": "删除目录",
207+
"directory_removed": "目录已删除",
208+
"creating_block_file": "创建阻止文件",
209+
"block_file_created": "阻止文件已创建"
196210
}
197211
}

locales/zh_tw.json

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"invalid_choice": "無效選擇,請重試",
1212
"program_terminated": "程序被用戶終止",
1313
"error_occurred": "發生錯誤: {error}",
14-
"press_enter": "按回車鍵退出"
14+
"press_enter": "按回車鍵退出",
15+
"disable_auto_update": "禁用 Cursor 自動更新"
1516
},
1617
"languages": {
1718
"en": "English",
@@ -193,6 +194,18 @@
193194
"verification_code_not_found": "未找到驗證碼",
194195
"verification_code_error": "驗證碼錯誤: {error}",
195196
"address": "郵箱地址"
196-
}
197-
197+
},
198+
"update": {
199+
"title": "禁用 Cursor 自动更新",
200+
"disable_success": "自動更新禁用成功",
201+
"disable_failed": "禁用自動更新失敗: {error}",
202+
"press_enter": "按回車鍵退出",
203+
"start_disable": "開始禁用自動更新",
204+
"killing_processes": "殺死進程",
205+
"processes_killed": "進程已殺死",
206+
"removing_directory": "刪除目錄",
207+
"directory_removed": "目錄已刪除",
208+
"creating_block_file": "創建阻止文件",
209+
"block_file_created": "阻止文件已創建"
210+
}
198211
}

main.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"RESET": "🔄",
2020
"MENU": "📋",
2121
"ARROW": "➜",
22-
"LANG": "🌐"
22+
"LANG": "🌐",
23+
"UPDATE": "🔄"
2324
}
2425

2526
class Translator:
@@ -74,6 +75,7 @@ def print_menu():
7475
print(f"{Fore.GREEN}3{Style.RESET_ALL}. {EMOJI['SUCCESS']} {translator.get('menu.register_manual')}")
7576
print(f"{Fore.GREEN}4{Style.RESET_ALL}. {EMOJI['ERROR']} {translator.get('menu.quit')}")
7677
print(f"{Fore.GREEN}5{Style.RESET_ALL}. {EMOJI['LANG']} {translator.get('menu.select_language')}")
78+
print(f"{Fore.GREEN}6{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.disable_auto_update')}")
7779
print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}")
7880

7981
def select_language():
@@ -103,7 +105,7 @@ def main():
103105

104106
while True:
105107
try:
106-
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices='0-5')}: {Style.RESET_ALL}")
108+
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices='0-6')}: {Style.RESET_ALL}")
107109

108110
if choice == "0":
109111
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.exit')}...{Style.RESET_ALL}")
@@ -129,6 +131,10 @@ def main():
129131
if select_language():
130132
print_menu()
131133
continue
134+
elif choice == "6":
135+
import disable_auto_update
136+
disable_auto_update.run(translator)
137+
break
132138
else:
133139
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
134140
print_menu()

0 commit comments

Comments
 (0)