feat: Enhance account deletion process with improved translations and error handling

- Added multilingual support for account deletion messages in delete_cursor_google.py and oauth_auth.py
- Updated CHANGELOG.md to reflect new features and fixes
- Improved user prompts and error messages for better clarity and user experience
This commit is contained in:
Pin Studios 2025-04-05 18:30:44 +08:00
parent b3e7c101d3
commit 35e01edf9c
6 changed files with 88 additions and 25 deletions

View File

@ -1,9 +1,15 @@
# Change Log
## v1.8.06
1. Add: Google Account Deletion Feature 添加 Google 账号删除功能
2. Update: Menu with new account deletion option 更新菜单添加账号删除选项
3. Add: Multilanguage support for account deletion 添加账号删除功能的多语言支持
1. Add: Google Account Deletion Feature | 添加 Google 账号删除功能
2. Update: Menu with new account deletion option | 更新菜单添加账号删除选项
3. Add: Multilanguage support for account deletion | 添加账号删除功能的多语言支持
4. Fix: Improve usage limits check and tuple index error | 修复使用限制检查和元组索引错误
5. Fix: bug in disable cursor auto update | 修复禁用 Cursor 自动更新的错误
6. Fix: Linux-appimage | 修复 Linux-appimage 问题
7. Add: Support for custom Cursor installation paths on Windows | 添加 Windows 系统下自定义 Cursor 安装路径支持
8. Add: Chrome profile selection feature | 添加 Chrome 配置文件选择功能
9. Fix: improve account usage limit detection | 修復賬號檢測
## v1.8.05
1. Fix: Linux Path Not Found 修復linuxpath問題

View File

