from __future__ import annotations import shutil from datetime import UTC, datetime, timedelta from math import ceil from core.configs import get_settings from db.models.video import Quality as DBQuality from pyokru.errors import ( CopyrightsRestrictedError, NotReadyError, UnknownError, VideoNotFoundError, VideoProcessingError, ) from pyokru.models.video import Quality, Video from pyrogram import Client from pyrogram.enums import MessageMediaType from utils.client import MyClient from utils.i18n import tr as _ from utils.messages import message_handler from utils.models import Task as TeleTask from utils.queue import ( QueueEmpty, okru_queue, okru_queue_lock, ) from utils.tasks import gather_with_concurrency settings = get_settings() LOG_CHANNEL = settings.LOG_CHANNEL_ID async def check_unfinished_tasks(client: MyClient) -> None: try: async with okru_queue_lock: tele_task: TeleTask = okru_queue.get_nowait() except QueueEmpty: return if datetime.now(UTC) < tele_task.next_check_time: async with okru_queue_lock: await okru_queue.insert(2 if tele_task.user.is_paid() else 5, tele_task) return await check_task(client, tele_task) async def check_task(client: MyClient, tele_task: TeleTask) -> None: video = Video( id=tele_task.task.video.okru_id, title=tele_task.task.video.file_unique_id, file_path="", ) try: result = await client.okru.fetch_video_info(video, only_one_type=True) except NotReadyError: async with okru_queue_lock: await okru_queue.insert(2 if tele_task.user.is_paid() else 5, tele_task) offset = ceil(tele_task.video_duration / 10) tele_task.next_check_time += timedelta(seconds=offset) return except ( VideoNotFoundError, VideoProcessingError, CopyrightsRestrictedError, UnknownError, ) as err: await message_handler( client.send_message, chat_id=LOG_CHANNEL, text=_( "cp.task_failed", user_id=tele_task.user.user_id, video_id=video.id, file_id=tele_task.get_file().file_unique_id, error=err, ), ) await message_handler( tele_task.progress_message.edit, _( "video.task_failed", locale=tele_task.user.language, user_id=tele_task.user.user_id, ), ) shutil.rmtree(tele_task.temp_folder, ignore_errors=True) if not result: offset = ceil(tele_task.video_duration / 7.5) tele_task.next_check_time += timedelta(seconds=offset) if tele_task.okru_tries > 40: await message_handler( client.send_message, chat_id=LOG_CHANNEL, text=_( "cp.task_failed", user_id=tele_task.user.user_id, video_id=video.id, file_id=tele_task.get_file().file_unique_id, error="Tries Out !", ), ) await message_handler( tele_task.progress_message.edit, _( "video.task_failed", locale=tele_task.user.language, user_id=tele_task.user.user_id, ), ) shutil.rmtree(tele_task.temp_folder, ignore_errors=True) return async with okru_queue_lock: await okru_queue.insert(2 if tele_task.user.is_paid() else 5, tele_task) tele_task.okru_tries += 1 return await message_handler( tele_task.progress_message.edit, _("video.uploading", locale=tele_task.user.language) ) qualities = video.qualities[:-1] if len(video.qualities) > 1 else video.qualities if tele_task.user.is_paid(): qualities = video.qualities tasks = map( lambda q: handle_quality(client, tele_task, q, int(video.duration)), qualities, ) await gather_with_concurrency(3, tasks) tele_task.task.finished = True await tele_task.task.save() await client.okru.delete_video(tele_task.task.video.okru_delete_id) await message_handler(tele_task.progress_message.delete) tele_task.thumbnail_path.unlink() shutil.rmtree(tele_task.temp_folder, ignore_errors=True) async def handle_quality( client: Client, tele_task: TeleTask, quality: Quality, duration: int, ) -> None: file = tele_task.get_file() file_name = file.file_name.rsplit(".", 1)[0] if file.file_name else file.file_unique_id video_path = tele_task.temp_folder / f"{file_name}[{quality.name}].mp4" await quality.download(video_path) if not video_path.exists(): await handle_quality(client, tele_task, quality, duration) if (video_path.stat().st_size / pow(1024, 2)) > 2000: video_path.unlink() return video_path = video_path.rename( video_path.parent / f"{file_name}[{min(*quality.local_resolution)}p].mp4" ) to_log = False msg = await message_handler( client.send_video, chat_id=tele_task.video_message.from_user.id, video=str(video_path), reply_to_message_id=tele_task.video_message.id, caption=_( "video.caption", quality=min(*quality.local_resolution), locale=tele_task.user.language ) + "\n" + _("video.copyright"), duration=duration, width=quality.local_resolution[0], height=quality.local_resolution[1], thumb=str(tele_task.thumbnail_path), supports_streaming=True, # protect_content=not task.user.is_paid(), ) if msg is None: msg = await message_handler( client.send_video, chat_id=LOG_CHANNEL, video=str(video_path), caption=_( "video.caption", quality=min(*quality.local_resolution), locale=tele_task.user.language, ) + "\n" + _("video.copyright"), duration=duration, width=quality.local_resolution[0], height=quality.local_resolution[1], thumb=str(tele_task.thumbnail_path), supports_streaming=True, ) to_log = True video_path.unlink() video = tele_task.task.video if msg.media is MessageMediaType.ANIMATION: video.media_type = "animation" media_id = msg.animation.file_id else: media_id = msg.video.file_id video.qualities.append( DBQuality(name=quality.name, file_id=media_id, resolution=quality.local_resolution) ) await video.save() if to_log: await message_handler(msg.delete)