mirror of
https://github.com/yeongpin/cursor-free-vip.git
synced 2025-08-03 04:57:36 +08:00
refactor: Internationalize and Clean Up Code Comments
- Translate Chinese comments to English across multiple files - Improve code readability by using consistent, clear comments - Remove redundant comments and simplify language-specific annotations - Maintain existing code structure while enhancing internationalization
This commit is contained in:
parent
ff358588bb
commit
b98f094407
@ -13,7 +13,7 @@ def setup_config(translator=None):
|
|||||||
|
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
# 默認配置
|
# Default configuration
|
||||||
default_config = {
|
default_config = {
|
||||||
'Chrome': {
|
'Chrome': {
|
||||||
'chromepath': get_default_chrome_path()
|
'chromepath': get_default_chrome_path()
|
||||||
@ -40,7 +40,7 @@ def setup_config(translator=None):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# 添加系統特定路徑配置
|
# Add system-specific path configuration
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
appdata = os.getenv("APPDATA")
|
appdata = os.getenv("APPDATA")
|
||||||
localappdata = os.getenv("LOCALAPPDATA", "")
|
localappdata = os.getenv("LOCALAPPDATA", "")
|
||||||
@ -71,7 +71,7 @@ def setup_config(translator=None):
|
|||||||
'updater_path': os.path.expanduser("~/.config/cursor-updater")
|
'updater_path': os.path.expanduser("~/.config/cursor-updater")
|
||||||
}
|
}
|
||||||
|
|
||||||
# 讀取現有配置並合併
|
# Read existing configuration and merge
|
||||||
if os.path.exists(config_file):
|
if os.path.exists(config_file):
|
||||||
config.read(config_file, encoding='utf-8')
|
config.read(config_file, encoding='utf-8')
|
||||||
config_modified = False
|
config_modified = False
|
||||||
|
@ -4,10 +4,10 @@ import sys
|
|||||||
from colorama import Fore, Style, init
|
from colorama import Fore, Style, init
|
||||||
from config import get_config
|
from config import get_config
|
||||||
|
|
||||||
# 初始化colorama
|
# Initialize colorama
|
||||||
init()
|
init()
|
||||||
|
|
||||||
# 定义emoji和颜色常量
|
# Define emoji and color constants
|
||||||
EMOJI = {
|
EMOJI = {
|
||||||
'DB': '🗄️',
|
'DB': '🗄️',
|
||||||
'UPDATE': '🔄',
|
'UPDATE': '🔄',
|
||||||
@ -23,13 +23,13 @@ class CursorAuth:
|
|||||||
def __init__(self, translator=None):
|
def __init__(self, translator=None):
|
||||||
self.translator = translator
|
self.translator = translator
|
||||||
|
|
||||||
# 获取配置
|
# Get configuration
|
||||||
config = get_config(translator)
|
config = get_config(translator)
|
||||||
if not config:
|
if not config:
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.config_error') if self.translator else 'Failed to load configuration'}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.config_error') if self.translator else 'Failed to load configuration'}{Style.RESET_ALL}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# 根据操作系统获取路径
|
# Get path based on operating system
|
||||||
try:
|
try:
|
||||||
if sys.platform == "win32": # Windows
|
if sys.platform == "win32": # Windows
|
||||||
if not config.has_section('WindowsPaths'):
|
if not config.has_section('WindowsPaths'):
|
||||||
@ -50,7 +50,7 @@ class CursorAuth:
|
|||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.unsupported_platform') if self.translator else 'Unsupported platform'}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.unsupported_platform') if self.translator else 'Unsupported platform'}{Style.RESET_ALL}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# 验证路径是否存在
|
# Verify if the path exists
|
||||||
if not os.path.exists(os.path.dirname(self.db_path)):
|
if not os.path.exists(os.path.dirname(self.db_path)):
|
||||||
raise FileNotFoundError(f"Database directory not found: {os.path.dirname(self.db_path)}")
|
raise FileNotFoundError(f"Database directory not found: {os.path.dirname(self.db_path)}")
|
||||||
|
|
||||||
@ -58,12 +58,12 @@ class CursorAuth:
|
|||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.path_error', error=str(e)) if self.translator else f'Error getting database path: {str(e)}'}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.path_error', error=str(e)) if self.translator else f'Error getting database path: {str(e)}'}{Style.RESET_ALL}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# 检查数据库文件是否存在
|
# Check if the database file exists
|
||||||
if not os.path.exists(self.db_path):
|
if not os.path.exists(self.db_path):
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.db_not_found', path=self.db_path)}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.db_not_found', path=self.db_path)}{Style.RESET_ALL}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# 检查文件权限
|
# Check file permissions
|
||||||
if not os.access(self.db_path, os.R_OK | os.W_OK):
|
if not os.access(self.db_path, os.R_OK | os.W_OK):
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.db_permission_error')}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.db_permission_error')}{Style.RESET_ALL}")
|
||||||
return
|
return
|
||||||
@ -78,12 +78,12 @@ class CursorAuth:
|
|||||||
def update_auth(self, email=None, access_token=None, refresh_token=None):
|
def update_auth(self, email=None, access_token=None, refresh_token=None):
|
||||||
conn = None
|
conn = None
|
||||||
try:
|
try:
|
||||||
# 确保目录存在并设置正确权限
|
# Ensure the directory exists and set the correct permissions
|
||||||
db_dir = os.path.dirname(self.db_path)
|
db_dir = os.path.dirname(self.db_path)
|
||||||
if not os.path.exists(db_dir):
|
if not os.path.exists(db_dir):
|
||||||
os.makedirs(db_dir, mode=0o755, exist_ok=True)
|
os.makedirs(db_dir, mode=0o755, exist_ok=True)
|
||||||
|
|
||||||
# 如果数据库文件不存在,创建一个新的
|
# If the database file does not exist, create a new one
|
||||||
if not os.path.exists(self.db_path):
|
if not os.path.exists(self.db_path):
|
||||||
conn = sqlite3.connect(self.db_path)
|
conn = sqlite3.connect(self.db_path)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
@ -98,17 +98,17 @@ class CursorAuth:
|
|||||||
os.chmod(self.db_path, 0o644)
|
os.chmod(self.db_path, 0o644)
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
# 重新连接数据库
|
# Reconnect to the database
|
||||||
conn = sqlite3.connect(self.db_path)
|
conn = sqlite3.connect(self.db_path)
|
||||||
print(f"{EMOJI['INFO']} {Fore.GREEN} {self.translator.get('auth.connected_to_database')}{Style.RESET_ALL}")
|
print(f"{EMOJI['INFO']} {Fore.GREEN} {self.translator.get('auth.connected_to_database')}{Style.RESET_ALL}")
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
# 增加超时和其他优化设置
|
# Add timeout and other optimization settings
|
||||||
conn.execute("PRAGMA busy_timeout = 5000")
|
conn.execute("PRAGMA busy_timeout = 5000")
|
||||||
conn.execute("PRAGMA journal_mode = WAL")
|
conn.execute("PRAGMA journal_mode = WAL")
|
||||||
conn.execute("PRAGMA synchronous = NORMAL")
|
conn.execute("PRAGMA synchronous = NORMAL")
|
||||||
|
|
||||||
# 设置要更新的键值对
|
# Set the key-value pairs to update
|
||||||
updates = []
|
updates = []
|
||||||
|
|
||||||
updates.append(("cursorAuth/cachedSignUpType", "Auth_0"))
|
updates.append(("cursorAuth/cachedSignUpType", "Auth_0"))
|
||||||
@ -121,11 +121,11 @@ class CursorAuth:
|
|||||||
updates.append(("cursorAuth/refreshToken", refresh_token))
|
updates.append(("cursorAuth/refreshToken", refresh_token))
|
||||||
|
|
||||||
|
|
||||||
# 使用事务来确保数据完整性
|
# Use transactions to ensure data integrity
|
||||||
cursor.execute("BEGIN TRANSACTION")
|
cursor.execute("BEGIN TRANSACTION")
|
||||||
try:
|
try:
|
||||||
for key, value in updates:
|
for key, value in updates:
|
||||||
# 检查键是否存在
|
# Check if the key exists
|
||||||
cursor.execute("SELECT COUNT(*) FROM ItemTable WHERE key = ?", (key,))
|
cursor.execute("SELECT COUNT(*) FROM ItemTable WHERE key = ?", (key,))
|
||||||
if cursor.fetchone()[0] == 0:
|
if cursor.fetchone()[0] == 0:
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
|
@ -42,7 +42,7 @@ class CursorRegistration:
|
|||||||
self.signup_tab = None
|
self.signup_tab = None
|
||||||
self.email_tab = None
|
self.email_tab = None
|
||||||
|
|
||||||
# 账号信息
|
# Account information
|
||||||
self.password = self._generate_password()
|
self.password = self._generate_password()
|
||||||
# Generate first name and last name separately
|
# Generate first name and last name separately
|
||||||
first_name = random.choice([
|
first_name = random.choice([
|
||||||
@ -196,17 +196,17 @@ class CursorRegistration:
|
|||||||
def _save_account_info(self, token, total_usage):
|
def _save_account_info(self, token, total_usage):
|
||||||
"""Save Account Information to File"""
|
"""Save Account Information to File"""
|
||||||
try:
|
try:
|
||||||
# 先更新认证信息
|
# Update authentication information first
|
||||||
print(f"{Fore.CYAN}{EMOJI['KEY']} {self.translator.get('register.update_cursor_auth_info')}...{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['KEY']} {self.translator.get('register.update_cursor_auth_info')}...{Style.RESET_ALL}")
|
||||||
if self.update_cursor_auth(email=self.email_address, access_token=token, refresh_token=token):
|
if self.update_cursor_auth(email=self.email_address, access_token=token, refresh_token=token):
|
||||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('register.cursor_auth_info_updated')}...{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('register.cursor_auth_info_updated')}...{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.cursor_auth_info_update_failed')}...{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.cursor_auth_info_update_failed')}...{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 重置机器ID
|
# Reset machine ID
|
||||||
print(f"{Fore.CYAN}{EMOJI['UPDATE']} {self.translator.get('register.reset_machine_id')}...{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['UPDATE']} {self.translator.get('register.reset_machine_id')}...{Style.RESET_ALL}")
|
||||||
resetter = MachineIDResetter(self.translator) # 创建实例时传入translator
|
resetter = MachineIDResetter(self.translator) # Pass translator when creating instance
|
||||||
if not resetter.reset_machine_ids(): # 直接调用reset_machine_ids方法
|
if not resetter.reset_machine_ids(): # Call reset_machine_ids method directly
|
||||||
raise Exception("Failed to reset machine ID")
|
raise Exception("Failed to reset machine ID")
|
||||||
|
|
||||||
# Save account information to file
|
# Save account information to file
|
||||||
|
@ -26,7 +26,7 @@ class AutoUpdateDisabler:
|
|||||||
self.translator = translator
|
self.translator = translator
|
||||||
self.system = platform.system()
|
self.system = platform.system()
|
||||||
|
|
||||||
# 从配置文件获取路径
|
# Get path from configuration file
|
||||||
config = get_config(translator)
|
config = get_config(translator)
|
||||||
if config:
|
if config:
|
||||||
if self.system == "Windows":
|
if self.system == "Windows":
|
||||||
@ -36,7 +36,7 @@ class AutoUpdateDisabler:
|
|||||||
elif self.system == "Linux":
|
elif self.system == "Linux":
|
||||||
self.updater_path = config.get('LinuxPaths', 'updater_path', fallback=os.path.expanduser("~/.config/cursor-updater"))
|
self.updater_path = config.get('LinuxPaths', 'updater_path', fallback=os.path.expanduser("~/.config/cursor-updater"))
|
||||||
else:
|
else:
|
||||||
# 如果配置加载失败,使用默认路径
|
# If configuration loading fails, use default paths
|
||||||
self.updater_paths = {
|
self.updater_paths = {
|
||||||
"Windows": os.path.join(os.getenv("LOCALAPPDATA", ""), "cursor-updater"),
|
"Windows": os.path.join(os.getenv("LOCALAPPDATA", ""), "cursor-updater"),
|
||||||
"Darwin": os.path.expanduser("~/Library/Application Support/cursor-updater"),
|
"Darwin": os.path.expanduser("~/Library/Application Support/cursor-updater"),
|
||||||
|
18
main.py
18
main.py
@ -11,16 +11,16 @@ import requests
|
|||||||
import subprocess
|
import subprocess
|
||||||
from config import get_config
|
from config import get_config
|
||||||
|
|
||||||
# 只在 Windows 系统上导入 windll
|
# Only import windll on Windows systems
|
||||||
if platform.system() == 'Windows':
|
if platform.system() == 'Windows':
|
||||||
import ctypes
|
import ctypes
|
||||||
# 只在 Windows 上导入 windll
|
# 只在 Windows 上导入 windll
|
||||||
from ctypes import windll
|
from ctypes import windll
|
||||||
|
|
||||||
# 初始化colorama
|
# Initialize colorama
|
||||||
init()
|
init()
|
||||||
|
|
||||||
# 定义emoji和颜色常量
|
# Define emoji and color constants
|
||||||
EMOJI = {
|
EMOJI = {
|
||||||
"FILE": "📄",
|
"FILE": "📄",
|
||||||
"BACKUP": "💾",
|
"BACKUP": "💾",
|
||||||
@ -37,7 +37,7 @@ EMOJI = {
|
|||||||
class Translator:
|
class Translator:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.translations = {}
|
self.translations = {}
|
||||||
self.current_language = self.detect_system_language() # 使用正确的方法名
|
self.current_language = self.detect_system_language() # Use correct method name
|
||||||
self.fallback_language = 'en' # Fallback language if translation is missing
|
self.fallback_language = 'en' # Fallback language if translation is missing
|
||||||
self.load_translations()
|
self.load_translations()
|
||||||
|
|
||||||
@ -58,11 +58,11 @@ class Translator:
|
|||||||
def _detect_windows_language(self):
|
def _detect_windows_language(self):
|
||||||
"""Detect language on Windows systems"""
|
"""Detect language on Windows systems"""
|
||||||
try:
|
try:
|
||||||
# 确保我们在 Windows 上
|
# Ensure we are on Windows
|
||||||
if platform.system() != 'Windows':
|
if platform.system() != 'Windows':
|
||||||
return 'en'
|
return 'en'
|
||||||
|
|
||||||
# 获取键盘布局
|
# Get keyboard layout
|
||||||
user32 = ctypes.windll.user32
|
user32 = ctypes.windll.user32
|
||||||
hwnd = user32.GetForegroundWindow()
|
hwnd = user32.GetForegroundWindow()
|
||||||
threadid = user32.GetWindowThreadProcessId(hwnd, 0)
|
threadid = user32.GetWindowThreadProcessId(hwnd, 0)
|
||||||
@ -168,7 +168,7 @@ class Translator:
|
|||||||
"""Get list of available languages"""
|
"""Get list of available languages"""
|
||||||
return list(self.translations.keys())
|
return list(self.translations.keys())
|
||||||
|
|
||||||
# 创建翻译器实例
|
# Create translator instance
|
||||||
translator = Translator()
|
translator = Translator()
|
||||||
|
|
||||||
def print_menu():
|
def print_menu():
|
||||||
@ -239,7 +239,7 @@ def check_latest_version():
|
|||||||
if latest_version != version:
|
if latest_version != version:
|
||||||
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.new_version_available', current=version, latest=latest_version)}{Style.RESET_ALL}")
|
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.new_version_available', current=version, latest=latest_version)}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 詢問用戶是否要更新
|
# Ask user if they want to update
|
||||||
while True:
|
while True:
|
||||||
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('updater.update_confirm', choices='Y/n')}: {Style.RESET_ALL}").lower()
|
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('updater.update_confirm', choices='Y/n')}: {Style.RESET_ALL}").lower()
|
||||||
if choice in ['', 'y', 'yes']:
|
if choice in ['', 'y', 'yes']:
|
||||||
@ -298,7 +298,7 @@ def check_latest_version():
|
|||||||
def main():
|
def main():
|
||||||
print_logo()
|
print_logo()
|
||||||
|
|
||||||
# 初始化配置
|
# Initialize configuration
|
||||||
config = get_config(translator)
|
config = get_config(translator)
|
||||||
if not config:
|
if not config:
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.config_init_failed')}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.config_init_failed')}{Style.RESET_ALL}")
|
||||||
|
202
new_signup.py
202
new_signup.py
@ -9,12 +9,12 @@ from pathlib import Path
|
|||||||
import sys
|
import sys
|
||||||
from config import get_config
|
from config import get_config
|
||||||
|
|
||||||
# 在文件开头添加全局变量
|
# Add global variable at the beginning of the file
|
||||||
_translator = None
|
_translator = None
|
||||||
|
|
||||||
def cleanup_chrome_processes(translator=None):
|
def cleanup_chrome_processes(translator=None):
|
||||||
"""清理所有Chrome相关进程"""
|
"""Clean all Chrome related processes"""
|
||||||
print("\n正在清理Chrome进程...")
|
print("\nCleaning Chrome processes...")
|
||||||
try:
|
try:
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
os.system('taskkill /F /IM chrome.exe /T 2>nul')
|
os.system('taskkill /F /IM chrome.exe /T 2>nul')
|
||||||
@ -29,7 +29,7 @@ def cleanup_chrome_processes(translator=None):
|
|||||||
print(f"清理进程时出错: {e}")
|
print(f"清理进程时出错: {e}")
|
||||||
|
|
||||||
def signal_handler(signum, frame):
|
def signal_handler(signum, frame):
|
||||||
"""处理Ctrl+C信号"""
|
"""Handle Ctrl+C signal"""
|
||||||
global _translator
|
global _translator
|
||||||
if _translator:
|
if _translator:
|
||||||
print(f"{Fore.CYAN}{_translator.get('register.exit_signal')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{_translator.get('register.exit_signal')}{Style.RESET_ALL}")
|
||||||
@ -39,45 +39,45 @@ def signal_handler(signum, frame):
|
|||||||
os._exit(0)
|
os._exit(0)
|
||||||
|
|
||||||
def simulate_human_input(page, url, config, translator=None):
|
def simulate_human_input(page, url, config, translator=None):
|
||||||
"""访问网址"""
|
"""Visit URL"""
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}🚀 {translator.get('register.visiting_url')}: {url}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🚀 {translator.get('register.visiting_url')}: {url}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 先访问空白页面
|
# First visit blank page
|
||||||
page.get('about:blank')
|
page.get('about:blank')
|
||||||
time.sleep(get_random_wait_time(config, 'page_load_wait'))
|
time.sleep(get_random_wait_time(config, 'page_load_wait'))
|
||||||
|
|
||||||
# 访问目标页面
|
# Visit target page
|
||||||
page.get(url)
|
page.get(url)
|
||||||
time.sleep(get_random_wait_time(config, 'page_load_wait'))
|
time.sleep(get_random_wait_time(config, 'page_load_wait'))
|
||||||
|
|
||||||
def fill_signup_form(page, first_name, last_name, email, config, translator=None):
|
def fill_signup_form(page, first_name, last_name, email, config, translator=None):
|
||||||
"""填写注册表单"""
|
"""Fill signup form"""
|
||||||
try:
|
try:
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}📧 {translator.get('register.filling_form')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}📧 {translator.get('register.filling_form')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print("\n正在填写注册表单...")
|
print("\n正在填写注册表单...")
|
||||||
|
|
||||||
# 填写名字
|
# Fill first name
|
||||||
first_name_input = page.ele("@name=first_name")
|
first_name_input = page.ele("@name=first_name")
|
||||||
if first_name_input:
|
if first_name_input:
|
||||||
first_name_input.input(first_name)
|
first_name_input.input(first_name)
|
||||||
time.sleep(get_random_wait_time(config, 'input_wait'))
|
time.sleep(get_random_wait_time(config, 'input_wait'))
|
||||||
|
|
||||||
# 填写姓氏
|
# Fill last name
|
||||||
last_name_input = page.ele("@name=last_name")
|
last_name_input = page.ele("@name=last_name")
|
||||||
if last_name_input:
|
if last_name_input:
|
||||||
last_name_input.input(last_name)
|
last_name_input.input(last_name)
|
||||||
time.sleep(get_random_wait_time(config, 'input_wait'))
|
time.sleep(get_random_wait_time(config, 'input_wait'))
|
||||||
|
|
||||||
# 填写邮箱
|
# Fill email
|
||||||
email_input = page.ele("@name=email")
|
email_input = page.ele("@name=email")
|
||||||
if email_input:
|
if email_input:
|
||||||
email_input.input(email)
|
email_input.input(email)
|
||||||
time.sleep(get_random_wait_time(config, 'input_wait'))
|
time.sleep(get_random_wait_time(config, 'input_wait'))
|
||||||
|
|
||||||
# 点击提交按钮
|
# Click submit button
|
||||||
submit_button = page.ele("@type=submit")
|
submit_button = page.ele("@type=submit")
|
||||||
if submit_button:
|
if submit_button:
|
||||||
submit_button.click()
|
submit_button.click()
|
||||||
@ -86,14 +86,14 @@ def fill_signup_form(page, first_name, last_name, email, config, translator=None
|
|||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.GREEN}✅ {translator.get('register.form_success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {translator.get('register.form_success')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print("表单填写完成")
|
print("Form filled successfully")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.RED}❌ {translator.get('register.form_error', error=str(e))}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {translator.get('register.form_error', error=str(e))}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"填写表单时出错: {e}")
|
print(f"Error filling form: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_default_chrome_path():
|
def get_default_chrome_path():
|
||||||
@ -143,7 +143,7 @@ def get_random_wait_time(config, timing_type='page_load_wait'):
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
if not config.has_section('Timing'):
|
if not config.has_section('Timing'):
|
||||||
return random.uniform(0.1, 0.8) # 默认值
|
return random.uniform(0.1, 0.8) # Default value
|
||||||
|
|
||||||
if timing_type == 'random':
|
if timing_type == 'random':
|
||||||
min_time = float(config.get('Timing', 'min_random_time', fallback='0.1'))
|
min_time = float(config.get('Timing', 'min_random_time', fallback='0.1'))
|
||||||
@ -152,20 +152,20 @@ def get_random_wait_time(config, timing_type='page_load_wait'):
|
|||||||
|
|
||||||
time_value = config.get('Timing', timing_type, fallback='0.1-0.8')
|
time_value = config.get('Timing', timing_type, fallback='0.1-0.8')
|
||||||
|
|
||||||
# 检查是否为固定时间值
|
# Check if it's a fixed time value
|
||||||
if '-' not in time_value and ',' not in time_value:
|
if '-' not in time_value and ',' not in time_value:
|
||||||
return float(time_value) # 返回固定时间
|
return float(time_value) # Return fixed time
|
||||||
|
|
||||||
# 处理范围时间
|
# Process range time
|
||||||
min_time, max_time = map(float, time_value.split('-' if '-' in time_value else ','))
|
min_time, max_time = map(float, time_value.split('-' if '-' in time_value else ','))
|
||||||
return random.uniform(min_time, max_time)
|
return random.uniform(min_time, max_time)
|
||||||
except:
|
except:
|
||||||
return random.uniform(0.1, 0.8) # 出错时返回默认值
|
return random.uniform(0.1, 0.8) # Return default value when error
|
||||||
|
|
||||||
def setup_driver(translator=None):
|
def setup_driver(translator=None):
|
||||||
"""Setup browser driver"""
|
"""Setup browser driver"""
|
||||||
try:
|
try:
|
||||||
# 获取配置
|
# Get config
|
||||||
config = get_config(translator)
|
config = get_config(translator)
|
||||||
|
|
||||||
# Get Chrome path
|
# Get Chrome path
|
||||||
@ -185,17 +185,17 @@ def setup_driver(translator=None):
|
|||||||
# Use incognito mode
|
# Use incognito mode
|
||||||
co.set_argument("--incognito")
|
co.set_argument("--incognito")
|
||||||
|
|
||||||
# 设置随机端口
|
# Set random port
|
||||||
co.set_argument("--no-sandbox")
|
co.set_argument("--no-sandbox")
|
||||||
|
|
||||||
# 设置随机端口
|
# Set random port
|
||||||
co.auto_port()
|
co.auto_port()
|
||||||
|
|
||||||
# 使用有头模式(一定要设置为False,模拟人类操作)
|
# Use headless mode (must be set to False, simulate human operation)
|
||||||
co.headless(False)
|
co.headless(False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 加载插件
|
# Load extension
|
||||||
extension_path = os.path.join(os.getcwd(), "turnstilePatch")
|
extension_path = os.path.join(os.getcwd(), "turnstilePatch")
|
||||||
if os.path.exists(extension_path):
|
if os.path.exists(extension_path):
|
||||||
co.set_argument("--allow-extensions-in-incognito")
|
co.set_argument("--allow-extensions-in-incognito")
|
||||||
@ -204,12 +204,12 @@ def setup_driver(translator=None):
|
|||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.RED}❌ {translator.get('register.extension_load_error', error=str(e))}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {translator.get('register.extension_load_error', error=str(e))}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"加载插件失败: {e}")
|
print(f"Error loading extension: {e}")
|
||||||
|
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}🚀 {translator.get('register.starting_browser')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🚀 {translator.get('register.starting_browser')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print("正在启动浏览器...")
|
print("Starting browser...")
|
||||||
|
|
||||||
page = ChromiumPage(co)
|
page = ChromiumPage(co)
|
||||||
return config, page
|
return config, page
|
||||||
@ -218,26 +218,26 @@ def setup_driver(translator=None):
|
|||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.RED}❌ {translator.get('register.browser_setup_error', error=str(e))}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {translator.get('register.browser_setup_error', error=str(e))}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"设置浏览器时出错: {e}")
|
print(f"Error setting up browser: {e}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def handle_turnstile(page, config, translator=None):
|
def handle_turnstile(page, config, translator=None):
|
||||||
"""处理 Turnstile 验证"""
|
"""Handle Turnstile verification"""
|
||||||
try:
|
try:
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}🔄 {translator.get('register.handling_turnstile')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔄 {translator.get('register.handling_turnstile')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print("\n正在处理 Turnstile 验证...")
|
print("\nHandling Turnstile verification...")
|
||||||
|
|
||||||
# from config
|
# from config
|
||||||
turnstile_time = float(config.get('Turnstile', 'handle_turnstile_time', fallback='2'))
|
turnstile_time = float(config.get('Turnstile', 'handle_turnstile_time', fallback='2'))
|
||||||
random_time_str = config.get('Turnstile', 'handle_turnstile_random_time', fallback='1-3')
|
random_time_str = config.get('Turnstile', 'handle_turnstile_random_time', fallback='1-3')
|
||||||
|
|
||||||
# 解析随机时间范围
|
# Parse random time range
|
||||||
try:
|
try:
|
||||||
min_time, max_time = map(float, random_time_str.split('-'))
|
min_time, max_time = map(float, random_time_str.split('-'))
|
||||||
except:
|
except:
|
||||||
min_time, max_time = 1, 3 # 默认值
|
min_time, max_time = 1, 3 # Default value
|
||||||
|
|
||||||
max_retries = 2
|
max_retries = 2
|
||||||
retry_count = 0
|
retry_count = 0
|
||||||
@ -247,14 +247,14 @@ def handle_turnstile(page, config, translator=None):
|
|||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}🔄 {translator.get('register.retry_verification', attempt=retry_count)}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔄 {translator.get('register.retry_verification', attempt=retry_count)}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"第 {retry_count} 次尝试验证...")
|
print(f"Attempt {retry_count} of verification...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 尝试重置 turnstile
|
# Try to reset turnstile
|
||||||
page.run_js("try { turnstile.reset() } catch(e) { }")
|
page.run_js("try { turnstile.reset() } catch(e) { }")
|
||||||
time.sleep(turnstile_time) # from config
|
time.sleep(turnstile_time) # from config
|
||||||
|
|
||||||
# 定位验证框元素
|
# Locate verification box element
|
||||||
challenge_check = (
|
challenge_check = (
|
||||||
page.ele("@id=cf-turnstile", timeout=2)
|
page.ele("@id=cf-turnstile", timeout=2)
|
||||||
.child()
|
.child()
|
||||||
@ -267,7 +267,7 @@ def handle_turnstile(page, config, translator=None):
|
|||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}🔄 {translator.get('register.detect_turnstile')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔄 {translator.get('register.detect_turnstile')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print("检测到验证框...")
|
print("Detected verification box...")
|
||||||
|
|
||||||
# from config
|
# from config
|
||||||
time.sleep(random.uniform(min_time, max_time))
|
time.sleep(random.uniform(min_time, max_time))
|
||||||
@ -279,21 +279,21 @@ def handle_turnstile(page, config, translator=None):
|
|||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print("验证通过!")
|
print("Verification successful!")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.RED}❌ {translator.get('register.verification_failed')}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {translator.get('register.verification_failed')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"验证尝试失败: {e}")
|
print(f"Verification attempt failed: {e}")
|
||||||
|
|
||||||
# 检查是否已经验证成功
|
# Check if verification has been successful
|
||||||
if check_verification_success(page, translator):
|
if check_verification_success(page, translator):
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print("验证通过!")
|
print("Verification successful!")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
time.sleep(random.uniform(min_time, max_time))
|
time.sleep(random.uniform(min_time, max_time))
|
||||||
@ -301,27 +301,27 @@ def handle_turnstile(page, config, translator=None):
|
|||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.RED}❌ {translator.get('register.verification_failed')}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {translator.get('register.verification_failed')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print("超出最大重试次数")
|
print("Exceeded maximum retry attempts")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.RED}❌ {translator.get('register.verification_error', error=str(e))}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {translator.get('register.verification_error', error=str(e))}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"验证过程出错: {e}")
|
print(f"Error in verification process: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def check_verification_success(page, translator=None):
|
def check_verification_success(page, translator=None):
|
||||||
"""检查验证是否成功"""
|
"""Check if verification is successful"""
|
||||||
try:
|
try:
|
||||||
# 检查是否存在后续表单元素,这表示验证已通过
|
# Check if there is a subsequent form element, indicating verification has passed
|
||||||
if (page.ele("@name=password", timeout=0.5) or
|
if (page.ele("@name=password", timeout=0.5) or
|
||||||
page.ele("@name=email", timeout=0.5) or
|
page.ele("@name=email", timeout=0.5) or
|
||||||
page.ele("@data-index=0", timeout=0.5) or
|
page.ele("@data-index=0", timeout=0.5) or
|
||||||
page.ele("Account Settings", timeout=0.5)):
|
page.ele("Account Settings", timeout=0.5)):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# 检查是否出现错误消息
|
# Check if there is an error message
|
||||||
error_messages = [
|
error_messages = [
|
||||||
'xpath://div[contains(text(), "Can\'t verify the user is human")]',
|
'xpath://div[contains(text(), "Can\'t verify the user is human")]',
|
||||||
'xpath://div[contains(text(), "Error: 600010")]',
|
'xpath://div[contains(text(), "Error: 600010")]',
|
||||||
@ -337,49 +337,49 @@ def check_verification_success(page, translator=None):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def generate_password(length=12):
|
def generate_password(length=12):
|
||||||
"""生成随机密码"""
|
"""Generate random password"""
|
||||||
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
|
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"
|
||||||
return ''.join(random.choices(chars, k=length))
|
return ''.join(random.choices(chars, k=length))
|
||||||
|
|
||||||
def fill_password(page, password: str, config, translator=None):
|
def fill_password(page, password: str, config, translator=None):
|
||||||
"""
|
"""
|
||||||
填写密码表单
|
Fill password form
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
print(f"{Fore.CYAN}🔑 {translator.get('register.setting_password') if translator else '设置密码'}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔑 {translator.get('register.setting_password') if translator else 'Setting password'}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 填写密码
|
# Fill password
|
||||||
password_input = page.ele("@name=password")
|
password_input = page.ele("@name=password")
|
||||||
print(f"{Fore.CYAN}🔑 {translator.get('register.setting_on_password')}: {password}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔑 {translator.get('register.setting_on_password')}: {password}{Style.RESET_ALL}")
|
||||||
if password_input:
|
if password_input:
|
||||||
password_input.input(password)
|
password_input.input(password)
|
||||||
|
|
||||||
# 点击提交按钮
|
# Click submit button
|
||||||
submit_button = page.ele("@type=submit")
|
submit_button = page.ele("@type=submit")
|
||||||
if submit_button:
|
if submit_button:
|
||||||
submit_button.click()
|
submit_button.click()
|
||||||
time.sleep(get_random_wait_time(config, 'submit_wait'))
|
time.sleep(get_random_wait_time(config, 'submit_wait'))
|
||||||
|
|
||||||
print(f"{Fore.GREEN}✅ {translator.get('register.password_submitted') if translator else '密码已提交'}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {translator.get('register.password_submitted') if translator else 'Password submitted'}{Style.RESET_ALL}")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{Fore.RED}❌ {translator.get('register.password_error', error=str(e)) if translator else f'设置密码时出错: {str(e)}'}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {translator.get('register.password_error', error=str(e)) if translator else f'Error setting password: {str(e)}'}{Style.RESET_ALL}")
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def handle_verification_code(browser_tab, email_tab, controller, config, translator=None):
|
def handle_verification_code(browser_tab, email_tab, controller, config, translator=None):
|
||||||
"""处理验证码"""
|
"""Handle verification code"""
|
||||||
try:
|
try:
|
||||||
if translator:
|
if translator:
|
||||||
print(f"\n{Fore.CYAN}🔄 {translator.get('register.waiting_for_verification_code')}{Style.RESET_ALL}")
|
print(f"\n{Fore.CYAN}🔄 {translator.get('register.waiting_for_verification_code')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 检查是否使用手动输入验证码
|
# Check if using manual input verification code
|
||||||
if hasattr(controller, 'get_verification_code') and email_tab is None: # 手动模式
|
if hasattr(controller, 'get_verification_code') and email_tab is None: # Manual mode
|
||||||
verification_code = controller.get_verification_code()
|
verification_code = controller.get_verification_code()
|
||||||
if verification_code:
|
if verification_code:
|
||||||
# 在注册页面填写验证码
|
# Fill verification code in registration page
|
||||||
for i, digit in enumerate(verification_code):
|
for i, digit in enumerate(verification_code):
|
||||||
browser_tab.ele(f"@data-index={i}").input(digit)
|
browser_tab.ele(f"@data-index={i}").input(digit)
|
||||||
time.sleep(get_random_wait_time(config, 'verification_code_input'))
|
time.sleep(get_random_wait_time(config, 'verification_code_input'))
|
||||||
@ -387,13 +387,13 @@ def handle_verification_code(browser_tab, email_tab, controller, config, transla
|
|||||||
print(f"{translator.get('register.verification_success')}")
|
print(f"{translator.get('register.verification_success')}")
|
||||||
time.sleep(get_random_wait_time(config, 'verification_success_wait'))
|
time.sleep(get_random_wait_time(config, 'verification_success_wait'))
|
||||||
|
|
||||||
# 处理最后一次 Turnstile 验证
|
# Handle last Turnstile verification
|
||||||
if handle_turnstile(browser_tab, config, translator):
|
if handle_turnstile(browser_tab, config, translator):
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
||||||
time.sleep(get_random_wait_time(config, 'verification_retry_wait'))
|
time.sleep(get_random_wait_time(config, 'verification_retry_wait'))
|
||||||
|
|
||||||
# 访问设置页面
|
# Visit settings page
|
||||||
print(f"{Fore.CYAN}🔑 {translator.get('register.visiting_url')}: https://www.cursor.com/settings{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔑 {translator.get('register.visiting_url')}: https://www.cursor.com/settings{Style.RESET_ALL}")
|
||||||
browser_tab.get("https://www.cursor.com/settings")
|
browser_tab.get("https://www.cursor.com/settings")
|
||||||
time.sleep(get_random_wait_time(config, 'settings_page_load_wait'))
|
time.sleep(get_random_wait_time(config, 'settings_page_load_wait'))
|
||||||
@ -401,20 +401,20 @@ def handle_verification_code(browser_tab, email_tab, controller, config, transla
|
|||||||
|
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
# 自动获取验证码逻辑
|
# Automatic verification code logic
|
||||||
elif email_tab:
|
elif email_tab:
|
||||||
print(f"{Fore.CYAN}🔄 {translator.get('register.waiting_for_verification_code')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔄 {translator.get('register.waiting_for_verification_code')}{Style.RESET_ALL}")
|
||||||
time.sleep(get_random_wait_time(config, 'email_check_initial_wait'))
|
time.sleep(get_random_wait_time(config, 'email_check_initial_wait'))
|
||||||
|
|
||||||
# 使用已有的 email_tab 刷新邮箱
|
# Use existing email_tab to refresh email
|
||||||
email_tab.refresh_inbox()
|
email_tab.refresh_inbox()
|
||||||
time.sleep(get_random_wait_time(config, 'email_refresh_wait'))
|
time.sleep(get_random_wait_time(config, 'email_refresh_wait'))
|
||||||
|
|
||||||
# 检查邮箱是否有验证码邮件
|
# Check if there is a verification code email
|
||||||
if email_tab.check_for_cursor_email():
|
if email_tab.check_for_cursor_email():
|
||||||
verification_code = email_tab.get_verification_code()
|
verification_code = email_tab.get_verification_code()
|
||||||
if verification_code:
|
if verification_code:
|
||||||
# 在注册页面填写验证码
|
# Fill verification code in registration page
|
||||||
for i, digit in enumerate(verification_code):
|
for i, digit in enumerate(verification_code):
|
||||||
browser_tab.ele(f"@data-index={i}").input(digit)
|
browser_tab.ele(f"@data-index={i}").input(digit)
|
||||||
time.sleep(get_random_wait_time(config, 'verification_code_input'))
|
time.sleep(get_random_wait_time(config, 'verification_code_input'))
|
||||||
@ -423,13 +423,13 @@ def handle_verification_code(browser_tab, email_tab, controller, config, transla
|
|||||||
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
||||||
time.sleep(get_random_wait_time(config, 'verification_success_wait'))
|
time.sleep(get_random_wait_time(config, 'verification_success_wait'))
|
||||||
|
|
||||||
# 处理最后一次 Turnstile 验证
|
# Handle last Turnstile verification
|
||||||
if handle_turnstile(browser_tab, config, translator):
|
if handle_turnstile(browser_tab, config, translator):
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
||||||
time.sleep(get_random_wait_time(config, 'verification_retry_wait'))
|
time.sleep(get_random_wait_time(config, 'verification_retry_wait'))
|
||||||
|
|
||||||
# 访问设置页面
|
# Visit settings page
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}🔑 {translator.get('register.visiting_url')}: https://www.cursor.com/settings{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔑 {translator.get('register.visiting_url')}: https://www.cursor.com/settings{Style.RESET_ALL}")
|
||||||
browser_tab.get("https://www.cursor.com/settings")
|
browser_tab.get("https://www.cursor.com/settings")
|
||||||
@ -443,18 +443,18 @@ def handle_verification_code(browser_tab, email_tab, controller, config, transla
|
|||||||
print("最后一次验证失败")
|
print("最后一次验证失败")
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
# 获取验证码,设置超时
|
# Get verification code, set timeout
|
||||||
verification_code = None
|
verification_code = None
|
||||||
max_attempts = 20
|
max_attempts = 20
|
||||||
retry_interval = get_random_wait_time(config, 'retry_interval') # 使用 get_random_wait_time
|
retry_interval = get_random_wait_time(config, 'retry_interval') # Use get_random_wait_time
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
timeout = float(config.get('Timing', 'max_timeout', fallback='160')) # 這個可以保持不變因為是固定值
|
timeout = float(config.get('Timing', 'max_timeout', fallback='160')) # This can be kept unchanged because it is a fixed value
|
||||||
|
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}{translator.get('register.start_getting_verification_code')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{translator.get('register.start_getting_verification_code')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
for attempt in range(max_attempts):
|
for attempt in range(max_attempts):
|
||||||
# 检查是否超时
|
# Check if timeout
|
||||||
if time.time() - start_time > timeout:
|
if time.time() - start_time > timeout:
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.RED}❌ {translator.get('register.verification_timeout')}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {translator.get('register.verification_timeout')}{Style.RESET_ALL}")
|
||||||
@ -470,12 +470,12 @@ def handle_verification_code(browser_tab, email_tab, controller, config, transla
|
|||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}{translator.get('register.try_get_code', attempt=attempt + 1, time=remaining_time)}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{translator.get('register.try_get_code', attempt=attempt + 1, time=remaining_time)}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 刷新邮箱
|
# Refresh email
|
||||||
email_tab.refresh_inbox()
|
email_tab.refresh_inbox()
|
||||||
time.sleep(retry_interval) # 使用 get_random_wait_time
|
time.sleep(retry_interval) # Use get_random_wait_time
|
||||||
|
|
||||||
if verification_code:
|
if verification_code:
|
||||||
# 在注册页面填写验证码
|
# Fill verification code in registration page
|
||||||
for i, digit in enumerate(verification_code):
|
for i, digit in enumerate(verification_code):
|
||||||
browser_tab.ele(f"@data-index={i}").input(digit)
|
browser_tab.ele(f"@data-index={i}").input(digit)
|
||||||
time.sleep(get_random_wait_time(config, 'verification_code_input'))
|
time.sleep(get_random_wait_time(config, 'verification_code_input'))
|
||||||
@ -484,19 +484,19 @@ def handle_verification_code(browser_tab, email_tab, controller, config, transla
|
|||||||
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
||||||
time.sleep(get_random_wait_time(config, 'verification_success_wait'))
|
time.sleep(get_random_wait_time(config, 'verification_success_wait'))
|
||||||
|
|
||||||
# 处理最后一次 Turnstile 验证
|
# Handle last Turnstile verification
|
||||||
if handle_turnstile(browser_tab, config, translator):
|
if handle_turnstile(browser_tab, config, translator):
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {translator.get('register.verification_success')}{Style.RESET_ALL}")
|
||||||
time.sleep(get_random_wait_time(config, 'verification_retry_wait'))
|
time.sleep(get_random_wait_time(config, 'verification_retry_wait'))
|
||||||
|
|
||||||
# 直接访问设置页面
|
# Visit settings page
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}{translator.get('register.visiting_url')}: https://www.cursor.com/settings{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{translator.get('register.visiting_url')}: https://www.cursor.com/settings{Style.RESET_ALL}")
|
||||||
browser_tab.get("https://www.cursor.com/settings")
|
browser_tab.get("https://www.cursor.com/settings")
|
||||||
time.sleep(get_random_wait_time(config, 'settings_page_load_wait'))
|
time.sleep(get_random_wait_time(config, 'settings_page_load_wait'))
|
||||||
|
|
||||||
# 直接返回成功,让 cursor_register.py 处理账户信息获取
|
# Return success directly, let cursor_register.py handle account information acquisition
|
||||||
return True, browser_tab
|
return True, browser_tab
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -512,58 +512,58 @@ def handle_verification_code(browser_tab, email_tab, controller, config, transla
|
|||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
def handle_sign_in(browser_tab, email, password, translator=None):
|
def handle_sign_in(browser_tab, email, password, translator=None):
|
||||||
"""处理登录流程"""
|
"""Handle login process"""
|
||||||
try:
|
try:
|
||||||
# 检查是否在登录页面
|
# Check if on login page
|
||||||
sign_in_header = browser_tab.ele('xpath://h1[contains(text(), "Sign in")]')
|
sign_in_header = browser_tab.ele('xpath://h1[contains(text(), "Sign in")]')
|
||||||
if not sign_in_header:
|
if not sign_in_header:
|
||||||
return True # 如果不是登录页面,说明已经登录成功
|
return True # If not on login page, it means login is successful
|
||||||
|
|
||||||
print(f"{Fore.CYAN}检测到登录页面,开始登录...{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}检测到登录页面,开始登录...{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 填写邮箱
|
# Fill email
|
||||||
email_input = browser_tab.ele('@name=email')
|
email_input = browser_tab.ele('@name=email')
|
||||||
if email_input:
|
if email_input:
|
||||||
email_input.input(email)
|
email_input.input(email)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
# 点击 Continue
|
# Click Continue
|
||||||
continue_button = browser_tab.ele('xpath://button[contains(@class, "BrandedButton") and text()="Continue"]')
|
continue_button = browser_tab.ele('xpath://button[contains(@class, "BrandedButton") and text()="Continue"]')
|
||||||
if continue_button:
|
if continue_button:
|
||||||
continue_button.click()
|
continue_button.click()
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
# 处理 Turnstile 验证
|
# Handle Turnstile verification
|
||||||
if handle_turnstile(browser_tab, translator):
|
if handle_turnstile(browser_tab, translator):
|
||||||
# 填写密码
|
# Fill password
|
||||||
password_input = browser_tab.ele('@name=password')
|
password_input = browser_tab.ele('@name=password')
|
||||||
if password_input:
|
if password_input:
|
||||||
password_input.input(password)
|
password_input.input(password)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
# 点击 Sign in
|
# Click Sign in
|
||||||
sign_in_button = browser_tab.ele('xpath://button[@name="intent" and @value="password"]')
|
sign_in_button = browser_tab.ele('xpath://button[@name="intent" and @value="password"]')
|
||||||
if sign_in_button:
|
if sign_in_button:
|
||||||
sign_in_button.click()
|
sign_in_button.click()
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
# 处理最后一次 Turnstile 验证
|
# Handle last Turnstile verification
|
||||||
if handle_turnstile(browser_tab, translator):
|
if handle_turnstile(browser_tab, translator):
|
||||||
print(f"{Fore.GREEN}登录成功!{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}Login successful!{Style.RESET_ALL}")
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
print(f"{Fore.RED}登录失败{Style.RESET_ALL}")
|
print(f"{Fore.RED}Login failed{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{Fore.RED}登录过程出错: {str(e)}{Style.RESET_ALL}")
|
print(f"{Fore.RED}Login process error: {str(e)}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def main(email=None, password=None, first_name=None, last_name=None, email_tab=None, controller=None, translator=None):
|
def main(email=None, password=None, first_name=None, last_name=None, email_tab=None, controller=None, translator=None):
|
||||||
"""主函数,可以接收账号信息、邮箱标签页和翻译器"""
|
"""Main function, can receive account information, email tab, and translator"""
|
||||||
global _translator
|
global _translator
|
||||||
_translator = translator # 保存到全局变量
|
_translator = translator # Save to global variable
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
signal.signal(signal.SIGTERM, signal_handler)
|
signal.signal(signal.SIGTERM, signal_handler)
|
||||||
@ -575,45 +575,45 @@ def main(email=None, password=None, first_name=None, last_name=None, email_tab=N
|
|||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}🚀 {translator.get('register.browser_started')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🚀 {translator.get('register.browser_started')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 访问注册页面
|
# Visit registration page
|
||||||
url = "https://authenticator.cursor.sh/sign-up"
|
url = "https://authenticator.cursor.sh/sign-up"
|
||||||
|
|
||||||
# 访问页面
|
# Visit page
|
||||||
simulate_human_input(page, url, config, translator)
|
simulate_human_input(page, url, config, translator)
|
||||||
if translator:
|
if translator:
|
||||||
print(f"{Fore.CYAN}🔄 {translator.get('register.waiting_for_page_load')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔄 {translator.get('register.waiting_for_page_load')}{Style.RESET_ALL}")
|
||||||
time.sleep(get_random_wait_time(config, 'page_load_wait'))
|
time.sleep(get_random_wait_time(config, 'page_load_wait'))
|
||||||
|
|
||||||
# 如果没有提供账号信息,则生成随机信息
|
# If account information is not provided, generate random information
|
||||||
if not all([email, password, first_name, last_name]):
|
if not all([email, password, first_name, last_name]):
|
||||||
first_name = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz', k=6)).capitalize()
|
first_name = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz', k=6)).capitalize()
|
||||||
last_name = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz', k=6)).capitalize()
|
last_name = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz', k=6)).capitalize()
|
||||||
email = f"{first_name.lower()}{random.randint(100,999)}@example.com"
|
email = f"{first_name.lower()}{random.randint(100,999)}@example.com"
|
||||||
password = generate_password()
|
password = generate_password()
|
||||||
|
|
||||||
# 保存账号信息
|
# Save account information
|
||||||
with open('test_accounts.txt', 'a', encoding='utf-8') as f:
|
with open('test_accounts.txt', 'a', encoding='utf-8') as f:
|
||||||
f.write(f"\n{'='*50}\n")
|
f.write(f"\n{'='*50}\n")
|
||||||
f.write(f"Email: {email}\n")
|
f.write(f"Email: {email}\n")
|
||||||
f.write(f"Password: {password}\n")
|
f.write(f"Password: {password}\n")
|
||||||
f.write(f"{'='*50}\n")
|
f.write(f"{'='*50}\n")
|
||||||
|
|
||||||
# 填写表单
|
# Fill form
|
||||||
if fill_signup_form(page, first_name, last_name, email, config, translator):
|
if fill_signup_form(page, first_name, last_name, email, config, translator):
|
||||||
if translator:
|
if translator:
|
||||||
print(f"\n{Fore.GREEN}✅ {translator.get('register.form_submitted')}{Style.RESET_ALL}")
|
print(f"\n{Fore.GREEN}✅ {translator.get('register.form_submitted')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 处理第一次 Turnstile 验证
|
# Handle first Turnstile verification
|
||||||
if handle_turnstile(page, config, translator):
|
if handle_turnstile(page, config, translator):
|
||||||
if translator:
|
if translator:
|
||||||
print(f"\n{Fore.GREEN}✅ {translator.get('register.first_verification_passed')}{Style.RESET_ALL}")
|
print(f"\n{Fore.GREEN}✅ {translator.get('register.first_verification_passed')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 填写密码
|
# Fill password
|
||||||
if fill_password(page, password, config, translator):
|
if fill_password(page, password, config, translator):
|
||||||
if translator:
|
if translator:
|
||||||
print(f"\n{Fore.CYAN}🔄 {translator.get('register.waiting_for_second_verification')}{Style.RESET_ALL}")
|
print(f"\n{Fore.CYAN}🔄 {translator.get('register.waiting_for_second_verification')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 处理第二次 Turnstile 验证
|
# Handle second Turnstile verification
|
||||||
if handle_turnstile(page, config, translator):
|
if handle_turnstile(page, config, translator):
|
||||||
if translator:
|
if translator:
|
||||||
print(f"\n{Fore.CYAN}🔄 {translator.get('register.waiting_for_verification_code')}{Style.RESET_ALL}")
|
print(f"\n{Fore.CYAN}🔄 {translator.get('register.waiting_for_verification_code')}{Style.RESET_ALL}")
|
||||||
@ -621,13 +621,13 @@ def main(email=None, password=None, first_name=None, last_name=None, email_tab=N
|
|||||||
success = True
|
success = True
|
||||||
return True, page
|
return True, page
|
||||||
else:
|
else:
|
||||||
print(f"\n{Fore.RED}❌ {translator.get('register.verification_code_processing_failed') if translator else '验证码处理失败'}{Style.RESET_ALL}")
|
print(f"\n{Fore.RED}❌ {translator.get('register.verification_code_processing_failed') if translator else 'Verification code processing failed'}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"\n{Fore.RED}❌ {translator.get('register.second_verification_failed') if translator else '第二次验证失败'}{Style.RESET_ALL}")
|
print(f"\n{Fore.RED}❌ {translator.get('register.second_verification_failed') if translator else 'Second verification failed'}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"\n{Fore.RED}❌ {translator.get('register.second_verification_failed') if translator else '第二次验证失败'}{Style.RESET_ALL}")
|
print(f"\n{Fore.RED}❌ {translator.get('register.second_verification_failed') if translator else 'Second verification failed'}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
print(f"\n{Fore.RED}❌ {translator.get('register.first_verification_failed') if translator else '第一次验证失败'}{Style.RESET_ALL}")
|
print(f"\n{Fore.RED}❌ {translator.get('register.first_verification_failed') if translator else 'First verification failed'}{Style.RESET_ALL}")
|
||||||
|
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
@ -635,7 +635,7 @@ def main(email=None, password=None, first_name=None, last_name=None, email_tab=N
|
|||||||
print(f"发生错误: {e}")
|
print(f"发生错误: {e}")
|
||||||
return False, None
|
return False, None
|
||||||
finally:
|
finally:
|
||||||
if page and not success: # 只在失败时清理
|
if page and not success: # Only clean up when failed
|
||||||
try:
|
try:
|
||||||
page.quit()
|
page.quit()
|
||||||
except:
|
except:
|
||||||
@ -643,4 +643,4 @@ def main(email=None, password=None, first_name=None, last_name=None, email_tab=N
|
|||||||
cleanup_chrome_processes(translator)
|
cleanup_chrome_processes(translator)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main() # 直接运行时不传参数,使用随机生成的信息
|
main() # Run without parameters, use randomly generated information
|
@ -263,7 +263,7 @@ class NewTempEmail:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def check_for_cursor_email(self):
|
def check_for_cursor_email(self):
|
||||||
"""检查是否有 Cursor 的验证邮件"""
|
"""Check if there is a Cursor verification email"""
|
||||||
try:
|
try:
|
||||||
# Use API to get email list
|
# Use API to get email list
|
||||||
headers = {"Authorization": f"Bearer {self.token}"}
|
headers = {"Authorization": f"Bearer {self.token}"}
|
||||||
|
@ -32,7 +32,7 @@ def get_cursor_paths(translator=None) -> Tuple[str, str]:
|
|||||||
""" Get Cursor related paths"""
|
""" Get Cursor related paths"""
|
||||||
system = platform.system()
|
system = platform.system()
|
||||||
|
|
||||||
# 讀取配置文件
|
# Read config file
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config_dir = os.path.join(get_user_documents_path(), ".cursor-free-vip")
|
config_dir = os.path.join(get_user_documents_path(), ".cursor-free-vip")
|
||||||
config_file = os.path.join(config_dir, "config.ini")
|
config_file = os.path.join(config_dir, "config.ini")
|
||||||
@ -40,9 +40,9 @@ def get_cursor_paths(translator=None) -> Tuple[str, str]:
|
|||||||
if not os.path.exists(config_file):
|
if not os.path.exists(config_file):
|
||||||
raise OSError(translator.get('reset.config_not_found') if translator else "找不到配置文件")
|
raise OSError(translator.get('reset.config_not_found') if translator else "找不到配置文件")
|
||||||
|
|
||||||
config.read(config_file, encoding='utf-8') # 指定編碼
|
config.read(config_file, encoding='utf-8') # Specify encoding
|
||||||
|
|
||||||
# 根據系統獲取路徑
|
# Get path based on system
|
||||||
if system == "Darwin":
|
if system == "Darwin":
|
||||||
section = 'MacPaths'
|
section = 'MacPaths'
|
||||||
elif system == "Windows":
|
elif system == "Windows":
|
||||||
@ -63,7 +63,7 @@ def get_cursor_paths(translator=None) -> Tuple[str, str]:
|
|||||||
pkg_path = os.path.join(base_path, "package.json")
|
pkg_path = os.path.join(base_path, "package.json")
|
||||||
main_path = os.path.join(base_path, "out/main.js")
|
main_path = os.path.join(base_path, "out/main.js")
|
||||||
|
|
||||||
# 檢查文件是否存在
|
# Check if files exist
|
||||||
if not os.path.exists(pkg_path):
|
if not os.path.exists(pkg_path):
|
||||||
raise OSError(translator.get('reset.package_not_found', path=pkg_path) if translator else f"找不到 package.json: {pkg_path}")
|
raise OSError(translator.get('reset.package_not_found', path=pkg_path) if translator else f"找不到 package.json: {pkg_path}")
|
||||||
if not os.path.exists(main_path):
|
if not os.path.exists(main_path):
|
||||||
@ -187,7 +187,7 @@ def check_cursor_version(translator) -> bool:
|
|||||||
with open(pkg_path, "r", encoding="utf-8") as f:
|
with open(pkg_path, "r", encoding="utf-8") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
# 如果 UTF-8 讀取失敗,嘗試其他編碼
|
# If UTF-8 reading fails, try other encodings
|
||||||
with open(pkg_path, "r", encoding="latin-1") as f:
|
with open(pkg_path, "r", encoding="latin-1") as f:
|
||||||
data = json.load(f)
|
data = json.load(f)
|
||||||
|
|
||||||
@ -206,15 +206,15 @@ def check_cursor_version(translator) -> bool:
|
|||||||
|
|
||||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('reset.found_version', version=version)}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('reset.found_version', version=version)}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 檢查版本格式
|
# Check version format
|
||||||
if not re.match(r"^\d+\.\d+\.\d+$", version):
|
if not re.match(r"^\d+\.\d+\.\d+$", version):
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.invalid_version_format', version=version)}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('reset.invalid_version_format', version=version)}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 比較版本
|
# Compare versions
|
||||||
try:
|
try:
|
||||||
current = tuple(map(int, version.split(".")))
|
current = tuple(map(int, version.split(".")))
|
||||||
min_ver = (0, 45, 0) # 直接使用元組而不是字符串
|
min_ver = (0, 45, 0) # Use tuple directly instead of string
|
||||||
|
|
||||||
if current >= min_ver:
|
if current >= min_ver:
|
||||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('reset.version_check_passed', version=version, min_version='0.45.0')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('reset.version_check_passed', version=version, min_version='0.45.0')}{Style.RESET_ALL}")
|
||||||
@ -445,7 +445,7 @@ class MachineIDResetter:
|
|||||||
elif sys.platform == "linux": # Linux
|
elif sys.platform == "linux": # Linux
|
||||||
if not config.has_section('LinuxPaths'):
|
if not config.has_section('LinuxPaths'):
|
||||||
config.add_section('LinuxPaths')
|
config.add_section('LinuxPaths')
|
||||||
# 获取实际用户的主目录
|
# Get actual user's home directory
|
||||||
sudo_user = os.environ.get('SUDO_USER')
|
sudo_user = os.environ.get('SUDO_USER')
|
||||||
actual_home = f"/home/{sudo_user}" if sudo_user else os.path.expanduser("~")
|
actual_home = f"/home/{sudo_user}" if sudo_user else os.path.expanduser("~")
|
||||||
|
|
||||||
|
2
utils.py
2
utils.py
@ -28,5 +28,5 @@ def get_linux_cursor_path():
|
|||||||
os.path.expanduser("~/.local/share/cursor/resources/app")
|
os.path.expanduser("~/.local/share/cursor/resources/app")
|
||||||
]
|
]
|
||||||
|
|
||||||
# 返回第一个存在的路径,如果都不存在则返回第一个路径
|
# return the first path that exists
|
||||||
return next((path for path in possible_paths if os.path.exists(path)), possible_paths[0])
|
return next((path for path in possible_paths if os.path.exists(path)), possible_paths[0])
|
Loading…
x
Reference in New Issue
Block a user