Compare commits

...

7 Commits

Author SHA1 Message Date
yeongpin
6ac1294bee Add Disable Cursor Auto Update Feature 2025-02-24 11:18:57 +08:00
Pin Studios
fb443592d3 Update README.md 2025-02-21 18:02:22 +08:00
Pin Studios
c30a62b072 Update README.md 2025-02-17 16:30:55 +08:00
Pin Studios
8bc509cccf Update README.md 2025-02-17 16:29:16 +08:00
yeongpin
9f814708d1 Update CHANGELOG.md for v1.3.02 release 2025-02-13 15:33:09 +08:00
Pin Studios
1889f9827a Update README.md 2025-02-13 15:28:00 +08:00
yeongpin
57d2d40e67 update coffee 2025-02-13 15:24:40 +08:00
11 changed files with 221 additions and 12 deletions

4
.env
View File

@@ -1,2 +1,2 @@
version=1.3.02 version=1.4.01
VERSION=1.3.02 VERSION=1.4.01

View File

@@ -6,7 +6,7 @@ on:
version: version:
description: 'Version number (e.g. 1.0.9)' description: 'Version number (e.g. 1.0.9)'
required: true required: true
default: '1.0.9-dev' default: '1.4.01'
permissions: permissions:
contents: write contents: write

View File

@@ -1,5 +1,16 @@
# Change Log # Change Log
## v1.4.01
1. Add Disable Cursor Auto Upgrade | 增加禁用Cursor自動升級
## v1.3.02
1. Add Buy Me a Coffee | 增加請我喝杯咖啡
2. Add PayPal | 增加PayPal
3. Very Small Fix | 非常小的修復
4. Fix main.py option number | 修復main.py選項數量
## v1.3.01 ## v1.3.01
1. Add Manual Email Input | 增加手動輸入郵箱地址 1. Add Manual Email Input | 增加手動輸入郵箱地址

View File

@@ -9,6 +9,7 @@
[![Release](https://img.shields.io/github/v/release/yeongpin/cursor-free-vip?style=flat-square&logo=github&color=blue)](https://github.com/yeongpin/cursor-free-vip/releases/latest) [![Release](https://img.shields.io/github/v/release/yeongpin/cursor-free-vip?style=flat-square&logo=github&color=blue)](https://github.com/yeongpin/cursor-free-vip/releases/latest)
[![License: CC BY-NC-ND 4.0](https://img.shields.io/badge/License-CC_BY--NC--ND_4.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/) [![License: CC BY-NC-ND 4.0](https://img.shields.io/badge/License-CC_BY--NC--ND_4.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/)
[![Stars](https://img.shields.io/github/stars/yeongpin/cursor-free-vip?style=flat-square&logo=github)](https://github.com/yeongpin/cursor-free-vip/stargazers) [![Stars](https://img.shields.io/github/stars/yeongpin/cursor-free-vip?style=flat-square&logo=github)](https://github.com/yeongpin/cursor-free-vip/stargazers)
[![Download](https://img.shields.io/github/downloads/yeongpin/cursor-free-vip/total?style=flat-square&logo=github&color=52c41a)](https://github.com/yeongpin/cursor-free-vip/releases/latest)
</p> </p>
<h4>Support Latest 0.45.11 Version | 支持最新0.45.11版本</h4> <h4>Support Latest 0.45.11 Version | 支持最新0.45.11版本</h4>
@@ -111,6 +112,21 @@ irm https://raw.githubusercontent.com/yeongpin/cursor-free-vip/main/scripts/rese
本工具僅供學習和研究使用,使用本工具所產生的任何後果由使用者自行承擔。 <br> 本工具僅供學習和研究使用,使用本工具所產生的任何後果由使用者自行承擔。 <br>
源代碼靈感來之 | Original code inspiration from [Here](https://github.com/hmhm2022/gpt-cursor-auto)
This tool is only for learning and research purposes, and any consequences arising from the use of this tool are borne by the user. This tool is only for learning and research purposes, and any consequences arising from the use of this tool are borne by the user.
## 💰 Buy Me a Coffee | 請我喝杯咖啡
<div align="center">
<table>
<tr>
<td>
<img src="./images/provi-code.jpg" alt="buy_me_a_coffee" width="280"/><br>
</td>
<td>
<img src="./images/paypal.png" alt="buy_me_a_coffee" width="280"/><br>
</td>
</tr>
</table>
</div>

135
disable_auto_update.py Normal file
View File

@@ -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)

BIN
images/paypal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
images/provi-code.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

View File

@@ -11,7 +11,8 @@
"invalid_choice": "Invalid choice. Please try again", "invalid_choice": "Invalid choice. Please try again",
"program_terminated": "Program terminated by user", "program_terminated": "Program terminated by user",
"error_occurred": "An error occurred: {error}", "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": { "languages": {
"en": "English", "en": "English",
@@ -196,5 +197,18 @@
"verification_code_not_found": "Verification Code Not Found", "verification_code_not_found": "Verification Code Not Found",
"verification_code_error": "Verification Code Error: {error}", "verification_code_error": "Verification Code Error: {error}",
"address": "Email Address" "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"
} }
} }

View File

@@ -11,7 +11,8 @@
"invalid_choice": "无效选择,请重试", "invalid_choice": "无效选择,请重试",
"program_terminated": "程序被用户终止", "program_terminated": "程序被用户终止",
"error_occurred": "发生错误: {error}", "error_occurred": "发生错误: {error}",
"press_enter": "按回车键退出" "press_enter": "按回车键退出",
"disable_auto_update": "禁用 Cursor 自动更新"
}, },
"languages": { "languages": {
"en": "English", "en": "English",
@@ -193,5 +194,18 @@
"verification_code_not_found": "未找到验证码", "verification_code_not_found": "未找到验证码",
"verification_code_error": "验证码错误: {error}", "verification_code_error": "验证码错误: {error}",
"address": "邮箱地址" "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": "阻止文件已创建"
} }
} }

View File

@@ -11,7 +11,8 @@
"invalid_choice": "無效選擇,請重試", "invalid_choice": "無效選擇,請重試",
"program_terminated": "程序被用戶終止", "program_terminated": "程序被用戶終止",
"error_occurred": "發生錯誤: {error}", "error_occurred": "發生錯誤: {error}",
"press_enter": "按回車鍵退出" "press_enter": "按回車鍵退出",
"disable_auto_update": "禁用 Cursor 自動更新"
}, },
"languages": { "languages": {
"en": "English", "en": "English",
@@ -193,6 +194,18 @@
"verification_code_not_found": "未找到驗證碼", "verification_code_not_found": "未找到驗證碼",
"verification_code_error": "驗證碼錯誤: {error}", "verification_code_error": "驗證碼錯誤: {error}",
"address": "郵箱地址" "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": "阻止文件已創建"
} }
} }

10
main.py
View File

@@ -19,7 +19,8 @@ EMOJI = {
"RESET": "🔄", "RESET": "🔄",
"MENU": "📋", "MENU": "📋",
"ARROW": "", "ARROW": "",
"LANG": "🌐" "LANG": "🌐",
"UPDATE": "🔄"
} }
class Translator: 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}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}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}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}") print(f"{Fore.YELLOW}{'' * 40}{Style.RESET_ALL}")
def select_language(): def select_language():
@@ -103,7 +105,7 @@ def main():
while True: while True:
try: 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": if choice == "0":
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.exit')}...{Style.RESET_ALL}") print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.exit')}...{Style.RESET_ALL}")
@@ -129,6 +131,10 @@ def main():
if select_language(): if select_language():
print_menu() print_menu()
continue continue
elif choice == "6":
import disable_auto_update
disable_auto_update.run(translator)
break
else: else:
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}") print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
print_menu() print_menu()