File size: 7,212 Bytes
d12c7eb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | import gradio as gr
import asyncio
import sys
import json
import random
from pathlib import Path
import zipfile
from datetime import datetime
TOKEN_DIR = Path("/app/tokens")
TOKEN_DIR.mkdir(exist_ok=True)
ACCOUNTS_FILE = TOKEN_DIR / "accounts.txt"
# 全局状态
current_process = None
async def run_registration(proxy: str, loop_mode: bool = False, progress=gr.Progress()):
"""
执行注册,loop_mode=False 表示单次(带 --once),loop_mode=True 表示无限循环(不带 --once)
返回实时日志的异步生成器
"""
global current_process
cmd = [sys.executable, "/app/register.py"]
if not loop_mode:
cmd.append("--once")
if proxy and proxy.strip():
cmd.extend(["--proxy", proxy.strip()])
process = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT,
)
current_process = process
lines = []
async for line in process.stdout:
decoded = line.decode('utf-8', errors='replace').rstrip()
lines.append(decoded)
if len(lines) % 10 == 0:
progress(0.5, desc="运行中...")
yield "\n".join(lines)
await process.wait()
current_process = None
progress(1.0, desc="进程结束")
yield "\n".join(lines) + "\n\n✅ 进程已结束。"
def stop_registration():
global current_process
if current_process and current_process.returncode is None:
current_process.terminate()
return "⏹️ 已发送停止信号"
return "没有正在运行的进程"
def list_token_files():
files = list(TOKEN_DIR.glob("token_*.json"))
return [str(f) for f in files]
def get_accounts_content():
if ACCOUNTS_FILE.exists():
return ACCOUNTS_FILE.read_text(encoding='utf-8')
return "暂无账号信息"
def download_accounts():
if ACCOUNTS_FILE.exists():
return str(ACCOUNTS_FILE)
return None
def download_all_files():
token_files = list(TOKEN_DIR.glob("token_*.json"))
if not token_files and not ACCOUNTS_FILE.exists():
return None
zip_path = TOKEN_DIR / f"all_files_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip"
with zipfile.ZipFile(zip_path, 'w') as zipf:
for f in token_files:
zipf.write(f, arcname=f.name)
if ACCOUNTS_FILE.exists():
zipf.write(ACCOUNTS_FILE, arcname="accounts.txt")
return str(zip_path)
def download_latest():
files = list(TOKEN_DIR.glob("token_*.json"))
if files:
latest = max(files, key=lambda p: p.stat().st_mtime)
return latest
return None
def update_file_list():
files = list_token_files()
count = len(files)
return gr.update(value=files), gr.update(value=count)
# 构建 Gradio 界面
with gr.Blocks(title="OpenAI 自动注册 (双模式版)") as demo:
gr.Markdown("""
# 🤖 OpenAI 自动注册 (双模式版)
- **单次注册**:执行一次注册,完成后停止。
- **无限循环**:启动后 `register.py` 自己无限循环注册,可随时停止。
- 所有生成的 token 文件及 `accounts.txt` 均可单独下载或打包下载全部。
""")
with gr.Row():
proxy_input = gr.Textbox(
label="代理地址 (可选)",
placeholder="例如 http://127.0.0.1:7890"
)
with gr.Row():
single_btn = gr.Button("▶️ 单次注册", variant="primary")
loop_btn = gr.Button("🔄 无限循环", variant="primary")
stop_btn = gr.Button("⏹️ 停止", variant="secondary")
output = gr.Textbox(label="实时日志", lines=20, interactive=False)
progress_bar = gr.Progress()
gr.Markdown("---\n### 📁 生成的 Token 文件")
with gr.Row():
file_count = gr.Number(value=0, label="当前 Token 数量", interactive=False)
file_list = gr.Files(label="所有 Token 文件", file_count="multiple")
with gr.Row():
refresh_btn = gr.Button("🔄 刷新文件列表")
download_latest_btn = gr.Button("📥 下载最新 Token")
download_all_btn = gr.Button("📦 下载全部文件")
gr.Markdown("---\n### 📋 账号信息 (accounts.txt)")
with gr.Row():
accounts_display = gr.Textbox(label="accounts.txt 内容", lines=10, interactive=False)
refresh_accounts_btn = gr.Button("🔄 刷新账号列表")
download_accounts_btn = gr.Button("📥 下载 accounts.txt")
# 单次注册
async def single_run(proxy):
yield gr.update(interactive=False), gr.update(interactive=False), gr.update(interactive=True), None
logs = ""
async for log in run_registration(proxy, loop_mode=False):
logs = log
yield gr.update(), gr.update(), gr.update(), logs
yield gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=False), logs
single_btn.click(
fn=single_run,
inputs=proxy_input,
outputs=[single_btn, loop_btn, stop_btn, output],
queue=True
).then(
fn=update_file_list,
outputs=[file_list, file_count]
).then(
fn=get_accounts_content,
outputs=accounts_display
)
# 无限循环
async def loop_run(proxy):
yield gr.update(interactive=False), gr.update(interactive=False), gr.update(interactive=True), None
logs = ""
async for log in run_registration(proxy, loop_mode=True):
logs = log
yield gr.update(), gr.update(), gr.update(), logs
yield gr.update(interactive=True), gr.update(interactive=True), gr.update(interactive=False), logs
loop_btn.click(
fn=loop_run,
inputs=proxy_input,
outputs=[single_btn, loop_btn, stop_btn, output],
queue=True
).then(
fn=update_file_list,
outputs=[file_list, file_count]
).then(
fn=get_accounts_content,
outputs=accounts_display
)
# 停止
def stop_fn():
msg = stop_registration()
return gr.update(interactive=False), msg
stop_btn.click(
fn=stop_fn,
outputs=[stop_btn, output]
).then(
fn=update_file_list,
outputs=[file_list, file_count]
).then(
fn=get_accounts_content,
outputs=accounts_display
)
# 刷新文件列表
refresh_btn.click(
fn=update_file_list,
outputs=[file_list, file_count]
)
download_latest_btn.click(
fn=download_latest,
outputs=gr.File(label="下载最新 Token")
)
download_all_btn.click(
fn=download_all_files,
outputs=gr.File(label="下载全部文件")
)
# 账号相关
refresh_accounts_btn.click(
fn=get_accounts_content,
outputs=accounts_display
)
download_accounts_btn.click(
fn=download_accounts,
outputs=gr.File(label="下载 accounts.txt")
)
demo.queue()
demo.launch(server_name="0.0.0.0", server_port=7860) |