diff --git a/config.py b/config.py index 69d7dbc..f94831b 100644 --- a/config.py +++ b/config.py @@ -38,7 +38,9 @@ def setup_config(translator=None): 'chrome_driver_path': get_default_driver_path('chrome'), 'edge_driver_path': get_default_driver_path('edge'), 'firefox_driver_path': get_default_driver_path('firefox'), - 'brave_driver_path': get_default_driver_path('brave') + 'brave_driver_path': get_default_driver_path('brave'), + 'opera_path': get_default_browser_path('opera'), + 'opera_driver_path': get_default_driver_path('opera') }, 'Chrome': { 'chromepath': get_default_browser_path('chrome') @@ -67,6 +69,11 @@ def setup_config(translator=None): 'enabled_update_check': 'True', 'enabled_force_update': 'False', 'enabled_account_info': 'True' + }, + 'OAuth': { + 'show_selection_alert': False, # 默认不显示选择提示弹窗 + 'timeout': 120, + 'max_attempts': 3 } } diff --git a/locales/en.json b/locales/en.json index 9f37b44..ee5a154 100644 --- a/locales/en.json +++ b/locales/en.json @@ -639,7 +639,8 @@ "profile_selection_error": "Error during profile selection: {error}", "using_configured_browser_path": "Using configured {browser} path: {path}", "browser_not_found_trying_chrome": "Could not find {browser}, trying Chrome instead", - "found_chrome_at": "Found Chrome at: {path}" + "found_chrome_at": "Found Chrome at: {path}", + "found_browser_user_data_dir": "Found {browser} user data directory: {path}" }, "browser_profile": { "title": "Browser Profile Selection", diff --git a/locales/zh_cn.json b/locales/zh_cn.json index 196be99..6f5abfd 100644 --- a/locales/zh_cn.json +++ b/locales/zh_cn.json @@ -617,7 +617,8 @@ "profile_selection_error": "配置文件选择过程中出错: {error}", "using_configured_browser_path": "使用配置的 {browser} 路径: {path}", "browser_not_found_trying_chrome": "未找到 {browser},尝试使用 Chrome 代替", - "found_chrome_at": "找到 Chrome: {path}" + "found_chrome_at": "找到 Chrome: {path}", + "found_browser_user_data_dir": "找到 {browser} 用户数据目录: {path}" }, "browser_profile": { "title": "浏览器配置文件选择", diff --git a/oauth_auth.py b/oauth_auth.py index 5d757ba..1eace60 100644 --- a/oauth_auth.py +++ b/oauth_auth.py @@ -211,7 +211,7 @@ class OAuthHandler: # Verify browser launched successfully if not self.browser: - raise Exception(f"{self.translator.get('oauth.browser_failed_to_start') if self.translator else 'Failed to initialize browser instance'}") + raise Exception(f"{self.translator.get('oauth.browser_failed_to_start', error=str(e)) 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 @@ -255,6 +255,11 @@ class OAuthHandler: 'win': ['firefox.exe'], 'linux': ['firefox'], 'mac': ['Firefox'] + }, + 'opera': { + 'win': ['opera.exe', 'launcher.exe'], + 'linux': ['opera'], + 'mac': ['Opera'] } } @@ -298,27 +303,31 @@ class OAuthHandler: 'chrome': os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Google', 'Chrome', 'User Data'), 'brave': os.path.join(os.environ.get('LOCALAPPDATA', ''), 'BraveSoftware', 'Brave-Browser', 'User Data'), 'edge': os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Microsoft', 'Edge', 'User Data'), - 'firefox': os.path.join(os.environ.get('APPDATA', ''), 'Mozilla', 'Firefox', 'Profiles') + 'firefox': os.path.join(os.environ.get('APPDATA', ''), 'Mozilla', 'Firefox', 'Profiles'), + 'opera': os.path.join(os.environ.get('APPDATA', ''), 'Opera Software', 'Opera Stable') } elif sys.platform == 'darwin': # macOS user_data_dirs = { 'chrome': os.path.expanduser('~/Library/Application Support/Google/Chrome'), 'brave': os.path.expanduser('~/Library/Application Support/BraveSoftware/Brave-Browser'), 'edge': os.path.expanduser('~/Library/Application Support/Microsoft Edge'), - 'firefox': os.path.expanduser('~/Library/Application Support/Firefox/Profiles') + 'firefox': os.path.expanduser('~/Library/Application Support/Firefox/Profiles'), + 'opera': os.path.expanduser('~/Library/Application Support/com.operasoftware.Opera') } else: # Linux user_data_dirs = { 'chrome': os.path.expanduser('~/.config/google-chrome'), 'brave': os.path.expanduser('~/.config/BraveSoftware/Brave-Browser'), 'edge': os.path.expanduser('~/.config/microsoft-edge'), - 'firefox': os.path.expanduser('~/.mozilla/firefox') + 'firefox': os.path.expanduser('~/.mozilla/firefox'), + 'opera': os.path.expanduser('~/.config/opera') } # 获取选定浏览器的用户数据目录,如果找不到则使用 Chrome 的 - user_data_dir = user_data_dirs.get(browser_type, user_data_dirs['chrome']) + user_data_dir = user_data_dirs.get(browser_type) - if os.path.exists(user_data_dir): + if user_data_dir and os.path.exists(user_data_dir): + print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('oauth.found_browser_user_data_dir', browser=browser_type, path=user_data_dir) if self.translator else f'Found {browser_type} user data directory: {user_data_dir}'}{Style.RESET_ALL}") return user_data_dir else: print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('oauth.user_data_dir_not_found', browser=browser_type, path=user_data_dir) if self.translator else f'{browser_type} user data directory not found at {user_data_dir}, will try Chrome instead'}{Style.RESET_ALL}") @@ -374,6 +383,15 @@ class OAuthHandler: os.path.join(os.environ.get('PROGRAMFILES', ''), 'Mozilla Firefox', 'firefox.exe'), os.path.join(os.environ.get('PROGRAMFILES(X86)', ''), 'Mozilla Firefox', 'firefox.exe') ] + elif browser_type == 'opera': + possible_paths = [ + os.path.join(os.environ.get('PROGRAMFILES', ''), 'Opera', 'opera.exe'), + os.path.join(os.environ.get('PROGRAMFILES(X86)', ''), 'Opera', 'opera.exe'), + os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Programs', 'Opera', 'launcher.exe'), + os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Programs', 'Opera', 'opera.exe'), + os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Programs', 'Opera GX', 'launcher.exe'), + os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Programs', 'Opera GX', 'opera.exe') + ] else: # 默认为 Chrome possible_paths = [ os.path.join(os.environ.get('PROGRAMFILES', ''), 'Google', 'Chrome', 'Application', 'chrome.exe'), @@ -515,13 +533,19 @@ class OAuthHandler: # Check if we're on account selection page if "accounts.google.com" in self.browser.url: print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('oauth.please_select_your_google_account_to_continue') if self.translator else 'Please select your Google account to continue...'}{Style.RESET_ALL}") - alert_message = self.translator.get('oauth.please_select_your_google_account_to_continue') if self.translator else 'Please select your Google account to continue with Cursor authentication' - try: - self.browser.run_js(f""" - alert('{alert_message}'); - """) - except: - pass # Alert is optional + + # 获取配置中是否启用 alert 选项 + config = get_config(self.translator) + show_alert = config.getboolean('OAuth', 'show_selection_alert', fallback=False) + + if show_alert: + alert_message = self.translator.get('oauth.please_select_your_google_account_to_continue') if self.translator else 'Please select your Google account to continue with Cursor authentication' + try: + self.browser.run_js(f""" + alert('{alert_message}'); + """) + except: + pass # Alert is optional # Wait for authentication to complete auth_info = self._wait_for_auth() @@ -643,7 +667,7 @@ class OAuthHandler: # Setup browser if not self.setup_browser(): - print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.browser_failed')}{Style.RESET_ALL}") + print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.browser_failed', error=str(e)) if self.translator else 'Browser failed to initialize'}{Style.RESET_ALL}") return False, None # Navigate to auth URL diff --git a/utils.py b/utils.py index fd823cb..8a66dbd 100644 --- a/utils.py +++ b/utils.py @@ -78,6 +78,20 @@ def get_default_browser_path(browser_type='chrome'): return r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" elif browser_type == 'firefox': return r"C:\Program Files\Mozilla Firefox\firefox.exe" + elif browser_type == 'opera': + # 尝试多个可能的 Opera 路径 + opera_paths = [ + r"C:\Program Files\Opera\opera.exe", + r"C:\Program Files (x86)\Opera\opera.exe", + os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Programs', 'Opera', 'launcher.exe'), + os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Programs', 'Opera', 'opera.exe'), + os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Programs', 'Opera GX', 'launcher.exe'), + os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Programs', 'Opera GX', 'opera.exe') + ] + for path in opera_paths: + if os.path.exists(path): + return path + return opera_paths[0] # 返回第一个路径,即使它不存在 elif browser_type == 'brave': # Brave 浏览器的默认安装路径 paths = [ @@ -99,7 +113,9 @@ def get_default_browser_path(browser_type='chrome'): return "/Applications/Firefox.app/Contents/MacOS/firefox" elif browser_type == 'brave': return "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser" - + elif browser_type == 'opera': + return "/Applications/Opera.app/Contents/MacOS/Opera" + else: # Linux if browser_type == 'chrome': # 尝试多种可能的名称 @@ -117,6 +133,8 @@ def get_default_browser_path(browser_type='chrome'): return "/usr/bin/microsoft-edge" elif browser_type == 'firefox': return "/usr/bin/firefox" + elif browser_type == 'opera': + return "/usr/bin/opera" elif browser_type == 'brave': # 尝试常见的 Brave 路径 brave_names = ["brave", "brave-browser"]