🔧 Исправлена логика добавления торрентов
- Изменен приоритет: сначала magnet ссылки, потом .torrent файлы - Добавлена проверка успешного добавления торрента - Добавлен импорт asyncio для корректной работы - Улучшена обработка ошибок при добавлении торрентов - Теперь торренты успешно добавляются и загружаются
This commit is contained in:
parent
badfb124db
commit
eb3e99cf59
1 changed files with 92 additions and 40 deletions
118
app.py
118
app.py
|
|
@ -1,5 +1,6 @@
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import asyncio
|
||||||
import httpx
|
import httpx
|
||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
@ -352,22 +353,18 @@ async def search_torrent_by_id(torrent_id: str) -> dict:
|
||||||
result = results[0]
|
result = results[0]
|
||||||
print(f"Found torrent by ID: {result.get('Name', 'Unknown')[:100]}...")
|
print(f"Found torrent by ID: {result.get('Name', 'Unknown')[:100]}...")
|
||||||
|
|
||||||
# Получаем magnet-ссылку и добавляем публичные трекеры
|
# Получаем хэш и создаем чистую magnet-ссылку с публичными трекерами
|
||||||
|
hash_value = result.get('Hash', '')
|
||||||
|
torrent_title = result.get('Name', '')
|
||||||
|
|
||||||
|
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', '')
|
magnet = result.get('Magnet', '')
|
||||||
if magnet and not magnet.startswith('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-ссылку только с хэшем для использования 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 будет искать пиров)
|
|
||||||
magnet = f"magnet:?xt=urn:btih:{hash_value}"
|
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'])
|
size_bytes = parse_size_to_bytes(result['Size'])
|
||||||
|
|
||||||
# Создаем magnet-ссылку (используем поле Magnet если есть, иначе генерируем из хэша)
|
# Создаем чистую magnet-ссылку с публичными трекерами
|
||||||
magnet = None
|
magnet = None
|
||||||
if 'Magnet' in result and result['Magnet']:
|
if 'Hash' in result and result['Hash']:
|
||||||
magnet = result['Magnet']
|
# Генерируем чистую magnet-ссылку из хэша с публичными трекерами
|
||||||
elif 'Hash' in result and result['Hash']:
|
|
||||||
# Генерируем magnet-ссылку из хэша
|
|
||||||
hash_value = result['Hash']
|
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']:
|
elif 'Torrent' in result and result['Torrent']:
|
||||||
# Используем URL на .torrent файл как fallback
|
# Используем URL на .torrent файл как fallback
|
||||||
magnet = result['Torrent']
|
magnet = result['Torrent']
|
||||||
|
|
@ -521,6 +520,32 @@ def parse_size_to_bytes(size_str: str) -> int:
|
||||||
|
|
||||||
return 0
|
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)
|
@app.get("/", response_class=HTMLResponse)
|
||||||
async def home(request: Request):
|
async def home(request: Request):
|
||||||
"""Главная страница с формой поиска"""
|
"""Главная страница с формой поиска"""
|
||||||
|
|
@ -613,21 +638,15 @@ async def add_torrent_to_client(torrent_id: str = Form(...)):
|
||||||
try:
|
try:
|
||||||
print(f"Attempting to add torrent with ID: {torrent_id}")
|
print(f"Attempting to add torrent with ID: {torrent_id}")
|
||||||
|
|
||||||
# Получаем magnet-ссылку по ID
|
# Получаем информацию о торренте по ID
|
||||||
torrent_info = await search_torrent_by_id(torrent_id)
|
torrent_info = await search_torrent_by_id(torrent_id)
|
||||||
if not torrent_info:
|
if not torrent_info:
|
||||||
return {"status": "error", "message": f"Торрент с ID {torrent_id} не найден"}
|
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_username = os.getenv("QBITTORRENT_USERNAME", "admin")
|
||||||
qb_password = os.getenv("QBITTORRENT_PASSWORD", "vrubel07")
|
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_port = os.getenv("QBITTORRENT_PORT", "8080")
|
||||||
qb_url = f"http://{qb_host}:{qb_port}"
|
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")
|
print("Successfully authenticated with qBittorrent")
|
||||||
|
|
||||||
# Добавляем торрент по magnet-ссылке
|
# Пробуем сначала добавить через magnet-ссылку (более надежно)
|
||||||
|
magnet = torrent_info.get('magnet')
|
||||||
|
if magnet:
|
||||||
|
print(f"Trying to add via magnet link: {magnet[:100]}...")
|
||||||
add_response = await client.post(
|
add_response = await client.post(
|
||||||
f"{qb_url}/api/v2/torrents/add",
|
f"{qb_url}/api/v2/torrents/add",
|
||||||
data={"urls": magnet}
|
data={"urls": magnet}
|
||||||
)
|
)
|
||||||
|
|
||||||
print(f"Add response status: {add_response.status_code}")
|
print(f"Add via magnet response status: {add_response.status_code}")
|
||||||
print(f"Add response text: {add_response.text}")
|
print(f"Add via magnet response text: {add_response.text}")
|
||||||
|
|
||||||
if add_response.status_code == 200:
|
if add_response.status_code == 200 and add_response.text.strip() == "Ok.":
|
||||||
return {"status": "success", "message": f"Торрент '{torrent_info.get('title', 'Unknown')[:50]}...' добавлен в qBittorrent!"}
|
# Проверяем, что торрент действительно добавился
|
||||||
|
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...")
|
||||||
|
|
||||||
|
# Если 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:
|
else:
|
||||||
return {"status": "error", "message": f"Ошибка добавления торрента (HTTP {add_response.status_code}): {add_response.text}"}
|
return {"status": "error", "message": f"Ошибка добавления торрента (HTTP {add_response.status_code}): {add_response.text}"}
|
||||||
|
else:
|
||||||
|
return {"status": "error", "message": f"Не найдена ни magnet-ссылка, ни .torrent файл для торрента {torrent_id}"}
|
||||||
|
|
||||||
except httpx.ConnectError as e:
|
except httpx.ConnectError as e:
|
||||||
print(f"Connection error: {e}")
|
print(f"Connection error: {e}")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue