Files
mhdzumair ec20feca52 refactor: streamline torrent file selection and metadata update process
Add support for telegram notification when unable to detect episode files, refactor file selection and update db function
2025-02-20 10:13:04 +05:30

122 lines
4.4 KiB
Python

import asyncio
from typing import List, Optional
from db.models import TorrentStreams
from db.schemas import UserData
from streaming_providers.exceptions import ProviderException
from streaming_providers.offcloud.client import OffCloud
async def get_video_url_from_offcloud(
info_hash: str,
magnet_link: str,
user_data: UserData,
stream: TorrentStreams,
filename: Optional[str] = None,
season: Optional[int] = None,
episode: Optional[int] = None,
max_retries: int = 5,
retry_interval: int = 5,
**kwargs,
) -> str:
async with OffCloud(token=user_data.streaming_provider.token) as oc_client:
# Check if the torrent already exists
torrent_info = await oc_client.get_available_torrent(info_hash)
if torrent_info:
request_id = torrent_info.get("requestId")
torrent_info = await oc_client.get_torrent_info(request_id)
if torrent_info["status"] == "downloaded":
return await oc_client.create_download_link(
request_id,
torrent_info,
stream,
filename,
season,
episode,
)
if torrent_info["status"] == "error":
raise ProviderException(
f"Error transferring magnet link to OffCloud. {torrent_info['errorMessage']}",
"transfer_error.mp4",
)
else:
# If torrent doesn't exist, add it
if stream.torrent_file:
response_data = await oc_client.add_torrent_file(
stream.torrent_file, stream.torrent_name
)
else:
response_data = await oc_client.add_magnet_link(magnet_link)
request_id = response_data["requestId"]
# Wait for download completion and get the direct link
torrent_info = await oc_client.wait_for_status(
request_id, "downloaded", max_retries, retry_interval
)
return await oc_client.create_download_link(
request_id,
torrent_info,
stream,
filename,
season,
episode,
)
async def update_oc_cache_status(
streams: List[TorrentStreams], user_data: UserData, **kwargs
):
"""Updates the cache status of streams based on OffCloud's instant availability."""
try:
async with OffCloud(token=user_data.streaming_provider.token) as oc_client:
instant_availability_data = (
await oc_client.get_torrent_instant_availability(
[stream.id for stream in streams]
)
)
if not instant_availability_data:
return
for stream in streams:
stream.cached = stream.id in instant_availability_data
except ProviderException:
pass
async def fetch_downloaded_info_hashes_from_oc(
user_data: UserData, **kwargs
) -> List[str]:
"""Fetches the info_hashes of all torrents downloaded in the OffCloud account."""
try:
async with OffCloud(token=user_data.streaming_provider.token) as oc_client:
available_torrents = await oc_client.get_user_torrent_list()
return [
torrent["originalLink"].split("btih:")[1].split("&")[0]
for torrent in available_torrents
if "btih:" in torrent["originalLink"]
]
except ProviderException:
return []
async def delete_all_torrents_from_oc(user_data: UserData, **kwargs):
"""Deletes all torrents from the Offcloud account."""
async with OffCloud(token=user_data.streaming_provider.token) as oc_client:
torrents = await oc_client.get_user_torrent_list()
await asyncio.gather(
*[oc_client.delete_torrent(torrent["requestId"]) for torrent in torrents],
return_exceptions=True,
)
async def validate_offcloud_credentials(user_data: UserData, **kwargs) -> dict:
"""Validates the OffCloud credentials."""
try:
async with OffCloud(token=user_data.streaming_provider.token) as oc_client:
await oc_client.get_user_torrent_list()
return {"status": "success"}
except ProviderException:
return {
"status": "error",
"message": "OffCloud API key is invalid or has expired",
}