diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bc0cd9..6c98613 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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問題 diff --git a/delete_cursor_google.py b/delete_cursor_google.py index 39b3457..baa233f 100644 --- a/delete_cursor_google.py +++ b/delete_cursor_google.py @@ -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}") diff --git a/locales/en.json b/locales/en.json index 05e29cc..e1af20f 100644 --- a/locales/en.json +++ b/locales/en.json @@ -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): " } } \ No newline at end of file diff --git a/locales/zh_cn.json b/locales/zh_cn.json index 321e807..1bffbd6 100644 --- a/locales/zh_cn.json +++ b/locales/zh_cn.json @@ -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): " } } \ No newline at end of file diff --git a/locales/zh_tw.json b/locales/zh_tw.json index 1748909..dc0acd4 100644 --- a/locales/zh_tw.json +++ b/locales/zh_tw.json @@ -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\"" } } \ No newline at end of file diff --git a/oauth_auth.py b/oauth_auth.py index 94e8695..38c350d 100644 --- a/oauth_auth.py +++ b/oauth_auth.py @@ -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