mirror of
https://github.com/yeongpin/cursor-free-vip.git
synced 2025-08-03 04:57:36 +08:00
Merge pull request #94 from UntaDotMy/main
feat: Add support for Cursor v0.46.X and improve email service
This commit is contained in:
commit
4c91525082
33
.github/workflows/build.yml
vendored
33
.github/workflows/build.yml
vendored
@ -63,7 +63,7 @@ jobs:
|
|||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: CursorFreeVIP_${{ env.VERSION }}_windows.exe
|
name: CursorFreeVIP_${{ env.VERSION }}_windows.exe
|
||||||
path: dist/*
|
path: dist/CursorFreeVIP_${{ env.VERSION }}_windows.exe
|
||||||
|
|
||||||
build-macos-arm64:
|
build-macos-arm64:
|
||||||
needs: create-tag
|
needs: create-tag
|
||||||
@ -90,12 +90,13 @@ jobs:
|
|||||||
- name: Build MacOS ARM executable
|
- name: Build MacOS ARM executable
|
||||||
run: |
|
run: |
|
||||||
pyinstaller build.spec
|
pyinstaller build.spec
|
||||||
|
mv "dist/CursorFreeVIP_${{ env.VERSION }}_mac" "dist/CursorFreeVIP_${{ env.VERSION }}_mac_arm64"
|
||||||
|
|
||||||
- name: Upload MacOS ARM artifact
|
- name: Upload MacOS ARM artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
name: CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
||||||
path: dist/*
|
path: dist/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
||||||
|
|
||||||
build-linux:
|
build-linux:
|
||||||
needs: create-tag
|
needs: create-tag
|
||||||
@ -120,14 +121,18 @@ jobs:
|
|||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
|
||||||
- name: Build Linux executable
|
- name: Build Linux executable
|
||||||
|
env:
|
||||||
|
VERSION: ${{ env.VERSION }}
|
||||||
run: |
|
run: |
|
||||||
pyinstaller build.spec
|
pyinstaller build.spec
|
||||||
|
echo "Contents of dist directory:"
|
||||||
|
ls -la dist/
|
||||||
|
|
||||||
- name: Upload Linux artifact
|
- name: Upload Linux artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: CursorFreeVIP_${{ env.VERSION }}_linux
|
name: CursorFreeVIP_${{ env.VERSION }}_linux
|
||||||
path: dist/*
|
path: dist/CursorFreeVIP_${{ env.VERSION }}_linux
|
||||||
|
|
||||||
|
|
||||||
build-macos-intel:
|
build-macos-intel:
|
||||||
@ -155,14 +160,16 @@ jobs:
|
|||||||
- name: Build MacOS Intel executable
|
- name: Build MacOS Intel executable
|
||||||
env:
|
env:
|
||||||
TARGET_ARCH: 'x86_64'
|
TARGET_ARCH: 'x86_64'
|
||||||
|
VERSION: ${{ env.VERSION }}
|
||||||
run: |
|
run: |
|
||||||
arch -x86_64 python3 -m PyInstaller build.spec
|
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
|
- name: Upload MacOS Intel artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
name: CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
||||||
path: dist/*
|
path: dist/CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
||||||
|
|
||||||
|
|
||||||
create-release:
|
create-release:
|
||||||
@ -182,24 +189,20 @@ jobs:
|
|||||||
- name: Prepare release files
|
- name: Prepare release files
|
||||||
run: |
|
run: |
|
||||||
cd artifacts
|
cd artifacts
|
||||||
# 重命名文件为最终的可执行文件名
|
echo "Contents of artifacts directory:"
|
||||||
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 */
|
|
||||||
ls -la
|
ls -la
|
||||||
|
echo "Contents of subdirectories:"
|
||||||
|
ls -la */
|
||||||
|
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
tag_name: v${{ env.VERSION }}
|
tag_name: v${{ env.VERSION }}
|
||||||
files: |
|
files: |
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe/CursorFreeVIP_${{ env.VERSION }}_windows.exe
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_linux
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_linux/CursorFreeVIP_${{ env.VERSION }}_linux
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_intel/CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
||||||
draft: false
|
draft: false
|
||||||
prerelease: false
|
prerelease: false
|
||||||
env:
|
env:
|
||||||
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
cursor_accounts.txt
|
||||||
|
/venv
|
||||||
|
/__pycache__
|
10
CHANGELOG.md
10
CHANGELOG.md
@ -1,5 +1,15 @@
|
|||||||
# Change Log
|
# 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
|
## v1.4.01
|
||||||
|
|
||||||
1. Add Disable Cursor Auto Upgrade | 增加禁用Cursor自動升級
|
1. Add Disable Cursor Auto Upgrade | 增加禁用Cursor自動升級
|
||||||
|
@ -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.45.16 Version | 支持最新0.45.16版本</h4>
|
<h4>Support Latest 0.46.3 Version | 支持最新0.46.3本</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.
|
||||||
|
|
||||||
|
@ -31,6 +31,23 @@ class CursorAuth:
|
|||||||
"~/Library/Application Support/Cursor/User/globalStorage/state.vscdb"
|
"~/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):
|
def update_auth(self, email=None, access_token=None, refresh_token=None):
|
||||||
conn = None
|
conn = None
|
||||||
try:
|
try:
|
||||||
|
@ -76,10 +76,9 @@ class CursorRegistration:
|
|||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.email_create_failed')}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.email_create_failed')}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# 保存邮箱地址和浏览器实例
|
# 保存邮箱地址
|
||||||
self.email_address = email_address
|
self.email_address = email_address
|
||||||
self.email_tab = self.temp_email # 传递 NewTempEmail 实例而不是 page
|
self.email_tab = self.temp_email # 传递 NewTempEmail 实例
|
||||||
self.controller = BrowserControl(self.temp_email.page, self.translator)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -2,17 +2,17 @@
|
|||||||
"menu": {
|
"menu": {
|
||||||
"title": "Available Options",
|
"title": "Available Options",
|
||||||
"exit": "Exit Program",
|
"exit": "Exit Program",
|
||||||
"reset": "Reset Machine Manual",
|
"reset": "Reset Machine ID",
|
||||||
"register": "Register Cursor",
|
"register": "Register New Cursor Account",
|
||||||
"register_manual": "Register Cursor With Manual Email",
|
"register_manual": "Register Cursor with Custom Email",
|
||||||
"quit": "Quit Cursor",
|
"quit": "Close Cursor Application",
|
||||||
"select_language": "Select Language",
|
"select_language": "Change Language",
|
||||||
"input_choice": "Enter your choice ({choices})",
|
"input_choice": "Please enter your choice ({choices})",
|
||||||
"invalid_choice": "Invalid choice. Please try again",
|
"invalid_choice": "Invalid selection. Please enter a number from {choices}",
|
||||||
"program_terminated": "Program terminated by user",
|
"program_terminated": "Program was terminated by user",
|
||||||
"error_occurred": "An error occurred: {error}",
|
"error_occurred": "An error occurred: {error}. Please try again",
|
||||||
"press_enter": "Press Enter to Exit",
|
"press_enter": "Press Enter to Exit",
|
||||||
"disable_auto_update": "Disable Cursor Auto Update"
|
"disable_auto_update": "Disable Cursor Auto-Update"
|
||||||
},
|
},
|
||||||
"languages": {
|
"languages": {
|
||||||
"en": "English",
|
"en": "English",
|
||||||
@ -68,21 +68,21 @@
|
|||||||
},
|
},
|
||||||
"register": {
|
"register": {
|
||||||
"title": "Cursor Registration Tool",
|
"title": "Cursor Registration Tool",
|
||||||
"start": "Starting Registration Process",
|
"start": "Starting registration process...",
|
||||||
"handling_turnstile": "Handling Turnstile",
|
"handling_turnstile": "Processing security verification...",
|
||||||
"retry_verification": "Retry Verification",
|
"retry_verification": "Retrying verification...",
|
||||||
"detect_turnstile": "Detect Turnstile",
|
"detect_turnstile": "Checking security verification...",
|
||||||
"verification_success": "Verification Success",
|
"verification_success": "Security verification successful",
|
||||||
"starting_browser": "Starting Browser",
|
"starting_browser": "Opening browser...",
|
||||||
"form_success": "Form Success",
|
"form_success": "Form submitted successfully",
|
||||||
"browser_started": "Browser Started",
|
"browser_started": "Browser opened successfully",
|
||||||
"waiting_for_second_verification": "Waiting for Second Verification",
|
"waiting_for_second_verification": "Waiting for email verification...",
|
||||||
"waiting_for_verification_code": "Waiting for Verification Code",
|
"waiting_for_verification_code": "Waiting for verification code...",
|
||||||
"password_success": "Password Set Successfully",
|
"password_success": "Password set successfully",
|
||||||
"password_error": "Password Set Failed: {error}",
|
"password_error": "Could not set password: {error}. Please try again",
|
||||||
"waiting_for_page_load": "Waiting for Page Load",
|
"waiting_for_page_load": "Loading page...",
|
||||||
"first_verification_passed": "First Verification Passed",
|
"first_verification_passed": "Initial verification successful",
|
||||||
"mailbox": "Successfully Entered Mailbox",
|
"mailbox": "Successfully accessed email inbox",
|
||||||
"register_start": "Start Register",
|
"register_start": "Start Register",
|
||||||
"form_submitted": "Form Submitted, Start Verification...",
|
"form_submitted": "Form Submitted, Start Verification...",
|
||||||
"filling_form": "Fill Form",
|
"filling_form": "Fill Form",
|
||||||
@ -145,7 +145,10 @@
|
|||||||
"database_connection_closed": "Database Connection Closed",
|
"database_connection_closed": "Database Connection Closed",
|
||||||
"database_updated_successfully": "Database Updated Successfully",
|
"database_updated_successfully": "Database Updated Successfully",
|
||||||
"connected_to_database": "Connected to Database",
|
"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": {
|
"control": {
|
||||||
"generate_email": "Generating New Email",
|
"generate_email": "Generating New Email",
|
||||||
@ -182,7 +185,7 @@
|
|||||||
},
|
},
|
||||||
"email": {
|
"email": {
|
||||||
"starting_browser": "Starting Browser",
|
"starting_browser": "Starting Browser",
|
||||||
"visiting_site": "Visiting smailpro.com",
|
"visiting_site": "Visiting mail.tm",
|
||||||
"create_success": "Email Created Successfully",
|
"create_success": "Email Created Successfully",
|
||||||
"create_failed": "Failed to Create Email",
|
"create_failed": "Failed to Create Email",
|
||||||
"create_error": "Email Creation Error: {error}",
|
"create_error": "Email Creation Error: {error}",
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
"title": "可用选项",
|
"title": "可用选项",
|
||||||
"exit": "退出程序",
|
"exit": "退出程序",
|
||||||
"reset": "重置机器标识",
|
"reset": "重置机器标识",
|
||||||
"register": "注册 Cursor",
|
"register": "注册新 Cursor 账号",
|
||||||
"register_manual": "手动指定邮箱注册 Cursor",
|
"register_manual": "使用自定义邮箱注册",
|
||||||
"quit": "退出 Cursor",
|
"quit": "关闭 Cursor 应用",
|
||||||
"select_language": "选择语言",
|
"select_language": "更改语言",
|
||||||
"input_choice": "输入选择 ({choices})",
|
"input_choice": "请输入您的选择 ({choices})",
|
||||||
"invalid_choice": "无效选择,请重试",
|
"invalid_choice": "选择无效,请输入 {choices} 范围内的数字",
|
||||||
"program_terminated": "程序被用户终止",
|
"program_terminated": "程序已被用户终止",
|
||||||
"error_occurred": "发生错误: {error}",
|
"error_occurred": "发生错误:{error},请重试",
|
||||||
"press_enter": "按回车键退出",
|
"press_enter": "按回车键退出",
|
||||||
"disable_auto_update": "禁用 Cursor 自动更新"
|
"disable_auto_update": "禁用 Cursor 自动更新"
|
||||||
},
|
},
|
||||||
@ -68,25 +68,25 @@
|
|||||||
},
|
},
|
||||||
"register": {
|
"register": {
|
||||||
"title": "Cursor 注册工具",
|
"title": "Cursor 注册工具",
|
||||||
"start": "开始注册流程",
|
"start": "正在启动注册流程...",
|
||||||
"browser_started": "浏览器已启动",
|
"browser_started": "浏览器已成功打开",
|
||||||
"password_success": "密码设置完成",
|
"password_success": "密码设置成功",
|
||||||
"password_error": "密码设置失败: {error}",
|
"password_error": "无法设置密码:{error},请重试",
|
||||||
"waiting_for_page_load": "等待页面加载",
|
"waiting_for_page_load": "页面加载中...",
|
||||||
"mailbox": "成功进入邮箱",
|
"mailbox": "已成功访问邮箱",
|
||||||
"waiting_for_second_verification": "等待第二阶段验证",
|
"waiting_for_second_verification": "等待邮箱验证...",
|
||||||
"waiting_for_verification_code": "等待验证码",
|
"waiting_for_verification_code": "等待验证码...",
|
||||||
"first_verification_passed": "第一阶段验证通过",
|
"first_verification_passed": "初始验证通过",
|
||||||
"register_start": "开始注册流程",
|
"register_start": "开始注册流程",
|
||||||
"form_submitted": "表单已提交,开始验证...",
|
"form_submitted": "表单已提交,开始验证...",
|
||||||
"filling_form": "填写注册信息",
|
"filling_form": "填写注册信息",
|
||||||
"visiting_url": "访问URL",
|
"visiting_url": "访问URL",
|
||||||
"basic_info": "基本信息提交完成",
|
"basic_info": "基本信息提交完成",
|
||||||
"handling_turnstile": "处理 Turnstile 验证",
|
"handling_turnstile": "正在处理安全验证...",
|
||||||
"retry_verification": "重试验证",
|
"retry_verification": "正在重试验证...",
|
||||||
"detect_turnstile": "检测 Turnstile 验证",
|
"detect_turnstile": "正在检查安全验证...",
|
||||||
"verification_success": "验证成功",
|
"verification_success": "安全验证通过",
|
||||||
"starting_browser": "启动浏览器",
|
"starting_browser": "正在打开浏览器...",
|
||||||
"form_success": "表单提交成功",
|
"form_success": "表单提交成功",
|
||||||
"handle_turnstile": "处理 Turnstile 验证",
|
"handle_turnstile": "处理 Turnstile 验证",
|
||||||
"no_turnstile": "未检测到 Turnstile 验证",
|
"no_turnstile": "未检测到 Turnstile 验证",
|
||||||
@ -144,7 +144,10 @@
|
|||||||
"connected_to_database": "已连接到数据库",
|
"connected_to_database": "已连接到数据库",
|
||||||
"database_updated_successfully": "数据库更新成功",
|
"database_updated_successfully": "数据库更新成功",
|
||||||
"database_connection_closed": "数据库连接已关闭",
|
"database_connection_closed": "数据库连接已关闭",
|
||||||
"updating_pair": "更新键值对"
|
"updating_pair": "更新键值对",
|
||||||
|
"db_not_found": "未找到数据库文件:{path}",
|
||||||
|
"db_permission_error": "无法访问数据库文件,请检查权限",
|
||||||
|
"db_connection_error": "连接数据库失败:{error}"
|
||||||
},
|
},
|
||||||
"control": {
|
"control": {
|
||||||
"generate_email": "生成新邮箱",
|
"generate_email": "生成新邮箱",
|
||||||
@ -179,7 +182,7 @@
|
|||||||
},
|
},
|
||||||
"email": {
|
"email": {
|
||||||
"starting_browser": "启动浏览器",
|
"starting_browser": "启动浏览器",
|
||||||
"visiting_site": "访问 smailpro.com",
|
"visiting_site": "访问 mail.tm",
|
||||||
"create_success": "邮箱创建成功",
|
"create_success": "邮箱创建成功",
|
||||||
"create_failed": "邮箱创建失败",
|
"create_failed": "邮箱创建失败",
|
||||||
"create_error": "邮箱创建错误: {error}",
|
"create_error": "邮箱创建错误: {error}",
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
{
|
{
|
||||||
"menu": {
|
"menu": {
|
||||||
"title": "可用選項",
|
"title": "可用選項",
|
||||||
"exit": "退出程序",
|
"exit": "退出程式",
|
||||||
"reset": "重置機器標識",
|
"reset": "重置機器識別碼",
|
||||||
"register": "註冊 Cursor",
|
"register": "註冊新 Cursor 帳號",
|
||||||
"register_manual": "手動指定郵箱註冊 Cursor",
|
"register_manual": "使用自訂郵箱註冊",
|
||||||
"quit": "退出 Cursor",
|
"quit": "關閉 Cursor 應用程式",
|
||||||
"select_language": "選擇語言",
|
"select_language": "變更語言",
|
||||||
"input_choice": "輸入選擇 ({choices})",
|
"input_choice": "請輸入您的選擇 ({choices})",
|
||||||
"invalid_choice": "無效選擇,請重試",
|
"invalid_choice": "選擇無效,請輸入 {choices} 範圍內的數字",
|
||||||
"program_terminated": "程序被用戶終止",
|
"program_terminated": "程式已被使用者終止",
|
||||||
"error_occurred": "發生錯誤: {error}",
|
"error_occurred": "發生錯誤:{error},請重試",
|
||||||
"press_enter": "按回車鍵退出",
|
"press_enter": "按返回鍵退出",
|
||||||
"disable_auto_update": "禁用 Cursor 自動更新"
|
"disable_auto_update": "停用 Cursor 自動更新"
|
||||||
},
|
},
|
||||||
"languages": {
|
"languages": {
|
||||||
"en": "English",
|
"en": "English",
|
||||||
@ -68,17 +68,24 @@
|
|||||||
},
|
},
|
||||||
"register": {
|
"register": {
|
||||||
"title": "Cursor 註冊工具",
|
"title": "Cursor 註冊工具",
|
||||||
"start": "開始註冊流程",
|
"start": "正在啟動註冊流程...",
|
||||||
"mailbox": "成功進入郵箱",
|
"handling_turnstile": "正在處理安全驗證...",
|
||||||
"browser_started": "瀏覽器已啟動",
|
"retry_verification": "正在重試驗證...",
|
||||||
"waiting_for_page_load": "等待頁面加載",
|
"detect_turnstile": "正在檢查安全驗證...",
|
||||||
"password_success": "密碼設置完成",
|
"verification_success": "安全驗證通過",
|
||||||
"password_error": "密碼設置失敗: {error}",
|
"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",
|
"visiting_url": "訪問URL",
|
||||||
"first_verification_passed": "第一階段驗證通過",
|
|
||||||
"register_start": "開始註冊流程",
|
"register_start": "開始註冊流程",
|
||||||
"form_submitted": "表單已提交,開始驗證...",
|
"form_submitted": "表單已提交,開始驗證...",
|
||||||
"waiting_for_second_verification": "等待第二階段驗證",
|
|
||||||
"filling_form": "填寫註冊信息",
|
"filling_form": "填寫註冊信息",
|
||||||
"basic_info": "基本信息提交完成",
|
"basic_info": "基本信息提交完成",
|
||||||
"handle_turnstile": "處理 Turnstile 驗證",
|
"handle_turnstile": "處理 Turnstile 驗證",
|
||||||
@ -86,31 +93,6 @@
|
|||||||
"turnstile_passed": "驗證通過",
|
"turnstile_passed": "驗證通過",
|
||||||
"verification_start": "開始獲取驗證碼",
|
"verification_start": "開始獲取驗證碼",
|
||||||
"waiting_for_verification_code": "等待驗證碼",
|
"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": "驗證碼填寫完成",
|
"verification_code_filled": "驗證碼填寫完成",
|
||||||
"login_success_and_jump_to_settings_page": "成功登錄並跳轉到設置頁面",
|
"login_success_and_jump_to_settings_page": "成功登錄並跳轉到設置頁面",
|
||||||
"detect_login_page": "檢測到登錄頁面,開始登錄...",
|
"detect_login_page": "檢測到登錄頁面,開始登錄...",
|
||||||
@ -144,7 +126,10 @@
|
|||||||
"connected_to_database": "已連接到數據庫",
|
"connected_to_database": "已連接到數據庫",
|
||||||
"database_updated_successfully": "數據庫更新成功",
|
"database_updated_successfully": "數據庫更新成功",
|
||||||
"database_connection_closed": "數據庫連接已關閉",
|
"database_connection_closed": "數據庫連接已關閉",
|
||||||
"updating_pair": "更新鍵值對"
|
"updating_pair": "更新鍵值對",
|
||||||
|
"db_not_found": "未找到數據庫文件:{path}",
|
||||||
|
"db_permission_error": "無法訪問數據庫文件,請檢查權限",
|
||||||
|
"db_connection_error": "連接數據庫失敗:{error}"
|
||||||
},
|
},
|
||||||
"control": {
|
"control": {
|
||||||
"generate_email": "生成新郵箱",
|
"generate_email": "生成新郵箱",
|
||||||
@ -179,7 +164,7 @@
|
|||||||
},
|
},
|
||||||
"email": {
|
"email": {
|
||||||
"starting_browser": "啟動瀏覽器",
|
"starting_browser": "啟動瀏覽器",
|
||||||
"visiting_site": "訪問 smailpro.com",
|
"visiting_site": "訪問 mail.tm",
|
||||||
"create_success": "郵箱創建成功",
|
"create_success": "郵箱創建成功",
|
||||||
"create_failed": "郵箱創建失敗",
|
"create_failed": "郵箱創建失敗",
|
||||||
"create_error": "郵箱創建錯誤: {error}",
|
"create_error": "郵箱創建錯誤: {error}",
|
||||||
|
83
main.py
83
main.py
@ -25,43 +25,71 @@ EMOJI = {
|
|||||||
|
|
||||||
class Translator:
|
class Translator:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.current_language = 'zh_tw' # 默认语言
|
self.current_language = 'en' # Default language
|
||||||
self.translations = {}
|
self.translations = {}
|
||||||
|
self.fallback_language = 'en' # Fallback language if translation is missing
|
||||||
self.load_translations()
|
self.load_translations()
|
||||||
|
|
||||||
def load_translations(self):
|
def load_translations(self):
|
||||||
"""加载所有可用的翻译"""
|
"""Load all available translations"""
|
||||||
locales_dir = os.path.join(os.path.dirname(__file__), 'locales')
|
try:
|
||||||
if hasattr(sys, '_MEIPASS'):
|
locales_dir = os.path.join(os.path.dirname(__file__), 'locales')
|
||||||
locales_dir = os.path.join(sys._MEIPASS, 'locales')
|
if hasattr(sys, '_MEIPASS'):
|
||||||
|
locales_dir = os.path.join(sys._MEIPASS, 'locales')
|
||||||
|
|
||||||
for file in os.listdir(locales_dir):
|
if not os.path.exists(locales_dir):
|
||||||
if file.endswith('.json'):
|
print(f"{Fore.RED}{EMOJI['ERROR']} Locales directory not found{Style.RESET_ALL}")
|
||||||
lang_code = file[:-5] # 移除 .json
|
return
|
||||||
with open(os.path.join(locales_dir, file), 'r', encoding='utf-8') as f:
|
|
||||||
self.translations[lang_code] = json.load(f)
|
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):
|
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:
|
try:
|
||||||
keys = key.split('.')
|
keys = key.split('.')
|
||||||
value = self.translations.get(self.current_language, {})
|
value = self.translations.get(lang_code, {})
|
||||||
for k in keys:
|
for k in keys:
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
value = value.get(k, key)
|
value = value.get(k, key)
|
||||||
else:
|
else:
|
||||||
return key # 如果中間值不是字典,返回原始key
|
return key
|
||||||
return value.format(**kwargs) if kwargs else value
|
return value
|
||||||
except Exception:
|
except Exception:
|
||||||
return key # 出現任何錯誤時返回原始key
|
return key
|
||||||
|
|
||||||
def set_language(self, lang_code):
|
def set_language(self, lang_code):
|
||||||
"""设置当前语言"""
|
"""Set current language with validation"""
|
||||||
if lang_code in self.translations:
|
if lang_code in self.translations:
|
||||||
self.current_language = lang_code
|
self.current_language = lang_code
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_available_languages(self):
|
||||||
|
"""Get list of available languages"""
|
||||||
|
return list(self.translations.keys())
|
||||||
|
|
||||||
# 创建翻译器实例
|
# 创建翻译器实例
|
||||||
translator = Translator()
|
translator = Translator()
|
||||||
|
|
||||||
@ -79,25 +107,26 @@ def print_menu():
|
|||||||
print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}")
|
print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}")
|
||||||
|
|
||||||
def select_language():
|
def select_language():
|
||||||
"""语言选择菜单"""
|
"""Language selection menu"""
|
||||||
print(f"\n{Fore.CYAN}{EMOJI['LANG']} {translator.get('menu.select_language')}:{Style.RESET_ALL}")
|
print(f"\n{Fore.CYAN}{EMOJI['LANG']} {translator.get('menu.select_language')}:{Style.RESET_ALL}")
|
||||||
print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}")
|
print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}")
|
||||||
|
|
||||||
languages = translator.get('languages')
|
languages = translator.get_available_languages()
|
||||||
for i, (code, name) in enumerate(languages.items()):
|
for i, lang in enumerate(languages):
|
||||||
print(f"{Fore.GREEN}{i}{Style.RESET_ALL}. {name}")
|
lang_name = translator.get(f"languages.{lang}")
|
||||||
|
print(f"{Fore.GREEN}{i}{Style.RESET_ALL}. {lang_name}")
|
||||||
|
|
||||||
try:
|
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):
|
if choice.isdigit() and 0 <= int(choice) < len(languages):
|
||||||
lang_code = list(languages.keys())[int(choice)]
|
translator.set_language(languages[int(choice)])
|
||||||
translator.set_language(lang_code)
|
|
||||||
return True
|
return True
|
||||||
|
else:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
|
||||||
|
return False
|
||||||
except (ValueError, IndexError):
|
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():
|
def main():
|
||||||
print_logo()
|
print_logo()
|
||||||
|
213
new_tempemail.py
213
new_tempemail.py
@ -3,6 +3,9 @@ import time
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from colorama import Fore, Style, init
|
from colorama import Fore, Style, init
|
||||||
|
import requests
|
||||||
|
import random
|
||||||
|
import string
|
||||||
|
|
||||||
# 初始化 colorama
|
# 初始化 colorama
|
||||||
init()
|
init()
|
||||||
@ -10,95 +13,73 @@ init()
|
|||||||
class NewTempEmail:
|
class NewTempEmail:
|
||||||
def __init__(self, translator=None):
|
def __init__(self, translator=None):
|
||||||
self.translator = translator
|
self.translator = translator
|
||||||
self.page = None
|
# Randomly choose between mail.tm and mail.gw
|
||||||
self.setup_browser()
|
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):
|
def _generate_credentials(self):
|
||||||
"""获取插件路径"""
|
"""生成随机用户名和密码"""
|
||||||
root_dir = os.getcwd()
|
username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
|
||||||
extension_path = os.path.join(root_dir, "PBlock")
|
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):
|
def create_email(self):
|
||||||
"""创建临时邮箱"""
|
"""创建临时邮箱"""
|
||||||
try:
|
try:
|
||||||
if self.translator:
|
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:
|
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/")
|
domains_response = requests.get(f"{self.api_url}/domains")
|
||||||
time.sleep(2)
|
if domains_response.status_code != 200:
|
||||||
|
raise Exception("Failed to get available domains")
|
||||||
|
|
||||||
# 点击创建邮箱按钮
|
domains = domains_response.json()["hydra:member"]
|
||||||
create_button = self.page.ele('xpath://button[@title="Create temporary email"]')
|
if not domains:
|
||||||
if create_button:
|
raise Exception("No available domains")
|
||||||
create_button.click()
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
# 点击弹窗中的 Create 按钮
|
# 生成随机用户名和密码
|
||||||
modal_create_button = self.page.ele('xpath://button[contains(text(), "Create")]')
|
username, password = self._generate_credentials()
|
||||||
if modal_create_button:
|
self.password = password
|
||||||
modal_create_button.click()
|
|
||||||
time.sleep(2)
|
# 创建邮箱账户
|
||||||
|
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
|
||||||
|
|
||||||
# 获取邮箱地址 - 修改选择器
|
|
||||||
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
|
|
||||||
if self.translator:
|
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:
|
else:
|
||||||
print(f"{Fore.RED}❌ 创建邮箱失败{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ 创建邮箱成功: {email}{Style.RESET_ALL}")
|
||||||
return None
|
return email
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if self.translator:
|
if self.translator:
|
||||||
@ -120,11 +101,11 @@ class NewTempEmail:
|
|||||||
else:
|
else:
|
||||||
print(f"{Fore.CYAN}🔄 正在刷新邮箱...{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}🔄 正在刷新邮箱...{Style.RESET_ALL}")
|
||||||
|
|
||||||
# 点击刷新按钮
|
# 使用 API 获取最新邮件
|
||||||
refresh_button = self.page.ele('xpath://button[@id="refresh"]')
|
headers = {"Authorization": f"Bearer {self.token}"}
|
||||||
if refresh_button:
|
response = requests.get(f"{self.api_url}/messages", headers=headers)
|
||||||
refresh_button.click()
|
|
||||||
time.sleep(2) # 等待刷新完成
|
if response.status_code == 200:
|
||||||
if self.translator:
|
if self.translator:
|
||||||
print(f"{Fore.GREEN}✅ {self.translator.get('email.refresh_success')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}✅ {self.translator.get('email.refresh_success')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
@ -132,9 +113,9 @@ class NewTempEmail:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
if self.translator:
|
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:
|
else:
|
||||||
print(f"{Fore.RED}❌ 未找到刷新按钮{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ 刷新邮箱失败{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -147,17 +128,24 @@ class NewTempEmail:
|
|||||||
def check_for_cursor_email(self):
|
def check_for_cursor_email(self):
|
||||||
"""检查是否有 Cursor 的验证邮件"""
|
"""检查是否有 Cursor 的验证邮件"""
|
||||||
try:
|
try:
|
||||||
# 查找验证邮件 - 使用更精确的选择器
|
# 使用 API 获取邮件列表
|
||||||
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"]]')
|
headers = {"Authorization": f"Bearer {self.token}"}
|
||||||
if email_div:
|
response = requests.get(f"{self.api_url}/messages", headers=headers)
|
||||||
if self.translator:
|
|
||||||
print(f"{Fore.GREEN}✅ {self.translator.get('email.verification_found')}{Style.RESET_ALL}")
|
if response.status_code == 200:
|
||||||
else:
|
messages = response.json()["hydra:member"]
|
||||||
print(f"{Fore.GREEN}✅ 找到验证邮件{Style.RESET_ALL}")
|
for message in messages:
|
||||||
# 使用 JavaScript 点击元素
|
if message["from"]["address"] == "no-reply@cursor.sh" and "Verify your email address" in message["subject"]:
|
||||||
self.page.run_js('arguments[0].click()', email_div)
|
# 获取邮件内容
|
||||||
time.sleep(2) # 等待邮件内容加载
|
message_id = message["id"]
|
||||||
return True
|
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:
|
if self.translator:
|
||||||
print(f"{Fore.YELLOW}⚠️ {self.translator.get('email.verification_not_found')}{Style.RESET_ALL}")
|
print(f"{Fore.YELLOW}⚠️ {self.translator.get('email.verification_not_found')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
@ -174,16 +162,33 @@ class NewTempEmail:
|
|||||||
def get_verification_code(self):
|
def get_verification_code(self):
|
||||||
"""获取验证码"""
|
"""获取验证码"""
|
||||||
try:
|
try:
|
||||||
# 查找验证码元素
|
# 使用 API 获取邮件列表
|
||||||
code_element = self.page.ele('xpath://td//div[contains(@style, "font-size:28px") and contains(@style, "letter-spacing:2px")]')
|
headers = {"Authorization": f"Bearer {self.token}"}
|
||||||
if code_element:
|
response = requests.get(f"{self.api_url}/messages", headers=headers)
|
||||||
code = code_element.text.strip()
|
|
||||||
if code.isdigit() and len(code) == 6:
|
if response.status_code == 200:
|
||||||
if self.translator:
|
messages = response.json()["hydra:member"]
|
||||||
print(f"{Fore.GREEN}✅ {self.translator.get('email.verification_code_found')}: {code}{Style.RESET_ALL}")
|
for message in messages:
|
||||||
else:
|
if message["from"]["address"] == "no-reply@cursor.sh" and "Verify your email address" in message["subject"]:
|
||||||
print(f"{Fore.GREEN}✅ 获取验证码成功: {code}{Style.RESET_ALL}")
|
# 获取邮件内容
|
||||||
return code
|
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:
|
if self.translator:
|
||||||
print(f"{Fore.YELLOW}⚠️ {self.translator.get('email.verification_code_not_found')}{Style.RESET_ALL}")
|
print(f"{Fore.YELLOW}⚠️ {self.translator.get('email.verification_code_not_found')}{Style.RESET_ALL}")
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user