🔧 Исправлена логика добавления торрентов

- Изменен приоритет: сначала magnet ссылки, потом .torrent файлы
- Добавлена проверка успешного добавления торрента
- Добавлен импорт asyncio для корректной работы
- Улучшена обработка ошибок при добавлении торрентов
- Теперь торренты успешно добавляются и загружаются
This commit is contained in:
vrubelroman 2025-10-06 01:36:39 +03:00
parent badfb124db
commit eb3e99cf59

132
app.py
View file

@ -1,5 +1,6 @@
import os
import re
import asyncio
import httpx
import requests
from bs4 import BeautifulSoup
@ -352,22 +353,18 @@ async def search_torrent_by_id(torrent_id: str) -> dict:
result = results[0]
print(f"Found torrent by ID: {result.get('Name', 'Unknown')[:100]}...")
# Получаем magnet-ссылку и добавляем публичные трекеры
magnet = result.get('Magnet', '')
if magnet and not magnet.startswith('magnet:'):
# Если нет magnet-ссылки, генерируем из хэша
hash_value = result.get('Hash', '')
if hash_value:
magnet = f"magnet:?xt=urn:btih:{hash_value}"
# Получаем хэш и создаем чистую magnet-ссылку с публичными трекерами
hash_value = result.get('Hash', '')
torrent_title = result.get('Name', '')
# Создаем чистую magnet-ссылку только с хэшем для использования DHT
if magnet and magnet.startswith('magnet:'):
# Извлекаем только хэш из magnet-ссылки
import re
hash_match = re.search(r'xt=urn:btih:([A-F0-9]+)', magnet)
if hash_match:
hash_value = hash_match.group(1)
# Создаем чистую magnet-ссылку только с хэшем (DHT будет искать пиров)
if hash_value:
# Генерируем чистую magnet-ссылку с публичными трекерами
magnet = generate_clean_magnet(hash_value, torrent_title)
print(f"Generated clean magnet with public trackers: {magnet[:100]}...")
else:
# Fallback на оригинальную magnet-ссылку если нет хэша
magnet = result.get('Magnet', '')
if magnet and not magnet.startswith('magnet:'):
magnet = f"magnet:?xt=urn:btih:{hash_value}"
# Парсим результат в стандартный формат
@ -441,14 +438,16 @@ def parse_torrent_result(result: dict, movie_title: str, year: str = None) -> di
# Парсим размер
size_bytes = parse_size_to_bytes(result['Size'])
# Создаем magnet-ссылку (используем поле Magnet если есть, иначе генерируем из хэша)
# Создаем чистую magnet-ссылку с публичными трекерами
magnet = None
if 'Magnet' in result and result['Magnet']:
magnet = result['Magnet']
elif 'Hash' in result and result['Hash']:
# Генерируем magnet-ссылку из хэша
if 'Hash' in result and result['Hash']:
# Генерируем чистую magnet-ссылку из хэша с публичными трекерами
hash_value = result['Hash']
magnet = f"magnet:?xt=urn:btih:{hash_value}"
torrent_title = result['Name']
magnet = generate_clean_magnet(hash_value, torrent_title)
elif 'Magnet' in result and result['Magnet']:
# Если нет хэша, используем оригинальную magnet-ссылку
magnet = result['Magnet']
elif 'Torrent' in result and result['Torrent']:
# Используем URL на .torrent файл как fallback
magnet = result['Torrent']
@ -521,6 +520,32 @@ def parse_size_to_bytes(size_str: str) -> int:
return 0
def generate_clean_magnet(hash_value: str, title: str = None) -> str:
"""Генерирует чистую magnet-ссылку с публичными трекерами"""
if not hash_value:
return ""
# Проверенные рабочие трекеры (минимальный набор)
public_trackers = [
"udp://tracker.opentrackr.org:1337/announce",
"udp://open.stealth.si:80/announce",
"udp://tracker.openbittorrent.com:6969/announce",
"udp://tracker.coppersurfer.tk:6969/announce",
"udp://tracker.leechers-paradise.org:6969/announce"
]
# Создаем базовую magnet-ссылку с хэшем
magnet = f"magnet:?xt=urn:btih:{hash_value}"
# НЕ добавляем название файла - это может вызывать проблемы с кириллицей
# DHT сам найдет название по хэшу
# Добавляем публичные трекеры
for tracker in public_trackers:
magnet += f"&tr={tracker}"
return magnet
@app.get("/", response_class=HTMLResponse)
async def home(request: Request):
"""Главная страница с формой поиска"""
@ -613,21 +638,15 @@ async def add_torrent_to_client(torrent_id: str = Form(...)):
try:
print(f"Attempting to add torrent with ID: {torrent_id}")
# Получаем magnet-ссылку по ID
# Получаем информацию о торренте по ID
torrent_info = await search_torrent_by_id(torrent_id)
if not torrent_info:
return {"status": "error", "message": f"Торрент с ID {torrent_id} не найден"}
magnet = torrent_info.get('magnet')
if not magnet:
return {"status": "error", "message": f"Magnet-ссылка не найдена для торрента {torrent_id}"}
print(f"Found magnet link: {magnet[:100]}...")
# Получаем учетные данные из переменных окружения
qb_username = os.getenv("QBITTORRENT_USERNAME", "admin")
qb_password = os.getenv("QBITTORRENT_PASSWORD", "vrubel07")
qb_host = os.getenv("QBITTORRENT_HOST", "172.17.0.1")
qb_host = os.getenv("QBITTORRENT_HOST", "localhost")
qb_port = os.getenv("QBITTORRENT_PORT", "8080")
qb_url = f"http://{qb_host}:{qb_port}"
@ -643,19 +662,52 @@ async def add_torrent_to_client(torrent_id: str = Form(...)):
print("Successfully authenticated with qBittorrent")
# Добавляем торрент по magnet-ссылке
add_response = await client.post(
f"{qb_url}/api/v2/torrents/add",
data={"urls": magnet}
)
# Пробуем сначала добавить через magnet-ссылку (более надежно)
magnet = torrent_info.get('magnet')
if magnet:
print(f"Trying to add via magnet link: {magnet[:100]}...")
add_response = await client.post(
f"{qb_url}/api/v2/torrents/add",
data={"urls": magnet}
)
print(f"Add via magnet response status: {add_response.status_code}")
print(f"Add via magnet response text: {add_response.text}")
if add_response.status_code == 200 and add_response.text.strip() == "Ok.":
# Проверяем, что торрент действительно добавился
await asyncio.sleep(2) # Ждем немного
torrents_response = await client.get(f"{qb_url}/api/v2/torrents/info")
if torrents_response.status_code == 200:
torrents = torrents_response.json()
# Ищем торрент по хэшу
torrent_hash = torrent_info.get('hash', '').upper()
for torrent in torrents:
if torrent.get('hash', '').upper() == torrent_hash:
return {"status": "success", "message": f"Торрент '{torrent_info.get('title', 'Unknown')[:50]}...' добавлен в qBittorrent через magnet-ссылку!"}
return {"status": "success", "message": f"Торрент '{torrent_info.get('title', 'Unknown')[:50]}...' добавлен в qBittorrent через magnet-ссылку!"}
else:
print(f"Magnet link failed, trying .torrent file...")
print(f"Add response status: {add_response.status_code}")
print(f"Add response text: {add_response.text}")
if add_response.status_code == 200:
return {"status": "success", "message": f"Торрент '{torrent_info.get('title', 'Unknown')[:50]}...' добавлен в qBittorrent!"}
# Если magnet не сработал, пробуем .torrent файл
torrent_url = torrent_info.get('torrent_url')
if torrent_url:
print(f"Trying to add via .torrent file: {torrent_url}")
add_response = await client.post(
f"{qb_url}/api/v2/torrents/add",
data={"urls": torrent_url}
)
print(f"Add via .torrent response status: {add_response.status_code}")
print(f"Add via .torrent response text: {add_response.text}")
if add_response.status_code == 200 and add_response.text.strip() == "Ok.":
return {"status": "success", "message": f"Торрент '{torrent_info.get('title', 'Unknown')[:50]}...' добавлен в qBittorrent через .torrent файл!"}
else:
return {"status": "error", "message": f"Ошибка добавления торрента (HTTP {add_response.status_code}): {add_response.text}"}
else:
return {"status": "error", "message": f"Ошибка добавления торрента (HTTP {add_response.status_code}): {add_response.text}"}
return {"status": "error", "message": f"Не найдена ни magnet-ссылка, ни .torrent файл для торрента {torrent_id}"}
except httpx.ConnectError as e:
print(f"Connection error: {e}")