fix(app): исправление скачивания торрентов
- generate_clean_magnet: убраны мёртвые трекеры (coppersurfer.tk, leechers-paradise.org), добавлены рабочие (tamersunion.org, exodus.desync.com, moeking.me), включено &dn= с URL-кодированием кириллицы - extract_hash_from_result: новая единая функция извлечения хэша из 5 источников (Hash, InfoHash, Magnet, btih: в URL, Id) - /api/add-torrent: убран ложный success — после Ok. от qBittorrent идёт реальная верификация (торрент появился в списке по хэшу или названию). Если не появился — error. - /api/proxy-torrent-download: новый endpoint для скачивания .torrent файлов через NL-прокси (обходит DPI-блокировку) - torrents.html: кнопка Копировать magnet (Clipboard API + fallback), proxy-ссылки для .torrent, disabled-состояния для пустых magnet/torrent_url - tmdb-proxy: добавлен /proxy-torrent endpoint - urlencode filter для Jinja2 - test_app.py: 47 тестов на чистые функции
This commit is contained in:
parent
fb2aa5a60a
commit
a5497eef26
4 changed files with 598 additions and 130 deletions
|
|
@ -8,6 +8,7 @@ import os
|
|||
import logging
|
||||
import httpx
|
||||
from fastapi import FastAPI, HTTPException, Query
|
||||
from fastapi.responses import Response
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
|
||||
# Настройка логирования
|
||||
|
|
@ -130,6 +131,34 @@ async def get_movie_details(
|
|||
raise HTTPException(status_code=500, detail=f"Unexpected error: {str(e)}")
|
||||
|
||||
|
||||
@app.get("/proxy-torrent")
|
||||
async def proxy_torrent(url: str = Query(..., description="URL .torrent файла")):
|
||||
"""Скачивает .torrent файл через NL-сервер (обходит DPI-блокировки)"""
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
try:
|
||||
logger.info(f"Proxying .torrent download: {url}")
|
||||
response = await client.get(url, timeout=30.0)
|
||||
response.raise_for_status()
|
||||
return Response(
|
||||
content=response.content,
|
||||
media_type=response.headers.get("content-type", "application/x-bittorrent"),
|
||||
headers={
|
||||
"Content-Disposition": f'attachment; filename="torrent.torrent"',
|
||||
"Content-Length": str(len(response.content))
|
||||
}
|
||||
)
|
||||
except httpx.HTTPStatusError as e:
|
||||
logger.error(f".torrent proxy returned {e.response.status_code} for {url}")
|
||||
raise HTTPException(
|
||||
status_code=e.response.status_code,
|
||||
detail=f"Failed to download .torrent (status {e.response.status_code})"
|
||||
)
|
||||
except httpx.RequestError as e:
|
||||
logger.error(f".torrent proxy request failed for {url}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=502,
|
||||
detail=f"Cannot download .torrent: {str(e)}"
|
||||
)
|
||||
@app.get("/health")
|
||||
async def health_check():
|
||||
"""Проверка работоспособности сервиса"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue