ernoban commited on
Commit
5044684
·
verified ·
1 Parent(s): 3175af7

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +113 -0
app.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import socket
3
+ import time
4
+
5
+ def check_dns_resolution(domain):
6
+ """
7
+ 尝试将域名解析为IP地址。
8
+ 这是测试DNS问题的最直接方法。
9
+ 返回一个包含结果的元组 (domain, status, detail)。
10
+ """
11
+ try:
12
+ # socket.gethostbyname 是对系统DNS解析器的直接调用。
13
+ # 如果此调用失败,则说明从Space内部无法解析该域名。
14
+ ip_address = socket.gethostbyname(domain)
15
+ return (domain, "✅ 可访问", f"成功解析到IP: {ip_address}")
16
+ except socket.gaierror as e:
17
+ # socket.gaierror 是专门处理地址相关错误的异常(例如,主机名未知)。
18
+ return (domain, "❌ 无法访问", f"DNS解析失败: {e}")
19
+ except Exception as e:
20
+ return (domain, "❌ 出错", f"发生未知错误: {e}")
21
+
22
+ def batch_test_domains(domain_list_str, progress=gr.Progress(track_tqdm=True)):
23
+ """
24
+ 对给定的域名列表进行批量测试,并生成Markdown格式的报告。
25
+ """
26
+ if not domain_list_str or not domain_list_str.strip():
27
+ return "⚠️ 请在文本框中输入至少一个域名。"
28
+
29
+ # 将输入字符串分割成域名列表,并清除空白行和多余的空格
30
+ domains_to_test = [d.strip() for d in domain_list_str.split('\n') if d.strip()]
31
+ if not domains_to_test:
32
+ return "⚠️ 输入无效,请输入有效域名。"
33
+
34
+ total_domains = len(domains_to_test)
35
+ results = []
36
+
37
+ # 使用串行循环代替并发,并加入延迟,以避免触发速率限制
38
+ for i, domain in enumerate(domains_to_test):
39
+ # 更新进度条,这能保持与前端的连接,防止超时
40
+ progress(i / total_domains, desc=f"正在测试 ({i+1}/{total_domains}): {domain}")
41
+
42
+ # 执行DNS解析
43
+ result = check_dns_resolution(domain)
44
+ results.append(result)
45
+
46
+ # !!! 重要: 加入短暂延迟,防止请求过于密集而被服务器限制 !!!
47
+ time.sleep(0.25)
48
+
49
+ # --- 开始生成报告 ---
50
+ accessible_domains = []
51
+ inaccessible_domains = []
52
+
53
+ for domain, status, detail in results:
54
+ # 使用 Markdown 的代码格式 `domain` 来突出显示域名
55
+ formatted_line = f"`{domain}` - {detail}"
56
+ if "可访问" in status:
57
+ accessible_domains.append(formatted_line)
58
+ else:
59
+ inaccessible_domains.append(formatted_line)
60
+
61
+ report = f"## 批量测试报告 (共测试 {total_domains} 个域名)\n\n"
62
+
63
+ report += f"### ✅ 可访问的域名 ({len(accessible_domains)} 个)\n"
64
+ if accessible_domains:
65
+ report += "\n".join([f"- {d}" for d in accessible_domains])
66
+ else:
67
+ report += "无"
68
+
69
+ report += f"\n\n### ❌ 无法访问或出错的域名 ({len(inaccessible_domains)} 个)\n"
70
+ if inaccessible_domains:
71
+ report += "\n".join([f"- {d}" for d in inaccessible_domains])
72
+ else:
73
+ report += "无"
74
+
75
+ return report
76
+
77
+ # --- Gradio 应用界面 ---
78
+ with gr.Blocks(theme=gr.themes.Default(primary_hue="blue", secondary_hue="blue")) as demo:
79
+ gr.Markdown(
80
+ """
81
+ # Hugging Face Space 出站网络可访问性测试 (优化版)
82
+ 在下面的文本框中输入或粘贴您需要测试的域名列表(每行一个)。
83
+ 工具将以安全、稳定的方式逐个测试,并生成清晰的报告,以避免IP被临时限制。
84
+ """
85
+ )
86
+
87
+ with gr.Row():
88
+ domain_input = gr.Textbox(
89
+ lines=15,
90
+ label="域名列表 (每行一个)",
91
+ placeholder="www.google.com\nwww.facebook.com\nhuggingface.co\napi.openai.com\n..."
92
+ )
93
+
94
+ submit_btn = gr.Button("🚀 开始批量测试", variant="primary")
95
+
96
+ output_report = gr.Markdown(label="测试报告")
97
+
98
+ # 将按钮点击事件连接到主函数
99
+ submit_btn.click(
100
+ fn=batch_test_domains,
101
+ inputs=domain_input,
102
+ outputs=output_report
103
+ )
104
+
105
+ gr.Examples(
106
+ [
107
+ "www.google.com\ngithub.com\nhuggingface.co\nwww.wikipedia.org",
108
+ "www.facebook.com\nwww.instagram.com\nwww.youtube.com\nweb.whatsapp.com"
109
+ ],
110
+ inputs=domain_input
111
+ )
112
+
113
+ demo.launch()