@ -153,11 +153,11 @@ class CursorGoogleAccountDeleter(OAuthHandler):
""")
if advanced_element_js:
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Found and clicked Advanced using direct JavaScript selector{Style.RESET_ALL}")
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('account_delete.advanced_tab_clicked', fallback='Found and clicked Advanced using direct JavaScript selector')}{Style.RESET_ALL}")
advanced_found = True
time.sleep(1) # Reduced from 2 seconds
except Exception as e:
print(f"{Fore.YELLOW}{EMOJI['WARNING']} JavaScript querySelector approach failed: {str(e)}{Style.RESET_ALL}")
print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('account_delete.advanced_tab_error', error=str(e), fallback='JavaScript querySelector approach failed: {str(e)}')}{Style.RESET_ALL}")
if not advanced_found:
# Fallback to direct URL navigation which is faster and more reliable
@ -240,7 +240,7 @@ class CursorGoogleAccountDeleter(OAuthHandler):
if delete_input:
delete_input.clear()
delete_input.input("Delete")
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Typed \"Delete\" in confirmation box{Style.RESET_ALL}")
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('account_delete.typed_delete', fallback='Typed \"Delete\" in confirmation box')}{Style.RESET_ALL}")
delete_input_found = True
time.sleep(2)
break
@ -254,7 +254,7 @@ class CursorGoogleAccountDeleter(OAuthHandler):
const changeEvent = new Event('change', {{ bubbles: true }});
arguments[0].dispatchEvent(changeEvent);
""", delete_input)
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Typed \"Delete\" using JavaScript{Style.RESET_ALL}")
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('account_delete.typed_delete_js', fallback='Typed \"Delete\" using JavaScript')}{Style.RESET_ALL}")
delete_input_found = True
time.sleep(2)
break
@ -262,7 +262,7 @@ class CursorGoogleAccountDeleter(OAuthHandler):
continue
if not delete_input_found:
print(f"{Fore.YELLOW}{EMOJI['WARNING']} Delete confirmation input not found, continuing anyway{Style.RESET_ALL}")
print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('account_delete.delete_input_not_found', fallback='Delete confirmation input not found, continuing anyway')}{Style.RESET_ALL}")
time.sleep(2)
# Wait before clicking the final DELETE button
@ -310,7 +310,7 @@ class CursorGoogleAccountDeleter(OAuthHandler):
""")
if delete_button_js:
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Clicked DELETE button{Style.RESET_ALL}")
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('account_delete.delete_button_clicked', fallback='Clicked DELETE button')}{Style.RESET_ALL}")
confirm_button_found = True
except:
pass
@ -327,7 +327,7 @@ class CursorGoogleAccountDeleter(OAuthHandler):
delete_button = self.browser.ele(selector, timeout=2)
if delete_button:
delete_button.click()
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Account deleted successfully!{Style.RESET_ALL}")
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('account_delete.delete_button_clicked', fallback='Account deleted successfully!')}{Style.RESET_ALL}")
confirm_button_found = True
break
except:
@ -362,7 +362,7 @@ def main(translator=None):
try:
# Ask for confirmation
print(f"{Fore.RED}{EMOJI['WARNING']} {translator.get('account_delete.warning') if translator else 'WARNING: This will permanently delete your Cursor account. This action cannot be undone.'}{Style.RESET_ALL}")
confirm = input(f"{Fore.RED}Are you sure you want to proceed? (y/N): {Style.RESET_ALL}").lower()
confirm = input(f"{Fore.RED} {translator.get('account_delete.confirm_prompt') if translator else 'Are you sure you want to proceed? (y/N): '}{Style.RESET_ALL}").lower()
if confirm != 'y':
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('account_delete.cancelled') if translator else 'Account deletion cancelled.'}{Style.RESET_ALL}")

View File

@ -26,7 +26,9 @@
"fixed_soon": "Fixed Soon",
"contribute": "Contribute to the Project",
"config": "Show Config",
"delete_google_account": "Delete Cursor Google Account"
"delete_google_account": "Delete Cursor Google Account",
"continue_prompt": "Continue? (y/N): ",
"operation_cancelled_by_user": "Operation cancelled by user"
},
"languages": {
"en": "English",
@ -599,7 +601,8 @@
"authentication_successful_getting_account_info": "Authentication successful, getting account info...",
"warning_could_not_kill_existing_browser_processes": "Warning: Could not kill existing browser processes: {error}",
"browser_failed_to_start": "Browser failed to start: {error}",
"browser_failed": "Browser failed to start: {error}"
"browser_failed": "Browser failed to start: {error}",
"browser_failed_to_start_fallback": "Browser failed to start: {error}"
},
"chrome_profile": {
"title": "Chrome Profile Selection",
@ -654,6 +657,7 @@
"interrupted": "Account deletion process interrupted by user.",
"unexpected_error": "Unexpected error: {error}",
"found_email": "Found email: {email}",
"email_not_found": "Email not found: {error}"
"email_not_found": "Email not found: {error}",
"confirm_prompt": "Are you sure you want to proceed? (y/N): "
}
}

View File

@ -26,7 +26,9 @@
"fixed_soon": "即将修复",
"contribute": "贡献项目",
"config": "显示配置",
"delete_google_account": "删除 Cursor Google 账号"
"delete_google_account": "删除 Cursor Google 账号",
"continue_prompt": "继续?(y/N): ",
"operation_cancelled_by_user": "操作被用户取消"
},
"languages": {
"en": "英语",
@ -577,7 +579,8 @@
"authentication_successful_getting_account_info": "认证成功, 获取账户信息...",
"warning_could_not_kill_existing_browser_processes": "警告: 无法杀死现有浏览器进程: {error}",
"browser_failed_to_start": "浏览器启动失败: {error}",
"browser_failed": "浏览器启动失败: {error}"
"browser_failed": "浏览器启动失败: {error}",
"browser_failed_to_start_fallback": "浏览器启动失败: {error}"
},
"chrome_profile": {
"title": "Chrome配置文件选择",
@ -632,6 +635,7 @@
"unexpected_error": "意外错误:{error}",
"found_email": "找到邮箱:{email}",
"email_not_found": "未找到邮箱: {error}",
"found_danger_zone": "已找到危险区域部分"
"found_danger_zone": "已找到危险区域部分",
"confirm_prompt": "您确定要继续吗?(y/N): "
}
}

View File

@ -25,7 +25,10 @@
"coming_soon": "即將推出",
"fixed_soon": "即將修復",
"contribute": "貢獻項目",
"config": "顯示配置"
"config": "顯示配置",
"delete_google_account": "刪除 Cursor Google 帳號",
"continue_prompt": "繼續?(y/N): ",
"operation_cancelled_by_user": "操作被使用者取消"
},
"languages": {
"en": "英文",
@ -557,7 +560,8 @@
"authentication_successful_getting_account_info": "認證成功, 獲取帳戶信息...",
"warning_could_not_kill_existing_browser_processes": "警告: 無法殺死現有瀏覽器進程: {error}",
"browser_failed_to_start": "瀏覽器啟動失敗: {error}",
"browser_failed": "瀏覽器啟動失敗: {error}"
"browser_failed": "瀏覽器啟動失敗: {error}",
"browser_failed_to_start_fallback": "瀏覽器啟動失敗: {error}"
},
"chrome_profile": {
"title": "Chrome配置檔案選擇",
@ -570,5 +574,50 @@
"profile_selected": "已選擇配置檔案:{profile}",
"invalid_selection": "選擇無效。請重試",
"warning_chrome_close": "警告這將關閉所有正在執行的Chrome程序"
},
"account_delete": {
"title": "Cursor Google 帳號刪除工具",
"warning": "警告:這將永久刪除您的 Cursor 帳號。此操作無法撤銷。",
"cancelled": "帳號刪除已取消。",
"starting_process": "開始帳號刪除過程...",
"google_button_not_found": "未找到 Google 登錄按鈕",
"logging_in": "正在使用 Google 登錄...",
"waiting_for_auth": "等待 Google 驗證...",
"login_successful": "登錄成功",
"unexpected_page": "登錄後頁面異常:{url}",
"trying_settings": "嘗試導航到設置頁面...",
"select_google_account": "請選擇您的 Google 帳號...",
"auth_timeout": "認證超時,繼續執行...",
"navigating_to_settings": "正在導航到設置頁面...",
"already_on_settings": "已在設置頁面",
"login_redirect_failed": "登錄重定向失敗,嘗試直接導航...",
"advanced_tab_not_found": "多次嘗試後未找到高級選項卡",
"advanced_tab_retry": "未找到高級選項卡,嘗試 {attempt}/{max_attempts}",
"advanced_tab_error": "查找高級選項卡時出錯:{error}",
"advanced_tab_clicked": "已點擊高級選項卡",
"direct_advanced_navigation": "嘗試直接導航到高級選項卡",
"delete_button_not_found": "多次嘗試後未找到刪除帳號按鈕",
"delete_button_retry": "未找到刪除按鈕,嘗試 {attempt}/{max_attempts}",
"delete_button_error": "查找刪除按鈕時出錯:{error}",
"delete_button_clicked": "已點擊刪除帳號按鈕",
"delete_input_not_found": "多次嘗試後未找到刪除確認輸入框",
"delete_input_retry": "未找到刪除輸入框,嘗試 {attempt}/{max_attempts}",
"delete_input_error": "查找刪除輸入框時出錯:{error}",
"delete_input_not_found_continuing": "未找到刪除確認輸入框,嘗試繼續執行...",
"typed_delete": "已在確認框中輸入\"Delete\"",
"confirm_button_not_found": "多次嘗試後未找到確認按鈕",
"confirm_button_retry": "未找到確認按鈕,嘗試 {attempt}/{max_attempts}",
"confirm_button_error": "查找確認按鈕時出錯:{error}",
"account_deleted": "帳號刪除成功!",
"error": "帳號刪除過程中出錯:{error}",
"success": "您的 Cursor 帳號已成功刪除!",
"failed": "帳號刪除過程失敗或已取消。",
"interrupted": "帳號刪除過程被用戶中斷。",
"unexpected_error": "意外錯誤:{error}",
"found_email": "找到郵箱:{email}",
"email_not_found": "未找到郵箱: {error}",
"found_danger_zone": "已找到危險區域部分",
"confirm_prompt": "您確定要繼續嗎?(y/N): ",
"typed_delete_js": "已使用 JavaScript 輸入\"Delete\""
}
}

View File

@ -97,11 +97,11 @@ class OAuthHandler:
def setup_browser(self):
"""Setup browser for OAuth flow using selected profile"""
try:
print(f"{Fore.CYAN}{EMOJI['INFO']} Initializing browser setup...{Style.RESET_ALL}")
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('oauth.initializing_browser_setup') if self.translator else 'Initializing browser setup...'}{Style.RESET_ALL}")
# Platform-specific initialization
platform_name = platform.system().lower()
print(f"{Fore.CYAN}{EMOJI['INFO']} Detected platform: {platform_name}{Style.RESET_ALL}")
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('oauth.detected_platform', platform=platform_name) if self.translator else f'Detected platform: {platform_name}'}{Style.RESET_ALL}")
# Get browser paths and user data directory
user_data_dir = self._get_user_data_directory()
@ -117,9 +117,9 @@ class OAuthHandler:
# Show warning about closing Chrome first
print(f"\n{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('chrome_profile.warning_chrome_close') if self.translator else 'Warning: This will close all running Chrome processes'}{Style.RESET_ALL}")
choice = input(f"{Fore.YELLOW}Continue? (y/N): {Style.RESET_ALL}").lower()
choice = input(f"{Fore.YELLOW} {self.translator.get('menu.continue_prompt', choices='y/N')} {Style.RESET_ALL}").lower()
if choice != 'y':
print(f"{Fore.YELLOW}{EMOJI['INFO']} Operation cancelled by user{Style.RESET_ALL}")
print(f"{Fore.YELLOW}{EMOJI['INFO']} {self.translator.get('menu.operation_cancelled_by_user') if self.translator else 'Operation cancelled by user'}{Style.RESET_ALL}")
return False
# Kill existing browser processes
@ -127,7 +127,7 @@ class OAuthHandler:
# Let user select a profile
if not self._select_profile():
print(f"{Fore.YELLOW}{EMOJI['INFO']} Operation cancelled by user{Style.RESET_ALL}")
print(f"{Fore.YELLOW}{EMOJI['INFO']} {self.translator.get('menu.operation_cancelled_by_user') if self.translator else 'Operation cancelled by user'}{Style.RESET_ALL}")
return False
# Configure browser options
@ -138,7 +138,7 @@ class OAuthHandler:
# Verify browser launched successfully
if not self.browser:
raise Exception("Failed to initialize browser instance")
raise Exception(f"{self.translator.get('oauth.browser_failed_to_start') if self.translator else 'Failed to initialize browser instance'}")
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('oauth.browser_setup_completed') if self.translator else 'Browser setup completed successfully'}{Style.RESET_ALL}")
return True