mirror of
https://github.com/yeongpin/cursor-free-vip.git
synced 2025-08-03 04:57:36 +08:00
Merge pull request #494 from saadtahir995/main
feat: Added Google OAuth Acc Deletion Tool
This commit is contained in:
commit
bfb2f5e95a
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,5 +1,16 @@
|
|||||||
# Change Log
|
# 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 | 添加账号删除功能的多语言支持
|
||||||
|
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
|
## v1.8.05
|
||||||
1. Fix: Linux Path Not Found | 修復linuxpath問題
|
1. Fix: Linux Path Not Found | 修復linuxpath問題
|
||||||
2. Add: support for detecting both 150/150 and 50/50 usage limits | 添加偵測50 或者150的使用量
|
2. Add: support for detecting both 150/150 and 50/50 usage limits | 添加偵測50 或者150的使用量
|
||||||
|
@ -54,6 +54,8 @@ Always clean your browser's cache and cookies. If possible, use a VPN to create
|
|||||||
|
|
||||||
* Reset Cursor's configuration<br>重置 Cursor 的配置<br>
|
* Reset Cursor's configuration<br>重置 Cursor 的配置<br>
|
||||||
|
|
||||||
|
* Delete Cursor Google Account<br>删除 Cursor Google 账号<br>
|
||||||
|
|
||||||
* Multi-language support (English, 简体中文, 繁體中文, Vietnamese)<br>多語言支持(英文、简体中文、繁體中文、越南語)<br>
|
* Multi-language support (English, 简体中文, 繁體中文, Vietnamese)<br>多語言支持(英文、简体中文、繁體中文、越南語)<br>
|
||||||
|
|
||||||
## 💻 System Support | 系統支持
|
## 💻 System Support | 系統支持
|
||||||
|
386
delete_cursor_google.py
Normal file
386
delete_cursor_google.py
Normal file
@ -0,0 +1,386 @@
|
|||||||
|
from oauth_auth import OAuthHandler
|
||||||
|
import time
|
||||||
|
from colorama import Fore, Style, init
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Initialize colorama
|
||||||
|
init()
|
||||||
|
|
||||||
|
# Define emoji constants
|
||||||
|
EMOJI = {
|
||||||
|
'START': '🚀',
|
||||||
|
'DELETE': '🗑️',
|
||||||
|
'SUCCESS': '✅',
|
||||||
|
'ERROR': '❌',
|
||||||
|
'WAIT': '⏳',
|
||||||
|
'INFO': 'ℹ️',
|
||||||
|
'WARNING': '⚠️'
|
||||||
|
}
|
||||||
|
|
||||||
|
class CursorGoogleAccountDeleter(OAuthHandler):
|
||||||
|
def __init__(self, translator=None):
|
||||||
|
super().__init__(translator, auth_type='google')
|
||||||
|
|
||||||
|
def delete_google_account(self):
|
||||||
|
"""Delete Cursor account using Google OAuth"""
|
||||||
|
try:
|
||||||
|
# Setup browser and select profile
|
||||||
|
if not self.setup_browser():
|
||||||
|
return False
|
||||||
|
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('account_delete.starting_process') if self.translator else 'Starting account deletion process...'}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
# Navigate to Cursor auth page - using the same URL as in registration
|
||||||
|
self.browser.get("https://authenticator.cursor.sh/sign-up")
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
# Click Google auth button using same selectors as in registration
|
||||||
|
selectors = [
|
||||||
|
"//a[contains(@href,'GoogleOAuth')]",
|
||||||
|
"//a[contains(@class,'auth-method-button') and contains(@href,'GoogleOAuth')]",
|
||||||
|
"(//a[contains(@class,'auth-method-button')])[1]" # First auth button as fallback
|
||||||
|
]
|
||||||
|
|
||||||
|
auth_btn = None
|
||||||
|
for selector in selectors:
|
||||||
|
try:
|
||||||
|
auth_btn = self.browser.ele(f"xpath:{selector}", timeout=2)
|
||||||
|
if auth_btn:
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not auth_btn:
|
||||||
|
raise Exception(self.translator.get('account_delete.google_button_not_found') if self.translator else "Google login button not found")
|
||||||
|
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('account_delete.logging_in') if self.translator else 'Logging in with Google...'}{Style.RESET_ALL}")
|
||||||
|
auth_btn.click()
|
||||||
|
|
||||||
|
# Wait for authentication to complete using a more robust method
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['WAIT']} {self.translator.get('account_delete.waiting_for_auth', fallback='Waiting for Google authentication...')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
# Dynamic wait for authentication
|
||||||
|
max_wait_time = 120 # Increase maximum wait time to 120 seconds
|
||||||
|
start_time = time.time()
|
||||||
|
check_interval = 3 # Check every 3 seconds
|
||||||
|
google_account_alert_shown = False # Track if we've shown the alert already
|
||||||
|
|
||||||
|
while time.time() - start_time < max_wait_time:
|
||||||
|
current_url = self.browser.url
|
||||||
|
|
||||||
|
# If we're already on the settings or dashboard page, we're successful
|
||||||
|
if "/dashboard" in current_url or "/settings" in current_url or "cursor.com" in current_url:
|
||||||
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('account_delete.login_successful') if self.translator else 'Login successful'}{Style.RESET_ALL}")
|
||||||
|
break
|
||||||
|
|
||||||
|
# If we're on Google accounts page or accounts.google.com, wait for user selection
|
||||||
|
if "accounts.google.com" in current_url:
|
||||||
|
# Only show the alert once to avoid spamming
|
||||||
|
if not google_account_alert_shown:
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('account_delete.select_google_account', fallback='Please select your Google account...')}{Style.RESET_ALL}")
|
||||||
|
# Alert to indicate user action needed
|
||||||
|
try:
|
||||||
|
self.browser.run_js("""
|
||||||
|
alert('Please select your Google account to continue with Cursor authentication');
|
||||||
|
""")
|
||||||
|
google_account_alert_shown = True # Mark that we've shown the alert
|
||||||
|
except:
|
||||||
|
pass # Alert is optional
|
||||||
|
|
||||||
|
# Sleep before checking again
|
||||||
|
time.sleep(check_interval)
|
||||||
|
else:
|
||||||
|
# If the loop completed without breaking, it means we hit the timeout
|
||||||
|
print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('account_delete.auth_timeout', fallback='Authentication timeout, continuing anyway...')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
# Check current URL to determine next steps
|
||||||
|
current_url = self.browser.url
|
||||||
|
|
||||||
|
# If we're already on the settings page, no need to navigate
|
||||||
|
if "/settings" in current_url and "cursor.com" in current_url:
|
||||||
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('account_delete.already_on_settings', fallback='Already on settings page')}{Style.RESET_ALL}")
|
||||||
|
# If we're on the dashboard or any Cursor page but not settings, navigate to settings
|
||||||
|
elif "cursor.com" in current_url or "authenticator.cursor.sh" in current_url:
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('account_delete.navigating_to_settings', fallback='Navigating to settings page...')}{Style.RESET_ALL}")
|
||||||
|
self.browser.get("https://www.cursor.com/settings")
|
||||||
|
# If we're still on Google auth or somewhere else, try directly going to settings
|
||||||
|
else:
|
||||||
|
print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('account_delete.login_redirect_failed', fallback='Login redirection failed, trying direct navigation...')}{Style.RESET_ALL}")
|
||||||
|
self.browser.get("https://www.cursor.com/settings")
|
||||||
|
|
||||||
|
# Wait for the settings page to load
|
||||||
|
time.sleep(3) # Reduced from 5 seconds
|
||||||
|
|
||||||
|
# First look for the email element to confirm we're logged in
|
||||||
|
try:
|
||||||
|
email_element = self.browser.ele("css:div[class='flex w-full flex-col gap-2'] div:nth-child(2) p:nth-child(2)")
|
||||||
|
if email_element:
|
||||||
|
email = email_element.text
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('account_delete.found_email', email=email, fallback=f'Found email: {email}')}{Style.RESET_ALL}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('account_delete.email_not_found', error=str(e), fallback=f'Email not found: {str(e)}')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
# Click on "Advanced" tab or dropdown - keep only the successful approach
|
||||||
|
advanced_found = False
|
||||||
|
|
||||||
|
# Direct JavaScript querySelector approach that worked according to logs
|
||||||
|
try:
|
||||||
|
advanced_element_js = self.browser.run_js("""
|
||||||
|
// Try to find the Advanced dropdown using querySelector with the exact classes
|
||||||
|
let advancedElement = document.querySelector('div.mb-0.flex.cursor-pointer.items-center.text-xs:not([style*="display: none"])');
|
||||||
|
|
||||||
|
// If not found, try a more general approach
|
||||||
|
if (!advancedElement) {
|
||||||
|
const allDivs = document.querySelectorAll('div');
|
||||||
|
for (const div of allDivs) {
|
||||||
|
if (div.textContent.includes('Advanced') &&
|
||||||
|
div.className.includes('mb-0') &&
|
||||||
|
div.className.includes('flex') &&
|
||||||
|
div.className.includes('cursor-pointer')) {
|
||||||
|
advancedElement = div;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Click the element if found
|
||||||
|
if (advancedElement) {
|
||||||
|
advancedElement.click();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
""")
|
||||||
|
|
||||||
|
if advanced_element_js:
|
||||||
|
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']} {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
|
||||||
|
try:
|
||||||
|
self.browser.get("https://www.cursor.com/settings?tab=advanced")
|
||||||
|
print(f"{Fore.YELLOW}{EMOJI['INFO']} {self.translator.get('account_delete.direct_advanced_navigation', fallback='Trying direct navigation to advanced tab')}{Style.RESET_ALL}")
|
||||||
|
advanced_found = True
|
||||||
|
except:
|
||||||
|
raise Exception(self.translator.get('account_delete.advanced_tab_not_found') if self.translator else "Advanced option not found after multiple attempts")
|
||||||
|
|
||||||
|
# Wait for dropdown/tab content to load
|
||||||
|
time.sleep(2) # Reduced from 4 seconds
|
||||||
|
|
||||||
|
# Find and click the "Delete Account" button
|
||||||
|
delete_button_found = False
|
||||||
|
|
||||||
|
# Simplified approach for delete button based on what worked
|
||||||
|
delete_button_selectors = [
|
||||||
|
'xpath://button[contains(., "Delete Account")]',
|
||||||
|
'xpath://button[text()="Delete Account"]',
|
||||||
|
'xpath://div[contains(text(), "Delete Account")]',
|
||||||
|
'xpath://button[contains(text(), "Delete") and contains(text(), "Account")]'
|
||||||
|
]
|
||||||
|
|
||||||
|
for selector in delete_button_selectors:
|
||||||
|
try:
|
||||||
|
delete_button = self.browser.ele(selector, timeout=2)
|
||||||
|
if delete_button:
|
||||||
|
delete_button.click()
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('account_delete.delete_button_clicked') if self.translator else 'Clicked on Delete Account button'}{Style.RESET_ALL}")
|
||||||
|
delete_button_found = True
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not delete_button_found:
|
||||||
|
raise Exception(self.translator.get('account_delete.delete_button_not_found') if self.translator else "Delete Account button not found")
|
||||||
|
|
||||||
|
# Wait for confirmation dialog to appear
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
# Check if we need to input "Delete" at all - some modals might not require it
|
||||||
|
input_required = True
|
||||||
|
try:
|
||||||
|
# Try detecting if the DELETE button is already enabled
|
||||||
|
delete_button_enabled = self.browser.run_js("""
|
||||||
|
const buttons = Array.from(document.querySelectorAll('button'));
|
||||||
|
const deleteButtons = buttons.filter(btn =>
|
||||||
|
btn.textContent.trim() === 'DELETE' ||
|
||||||
|
btn.textContent.trim() === 'Delete'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (deleteButtons.length > 0) {
|
||||||
|
return !deleteButtons.some(btn => btn.disabled);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
""")
|
||||||
|
|
||||||
|
if delete_button_enabled:
|
||||||
|
print(f"{Fore.CYAN}{EMOJI['INFO']} DELETE button appears to be enabled already. Input may not be required.{Style.RESET_ALL}")
|
||||||
|
input_required = False
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Type "Delete" in the confirmation input - only if required
|
||||||
|
delete_input_found = False
|
||||||
|
|
||||||
|
if input_required:
|
||||||
|
# Try common selectors for the input field
|
||||||
|
delete_input_selectors = [
|
||||||
|
'xpath://input[@placeholder="Delete"]',
|
||||||
|
'xpath://div[contains(@class, "modal")]//input',
|
||||||
|
'xpath://input',
|
||||||
|
'css:input'
|
||||||
|
]
|
||||||
|
|
||||||
|
for selector in delete_input_selectors:
|
||||||
|
try:
|
||||||
|
delete_input = self.browser.ele(selector, timeout=3)
|
||||||
|
if delete_input:
|
||||||
|
delete_input.clear()
|
||||||
|
delete_input.input("Delete")
|
||||||
|
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
|
||||||
|
except:
|
||||||
|
# Try direct JavaScript input as fallback
|
||||||
|
try:
|
||||||
|
self.browser.run_js(f"""
|
||||||
|
arguments[0].value = "Delete";
|
||||||
|
const event = new Event('input', {{ bubbles: true }});
|
||||||
|
arguments[0].dispatchEvent(event);
|
||||||
|
const changeEvent = new Event('change', {{ bubbles: true }});
|
||||||
|
arguments[0].dispatchEvent(changeEvent);
|
||||||
|
""", delete_input)
|
||||||
|
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
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not delete_input_found:
|
||||||
|
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
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
# Click on the final DELETE button
|
||||||
|
confirm_button_found = False
|
||||||
|
|
||||||
|
# Use JavaScript approach for the DELETE button
|
||||||
|
try:
|
||||||
|
delete_button_js = self.browser.run_js("""
|
||||||
|
// Try to find the DELETE button by exact text content
|
||||||
|
const buttons = Array.from(document.querySelectorAll('button'));
|
||||||
|
const deleteButton = buttons.find(btn =>
|
||||||
|
btn.textContent.trim() === 'DELETE' ||
|
||||||
|
btn.textContent.trim() === 'Delete'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (deleteButton) {
|
||||||
|
console.log("Found DELETE button with JavaScript");
|
||||||
|
deleteButton.click();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not found by text, try to find right-most button in the modal
|
||||||
|
const modalButtons = Array.from(document.querySelectorAll('.relative button, [role="dialog"] button, .modal button, [aria-modal="true"] button'));
|
||||||
|
|
||||||
|
if (modalButtons.length > 1) {
|
||||||
|
modalButtons.sort((a, b) => {
|
||||||
|
const rectA = a.getBoundingClientRect();
|
||||||
|
const rectB = b.getBoundingClientRect();
|
||||||
|
return rectB.right - rectA.right;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Clicking right-most button in modal");
|
||||||
|
modalButtons[0].click();
|
||||||
|
return true;
|
||||||
|
} else if (modalButtons.length === 1) {
|
||||||
|
console.log("Clicking single button found in modal");
|
||||||
|
modalButtons[0].click();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
""")
|
||||||
|
|
||||||
|
if delete_button_js:
|
||||||
|
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
|
||||||
|
|
||||||
|
if not confirm_button_found:
|
||||||
|
# Fallback to simple selectors
|
||||||
|
delete_button_selectors = [
|
||||||
|
'xpath://button[text()="DELETE"]',
|
||||||
|
'xpath://div[contains(@class, "modal")]//button[last()]'
|
||||||
|
]
|
||||||
|
|
||||||
|
for selector in delete_button_selectors:
|
||||||
|
try:
|
||||||
|
delete_button = self.browser.ele(selector, timeout=2)
|
||||||
|
if delete_button:
|
||||||
|
delete_button.click()
|
||||||
|
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:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if not confirm_button_found:
|
||||||
|
raise Exception(self.translator.get('account_delete.confirm_button_not_found') if self.translator else "Confirm button not found")
|
||||||
|
|
||||||
|
# Wait a moment to see the confirmation
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('account_delete.error', error=str(e)) if self.translator else f'Error during account deletion: {str(e)}'}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
|
finally:
|
||||||
|
# Clean up browser
|
||||||
|
if self.browser:
|
||||||
|
try:
|
||||||
|
self.browser.quit()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def main(translator=None):
|
||||||
|
"""Main function to handle Google account deletion"""
|
||||||
|
print(f"\n{Fore.CYAN}{EMOJI['START']} {translator.get('account_delete.title') if translator else 'Cursor Google Account Deletion Tool'}{Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.YELLOW}{'─' * 50}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
deleter = CursorGoogleAccountDeleter(translator)
|
||||||
|
|
||||||
|
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} {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}")
|
||||||
|
return
|
||||||
|
|
||||||
|
success = deleter.delete_google_account()
|
||||||
|
|
||||||
|
if success:
|
||||||
|
print(f"\n{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('account_delete.success') if translator else 'Your Cursor account has been successfully deleted!'}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
|
print(f"\n{Fore.RED}{EMOJI['ERROR']} {translator.get('account_delete.failed') if translator else 'Account deletion process failed or was cancelled.'}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('account_delete.interrupted') if translator else 'Account deletion process interrupted by user.'}{Style.RESET_ALL}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('account_delete.unexpected_error', error=str(e)) if translator else f'Unexpected error: {str(e)}'}{Style.RESET_ALL}")
|
||||||
|
finally:
|
||||||
|
print(f"{Fore.YELLOW}{'─' * 50}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -25,7 +25,10 @@
|
|||||||
"coming_soon": "Coming Soon",
|
"coming_soon": "Coming Soon",
|
||||||
"fixed_soon": "Fixed Soon",
|
"fixed_soon": "Fixed Soon",
|
||||||
"contribute": "Contribute to the Project",
|
"contribute": "Contribute to the Project",
|
||||||
"config": "Show Config"
|
"config": "Show Config",
|
||||||
|
"delete_google_account": "Delete Cursor Google Account",
|
||||||
|
"continue_prompt": "Continue? (y/N): ",
|
||||||
|
"operation_cancelled_by_user": "Operation cancelled by user"
|
||||||
},
|
},
|
||||||
"languages": {
|
"languages": {
|
||||||
"en": "English",
|
"en": "English",
|
||||||
@ -442,7 +445,24 @@
|
|||||||
"cursor_reset_completed": "Cursor AI Editor has been fully reset and trial detection bypassed!",
|
"cursor_reset_completed": "Cursor AI Editor has been fully reset and trial detection bypassed!",
|
||||||
"cursor_reset_failed": "Cursor AI Editor reset failed: {error}",
|
"cursor_reset_failed": "Cursor AI Editor reset failed: {error}",
|
||||||
"cursor_reset_cancelled": "Cursor AI Editor reset cancelled. Exiting without making any changes.",
|
"cursor_reset_cancelled": "Cursor AI Editor reset cancelled. Exiting without making any changes.",
|
||||||
"operation_cancelled": "Operation cancelled. Exiting without making any changes."
|
"operation_cancelled": "Operation cancelled. Exiting without making any changes.",
|
||||||
|
"navigating_to_settings": "Navigating to settings page...",
|
||||||
|
"already_on_settings": "Already on settings page",
|
||||||
|
"login_redirect_failed": "Login redirection failed, trying direct navigation...",
|
||||||
|
"advanced_tab_not_found": "Advanced tab not found after multiple attempts",
|
||||||
|
"advanced_tab_retry": "Advanced tab not found, attempt {attempt}/{max_attempts}",
|
||||||
|
"advanced_tab_error": "Error finding Advanced tab: {error}",
|
||||||
|
"advanced_tab_clicked": "Clicked on Advanced tab",
|
||||||
|
"direct_advanced_navigation": "Trying direct navigation to advanced tab",
|
||||||
|
"delete_button_not_found": "Delete Account button not found after multiple attempts",
|
||||||
|
"delete_button_retry": "Delete button not found, attempt {attempt}/{max_attempts}",
|
||||||
|
"delete_button_error": "Error finding Delete button: {error}",
|
||||||
|
"delete_button_clicked": "Clicked on Delete Account button",
|
||||||
|
"found_danger_zone": "Found Danger Zone section",
|
||||||
|
"delete_input_not_found": "Delete confirmation input not found after multiple attempts",
|
||||||
|
"delete_input_retry": "Delete input not found, attempt {attempt}/{max_attempts}",
|
||||||
|
"delete_input_error": "Error finding Delete input: {error}",
|
||||||
|
"delete_input_not_found_continuing": "Delete confirmation input not found, trying to continue anyway"
|
||||||
},
|
},
|
||||||
"github_register": {
|
"github_register": {
|
||||||
"title": "GitHub + Cursor AI Registration Automation",
|
"title": "GitHub + Cursor AI Registration Automation",
|
||||||
@ -590,7 +610,8 @@
|
|||||||
"authentication_successful_getting_account_info": "Authentication successful, getting account info...",
|
"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}",
|
"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_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": {
|
"chrome_profile": {
|
||||||
"title": "Chrome Profile Selection",
|
"title": "Chrome Profile Selection",
|
||||||
@ -603,5 +624,49 @@
|
|||||||
"profile_selected": "Selected profile: {profile}",
|
"profile_selected": "Selected profile: {profile}",
|
||||||
"invalid_selection": "Invalid selection. Please try again",
|
"invalid_selection": "Invalid selection. Please try again",
|
||||||
"warning_chrome_close": "Warning: This will close all running Chrome processes"
|
"warning_chrome_close": "Warning: This will close all running Chrome processes"
|
||||||
|
},
|
||||||
|
"account_delete": {
|
||||||
|
"title": "Cursor Google Account Deletion Tool",
|
||||||
|
"warning": "WARNING: This will permanently delete your Cursor account. This action cannot be undone.",
|
||||||
|
"cancelled": "Account deletion cancelled.",
|
||||||
|
"starting_process": "Starting account deletion process...",
|
||||||
|
"google_button_not_found": "Google login button not found",
|
||||||
|
"logging_in": "Logging in with Google...",
|
||||||
|
"waiting_for_auth": "Waiting for Google authentication...",
|
||||||
|
"login_successful": "Login successful",
|
||||||
|
"unexpected_page": "Unexpected page after login: {url}",
|
||||||
|
"trying_settings": "Trying to navigate to settings page...",
|
||||||
|
"select_google_account": "Please select your Google account...",
|
||||||
|
"auth_timeout": "Authentication timeout, continuing anyway...",
|
||||||
|
"navigating_to_settings": "Navigating to settings page...",
|
||||||
|
"already_on_settings": "Already on settings page",
|
||||||
|
"login_redirect_failed": "Login redirection failed, trying direct navigation...",
|
||||||
|
"advanced_tab_not_found": "Advanced tab not found after multiple attempts",
|
||||||
|
"advanced_tab_retry": "Advanced tab not found, attempt {attempt}/{max_attempts}",
|
||||||
|
"advanced_tab_error": "Error finding Advanced tab: {error}",
|
||||||
|
"advanced_tab_clicked": "Clicked on Advanced tab",
|
||||||
|
"direct_advanced_navigation": "Trying direct navigation to advanced tab",
|
||||||
|
"delete_button_not_found": "Delete Account button not found after multiple attempts",
|
||||||
|
"delete_button_retry": "Delete button not found, attempt {attempt}/{max_attempts}",
|
||||||
|
"delete_button_error": "Error finding Delete button: {error}",
|
||||||
|
"delete_button_clicked": "Clicked on Delete Account button",
|
||||||
|
"found_danger_zone": "Found Danger Zone section",
|
||||||
|
"delete_input_not_found": "Delete confirmation input not found after multiple attempts",
|
||||||
|
"delete_input_retry": "Delete input not found, attempt {attempt}/{max_attempts}",
|
||||||
|
"delete_input_error": "Error finding Delete input: {error}",
|
||||||
|
"delete_input_not_found_continuing": "Delete confirmation input not found, trying to continue anyway",
|
||||||
|
"typed_delete": "Typed \"Delete\" in confirmation box",
|
||||||
|
"confirm_button_not_found": "Confirm button not found after multiple attempts",
|
||||||
|
"confirm_button_retry": "Confirm button not found, attempt {attempt}/{max_attempts}",
|
||||||
|
"confirm_button_error": "Error finding Confirm button: {error}",
|
||||||
|
"account_deleted": "Account deleted successfully!",
|
||||||
|
"error": "Error during account deletion: {error}",
|
||||||
|
"success": "Your Cursor account has been successfully deleted!",
|
||||||
|
"failed": "Account deletion process failed or was cancelled.",
|
||||||
|
"interrupted": "Account deletion process interrupted by user.",
|
||||||
|
"unexpected_error": "Unexpected error: {error}",
|
||||||
|
"found_email": "Found email: {email}",
|
||||||
|
"email_not_found": "Email not found: {error}",
|
||||||
|
"confirm_prompt": "Are you sure you want to proceed? (y/N): "
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,7 +25,10 @@
|
|||||||
"coming_soon": "即将推出",
|
"coming_soon": "即将推出",
|
||||||
"fixed_soon": "即将修复",
|
"fixed_soon": "即将修复",
|
||||||
"contribute": "贡献项目",
|
"contribute": "贡献项目",
|
||||||
"config": "显示配置"
|
"config": "显示配置",
|
||||||
|
"delete_google_account": "删除 Cursor Google 账号",
|
||||||
|
"continue_prompt": "继续?(y/N): ",
|
||||||
|
"operation_cancelled_by_user": "操作被用户取消"
|
||||||
},
|
},
|
||||||
"languages": {
|
"languages": {
|
||||||
"en": "英语",
|
"en": "英语",
|
||||||
@ -585,7 +588,8 @@
|
|||||||
"authentication_successful_getting_account_info": "认证成功, 获取账户信息...",
|
"authentication_successful_getting_account_info": "认证成功, 获取账户信息...",
|
||||||
"warning_could_not_kill_existing_browser_processes": "警告: 无法杀死现有浏览器进程: {error}",
|
"warning_could_not_kill_existing_browser_processes": "警告: 无法杀死现有浏览器进程: {error}",
|
||||||
"browser_failed_to_start": "浏览器启动失败: {error}",
|
"browser_failed_to_start": "浏览器启动失败: {error}",
|
||||||
"browser_failed": "浏览器启动失败: {error}"
|
"browser_failed": "浏览器启动失败: {error}",
|
||||||
|
"browser_failed_to_start_fallback": "浏览器启动失败: {error}"
|
||||||
},
|
},
|
||||||
"chrome_profile": {
|
"chrome_profile": {
|
||||||
"title": "Chrome配置文件选择",
|
"title": "Chrome配置文件选择",
|
||||||
@ -598,5 +602,49 @@
|
|||||||
"profile_selected": "已选择配置文件:{profile}",
|
"profile_selected": "已选择配置文件:{profile}",
|
||||||
"invalid_selection": "选择无效。请重试",
|
"invalid_selection": "选择无效。请重试",
|
||||||
"warning_chrome_close": "警告:这将关闭所有正在运行的Chrome进程"
|
"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): "
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,7 +25,10 @@
|
|||||||
"coming_soon": "即將推出",
|
"coming_soon": "即將推出",
|
||||||
"fixed_soon": "即將修復",
|
"fixed_soon": "即將修復",
|
||||||
"contribute": "貢獻項目",
|
"contribute": "貢獻項目",
|
||||||
"config": "顯示配置"
|
"config": "顯示配置",
|
||||||
|
"delete_google_account": "刪除 Cursor Google 帳號",
|
||||||
|
"continue_prompt": "繼續?(y/N): ",
|
||||||
|
"operation_cancelled_by_user": "操作被使用者取消"
|
||||||
},
|
},
|
||||||
"languages": {
|
"languages": {
|
||||||
"en": "英文",
|
"en": "英文",
|
||||||
@ -566,7 +569,8 @@
|
|||||||
"authentication_successful_getting_account_info": "認證成功, 獲取帳戶信息...",
|
"authentication_successful_getting_account_info": "認證成功, 獲取帳戶信息...",
|
||||||
"warning_could_not_kill_existing_browser_processes": "警告: 無法殺死現有瀏覽器進程: {error}",
|
"warning_could_not_kill_existing_browser_processes": "警告: 無法殺死現有瀏覽器進程: {error}",
|
||||||
"browser_failed_to_start": "瀏覽器啟動失敗: {error}",
|
"browser_failed_to_start": "瀏覽器啟動失敗: {error}",
|
||||||
"browser_failed": "瀏覽器啟動失敗: {error}"
|
"browser_failed": "瀏覽器啟動失敗: {error}",
|
||||||
|
"browser_failed_to_start_fallback": "瀏覽器啟動失敗: {error}"
|
||||||
},
|
},
|
||||||
"chrome_profile": {
|
"chrome_profile": {
|
||||||
"title": "Chrome配置檔案選擇",
|
"title": "Chrome配置檔案選擇",
|
||||||
@ -579,5 +583,50 @@
|
|||||||
"profile_selected": "已選擇配置檔案:{profile}",
|
"profile_selected": "已選擇配置檔案:{profile}",
|
||||||
"invalid_selection": "選擇無效。請重試",
|
"invalid_selection": "選擇無效。請重試",
|
||||||
"warning_chrome_close": "警告:這將關閉所有正在執行的Chrome程序"
|
"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\""
|
||||||
}
|
}
|
||||||
}
|
}
|
9
main.py
9
main.py
@ -285,7 +285,8 @@ def print_menu():
|
|||||||
10: f"{Fore.GREEN}10{Style.RESET_ALL}. {EMOJI['RESET']} {translator.get('menu.totally_reset')}",
|
10: f"{Fore.GREEN}10{Style.RESET_ALL}. {EMOJI['RESET']} {translator.get('menu.totally_reset')}",
|
||||||
11: f"{Fore.GREEN}11{Style.RESET_ALL}. {EMOJI['CONTRIBUTE']} {translator.get('menu.contribute')}",
|
11: f"{Fore.GREEN}11{Style.RESET_ALL}. {EMOJI['CONTRIBUTE']} {translator.get('menu.contribute')}",
|
||||||
12: f"{Fore.GREEN}12{Style.RESET_ALL}. {EMOJI['SETTINGS']} {translator.get('menu.config')}",
|
12: f"{Fore.GREEN}12{Style.RESET_ALL}. {EMOJI['SETTINGS']} {translator.get('menu.config')}",
|
||||||
13: f"{Fore.GREEN}13{Style.RESET_ALL}. {EMOJI['SETTINGS']} {translator.get('menu.select_chrome_profile')}"
|
13: f"{Fore.GREEN}13{Style.RESET_ALL}. {EMOJI['SETTINGS']} {translator.get('menu.select_chrome_profile')}",
|
||||||
|
14: f"{Fore.GREEN}14{Style.RESET_ALL}. {EMOJI['ERROR']} {translator.get('menu.delete_google_account', fallback='Delete Cursor Google Account')}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Automatically calculate the number of menu items in the left and right columns
|
# Automatically calculate the number of menu items in the left and right columns
|
||||||
@ -557,7 +558,7 @@ def main():
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
choice_num = 13
|
choice_num = 14
|
||||||
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices=f'0-{choice_num}')}: {Style.RESET_ALL}")
|
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices=f'0-{choice_num}')}: {Style.RESET_ALL}")
|
||||||
|
|
||||||
if choice == "0":
|
if choice == "0":
|
||||||
@ -621,6 +622,10 @@ def main():
|
|||||||
if user_data_dir:
|
if user_data_dir:
|
||||||
oauth._select_profile(user_data_dir)
|
oauth._select_profile(user_data_dir)
|
||||||
print_menu()
|
print_menu()
|
||||||
|
elif choice == "14":
|
||||||
|
import delete_cursor_google
|
||||||
|
delete_cursor_google.main(translator)
|
||||||
|
print_menu()
|
||||||
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()
|
||||||
|
@ -97,11 +97,11 @@ class OAuthHandler:
|
|||||||
def setup_browser(self):
|
def setup_browser(self):
|
||||||
"""Setup browser for OAuth flow using selected profile"""
|
"""Setup browser for OAuth flow using selected profile"""
|
||||||
try:
|
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-specific initialization
|
||||||
platform_name = platform.system().lower()
|
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
|
# Get browser paths and user data directory
|
||||||
user_data_dir = self._get_user_data_directory()
|
user_data_dir = self._get_user_data_directory()
|
||||||
@ -117,9 +117,9 @@ class OAuthHandler:
|
|||||||
|
|
||||||
# Show warning about closing Chrome first
|
# 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}")
|
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':
|
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
|
return False
|
||||||
|
|
||||||
# Kill existing browser processes
|
# Kill existing browser processes
|
||||||
@ -127,7 +127,7 @@ class OAuthHandler:
|
|||||||
|
|
||||||
# Let user select a profile
|
# Let user select a profile
|
||||||
if not self._select_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
|
return False
|
||||||
|
|
||||||
# Configure browser options
|
# Configure browser options
|
||||||
@ -138,7 +138,7 @@ class OAuthHandler:
|
|||||||
|
|
||||||
# Verify browser launched successfully
|
# Verify browser launched successfully
|
||||||
if not self.browser:
|
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}")
|
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
|
return True
|
||||||
|
Loading…
x
Reference in New Issue
Block a user