mirror of
https://gitlab.com/10ho/wastream.git
synced 2026-08-15 19:59:42 +00:00
FIX: - WASource: series <-> movie conversion now works both ways (was movie -> series only) - Turbobit: canonicalize mirror domains (trbt.cc / turbobit.cc -> turbobit.net) ADD: - WASource: editable IMDB ID from the dashboard - Admin: export / import of the database data (backup) - Admin: all settings editable from the dashboard (values set in the .env stay read-only) - Admin: content cache browser (Cache tab) to view cached content / links - Config: resilient playback (fallback + racing), configurable in the user config - Config: export / import of the user config on the /configure page (credentials excluded) - Pastebin: multi-host support via known-domain detection (now also supports 1fichier links, etc.) - Pastebin: recursive automatic link discovery (index -> content)
73 lines
2.2 KiB
Python
73 lines
2.2 KiB
Python
import asyncio
|
|
from typing import Optional
|
|
|
|
import httpx
|
|
|
|
from wastream.config.settings import settings
|
|
|
|
|
|
# ===========================
|
|
# HTTP Client Singleton
|
|
# ===========================
|
|
class HTTPClient:
|
|
|
|
_instance: Optional['HTTPClient'] = None
|
|
_client: Optional[httpx.AsyncClient] = None
|
|
_drain_tasks: set = set()
|
|
|
|
def __new__(cls):
|
|
if cls._instance is None:
|
|
cls._instance = super().__new__(cls)
|
|
return cls._instance
|
|
|
|
async def get_client(self) -> httpx.AsyncClient:
|
|
if self._client is None:
|
|
client_args = {
|
|
"timeout": httpx.Timeout(float(settings.HTTP_TIMEOUT)),
|
|
"follow_redirects": True,
|
|
"limits": httpx.Limits(max_connections=None, max_keepalive_connections=None)
|
|
}
|
|
if settings.PROXY_URL:
|
|
client_args["proxy"] = settings.PROXY_URL
|
|
self._client = httpx.AsyncClient(**client_args)
|
|
return self._client
|
|
|
|
async def get(self, url: str, **kwargs) -> httpx.Response:
|
|
client = await self.get_client()
|
|
return await client.get(url, **kwargs)
|
|
|
|
async def post(self, url: str, **kwargs) -> httpx.Response:
|
|
client = await self.get_client()
|
|
return await client.post(url, **kwargs)
|
|
|
|
async def request(self, method: str, url: str, **kwargs) -> httpx.Response:
|
|
client = await self.get_client()
|
|
return await client.request(method, url, **kwargs)
|
|
|
|
async def close(self):
|
|
if self._client:
|
|
await self._client.aclose()
|
|
self._client = None
|
|
|
|
async def reload(self):
|
|
old = self._client
|
|
self._client = None
|
|
if old is not None:
|
|
task = asyncio.create_task(self._drain(old))
|
|
self._drain_tasks.add(task)
|
|
task.add_done_callback(self._drain_tasks.discard)
|
|
|
|
async def _drain(self, client: httpx.AsyncClient):
|
|
try:
|
|
await asyncio.sleep(float(settings.STREAM_REQUEST_TIMEOUT))
|
|
finally:
|
|
try:
|
|
await client.aclose()
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
# ===========================
|
|
# Global HTTP Client Instance
|
|
# ===========================
|
|
http_client = HTTPClient()
|