From aaea329bf66d6a738ae2b41dcf2618315ec96aa0 Mon Sep 17 00:00:00 2001 From: Benny Date: Wed, 4 Dec 2024 20:55:42 +0100 Subject: [PATCH] updated --- pdm.lock | 14 +++++----- pyproject.toml | 2 +- requirements.txt | 4 +-- src/engine/base.py | 11 ++++---- src/engine/direct.py | 60 +++++++++++++++++++++++-------------------- src/engine/generic.py | 5 ++-- 6 files changed, 50 insertions(+), 46 deletions(-) diff --git a/pdm.lock b/pdm.lock index 733753fa..3bd58083 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:20afae14c946f158e190b8bc1a6ba9cb25a10fb9214fac0338df1d3fa601a84c" +content_hash = "sha256:9e796c46fdd2f2190a9a88e31676d4d91a6606563f66e1080d45c23617dbd9c1" [[metadata.targets]] requires_python = ">3.9" @@ -438,11 +438,11 @@ files = [ [[package]] name = "pyrogram" -version = "2.1.32" +version = "2.1.33" requires_python = "~=3.8" git = "https://github.com/KurimuzonAkuma/pyrogram" -ref = "ba49bbff6e37cca6174d0620ef6813960d9d85b6" -revision = "ba49bbff6e37cca6174d0620ef6813960d9d85b6" +ref = "9ec94e01e8a9d3653d587d39e06856da4a030fbc" +revision = "9ec94e01e8a9d3653d587d39e06856da4a030fbc" summary = "Elegant, modern and asynchronous Telegram MTProto API framework in Python for users and bots" groups = ["default"] dependencies = [ @@ -709,11 +709,11 @@ files = [ [[package]] name = "yt-dlp" -version = "2024.11.18" +version = "2024.12.3" requires_python = ">=3.9" summary = "A feature-rich command-line audio/video downloader" groups = ["default"] files = [ - {file = "yt_dlp-2024.11.18-py3-none-any.whl", hash = "sha256:b9741695911dc566498b5f115cdd6b1abbc5be61cb01fd98abe649990a41656c"}, - {file = "yt_dlp-2024.11.18.tar.gz", hash = "sha256:b8a4c23d3c9afd7e476bcdb87f38b6c0e8e12e3a239d7988f13acb434200f54d"}, + {file = "yt_dlp-2024.12.3-py3-none-any.whl", hash = "sha256:a6b32ea879ce3f95b47b9b57948b755b4d61f3700d4fc24602b17537ddf0cf90"}, + {file = "yt_dlp-2024.12.3.tar.gz", hash = "sha256:35abff51c5762033103f2330ba0a8a1f48c4388a413a2d8cdc9b84642fe8edd4"}, ] diff --git a/pyproject.toml b/pyproject.toml index c8dc8f07..36e52f47 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ description = "Default template for PDM package" authors = [ {name = "Benny", email = "benny.think@gmail.com"}, ] -dependencies = ["Pyrogram @ git+https://github.com/KurimuzonAkuma/pyrogram@ba49bbff6e37cca6174d0620ef6813960d9d85b6", "tgcrypto>=1.2.5", "yt-dlp>=2024.11.18", "APScheduler>=3.11.0", "ffmpeg-python>=0.2.0", "PyMySQL>=1.1.1", "filetype>=1.2.0", "beautifulsoup4>=4.12.3", "fakeredis>=2.26.1", "redis>=5.2.0", "requests>=2.32.3", "tqdm>=4.67.1", "token-bucket>=0.3.0", "python-dotenv>=1.0.1", "black>=24.10.0", "sqlalchemy>=2.0.36", "psutil>=6.1.0", "ffpb>=0.4.1"] +dependencies = ["Pyrogram @ git+https://github.com/KurimuzonAkuma/pyrogram@9ec94e01e8a9d3653d587d39e06856da4a030fbc", "tgcrypto>=1.2.5", "yt-dlp==2024.12.3", "APScheduler>=3.11.0", "ffmpeg-python>=0.2.0", "PyMySQL>=1.1.1", "filetype>=1.2.0", "beautifulsoup4>=4.12.3", "fakeredis>=2.26.1", "redis>=5.2.0", "requests>=2.32.3", "tqdm>=4.67.1", "token-bucket>=0.3.0", "python-dotenv>=1.0.1", "black>=24.10.0", "sqlalchemy>=2.0.36", "psutil>=6.1.0", "ffpb>=0.4.1"] requires-python = ">3.9" readme = "README.md" license = {text = "Apache2.0"} diff --git a/requirements.txt b/requirements.txt index 5c5b7146..d72d3048 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ -git+https://github.com/KurimuzonAkuma/pyrogram@ba49bbff6e37cca6174d0620ef6813960d9d85b6 +git+https://github.com/KurimuzonAkuma/pyrogram@9ec94e01e8a9d3653d587d39e06856da4a030fbc tgcrypto>=1.2.5 -yt-dlp>=2024.11.18 +yt-dlp==2024.12.3 APScheduler>=3.11.0 ffmpeg-python>=0.2.0 PyMySQL>=1.1.1 diff --git a/src/engine/base.py b/src/engine/base.py index 0ecf6698..a209dae7 100644 --- a/src/engine/base.py +++ b/src/engine/base.py @@ -15,7 +15,7 @@ import ffmpeg import filetype from helper import debounce, sizeof_fmt -from pyrogram import types +from pyrogram import enums, types from tqdm import tqdm from config import TG_NORMAL_MAX_SIZE, Types @@ -128,14 +128,14 @@ def download_hook(self, d: dict): eta = self.__remove_bash_color(d.get("_eta_str", d.get("eta"))) text = self.__tqdm_progress("Downloading...", total, downloaded, speed, eta) # debounce in here - self.__edit_text(self._bot_msg, text) + self.edit_text(self._bot_msg, text) def upload_hook(self, current, total): text = self.__tqdm_progress("Uploading...", total, current) - self.__edit_text(self._bot_msg, text) + self.edit_text(self._bot_msg, text) @debounce(5) - def __edit_text(self, text: str): + def edit_text(self, text: str): self._bot_msg.edit_text(text) def get_cache_fileid(self): @@ -147,7 +147,7 @@ def _setup_formats(self) -> list | None: pass @abstractmethod - def _download(self, formats): + def _download(self, formats) -> list: # responsible for get format and download it pass @@ -162,6 +162,7 @@ def _methods(self): } def send_something(self, *, chat_id, files, _type, caption=None, thumb=None, **kwargs): + self._client.send_chat_action(chat_id, enums.ChatAction.UPLOAD_DOCUMENT) if len(files) > 1: inputs = generate_input_media(files, caption) return self._client.send_media_group(chat_id, inputs)[0] diff --git a/src/engine/direct.py b/src/engine/direct.py index e641a269..187fb08f 100644 --- a/src/engine/direct.py +++ b/src/engine/direct.py @@ -8,8 +8,11 @@ import pathlib import subprocess import tempfile +from pathlib import Path +from uuid import uuid4 import filetype +import requests from base import BaseDownloader from pyrogram import enums @@ -18,25 +21,30 @@ class DirectDownloader(BaseDownloader): - def start(self): - pass - def _setup_formats(self) -> list | None: + # direct download doesn't need to setup formats pass def _requests_download(self): - pass + response = requests.get(self._url, stream=True) + response.raise_for_status() + file = Path(self._tempdir).joinpath(uuid4().hex) + ext = filetype.guess_extension(file) + if ext is not None: + file = file.with_suffix(ext) + + with open(file, "wb") as f: + for chunk in response.iter_content(chunk_size=8192): + f.write(chunk) + return [file.as_posix()] def _aria2_download(self): - chat_id = self._bot_msg.chat.id - temp_dir = tempfile.TemporaryDirectory(prefix="ytdl-aria2-", dir=TMPFILE_PATH) - tempdir = temp_dir.name ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" response = None video_paths = None # Download process using aria2c try: - self._bot_msg.__edit_text(f"Download Starting...", disable_web_page_preview=True) + self._bot_msg.edit_text(f"Aria2 download starting...") # Command to engine the link using aria2c command = [ "aria2c", @@ -45,47 +53,43 @@ def _aria2_download(self): "--max-tries=5", "--console-log-level=warn", "-d", - tempdir, + self._tempdir, self._url, ] # Run the command using subprocess.Popen process = subprocess.Popen(command, bufsize=0, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - line = "" max_iterations = 100 # Set a reasonable maximum number of iterations iteration = 0 - while process.poll() is None and iteration < max_iterations: - line = process.stdout.readline().decode("utf-8") + line: str = process.stdout.readline().decode("utf-8") if line.startswith("[#"): line = line.strip() - self._bot_msg.__edit_text(f"Downloading... \n\n`{line}`", disable_web_page_preview=True) + self.edit_text(f"Aria2 downloading... \n\n`{line}`", disable_web_page_preview=True) break iteration += 1 if iteration >= max_iterations: - self._bot_msg.__edit_text("Something went wrong. Please try again.", disable_web_page_preview=True) + self.edit_text("Download exceed max iteration. Please try again later.", disable_web_page_preview=True) except Exception as e: - self._bot_msg.__edit_text(f"Download failed!❌\n\n`{e}`", disable_web_page_preview=True) + self.edit_text(f"Download failed!❌\n\n`{e}`", disable_web_page_preview=True) return # Get filename and extension correctly after engine - filepath = list(pathlib.Path(tempdir).glob("*")) - file_path_obj = filepath[0] - path_obj = pathlib.Path(file_path_obj) - filename = path_obj.name + file: Path = next(Path(self._tempdir).glob("*")) + filename = file.name logging.info("Downloaded file %s", filename) - self._bot_msg.__edit_text(f"Download Complete", disable_web_page_preview=True) - ext = filetype.guess_extension(file_path_obj) + self.edit_text(f"Download Complete", disable_web_page_preview=True) + ext = filetype.guess_extension(file) # Rename file if it doesn't have extension if ext is not None and not filename.endswith(ext): - new_filename = f"{tempdir}/{filename}.{ext}" - os.rename(file_path_obj, new_filename) + file.rename(f"{self._tempdir}/{filename}.{ext}") # Get file path of the downloaded file to upload - video_paths = list(pathlib.Path(tempdir).glob("*")) - self._client.send_chat_action(chat_id, enums.ChatAction.UPLOAD_DOCUMENT) - upload_processor(self._client, self._bot_msg, self._url, video_paths) - self._bot_msg.__edit_text("Download success!✅") + return [file.as_posix()] - def _download(self, formats): + def _download(self, formats=None) -> list: if ENABLE_ARIA2: return self._aria2_download() return self._requests_download() + + def start(self): + self._download() + self._upload() diff --git a/src/engine/generic.py b/src/engine/generic.py index 1902b5a6..bdd13fbd 100644 --- a/src/engine/generic.py +++ b/src/engine/generic.py @@ -35,7 +35,7 @@ def _setup_formats(self) -> list | None: # Add any remaining buttons as the last row if temp_row: markup.append(temp_row) - self._bot_msg.__edit_text("Choose the format", reply_markup=types.InlineKeyboardMarkup(markup)) + self._bot_msg.edit_text("Choose the format", reply_markup=types.InlineKeyboardMarkup(markup)) return None if download == "audio": # download audio only @@ -59,9 +59,8 @@ def _setup_formats(self) -> list | None: formats.append("worst") return formats - def _download(self, formats): + def _download(self, formats) -> list: output = Path(self._tempdir, "%(title).70s.%(ext)s").as_posix() - ydl_opts = { "progress_hooks": [lambda d: self.download_hook(d)], "outtmpl": output,