mirror of
https://git.axenov.dev/mirrors/cursor-free-vip.git
synced 2026-01-03 09:19:27 +03:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bdcc2f633 | ||
|
|
4aabe2e403 | ||
|
|
005aa2cd95 | ||
|
|
14f6dfc29d | ||
|
|
2e9bd269ad | ||
|
|
f9b7e23253 | ||
|
|
0d979f7543 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -6,7 +6,7 @@ on:
|
|||||||
version:
|
version:
|
||||||
description: 'Version number (e.g. 1.0.9)'
|
description: 'Version number (e.g. 1.0.9)'
|
||||||
required: true
|
required: true
|
||||||
default: '1.4.07'
|
default: '1.5.03'
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -45,3 +45,6 @@ Thumbs.db
|
|||||||
*.log
|
*.log
|
||||||
*.db
|
*.db
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
|
|
||||||
|
# Mac
|
||||||
|
run_venv.mac.command
|
||||||
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,5 +1,17 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## v1.6.01
|
||||||
|
1. Fix: Cursor Auth | 修復Cursor Auth
|
||||||
|
2. Add: Create Account Maximum Retry | 增加創建賬號最大重試次數
|
||||||
|
3. Fix: Cursor Auth Error | 修復Cursor Auth錯誤
|
||||||
|
4. Fix: Update Curl Faild | 修復更新Curl失敗
|
||||||
|
|
||||||
|
## v1.5.03
|
||||||
|
1. HOTFIX: Stuck on starting browser | 修復啟動瀏覽器卡住問題
|
||||||
|
2. Small Fix: Error Handling | 小修錯誤處理
|
||||||
|
3. Small Fix: Translation | 小修翻譯
|
||||||
|
4. Small Fix: Performance | 小修性能
|
||||||
|
|
||||||
## v1.5.02
|
## v1.5.02
|
||||||
1. Add: Generate Random Name Alias | 增加生成隨機真實姓名
|
1. Add: Generate Random Name Alias | 增加生成隨機真實姓名
|
||||||
2. Add: Realistic Name Input | 增加真實姓名輸入
|
2. Add: Realistic Name Input | 增加真實姓名輸入
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
[](https://github.com/yeongpin/cursor-free-vip/releases/latest)
|
[](https://github.com/yeongpin/cursor-free-vip/releases/latest)
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
<h4>Support Latest 0.46.3 Version | 支持最新0.46.3本</h4>
|
<h4>Support Latest 0.46.8 Version | 支持最新0.46.8本</h4>
|
||||||
|
|
||||||
This is a tool to automatically register , support Windows and macOS systems, complete Auth verification, and reset Cursor's configuration.
|
This is a tool to automatically register , support Windows and macOS systems, complete Auth verification, and reset Cursor's configuration.
|
||||||
|
|
||||||
@@ -109,6 +109,11 @@ irm https://raw.githubusercontent.com/yeongpin/cursor-free-vip/main/scripts/rese
|
|||||||
歡迎提交 Issue 和 Pull Request!
|
歡迎提交 Issue 和 Pull Request!
|
||||||
|
|
||||||
|
|
||||||
|
<a href="https://github.com/yeongpin/cursor-free-vip/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=yeongpin/cursor-free-vip" />
|
||||||
|
</a>
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
|
||||||
## 📩 Disclaimer | 免責聲明
|
## 📩 Disclaimer | 免責聲明
|
||||||
|
|
||||||
|
|||||||
@@ -22,18 +22,21 @@ class CursorAuth:
|
|||||||
def __init__(self, translator=None):
|
def __init__(self, translator=None):
|
||||||
self.translator = translator
|
self.translator = translator
|
||||||
# 判断操作系统
|
# 判断操作系统
|
||||||
if os.name == "nt": # Windows
|
if sys.platform == "win32": # Windows
|
||||||
self.db_path = os.path.join(
|
self.db_path = os.path.join(
|
||||||
os.getenv("APPDATA"), "Cursor", "User", "globalStorage", "state.vscdb"
|
os.getenv("APPDATA"), "Cursor", "User", "globalStorage", "state.vscdb"
|
||||||
)
|
)
|
||||||
elif os.name =='posix':
|
elif sys.platform == 'linux':
|
||||||
self.db_path = os.path.expanduser(
|
self.db_path = os.path.expanduser(
|
||||||
"~/.config/Cursor/User/globalStorage/state.vscdb"
|
"~/.config/Cursor/User/globalStorage/state.vscdb"
|
||||||
)
|
)
|
||||||
else: # macOS
|
elif sys.platform == 'darwin': # macOS
|
||||||
self.db_path = os.path.expanduser(
|
self.db_path = os.path.expanduser(
|
||||||
"~/Library/Application Support/Cursor/User/globalStorage/state.vscdb"
|
"~/Library/Application Support/Cursor/User/globalStorage/state.vscdb"
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.unsupported_platform')}{Style.RESET_ALL}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# 检查数据库文件是否存在
|
# 检查数据库文件是否存在
|
||||||
if not os.path.exists(self.db_path):
|
if not os.path.exists(self.db_path):
|
||||||
@@ -87,13 +90,16 @@ class CursorAuth:
|
|||||||
|
|
||||||
# 设置要更新的键值对
|
# 设置要更新的键值对
|
||||||
updates = []
|
updates = []
|
||||||
|
|
||||||
|
updates.append(("cursorAuth/cachedSignUpType", "Auth_0"))
|
||||||
|
|
||||||
if email is not None:
|
if email is not None:
|
||||||
updates.append(("cursorAuth/cachedEmail", email))
|
updates.append(("cursorAuth/cachedEmail", email))
|
||||||
if access_token is not None:
|
if access_token is not None:
|
||||||
updates.append(("cursorAuth/accessToken", access_token))
|
updates.append(("cursorAuth/accessToken", access_token))
|
||||||
if refresh_token is not None:
|
if refresh_token is not None:
|
||||||
updates.append(("cursorAuth/refreshToken", refresh_token))
|
updates.append(("cursorAuth/refreshToken", refresh_token))
|
||||||
updates.append(("cursorAuth/cachedSignUpType", "Auth_0"))
|
|
||||||
|
|
||||||
# 使用事务来确保数据完整性
|
# 使用事务来确保数据完整性
|
||||||
cursor.execute("BEGIN TRANSACTION")
|
cursor.execute("BEGIN TRANSACTION")
|
||||||
@@ -131,5 +137,3 @@ class CursorAuth:
|
|||||||
if conn:
|
if conn:
|
||||||
conn.close()
|
conn.close()
|
||||||
print(f"{EMOJI['DB']} {Fore.CYAN} {self.translator.get('auth.database_connection_closed')}{Style.RESET_ALL}")
|
print(f"{EMOJI['DB']} {Fore.CYAN} {self.translator.get('auth.database_connection_closed')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -224,7 +224,8 @@
|
|||||||
"blocked_domains_loaded_timeout": "Blocked Domains Loaded Timeout: {timeout}s",
|
"blocked_domains_loaded_timeout": "Blocked Domains Loaded Timeout: {timeout}s",
|
||||||
"blocked_domains_loaded_timeout_error": "Blocked Domains Loaded Timeout Error: {error}",
|
"blocked_domains_loaded_timeout_error": "Blocked Domains Loaded Timeout Error: {error}",
|
||||||
"available_domains_loaded": "Available Domains Loaded: {count}",
|
"available_domains_loaded": "Available Domains Loaded: {count}",
|
||||||
"domains_filtered": "Domains Filtered: {count}"
|
"domains_filtered": "Domains Filtered: {count}",
|
||||||
|
"trying_to_create_email": "Trying to create email: {email}"
|
||||||
},
|
},
|
||||||
"update": {
|
"update": {
|
||||||
"title": "Disable Cursor Auto Update",
|
"title": "Disable Cursor Auto Update",
|
||||||
|
|||||||
@@ -221,7 +221,8 @@
|
|||||||
"blocked_domains_loaded_timeout": "加载被屏蔽的域名超时: {timeout}秒",
|
"blocked_domains_loaded_timeout": "加载被屏蔽的域名超时: {timeout}秒",
|
||||||
"blocked_domains_loaded_timeout_error": "加载被屏蔽的域名超时错误: {error}",
|
"blocked_domains_loaded_timeout_error": "加载被屏蔽的域名超时错误: {error}",
|
||||||
"available_domains_loaded": "获取到 {count} 个可用域名",
|
"available_domains_loaded": "获取到 {count} 个可用域名",
|
||||||
"domains_filtered": "过滤后剩餘 {count} 個可用域名"
|
"domains_filtered": "过滤后剩餘 {count} 個可用域名",
|
||||||
|
"trying_to_create_email": "尝试创建邮箱: {email}"
|
||||||
},
|
},
|
||||||
"update": {
|
"update": {
|
||||||
"title": "禁用 Cursor 自动更新",
|
"title": "禁用 Cursor 自动更新",
|
||||||
|
|||||||
@@ -202,7 +202,8 @@
|
|||||||
"blocked_domains_loaded_timeout": "加載被屏蔽的域名超時: {timeout}秒",
|
"blocked_domains_loaded_timeout": "加載被屏蔽的域名超時: {timeout}秒",
|
||||||
"blocked_domains_loaded_timeout_error": "加載被屏蔽的域名超時錯誤: {error}",
|
"blocked_domains_loaded_timeout_error": "加載被屏蔽的域名超時錯誤: {error}",
|
||||||
"available_domains_loaded": "獲取到 {count} 個可用域名",
|
"available_domains_loaded": "獲取到 {count} 個可用域名",
|
||||||
"domains_filtered": "過濾後剩餘 {count} 個可用域名"
|
"domains_filtered": "過濾後剩餘 {count} 個可用域名",
|
||||||
|
"trying_to_create_email": "嘗試創建郵箱: {email}"
|
||||||
},
|
},
|
||||||
"update": {
|
"update": {
|
||||||
"title": "禁用 Cursor 自动更新",
|
"title": "禁用 Cursor 自动更新",
|
||||||
|
|||||||
60
main.py
60
main.py
@@ -210,30 +210,78 @@ def check_latest_version():
|
|||||||
try:
|
try:
|
||||||
print(f"\n{Fore.CYAN}{EMOJI['UPDATE']} {translator.get('updater.checking')}{Style.RESET_ALL}")
|
print(f"\n{Fore.CYAN}{EMOJI['UPDATE']} {translator.get('updater.checking')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# Get latest version from GitHub API with timeout
|
# Get latest version from GitHub API with timeout and proper headers
|
||||||
response = requests.get("https://api.github.com/repos/yeongpin/cursor-free-vip/releases/latest", timeout=5)
|
headers = {
|
||||||
latest_version = response.json()["tag_name"].lstrip('v')
|
'Accept': 'application/vnd.github.v3+json',
|
||||||
|
'User-Agent': 'CursorFreeVIP-Updater'
|
||||||
|
}
|
||||||
|
response = requests.get(
|
||||||
|
"https://api.github.com/repos/yeongpin/cursor-free-vip/releases/latest",
|
||||||
|
headers=headers,
|
||||||
|
timeout=10
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if response is successful
|
||||||
|
if response.status_code != 200:
|
||||||
|
raise Exception(f"GitHub API returned status code {response.status_code}")
|
||||||
|
|
||||||
|
response_data = response.json()
|
||||||
|
if "tag_name" not in response_data:
|
||||||
|
raise Exception("No version tag found in GitHub response")
|
||||||
|
|
||||||
|
latest_version = response_data["tag_name"].lstrip('v')
|
||||||
|
|
||||||
|
# Validate version format
|
||||||
|
if not latest_version:
|
||||||
|
raise Exception("Invalid version format received")
|
||||||
|
|
||||||
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}")
|
||||||
|
|
||||||
|
try:
|
||||||
# Execute update command based on platform
|
# Execute update command based on platform
|
||||||
if platform.system() == 'Windows':
|
if platform.system() == 'Windows':
|
||||||
update_command = 'irm https://raw.githubusercontent.com/yeongpin/cursor-free-vip/main/scripts/install.ps1 | iex'
|
update_command = 'irm https://raw.githubusercontent.com/yeongpin/cursor-free-vip/main/scripts/install.ps1 | iex'
|
||||||
subprocess.run(['powershell', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', update_command], check=True)
|
subprocess.run(['powershell', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', update_command], check=True)
|
||||||
else:
|
else:
|
||||||
update_command = 'curl -fsSL https://raw.githubusercontent.com/yeongpin/cursor-free-vip/main/scripts/install.sh -o install.sh && chmod +x install.sh && ./install.sh'
|
# For Linux/Mac, download and execute the install script
|
||||||
subprocess.Popen(update_command, shell=True)
|
install_script_url = 'https://raw.githubusercontent.com/yeongpin/cursor-free-vip/main/scripts/install.sh'
|
||||||
|
|
||||||
|
# First verify the script exists
|
||||||
|
script_response = requests.get(install_script_url, timeout=5)
|
||||||
|
if script_response.status_code != 200:
|
||||||
|
raise Exception("Installation script not found")
|
||||||
|
|
||||||
|
# Save and execute the script
|
||||||
|
with open('install.sh', 'wb') as f:
|
||||||
|
f.write(script_response.content)
|
||||||
|
|
||||||
|
os.chmod('install.sh', 0o755) # Make executable
|
||||||
|
subprocess.run(['./install.sh'], check=True)
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
if os.path.exists('install.sh'):
|
||||||
|
os.remove('install.sh')
|
||||||
|
|
||||||
print(f"\n{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('updater.updating')}{Style.RESET_ALL}")
|
print(f"\n{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('updater.updating')}{Style.RESET_ALL}")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
except Exception as update_error:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('updater.update_failed', error=str(update_error))}{Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.manual_update_required')}{Style.RESET_ALL}")
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('updater.up_to_date')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('updater.up_to_date')}{Style.RESET_ALL}")
|
||||||
|
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('updater.network_error', error=str(e))}{Style.RESET_ALL}")
|
||||||
|
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.continue_anyway')}{Style.RESET_ALL}")
|
||||||
|
return
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('updater.check_failed', error=str(e))}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('updater.check_failed', error=str(e))}{Style.RESET_ALL}")
|
||||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.continue_anyway')}{Style.RESET_ALL}")
|
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('updater.continue_anyway')}{Style.RESET_ALL}")
|
||||||
return # Continue with the program instead of blocking
|
return
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
print_logo()
|
print_logo()
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ def setup_driver(translator=None):
|
|||||||
# 使用无痕模式
|
# 使用无痕模式
|
||||||
co.set_argument("--incognito")
|
co.set_argument("--incognito")
|
||||||
|
|
||||||
|
# 设置随机端口
|
||||||
|
co.set_argument("--no-sandbox")
|
||||||
|
|
||||||
# 设置随机端口
|
# 设置随机端口
|
||||||
co.auto_port()
|
co.auto_port()
|
||||||
|
|
||||||
|
|||||||
@@ -66,13 +66,18 @@ class NewTempEmail:
|
|||||||
return filtered_domains
|
return filtered_domains
|
||||||
|
|
||||||
def _generate_credentials(self):
|
def _generate_credentials(self):
|
||||||
"""生成随机用户名和密码"""
|
"""generate random username and password"""
|
||||||
username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
|
username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
|
||||||
password = ''.join(random.choices(string.ascii_letters + string.digits + string.punctuation, k=12))
|
password = ''.join(random.choices(string.ascii_letters + string.digits + string.punctuation, k=12))
|
||||||
return username, password
|
return username, password
|
||||||
|
|
||||||
def create_email(self):
|
def create_email(self):
|
||||||
"""创建临时邮箱"""
|
"""create temporary email"""
|
||||||
|
max_retries = 3 # Maximum number of retries
|
||||||
|
attempt = 0 # Current attempt count
|
||||||
|
|
||||||
|
while attempt < max_retries:
|
||||||
|
attempt += 1
|
||||||
try:
|
try:
|
||||||
if self.translator:
|
if self.translator:
|
||||||
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.visiting_site').replace('mail.tm', self.selected_service['name'])}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.visiting_site').replace('mail.tm', self.selected_service['name'])}{Style.RESET_ALL}")
|
||||||
@@ -135,6 +140,9 @@ class NewTempEmail:
|
|||||||
selected_domain = filtered_domains[0]['domain']
|
selected_domain = filtered_domains[0]['domain']
|
||||||
email = f"{username}@{selected_domain}"
|
email = f"{username}@{selected_domain}"
|
||||||
|
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.trying_to_create_email', email=email)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
print(f"{Fore.CYAN}ℹ️ 尝试创建邮箱: {email}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}ℹ️ 尝试创建邮箱: {email}{Style.RESET_ALL}")
|
||||||
|
|
||||||
account_data = {
|
account_data = {
|
||||||
@@ -150,7 +158,13 @@ class NewTempEmail:
|
|||||||
create_response = requests.post(f"{self.api_url}/accounts", json=account_data, timeout=15)
|
create_response = requests.post(f"{self.api_url}/accounts", json=account_data, timeout=15)
|
||||||
|
|
||||||
if create_response.status_code != 201:
|
if create_response.status_code != 201:
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_create_account', error=create_response.status_code)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
print(f"{Fore.RED}❌ 创建账户失败: 状态码 {create_response.status_code}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ 创建账户失败: 状态码 {create_response.status_code}{Style.RESET_ALL}")
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_create_account', error=create_response.text)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
print(f"{Fore.RED}❌ 响应内容: {create_response.text}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ 响应内容: {create_response.text}{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 如果是域名问题,尝试下一个域名
|
# 如果是域名问题,尝试下一个域名
|
||||||
@@ -164,6 +178,9 @@ class NewTempEmail:
|
|||||||
|
|
||||||
raise Exception(f"{self.translator.get('email.failed_to_create_account') if self.translator else '创建账户失败'}")
|
raise Exception(f"{self.translator.get('email.failed_to_create_account') if self.translator else '创建账户失败'}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_create_account', error=str(e))}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
print(f"{Fore.RED}❌ 创建账户时出错: {str(e)}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ 创建账户时出错: {str(e)}{Style.RESET_ALL}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@@ -176,7 +193,13 @@ class NewTempEmail:
|
|||||||
|
|
||||||
token_response = requests.post(f"{self.api_url}/token", json=token_data, timeout=10)
|
token_response = requests.post(f"{self.api_url}/token", json=token_data, timeout=10)
|
||||||
if token_response.status_code != 200:
|
if token_response.status_code != 200:
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_get_access_token', error=token_response.status_code)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
print(f"{Fore.RED}❌ 获取令牌失败: 状态码 {token_response.status_code}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ 获取令牌失败: 状态码 {token_response.status_code}{Style.RESET_ALL}")
|
||||||
|
if self.translator:
|
||||||
|
print(f"{Fore.RED}❌ {self.translator.get('email.failed_to_get_access_token', error=token_response.text)}{Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
print(f"{Fore.RED}❌ 响应内容: {token_response.text}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ 响应内容: {token_response.text}{Style.RESET_ALL}")
|
||||||
raise Exception(f"{self.translator.get('email.failed_to_get_access_token') if self.translator else '获取访问令牌失败'}")
|
raise Exception(f"{self.translator.get('email.failed_to_get_access_token') if self.translator else '获取访问令牌失败'}")
|
||||||
|
|
||||||
@@ -193,6 +216,9 @@ class NewTempEmail:
|
|||||||
return email
|
return email
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if attempt < max_retries:
|
||||||
|
print(f"{Fore.YELLOW}⚠️ 尝试重新创建邮箱... (尝试 {attempt}/{max_retries}){Style.RESET_ALL}")
|
||||||
|
else:
|
||||||
if self.translator:
|
if self.translator:
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.create_error')}: {str(e)}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {self.translator.get('email.create_error')}: {str(e)}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
@@ -200,12 +226,12 @@ class NewTempEmail:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""关闭浏览器"""
|
"""close browser"""
|
||||||
if self.page:
|
if self.page:
|
||||||
self.page.quit()
|
self.page.quit()
|
||||||
|
|
||||||
def refresh_inbox(self):
|
def refresh_inbox(self):
|
||||||
"""刷新邮箱"""
|
"""refresh inbox"""
|
||||||
try:
|
try:
|
||||||
if self.translator:
|
if self.translator:
|
||||||
print(f"{Fore.CYAN}🔄 {self.translator.get('email.refreshing')}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔄 {self.translator.get('email.refreshing')}{Style.RESET_ALL}")
|
||||||
@@ -271,7 +297,7 @@ class NewTempEmail:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def get_verification_code(self):
|
def get_verification_code(self):
|
||||||
"""获取验证码"""
|
"""get verification code"""
|
||||||
try:
|
try:
|
||||||
# 使用 API 获取邮件列表
|
# 使用 API 获取邮件列表
|
||||||
headers = {"Authorization": f"Bearer {self.token}"}
|
headers = {"Authorization": f"Bearer {self.token}"}
|
||||||
|
|||||||
Reference in New Issue
Block a user