Update get_vpn.py

This commit is contained in:
2026-08-13 20:06:21 +03:00
parent 16ad22b503
commit 25a41761a8
+24 -27
View File
@@ -6,15 +6,12 @@ import requests
def get_vpn_servers(): def get_vpn_servers():
# Получаем ссылку из секретов Gitea
sub_url = os.getenv("VPN_SUB_URL") sub_url = os.getenv("VPN_SUB_URL")
if not sub_url: if not sub_url:
print("Ошибка: Переменная окружения VPN_SUB_URL не задана!") print("Ошибка: Переменная окружения VPN_SUB_URL не задана!")
sys.exit(1) sys.exit(1)
# 1. Сначала пробуем сделать запрос по исходной ссылке
# Имитируем заголовки приложения Happ
headers = { headers = {
"User-Agent": "Happ/2.1.0 (iPhone; iOS 15.5; Scale/3.00)", "User-Agent": "Happ/2.1.0 (iPhone; iOS 15.5; Scale/3.00)",
"Accept": "*/*", "Accept": "*/*",
@@ -25,47 +22,50 @@ def get_vpn_servers():
response = requests.get(sub_url, headers=headers, timeout=15) response = requests.get(sub_url, headers=headers, timeout=15)
if response.status_code != 200: if response.status_code != 200:
print(f"Ошибка сервера: Статус {response.status_code}") print(f"Ошибка服务器: Статус {response.status_code}")
sys.exit(1) sys.exit(1)
raw_content = response.text.strip() raw_content = response.text.strip()
# 2. Проверяем, не JSON ли это (на случай, если в секрет сразу зашит appConfig URL) # 1. Проверяем формат JSON
try: try:
data = json.loads(raw_content) data = json.loads(raw_content)
print("Обнаружен формат JSON (панель Happ API).") print("Обнаружен формат JSON.")
servers = data.get("data", {}).get("server_user", data)
# Если сервер вернул словарь, ищем ключи. Если вернул сразу список — берем его как есть.
if isinstance(data, dict):
servers = data.get("data", {}).get("server_user", data)
else:
servers = data
with open("servers.json", "w", encoding="utf-8") as f: with open("servers.json", "w", encoding="utf-8") as f:
json.dump(servers, f, indent=2, ensure_ascii=False) json.dump(servers, f, indent=2, ensure_ascii=False)
print("Данные сохранены в файл servers.json")
# Выводим количество найденных элементов для наглядности в логах
count = len(servers) if isinstance(servers, list) else 1
print(
f"Данные успешно сохранены в файл servers.json (Элементов: {count})"
)
return return
except json.JSONDecodeError: except json.JSONDecodeError:
# Если не JSON, идем дальше # Если не JSON, двигаемся к проверке Base64
pass pass
# 3. Проверяем, не Base64 ли это (стандартная подписка) # 2. Проверяем формат Base64 (на случай изменения выдачи)
try: try:
# Добавляем padding, если строка обрезана (стандартный трюк для base64 в Python)
padded_content = raw_content + "=" * (4 - len(raw_content) % 4) padded_content = raw_content + "=" * (4 - len(raw_content) % 4)
decoded_bytes = base64.b64decode(padded_content) decoded_bytes = base64.b64decode(padded_content)
decoded_text = decoded_bytes.decode("utf-8", errors="ignore").strip() decoded_text = decoded_bytes.decode("utf-8", errors="ignore").strip()
# Если внутри есть vless/ss/ssr/trojan/vmess ссылки
if any( if any(
proto in decoded_text proto in decoded_text
for proto in ["vless://", "vmess://", "ss://", "trojan://"] for proto in ["vless://", "vmess://", "ss://", "trojan://"]
): ):
print( print("Обнаружена Base64 подписка.")
"Обнаружена Base64 подписка. Успешно декодировано в список ссылок."
)
# Вариант А: Сохраняем как простой текстовый список серверов
with open("servers.txt", "w", encoding="utf-8") as f: with open("servers.txt", "w", encoding="utf-8") as f:
f.write(decoded_text) f.write(decoded_text)
print("Ссылки сохранены в файл servers.txt")
# Вариант Б: Для удобства сохраняем этот же список в JSON массив
links_list = [ links_list = [
line.strip() line.strip()
for line in decoded_text.splitlines() for line in decoded_text.splitlines()
@@ -73,12 +73,12 @@ def get_vpn_servers():
] ]
with open("servers.json", "w", encoding="utf-8") as f: with open("servers.json", "w", encoding="utf-8") as f:
json.dump(links_list, f, indent=2, ensure_ascii=False) json.dump(links_list, f, indent=2, ensure_ascii=False)
print("Ссылки также структурированы в servers.json") print("Ссылки сохранены в servers.txt и servers.json")
return return
except Exception as b64_err: except Exception:
print(f"Попытка декодировать Base64 не удалась: {b64_err}") pass
# 4. Если это и не JSON, и не Base64, возможно это уже готовый сырой текст со ссылками # 3. Проверяем сырой текст со ссылками
if any( if any(
proto in raw_content proto in raw_content
for proto in ["vless://", "vmess://", "ss://", "trojan://"] for proto in ["vless://", "vmess://", "ss://", "trojan://"]
@@ -95,10 +95,7 @@ def get_vpn_servers():
print("Данные сохранены в servers.txt и servers.json") print("Данные сохранены в servers.txt и servers.json")
return return
# 5. Если вообще ничего не подошло, сохраняем как есть для анализа print("Неизвестный формат ответа. Сохраняем в raw_response.txt")
print(
"Неизвестный формат ответа. Сохраняем raw-текст в raw_response.txt для отладки."
)
with open("raw_response.txt", "w", encoding="utf-8") as f: with open("raw_response.txt", "w", encoding="utf-8") as f:
f.write(raw_content) f.write(raw_content)
sys.exit(1) sys.exit(1)