diff --git a/.env b/.env
index d88c350..f44a1bc 100644
--- a/.env
+++ b/.env
@@ -1,2 +1,2 @@
-version=1.4.01
-VERSION=1.4.01
+version=1.4.03
+VERSION=1.4.03
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 39fe116..263f622 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -63,7 +63,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: CursorFreeVIP_${{ env.VERSION }}_windows.exe
- path: dist/*
+ path: dist/CursorFreeVIP_${{ env.VERSION }}_windows.exe
build-macos-arm64:
needs: create-tag
@@ -90,12 +90,13 @@ jobs:
- name: Build MacOS ARM executable
run: |
pyinstaller build.spec
+ mv "dist/CursorFreeVIP_${{ env.VERSION }}_mac" "dist/CursorFreeVIP_${{ env.VERSION }}_mac_arm64"
- name: Upload MacOS ARM artifact
uses: actions/upload-artifact@v4
with:
name: CursorFreeVIP_${{ env.VERSION }}_mac_arm64
- path: dist/*
+ path: dist/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
build-linux:
needs: create-tag
@@ -120,14 +121,18 @@ jobs:
pip install -r requirements.txt
- name: Build Linux executable
+ env:
+ VERSION: ${{ env.VERSION }}
run: |
pyinstaller build.spec
+ echo "Contents of dist directory:"
+ ls -la dist/
- name: Upload Linux artifact
uses: actions/upload-artifact@v4
with:
name: CursorFreeVIP_${{ env.VERSION }}_linux
- path: dist/*
+ path: dist/CursorFreeVIP_${{ env.VERSION }}_linux
build-macos-intel:
@@ -155,14 +160,16 @@ jobs:
- name: Build MacOS Intel executable
env:
TARGET_ARCH: 'x86_64'
+ VERSION: ${{ env.VERSION }}
run: |
arch -x86_64 python3 -m PyInstaller build.spec
+ mv "dist/CursorFreeVIP_${{ env.VERSION }}_mac" "dist/CursorFreeVIP_${{ env.VERSION }}_mac_intel"
- name: Upload MacOS Intel artifact
uses: actions/upload-artifact@v4
with:
name: CursorFreeVIP_${{ env.VERSION }}_mac_intel
- path: dist/*
+ path: dist/CursorFreeVIP_${{ env.VERSION }}_mac_intel
create-release:
@@ -182,24 +189,20 @@ jobs:
- name: Prepare release files
run: |
cd artifacts
- # 重命名文件为最终的可执行文件名
- mv CursorFreeVIP_${{ env.VERSION }}_windows.exe/CursorFreeVIP.exe CursorFreeVIP_${{ env.VERSION }}_windows.exe
- mv CursorFreeVIP_${{ env.VERSION }}_mac_arm64/CursorFreeVIP CursorFreeVIP_${{ env.VERSION }}_mac_arm64
- mv CursorFreeVIP_${{ env.VERSION }}_linux/CursorFreeVIP CursorFreeVIP_${{ env.VERSION }}_linux
- mv CursorFreeVIP_${{ env.VERSION }}_mac_intel/CursorFreeVIP CursorFreeVIP_${{ env.VERSION }}_mac_intel
- # 删除空目录
- rm -rf */
+ echo "Contents of artifacts directory:"
ls -la
-
+ echo "Contents of subdirectories:"
+ ls -la */
+
- name: Create Release
uses: softprops/action-gh-release@v1
with:
tag_name: v${{ env.VERSION }}
files: |
- artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe
- artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
- artifacts/CursorFreeVIP_${{ env.VERSION }}_linux
- artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_intel
+ artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe/CursorFreeVIP_${{ env.VERSION }}_windows.exe
+ artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
+ artifacts/CursorFreeVIP_${{ env.VERSION }}_linux/CursorFreeVIP_${{ env.VERSION }}_linux
+ artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_intel/CursorFreeVIP_${{ env.VERSION }}_mac_intel
draft: false
prerelease: false
env:
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..82438eb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+cursor_accounts.txt
+/venv
+/__pycache__
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 805fd55..e02e194 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,15 @@
# Change Log
+## v1.4.03
+
+1. Switch to API-based Registration System | 改用API註冊系統替代瀏覽器操作
+2. Add Support for Latest Cursor Version | 增加支持最新版本Cursor
+3. Enhance Translation System | 優化多語言翻譯系統
+4. Add Database Connection Status Messages | 增加數據庫連接狀態提示
+5. Improve Error Handling for Database Operations | 改進數據庫操作的錯誤處理
+6. Add New API Integration | 新增API集成
+7. Optimize Performance and Stability | 優化性能和穩定性
+
## v1.4.01
1. Add Disable Cursor Auto Upgrade | 增加禁用Cursor自動升級
diff --git a/README.md b/README.md
index 517934d..5e6d4fa 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
[](https://github.com/yeongpin/cursor-free-vip/releases/latest)
-Support Latest 0.45.16 Version | 支持最新0.45.16版本
+Support Latest 0.46.3 Version | 支持最新0.46.3本
This is a tool to automatically register , support Windows and macOS systems, complete Auth verification, and reset Cursor's configuration.
diff --git a/cursor_auth.py b/cursor_auth.py
index 4df112d..c2a2bbe 100644
--- a/cursor_auth.py
+++ b/cursor_auth.py
@@ -31,6 +31,23 @@ class CursorAuth:
"~/Library/Application Support/Cursor/User/globalStorage/state.vscdb"
)
+ # 检查数据库文件是否存在
+ 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}")
+ return
+
+ # 检查文件权限
+ 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}")
+ return
+
+ try:
+ self.conn = sqlite3.connect(self.db_path)
+ print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('auth.connected_to_database')}{Style.RESET_ALL}")
+ except sqlite3.Error as e:
+ print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('auth.db_connection_error', error=str(e))}{Style.RESET_ALL}")
+ return
+
def update_auth(self, email=None, access_token=None, refresh_token=None):
conn = None
try:
diff --git a/cursor_register.py b/cursor_register.py
index 05093b2..4623fd8 100644
--- a/cursor_register.py
+++ b/cursor_register.py
@@ -76,10 +76,9 @@ class CursorRegistration:
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.email_create_failed')}{Style.RESET_ALL}")
return False
- # 保存邮箱地址和浏览器实例
+ # 保存邮箱地址
self.email_address = email_address
- self.email_tab = self.temp_email # 传递 NewTempEmail 实例而不是 page
- self.controller = BrowserControl(self.temp_email.page, self.translator)
+ self.email_tab = self.temp_email # 传递 NewTempEmail 实例
return True
diff --git a/locales/en.json b/locales/en.json
index 8b50b00..e0f8905 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -2,17 +2,17 @@
"menu": {
"title": "Available Options",
"exit": "Exit Program",
- "reset": "Reset Machine Manual",
- "register": "Register Cursor",
- "register_manual": "Register Cursor With Manual Email",
- "quit": "Quit Cursor",
- "select_language": "Select Language",
- "input_choice": "Enter your choice ({choices})",
- "invalid_choice": "Invalid choice. Please try again",
- "program_terminated": "Program terminated by user",
- "error_occurred": "An error occurred: {error}",
+ "reset": "Reset Machine ID",
+ "register": "Register New Cursor Account",
+ "register_manual": "Register Cursor with Custom Email",
+ "quit": "Close Cursor Application",
+ "select_language": "Change Language",
+ "input_choice": "Please enter your choice ({choices})",
+ "invalid_choice": "Invalid selection. Please enter a number from {choices}",
+ "program_terminated": "Program was terminated by user",
+ "error_occurred": "An error occurred: {error}. Please try again",
"press_enter": "Press Enter to Exit",
- "disable_auto_update": "Disable Cursor Auto Update"
+ "disable_auto_update": "Disable Cursor Auto-Update"
},
"languages": {
"en": "English",
@@ -68,21 +68,21 @@
},
"register": {
"title": "Cursor Registration Tool",
- "start": "Starting Registration Process",
- "handling_turnstile": "Handling Turnstile",
- "retry_verification": "Retry Verification",
- "detect_turnstile": "Detect Turnstile",
- "verification_success": "Verification Success",
- "starting_browser": "Starting Browser",
- "form_success": "Form Success",
- "browser_started": "Browser Started",
- "waiting_for_second_verification": "Waiting for Second Verification",
- "waiting_for_verification_code": "Waiting for Verification Code",
- "password_success": "Password Set Successfully",
- "password_error": "Password Set Failed: {error}",
- "waiting_for_page_load": "Waiting for Page Load",
- "first_verification_passed": "First Verification Passed",
- "mailbox": "Successfully Entered Mailbox",
+ "start": "Starting registration process...",
+ "handling_turnstile": "Processing security verification...",
+ "retry_verification": "Retrying verification...",
+ "detect_turnstile": "Checking security verification...",
+ "verification_success": "Security verification successful",
+ "starting_browser": "Opening browser...",
+ "form_success": "Form submitted successfully",
+ "browser_started": "Browser opened successfully",
+ "waiting_for_second_verification": "Waiting for email verification...",
+ "waiting_for_verification_code": "Waiting for verification code...",
+ "password_success": "Password set successfully",
+ "password_error": "Could not set password: {error}. Please try again",
+ "waiting_for_page_load": "Loading page...",
+ "first_verification_passed": "Initial verification successful",
+ "mailbox": "Successfully accessed email inbox",
"register_start": "Start Register",
"form_submitted": "Form Submitted, Start Verification...",
"filling_form": "Fill Form",
@@ -145,7 +145,10 @@
"database_connection_closed": "Database Connection Closed",
"database_updated_successfully": "Database Updated Successfully",
"connected_to_database": "Connected to Database",
- "updating_pair": "Updating Key-Value Pair"
+ "updating_pair": "Updating Key-Value Pair",
+ "db_not_found": "Database file not found at: {path}",
+ "db_permission_error": "Cannot access database file. Please check permissions",
+ "db_connection_error": "Failed to connect to database: {error}"
},
"control": {
"generate_email": "Generating New Email",
@@ -182,7 +185,7 @@
},
"email": {
"starting_browser": "Starting Browser",
- "visiting_site": "Visiting smailpro.com",
+ "visiting_site": "Visiting mail.tm",
"create_success": "Email Created Successfully",
"create_failed": "Failed to Create Email",
"create_error": "Email Creation Error: {error}",
diff --git a/locales/zh_cn.json b/locales/zh_cn.json
index 0a0d536..422356a 100644
--- a/locales/zh_cn.json
+++ b/locales/zh_cn.json
@@ -3,14 +3,14 @@
"title": "可用选项",
"exit": "退出程序",
"reset": "重置机器标识",
- "register": "注册 Cursor",
- "register_manual": "手动指定邮箱注册 Cursor",
- "quit": "退出 Cursor",
- "select_language": "选择语言",
- "input_choice": "输入选择 ({choices})",
- "invalid_choice": "无效选择,请重试",
- "program_terminated": "程序被用户终止",
- "error_occurred": "发生错误: {error}",
+ "register": "注册新 Cursor 账号",
+ "register_manual": "使用自定义邮箱注册",
+ "quit": "关闭 Cursor 应用",
+ "select_language": "更改语言",
+ "input_choice": "请输入您的选择 ({choices})",
+ "invalid_choice": "选择无效,请输入 {choices} 范围内的数字",
+ "program_terminated": "程序已被用户终止",
+ "error_occurred": "发生错误:{error},请重试",
"press_enter": "按回车键退出",
"disable_auto_update": "禁用 Cursor 自动更新"
},
@@ -68,25 +68,25 @@
},
"register": {
"title": "Cursor 注册工具",
- "start": "开始注册流程",
- "browser_started": "浏览器已启动",
- "password_success": "密码设置完成",
- "password_error": "密码设置失败: {error}",
- "waiting_for_page_load": "等待页面加载",
- "mailbox": "成功进入邮箱",
- "waiting_for_second_verification": "等待第二阶段验证",
- "waiting_for_verification_code": "等待验证码",
- "first_verification_passed": "第一阶段验证通过",
+ "start": "正在启动注册流程...",
+ "browser_started": "浏览器已成功打开",
+ "password_success": "密码设置成功",
+ "password_error": "无法设置密码:{error},请重试",
+ "waiting_for_page_load": "页面加载中...",
+ "mailbox": "已成功访问邮箱",
+ "waiting_for_second_verification": "等待邮箱验证...",
+ "waiting_for_verification_code": "等待验证码...",
+ "first_verification_passed": "初始验证通过",
"register_start": "开始注册流程",
"form_submitted": "表单已提交,开始验证...",
"filling_form": "填写注册信息",
"visiting_url": "访问URL",
"basic_info": "基本信息提交完成",
- "handling_turnstile": "处理 Turnstile 验证",
- "retry_verification": "重试验证",
- "detect_turnstile": "检测 Turnstile 验证",
- "verification_success": "验证成功",
- "starting_browser": "启动浏览器",
+ "handling_turnstile": "正在处理安全验证...",
+ "retry_verification": "正在重试验证...",
+ "detect_turnstile": "正在检查安全验证...",
+ "verification_success": "安全验证通过",
+ "starting_browser": "正在打开浏览器...",
"form_success": "表单提交成功",
"handle_turnstile": "处理 Turnstile 验证",
"no_turnstile": "未检测到 Turnstile 验证",
@@ -144,7 +144,10 @@
"connected_to_database": "已连接到数据库",
"database_updated_successfully": "数据库更新成功",
"database_connection_closed": "数据库连接已关闭",
- "updating_pair": "更新键值对"
+ "updating_pair": "更新键值对",
+ "db_not_found": "未找到数据库文件:{path}",
+ "db_permission_error": "无法访问数据库文件,请检查权限",
+ "db_connection_error": "连接数据库失败:{error}"
},
"control": {
"generate_email": "生成新邮箱",
@@ -179,7 +182,7 @@
},
"email": {
"starting_browser": "启动浏览器",
- "visiting_site": "访问 smailpro.com",
+ "visiting_site": "访问 mail.tm",
"create_success": "邮箱创建成功",
"create_failed": "邮箱创建失败",
"create_error": "邮箱创建错误: {error}",
diff --git a/locales/zh_tw.json b/locales/zh_tw.json
index cb260aa..5fc0883 100644
--- a/locales/zh_tw.json
+++ b/locales/zh_tw.json
@@ -1,18 +1,18 @@
{
"menu": {
"title": "可用選項",
- "exit": "退出程序",
- "reset": "重置機器標識",
- "register": "註冊 Cursor",
- "register_manual": "手動指定郵箱註冊 Cursor",
- "quit": "退出 Cursor",
- "select_language": "選擇語言",
- "input_choice": "輸入選擇 ({choices})",
- "invalid_choice": "無效選擇,請重試",
- "program_terminated": "程序被用戶終止",
- "error_occurred": "發生錯誤: {error}",
- "press_enter": "按回車鍵退出",
- "disable_auto_update": "禁用 Cursor 自動更新"
+ "exit": "退出程式",
+ "reset": "重置機器識別碼",
+ "register": "註冊新 Cursor 帳號",
+ "register_manual": "使用自訂郵箱註冊",
+ "quit": "關閉 Cursor 應用程式",
+ "select_language": "變更語言",
+ "input_choice": "請輸入您的選擇 ({choices})",
+ "invalid_choice": "選擇無效,請輸入 {choices} 範圍內的數字",
+ "program_terminated": "程式已被使用者終止",
+ "error_occurred": "發生錯誤:{error},請重試",
+ "press_enter": "按返回鍵退出",
+ "disable_auto_update": "停用 Cursor 自動更新"
},
"languages": {
"en": "English",
@@ -68,17 +68,24 @@
},
"register": {
"title": "Cursor 註冊工具",
- "start": "開始註冊流程",
- "mailbox": "成功進入郵箱",
- "browser_started": "瀏覽器已啟動",
- "waiting_for_page_load": "等待頁面加載",
- "password_success": "密碼設置完成",
- "password_error": "密碼設置失敗: {error}",
+ "start": "正在啟動註冊流程...",
+ "handling_turnstile": "正在處理安全驗證...",
+ "retry_verification": "正在重試驗證...",
+ "detect_turnstile": "正在檢查安全驗證...",
+ "verification_success": "安全驗證通過",
+ "starting_browser": "正在開啟瀏覽器...",
+ "form_success": "表單提交成功",
+ "browser_started": "瀏覽器已成功開啟",
+ "waiting_for_second_verification": "等待郵箱驗證...",
+ "waiting_for_verification_code": "等待驗證碼...",
+ "password_success": "密碼設定成功",
+ "password_error": "無法設定密碼:{error},請重試",
+ "waiting_for_page_load": "頁面載入中...",
+ "first_verification_passed": "初始驗證通過",
+ "mailbox": "已成功存取郵箱",
"visiting_url": "訪問URL",
- "first_verification_passed": "第一階段驗證通過",
"register_start": "開始註冊流程",
"form_submitted": "表單已提交,開始驗證...",
- "waiting_for_second_verification": "等待第二階段驗證",
"filling_form": "填寫註冊信息",
"basic_info": "基本信息提交完成",
"handle_turnstile": "處理 Turnstile 驗證",
@@ -86,31 +93,6 @@
"turnstile_passed": "驗證通過",
"verification_start": "開始獲取驗證碼",
"waiting_for_verification_code": "等待驗證碼",
- "handling_turnstile": "處理 Turnstile 驗證",
- "retry_verification": "重試驗證",
- "detect_turnstile": "檢測 Turnstile 驗證",
- "verification_success": "驗證成功",
- "starting_browser": "啟動瀏覽器",
- "form_success": "表單提交成功",
- "verification_timeout": "獲取驗證碼超時",
- "verification_not_found": "未找到驗證碼",
- "try_get_code": "第 {attempt} 次嘗試獲取驗證碼 | 剩餘時間: {time}秒",
- "get_account": "獲取賬戶信息",
- "get_token": "獲取 Cursor Session Token",
- "token_success": "Token 獲取成功",
- "token_attempt": "第 {attempt} 次嘗試未獲取到 Token,{time}秒後重試",
- "token_max_attempts": "已達到最大嘗試次數({max}),獲取 Token 失敗",
- "token_failed": "獲取 Token 失敗: {error}",
- "account_error": "獲取賬戶信息失敗: {error}",
- "press_enter": "按回車鍵退出",
- "browser_start": "正在啟動瀏覽器",
- "open_mailbox": "正在打開郵箱頁面",
- "email_error": "獲取郵箱地址失敗",
- "setup_error": "郵箱設置出錯: {error}",
- "start_getting_verification_code": "開始獲取驗證碼,將在60秒內嘗試...",
- "get_verification_code_timeout": "獲取驗證碼超時",
- "get_verification_code_success": "成功獲取驗證碼",
- "try_get_verification_code": "第 {attempt} 次嘗試未獲取到驗證碼,剩餘時間: {remaining_time}秒",
"verification_code_filled": "驗證碼填寫完成",
"login_success_and_jump_to_settings_page": "成功登錄並跳轉到設置頁面",
"detect_login_page": "檢測到登錄頁面,開始登錄...",
@@ -144,7 +126,10 @@
"connected_to_database": "已連接到數據庫",
"database_updated_successfully": "數據庫更新成功",
"database_connection_closed": "數據庫連接已關閉",
- "updating_pair": "更新鍵值對"
+ "updating_pair": "更新鍵值對",
+ "db_not_found": "未找到數據庫文件:{path}",
+ "db_permission_error": "無法訪問數據庫文件,請檢查權限",
+ "db_connection_error": "連接數據庫失敗:{error}"
},
"control": {
"generate_email": "生成新郵箱",
@@ -179,7 +164,7 @@
},
"email": {
"starting_browser": "啟動瀏覽器",
- "visiting_site": "訪問 smailpro.com",
+ "visiting_site": "訪問 mail.tm",
"create_success": "郵箱創建成功",
"create_failed": "郵箱創建失敗",
"create_error": "郵箱創建錯誤: {error}",
diff --git a/main.py b/main.py
index 05335d9..a2c8b31 100644
--- a/main.py
+++ b/main.py
@@ -25,43 +25,71 @@ EMOJI = {
class Translator:
def __init__(self):
- self.current_language = 'zh_tw' # 默认语言
+ self.current_language = 'en' # Default language
self.translations = {}
+ self.fallback_language = 'en' # Fallback language if translation is missing
self.load_translations()
def load_translations(self):
- """加载所有可用的翻译"""
- locales_dir = os.path.join(os.path.dirname(__file__), 'locales')
- if hasattr(sys, '_MEIPASS'):
- locales_dir = os.path.join(sys._MEIPASS, 'locales')
+ """Load all available translations"""
+ try:
+ locales_dir = os.path.join(os.path.dirname(__file__), 'locales')
+ if hasattr(sys, '_MEIPASS'):
+ locales_dir = os.path.join(sys._MEIPASS, 'locales')
- for file in os.listdir(locales_dir):
- if file.endswith('.json'):
- lang_code = file[:-5] # 移除 .json
- with open(os.path.join(locales_dir, file), 'r', encoding='utf-8') as f:
- self.translations[lang_code] = json.load(f)
+ if not os.path.exists(locales_dir):
+ print(f"{Fore.RED}{EMOJI['ERROR']} Locales directory not found{Style.RESET_ALL}")
+ return
+
+ for file in os.listdir(locales_dir):
+ if file.endswith('.json'):
+ lang_code = file[:-5] # Remove .json
+ try:
+ with open(os.path.join(locales_dir, file), 'r', encoding='utf-8') as f:
+ self.translations[lang_code] = json.load(f)
+ except (json.JSONDecodeError, UnicodeDecodeError) as e:
+ print(f"{Fore.RED}{EMOJI['ERROR']} Error loading {file}: {e}{Style.RESET_ALL}")
+ continue
+ except Exception as e:
+ print(f"{Fore.RED}{EMOJI['ERROR']} Failed to load translations: {e}{Style.RESET_ALL}")
def get(self, key, **kwargs):
- """获取翻译文本"""
+ """Get translated text with fallback support"""
+ try:
+ # Try current language
+ result = self._get_translation(self.current_language, key)
+ if result == key and self.current_language != self.fallback_language:
+ # Try fallback language if translation not found
+ result = self._get_translation(self.fallback_language, key)
+ return result.format(**kwargs) if kwargs else result
+ except Exception:
+ return key
+
+ def _get_translation(self, lang_code, key):
+ """Get translation for a specific language"""
try:
keys = key.split('.')
- value = self.translations.get(self.current_language, {})
+ value = self.translations.get(lang_code, {})
for k in keys:
if isinstance(value, dict):
value = value.get(k, key)
else:
- return key # 如果中間值不是字典,返回原始key
- return value.format(**kwargs) if kwargs else value
+ return key
+ return value
except Exception:
- return key # 出現任何錯誤時返回原始key
+ return key
def set_language(self, lang_code):
- """设置当前语言"""
+ """Set current language with validation"""
if lang_code in self.translations:
self.current_language = lang_code
return True
return False
+ def get_available_languages(self):
+ """Get list of available languages"""
+ return list(self.translations.keys())
+
# 创建翻译器实例
translator = Translator()
@@ -79,25 +107,26 @@ def print_menu():
print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}")
def select_language():
- """语言选择菜单"""
+ """Language selection menu"""
print(f"\n{Fore.CYAN}{EMOJI['LANG']} {translator.get('menu.select_language')}:{Style.RESET_ALL}")
print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}")
- languages = translator.get('languages')
- for i, (code, name) in enumerate(languages.items()):
- print(f"{Fore.GREEN}{i}{Style.RESET_ALL}. {name}")
+ languages = translator.get_available_languages()
+ for i, lang in enumerate(languages):
+ lang_name = translator.get(f"languages.{lang}")
+ print(f"{Fore.GREEN}{i}{Style.RESET_ALL}. {lang_name}")
try:
- choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices='0-' + str(len(languages)-1))}: {Style.RESET_ALL}")
+ choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices=f'0-{len(languages)-1}')}: {Style.RESET_ALL}")
if choice.isdigit() and 0 <= int(choice) < len(languages):
- lang_code = list(languages.keys())[int(choice)]
- translator.set_language(lang_code)
+ translator.set_language(languages[int(choice)])
return True
+ else:
+ print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
+ return False
except (ValueError, IndexError):
- pass
-
- print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
- return False
+ print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
+ return False
def main():
print_logo()
@@ -151,4 +180,4 @@ def main():
input(f"{EMOJI['INFO']} {translator.get('menu.press_enter')}...{Style.RESET_ALL}")
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
\ No newline at end of file
diff --git a/new_tempemail.py b/new_tempemail.py
index cdca8b9..25c5b05 100644
--- a/new_tempemail.py
+++ b/new_tempemail.py
@@ -3,6 +3,9 @@ import time
import os
import sys
from colorama import Fore, Style, init
+import requests
+import random
+import string
# 初始化 colorama
init()
@@ -10,95 +13,73 @@ init()
class NewTempEmail:
def __init__(self, translator=None):
self.translator = translator
- self.page = None
- self.setup_browser()
+ # Randomly choose between mail.tm and mail.gw
+ self.services = [
+ {"name": "mail.tm", "api_url": "https://api.mail.tm"},
+ {"name": "mail.gw", "api_url": "https://api.mail.gw"}
+ ]
+ self.selected_service = random.choice(self.services)
+ self.api_url = self.selected_service["api_url"]
+ self.token = None
+ self.email = None
+ self.password = None
- def get_extension_block(self):
- """获取插件路径"""
- root_dir = os.getcwd()
- extension_path = os.path.join(root_dir, "PBlock")
+ def _generate_credentials(self):
+ """生成随机用户名和密码"""
+ username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
+ password = ''.join(random.choices(string.ascii_letters + string.digits + string.punctuation, k=12))
+ return username, password
- if hasattr(sys, "_MEIPASS"):
- extension_path = os.path.join(sys._MEIPASS, "PBlock")
-
- if not os.path.exists(extension_path):
- raise FileNotFoundError(f"插件不存在: {extension_path}")
-
- return extension_path
-
- def setup_browser(self):
- """设置浏览器"""
- try:
- if self.translator:
- print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.starting_browser')}{Style.RESET_ALL}")
- else:
- print(f"{Fore.CYAN}ℹ️ 正在启动浏览器...{Style.RESET_ALL}")
-
- # 创建浏览器选项
- co = ChromiumOptions()
- co.set_argument("--headless=new")
-
- co.auto_port() # 自动设置端口
-
- # 加载 uBlock 插件
- try:
- extension_path = self.get_extension_block()
- co.set_argument("--allow-extensions-in-incognito")
- co.add_extension(extension_path)
- except Exception as e:
- if self.translator:
- print(f"{Fore.YELLOW}⚠️ {self.translator.get('email.extension_load_error')}: {str(e)}{Style.RESET_ALL}")
- else:
- print(f"{Fore.YELLOW}⚠️ 加载插件失败: {str(e)}{Style.RESET_ALL}")
-
- self.page = ChromiumPage(co)
- return True
- except Exception as e:
- if self.translator:
- print(f"{Fore.RED}❌ {self.translator.get('email.browser_start_error')}: {str(e)}{Style.RESET_ALL}")
- else:
- print(f"{Fore.RED}❌ 启动浏览器失败: {str(e)}{Style.RESET_ALL}")
- return False
-
def create_email(self):
"""创建临时邮箱"""
try:
if self.translator:
- print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.visiting_site')}{Style.RESET_ALL}")
+ print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.visiting_site').replace('mail.tm', self.selected_service['name'])}{Style.RESET_ALL}")
else:
- print(f"{Fore.CYAN}ℹ️ 正在访问 smailpro.com...{Style.RESET_ALL}")
+ print(f"{Fore.CYAN}ℹ️ 正在访问 {self.selected_service['name']}...{Style.RESET_ALL}")
- # 访问网站
- self.page.get("https://smailpro.com/")
- time.sleep(2)
-
- # 点击创建邮箱按钮
- create_button = self.page.ele('xpath://button[@title="Create temporary email"]')
- if create_button:
- create_button.click()
- time.sleep(1)
+ # 获取可用域名列表
+ domains_response = requests.get(f"{self.api_url}/domains")
+ if domains_response.status_code != 200:
+ raise Exception("Failed to get available domains")
- # 点击弹窗中的 Create 按钮
- modal_create_button = self.page.ele('xpath://button[contains(text(), "Create")]')
- if modal_create_button:
- modal_create_button.click()
- time.sleep(2)
-
- # 获取邮箱地址 - 修改选择器
- email_div = self.page.ele('xpath://div[@class="text-base sm:text-lg md:text-xl text-gray-700"]')
- if email_div:
- email = email_div.text.strip()
- if '@' in email: # 验证是否是有效的邮箱地址
- if self.translator:
- print(f"{Fore.GREEN}✅ {self.translator.get('email.create_success')}: {email}{Style.RESET_ALL}")
- else:
- print(f"{Fore.GREEN}✅ 创建邮箱成功: {email}{Style.RESET_ALL}")
- return email
+ domains = domains_response.json()["hydra:member"]
+ if not domains:
+ raise Exception("No available domains")
+
+ # 生成随机用户名和密码
+ username, password = self._generate_credentials()
+ self.password = password
+
+ # 创建邮箱账户
+ email = f"{username}@{domains[0]['domain']}"
+ account_data = {
+ "address": email,
+ "password": password
+ }
+
+ create_response = requests.post(f"{self.api_url}/accounts", json=account_data)
+ if create_response.status_code != 201:
+ raise Exception("Failed to create account")
+
+ # 获取访问令牌
+ token_data = {
+ "address": email,
+ "password": password
+ }
+
+ token_response = requests.post(f"{self.api_url}/token", json=token_data)
+ if token_response.status_code != 200:
+ raise Exception("Failed to get access token")
+
+ self.token = token_response.json()["token"]
+ self.email = email
+
if self.translator:
- print(f"{Fore.RED}❌ {self.translator.get('email.create_failed')}{Style.RESET_ALL}")
+ print(f"{Fore.GREEN}✅ {self.translator.get('email.create_success')}: {email}{Style.RESET_ALL}")
else:
- print(f"{Fore.RED}❌ 创建邮箱失败{Style.RESET_ALL}")
- return None
+ print(f"{Fore.GREEN}✅ 创建邮箱成功: {email}{Style.RESET_ALL}")
+ return email
except Exception as e:
if self.translator:
@@ -120,11 +101,11 @@ class NewTempEmail:
else:
print(f"{Fore.CYAN}🔄 正在刷新邮箱...{Style.RESET_ALL}")
- # 点击刷新按钮
- refresh_button = self.page.ele('xpath://button[@id="refresh"]')
- if refresh_button:
- refresh_button.click()
- time.sleep(2) # 等待刷新完成
+ # 使用 API 获取最新邮件
+ headers = {"Authorization": f"Bearer {self.token}"}
+ response = requests.get(f"{self.api_url}/messages", headers=headers)
+
+ if response.status_code == 200:
if self.translator:
print(f"{Fore.GREEN}✅ {self.translator.get('email.refresh_success')}{Style.RESET_ALL}")
else:
@@ -132,9 +113,9 @@ class NewTempEmail:
return True
if self.translator:
- print(f"{Fore.RED}❌ {self.translator.get('email.refresh_button_not_found')}{Style.RESET_ALL}")
+ print(f"{Fore.RED}❌ {self.translator.get('email.refresh_failed')}{Style.RESET_ALL}")
else:
- print(f"{Fore.RED}❌ 未找到刷新按钮{Style.RESET_ALL}")
+ print(f"{Fore.RED}❌ 刷新邮箱失败{Style.RESET_ALL}")
return False
except Exception as e:
@@ -147,17 +128,24 @@ class NewTempEmail:
def check_for_cursor_email(self):
"""检查是否有 Cursor 的验证邮件"""
try:
- # 查找验证邮件 - 使用更精确的选择器
- email_div = self.page.ele('xpath://div[contains(@class, "p-2") and contains(@class, "cursor-pointer") and contains(@class, "bg-white") and contains(@class, "shadow") and .//b[text()="no-reply@cursor.sh"] and .//span[text()="Verify your email address"]]')
- if email_div:
- if self.translator:
- print(f"{Fore.GREEN}✅ {self.translator.get('email.verification_found')}{Style.RESET_ALL}")
- else:
- print(f"{Fore.GREEN}✅ 找到验证邮件{Style.RESET_ALL}")
- # 使用 JavaScript 点击元素
- self.page.run_js('arguments[0].click()', email_div)
- time.sleep(2) # 等待邮件内容加载
- return True
+ # 使用 API 获取邮件列表
+ headers = {"Authorization": f"Bearer {self.token}"}
+ response = requests.get(f"{self.api_url}/messages", headers=headers)
+
+ if response.status_code == 200:
+ messages = response.json()["hydra:member"]
+ for message in messages:
+ if message["from"]["address"] == "no-reply@cursor.sh" and "Verify your email address" in message["subject"]:
+ # 获取邮件内容
+ message_id = message["id"]
+ message_response = requests.get(f"{self.api_url}/messages/{message_id}", headers=headers)
+ if message_response.status_code == 200:
+ if self.translator:
+ print(f"{Fore.GREEN}✅ {self.translator.get('email.verification_found')}{Style.RESET_ALL}")
+ else:
+ print(f"{Fore.GREEN}✅ 找到验证邮件{Style.RESET_ALL}")
+ return True
+
if self.translator:
print(f"{Fore.YELLOW}⚠️ {self.translator.get('email.verification_not_found')}{Style.RESET_ALL}")
else:
@@ -174,16 +162,33 @@ class NewTempEmail:
def get_verification_code(self):
"""获取验证码"""
try:
- # 查找验证码元素
- code_element = self.page.ele('xpath://td//div[contains(@style, "font-size:28px") and contains(@style, "letter-spacing:2px")]')
- if code_element:
- code = code_element.text.strip()
- if code.isdigit() and len(code) == 6:
- if self.translator:
- print(f"{Fore.GREEN}✅ {self.translator.get('email.verification_code_found')}: {code}{Style.RESET_ALL}")
- else:
- print(f"{Fore.GREEN}✅ 获取验证码成功: {code}{Style.RESET_ALL}")
- return code
+ # 使用 API 获取邮件列表
+ headers = {"Authorization": f"Bearer {self.token}"}
+ response = requests.get(f"{self.api_url}/messages", headers=headers)
+
+ if response.status_code == 200:
+ messages = response.json()["hydra:member"]
+ for message in messages:
+ if message["from"]["address"] == "no-reply@cursor.sh" and "Verify your email address" in message["subject"]:
+ # 获取邮件内容
+ message_id = message["id"]
+ message_response = requests.get(f"{self.api_url}/messages/{message_id}", headers=headers)
+
+ if message_response.status_code == 200:
+ # 从邮件内容中提取验证码
+ email_content = message_response.json()["text"]
+ # 查找6位数字验证码
+ import re
+ code_match = re.search(r'\b\d{6}\b', email_content)
+
+ if code_match:
+ code = code_match.group(0)
+ if self.translator:
+ print(f"{Fore.GREEN}✅ {self.translator.get('email.verification_code_found')}: {code}{Style.RESET_ALL}")
+ else:
+ print(f"{Fore.GREEN}✅ 获取验证码成功: {code}{Style.RESET_ALL}")
+ return code
+
if self.translator:
print(f"{Fore.YELLOW}⚠️ {self.translator.get('email.verification_code_not_found')}{Style.RESET_ALL}")
else:
@@ -223,4 +228,4 @@ def main(translator=None):
temp_email.close()
if __name__ == "__main__":
- main()
\ No newline at end of file
+ main()
\ No newline at end of file