|
15 | 15 | import argparse |
16 | 16 | import os |
17 | 17 | import sys |
| 18 | +import socket |
18 | 19 | import json |
19 | 20 | import hashlib |
20 | 21 | import threading |
|
40 | 41 | DEFAULT_WORKERS = 4 # 默认并行下载数 |
41 | 42 |
|
42 | 43 |
|
| 44 | +def check_cernet() -> bool: |
| 45 | + """检查是否为教育网环境""" |
| 46 | + try: |
| 47 | + #设置较短超时,避免阻塞 |
| 48 | + resp = requests.get("http://ip-api.com/json/?fields=isp,org", timeout=3) |
| 49 | + if resp.ok: |
| 50 | + data = resp.json() |
| 51 | + isp = data.get("isp", "").lower() |
| 52 | + org = data.get("org", "").lower() |
| 53 | + # 常见的教育网标识 |
| 54 | + cernet_keywords = ["cernet", "education", "university"] |
| 55 | + if any(k in isp for k in cernet_keywords) or any(k in org for k in cernet_keywords): |
| 56 | + return True |
| 57 | + except: |
| 58 | + pass |
| 59 | + return False |
| 60 | + |
| 61 | + |
| 62 | +def configure_dns(force_ipv4: bool = False, force_ipv6: bool = False): |
| 63 | + """配置 DNS 解析优先级""" |
| 64 | + if not (force_ipv4 or force_ipv6): |
| 65 | + return |
| 66 | + |
| 67 | + original_getaddrinfo = socket.getaddrinfo |
| 68 | + |
| 69 | + def patched_getaddrinfo(host, port, family=0, type=0, proto=0, flags=0): |
| 70 | + # 如果强制指定了协议版本,则覆盖 family 参数 |
| 71 | + if force_ipv4: |
| 72 | + family = socket.AF_INET |
| 73 | + elif force_ipv6: |
| 74 | + family = socket.AF_INET6 |
| 75 | + return original_getaddrinfo(host, port, family, type, proto, flags) |
| 76 | + |
| 77 | + socket.getaddrinfo = patched_getaddrinfo |
| 78 | + |
| 79 | + |
43 | 80 | @dataclass |
44 | 81 | class FileInfo: |
45 | 82 | """文件信息""" |
@@ -318,8 +355,31 @@ def main(): |
318 | 355 | parser.add_argument("--token", help="Hugging Face Token (也可设置 HF_TOKEN 环境变量)") |
319 | 356 | parser.add_argument("--list-only", "-l", action="store_true", |
320 | 357 | help="仅列出文件,不下载") |
| 358 | + parser.add_argument("--ipv4", "-4", action="store_true", help="强制使用 IPv4") |
| 359 | + parser.add_argument("--ipv6", "-6", action="store_true", help="强制使用 IPv6") |
321 | 360 |
|
322 | 361 | args = parser.parse_args() |
| 362 | + |
| 363 | + # 处理 IP 协议选择 |
| 364 | + if args.ipv4 and args.ipv6: |
| 365 | + print("❌ 错误: 不能同时指定 -4 和 -6") |
| 366 | + sys.exit(1) |
| 367 | + |
| 368 | + use_ipv6 = args.ipv6 |
| 369 | + use_ipv4 = args.ipv4 |
| 370 | + |
| 371 | + # 如果未指定,自动检测是否为教育网 |
| 372 | + if not (use_ipv6 or use_ipv4): |
| 373 | + if check_cernet(): |
| 374 | + print("🎓 检测到教育网环境,自动启用 IPv6 优化") |
| 375 | + use_ipv6 = True |
| 376 | + |
| 377 | + if use_ipv6: |
| 378 | + print("🌐 已启用强制 IPv6 解析") |
| 379 | + configure_dns(force_ipv6=True) |
| 380 | + elif use_ipv4: |
| 381 | + print("🌐 已启用强制 IPv4 解析") |
| 382 | + configure_dns(force_ipv4=True) |
323 | 383 |
|
324 | 384 | print(f""" |
325 | 385 | ╔══════════════════════════════════════════════════════════════╗ |
|
0 commit comments