diff --git a/Dockerfile b/Dockerfile index a0064670..dc339a2d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ ENV LANGUAGE=en_US:en \ RUN apt-get -qq update && apt-get -qq install -y \ python3 python3-pip locales libmagic-dev \ - p7zip-full p7zip-rar unzip && \ + p7zip-full p7zip-rar unzip mediainfo ffmpeg && \ locale-gen en_US.UTF-8 COPY requirements.txt . diff --git a/README.md b/README.md index c7a3e912..8339e8d5 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ SearchX is a multipurpose Telegram bot written in Python for Google Drive - Compress data from Google Drive, AppDrive and GDToT - Extract data from Google Drive, AppDrive and GDToT - Count data from Google Drive +- Generate mediainfo of media files from Google Drive and URL +- Generate frames of media files from Google Drive and URL +- Generate collage of media files from Google Drive and URL - Delete data from Google Drive - Set data permission in Google Drive - Size Limit support for Clone, Compression and Extraction tasks @@ -60,6 +63,9 @@ clone - Clone data to Google Drive compress - Compress data to Google Drive extract - Extract data to Google Drive count - Count data from Google Drive +minfo - Generate mediainfo of a media file +ss - Generate frames of a media file +col - Generate collage of a media file cancel - Cancel a task status - Get status of all tasks share - Set data permission in Google Drive diff --git a/bot/__main__.py b/bot/__main__.py index d41fe954..119f6e2e 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -7,7 +7,7 @@ from telegram.ext import CommandHandler from bot import bot, LOGGER, botStartTime, TELEGRAPH, Interval, dispatcher, updater -from bot.modules import archive, auth, bookmark, cancel, clone, count, delete, eval, list, permission, shell, status +from bot.modules import archive, auth, bookmark, cancel, clone, collage, count, delete, eval, frames, list, mediainfo, permission, shell, status from bot.helper.ext_utils.bot_utils import get_readable_file_size, get_readable_time from bot.helper.ext_utils.fs_utils import start_cleanup, clean_all, exit_clean_up from bot.helper.telegram_helper.bot_commands import BotCommands @@ -78,6 +78,12 @@ def restart(update, context):

/{BotCommands.CountCommand} <drive_url>: Count data from Google Drive

+• /{BotCommands.MediainfoCommand} <url>: Generate mediainfo of a media file from Google Drive and URL +

+• /{BotCommands.FramesCommand} <url> <count>: Generate frames of a media file from Google Drive and URL (Count optional) +

+• /{BotCommands.CollageCommand} <url> <grid>: Generate collage of a media file from Google Drive and URL (Grid optional) +

/{BotCommands.CancelCommand} <gid>: Cancel a task

/{BotCommands.StatusCommand}: Get status of all tasks diff --git a/bot/helper/drive_utils/gdriveTools.py b/bot/helper/drive_utils/gdriveTools.py index 1ac83a78..dfb02ba6 100644 --- a/bot/helper/drive_utils/gdriveTools.py +++ b/bot/helper/drive_utils/gdriveTools.py @@ -117,6 +117,14 @@ def __alt_authorize(self): LOGGER.error("The token.json file is missing") return None + def __get_access_token(self): + creds = None + if os.path.exists('token.json'): + creds = Credentials.from_authorized_user_file('token.json', self.__OAUTH_SCOPE) + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + return creds.token + def __switchServiceAccount(self): if self.__service_account_index == SERVICE_ACCOUNTS_NUMBER - 1: self.__service_account_index = 0 @@ -169,6 +177,36 @@ def __getFilesByFolderId(self, folder_id): break return files + def fileinfo(self, link): + try: + file_id = self.__getIdFromUrl(link) + except (KeyError, IndexError): + msg = "Drive ID not found" + LOGGER.error(msg) + return msg, "", "", "", "", "" + try: + access_token = self.__get_access_token() + meta = self.__getFileMetadata(file_id) + name = meta.get("name") + size = get_readable_file_size(int(meta.get("size", 0))) + mime_type = meta.get("mimeType") + except Exception as err: + if isinstance(err, RetryError): + LOGGER.info(f"Total attempts: {err.last_attempt.attempt_number}") + err = err.last_attempt.exception() + err = str(err).replace('>', '').replace('<', '') + if "File not found" in err: + token_service = self.__alt_authorize() + if token_service is not None: + self.__service = token_service + return self.fileinfo(link) + msg = "File not found" + else: + msg = err + LOGGER.error(msg) + return msg, "", "", "", "", "" + return "", file_id, access_token, name, size, mime_type + def __gDrive_file(self, filee): size = int(filee.get('size', 0)) self.__total_bytes += size diff --git a/bot/helper/ext_utils/bot_utils.py b/bot/helper/ext_utils/bot_utils.py index e0f12b7a..d9846c01 100644 --- a/bot/helper/ext_utils/bot_utils.py +++ b/bot/helper/ext_utils/bot_utils.py @@ -1,9 +1,12 @@ +import os import re +import requests import threading import time from html import escape from psutil import virtual_memory, cpu_percent, disk_usage +from requests_toolbelt import MultipartEncoder from bot.helper.telegram_helper.bot_commands import BotCommands from bot import botStartTime, DOWNLOAD_DIR, download_dict, download_dict_lock @@ -115,6 +118,37 @@ def get_readable_time(seconds: int) -> str: result += f'{seconds}s' return result +def slowpics_collection(path): + img_list = os.listdir(path) + data = { + "collectionName": "SearchX", + "hentai": "false", + "optimizeImages": "false", + "public": "false" + } + for i in range(0, len(img_list)): + data[f"images[{i}].name"] = img_list[i] + data[f"images[{i}].file"] = (img_list[i], open(f"{path}/{img_list[i]}", 'rb'), 'image/png') + with requests.Session() as client: + client.get('https://slow.pics/api/collection') + files = MultipartEncoder(data) + length = str(files.len) + headers = { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "en-US,en;q=0.5", + "Content-Length": length, + "Content-Type": files.content_type, + "Origin": "https://slow.pics/", + "Referer": "https://slow.pics/collection", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36", + "X-XSRF-TOKEN": client.cookies.get_dict()["XSRF-TOKEN"] + } + response = client.post("https://slow.pics/api/collection", data=files, headers=headers) + return f"https://slow.pics/c/{response.text}" + def is_url(url: str): url = re.findall(URL_REGEX, url) return bool(url) diff --git a/bot/helper/telegram_helper/bot_commands.py b/bot/helper/telegram_helper/bot_commands.py index bcd9c646..6da6343f 100644 --- a/bot/helper/telegram_helper/bot_commands.py +++ b/bot/helper/telegram_helper/bot_commands.py @@ -7,6 +7,9 @@ def __init__(self): self.CompressCommand = 'compress' self.ExtractCommand = 'extract' self.CountCommand = 'count' + self.MediainfoCommand = 'minfo' + self.FramesCommand = 'ss' + self.CollageCommand = 'col' self.CancelCommand = 'cancel' self.StatusCommand = 'status' self.PermissionCommand = 'share' diff --git a/bot/modules/collage.py b/bot/modules/collage.py new file mode 100644 index 00000000..8dce875a --- /dev/null +++ b/bot/modules/collage.py @@ -0,0 +1,189 @@ +import datetime +import mimetypes +import os +import random +import requests +import string +import subprocess + +from PIL import Image, ImageFont, ImageDraw, ImageOps +from telegram.ext import CommandHandler +from urllib.parse import unquote_plus + +from bot import LOGGER, DOWNLOAD_DIR, dispatcher +from bot.helper.drive_utils.gdriveTools import GoogleDriveHelper +from bot.helper.ext_utils.bot_utils import new_thread, get_readable_file_size, slowpics_collection, is_url, is_gdrive_link +from bot.helper.ext_utils.exceptions import DDLExceptionHandler +from bot.helper.ext_utils.fs_utils import clean_download +from bot.helper.telegram_helper.message_utils import sendMessage, deleteMessage +from bot.helper.telegram_helper.bot_commands import BotCommands +from bot.helper.telegram_helper.button_builder import ButtonMaker +from bot.helper.telegram_helper.filters import CustomFilters + +@new_thread +def collageNode(update, context): + args = update.message.text.split() + reply_to = update.message.reply_to_message + link = '' + grid = '' + row = 4 + col = 4 + if len(args) > 1: + link = args[1].strip() + try: + grid = args[2].split("x", maxsplit=1) + row = int(grid[0]) + col = int(grid[1]) + except (IndexError, ValueError): + pass + if reply_to: + link = reply_to.text.split(maxsplit=1)[0].strip() + try: + grid = args[1].split("x", maxsplit=1) + row = int(grid[0]) + col = int(grid[1]) + except (IndexError, ValueError): + pass + if row > 5 or col > 5: + row = 5 + col = 5 + elif row != col: + row = 4 + col = 4 + if is_url(link): + msg = sendMessage(f"Getting {row}x{col} collage: {link}", context.bot, update.message) + LOGGER.info(f"Getting {row}x{col} collage: {link}") + if is_gdrive_link(link): + try: + gd = GoogleDriveHelper() + res, file_id, access_token, name, size, mime_type = gd.fileinfo(link) + if res != "": + deleteMessage(context.bot, msg) + return sendMessage(res, context.bot, update.message) + if mime_type == "application/vnd.google-apps.folder": + raise DDLExceptionHandler("Folder is not supported") + file_dl = f"https://www.googleapis.com/drive/v3/files/{file_id}\?supportsAllDrives\=true\&alt\=media" + header = f"Authorization: Bearer {access_token}" + out = subprocess.run(f"ffprobe -headers '{header}' -i {file_dl} -show_entries format=duration -v error -of csv=p=0", capture_output=True, shell=True) + stderr = out.stderr.decode('utf-8') + if "403 Forbidden" in stderr: + raise DDLExceptionHandler("Download quota exceeded") + duration = out.stdout.decode('utf-8') + if duration == '': + raise ValueError("Unsupported media file") + durationhms = str(datetime.timedelta(seconds=int(float(duration)))) + uid = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=12)) + path = f"{DOWNLOAD_DIR}{uid}" + os.makedirs(path) + for seconds in random.sample(range(int(float(duration))), int(row*col)): + img = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=3)) + genss = subprocess.run(f"ffmpeg -headers '{header}' -hide_banner -ss {seconds} -i {file_dl} -frames:v 1 -q:v 2 -y {path}/{img}.png", capture_output=True, shell=True) + if "403 Forbidden" in genss.stderr.decode('utf-8'): + raise DDLExceptionHandler("Download quota exceeded fucker") + img_list = os.listdir(path) + images = [Image.open(fp) for fp in [os.path.join(path, file) for file in img_list]] + widths, heights = zip(*(i.size for i in images)) + max_width = max(widths) + max_height = max(heights) + canvas_width = max_width*row + canvas_height = max_height*col + canvas = Image.new(mode="RGB", size=(canvas_width, canvas_height), color=(0, 0, 0)) + tile_count=0 + for j in range(0, canvas_height - 1, max_height): + for i in range(0, canvas_width - 1, max_width): + im = Image.open(f'{path}/{img_list[tile_count]}') + canvas.paste(im, box=(i, j)) + tile_count+=1 + canvas_exp = ImageOps.expand(canvas, border=(0,int(canvas_height/6.5),0,0), fill=(0, 0, 0)) + draw = ImageDraw.Draw(canvas_exp) + text = f"{name}\nSize: {size}\nDuration: {durationhms}\nDimension: {max_width}x{max_height}" + font = ImageFont.truetype(font="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", size=int(canvas_height/30)) + draw.text((30,10), text=text, fill=(255, 255, 255), font=font) + collage_path = f"{path}/collage" + os.makedirs(collage_path) + img = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=4)) + canvas_res = canvas_exp.resize(size=(max_width, max_height)) + canvas_res.save(f"{collage_path}/{img}.png") + img_link = slowpics_collection(collage_path) + LOGGER.info(f"img limk {img_link}") + result = "" + result += f"Name: {name}" + result += f"\nSize: {size}" + result += f"\nType: {mime_type}" + button = ButtonMaker() + button.build_button("VIEW COLLAGE 🗂️", f"{img_link}") + clean_download(path) + deleteMessage(context.bot, msg) + sendMessage(result, context.bot, update.message, button.build_menu(1)) + except Exception as err: + deleteMessage(context.bot, msg) + LOGGER.error(str(err)) + return sendMessage(str(err), context.bot, update.message) + else: + try: + res = requests.head(link, stream=True) + name = unquote_plus(link).rsplit('/', 1)[-1] + size = get_readable_file_size(int(res.headers["Content-Length"].strip())) + mime_type = res.headers.get("Content-Type", mimetypes.guess_type(name)).rsplit(";", 1)[0] + out = subprocess.run(["ffprobe", "-i", f"{link}", "-show_entries", "format=duration", "-v", "quiet", "-of", "csv=p=0"], capture_output=True) + duration = out.stdout.decode('utf-8') + if duration == '': + raise ValueError("Unsupported media file") + durationhms = str(datetime.timedelta(seconds=int(float(duration)))) + uid = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=12)) + path = f"{DOWNLOAD_DIR}{uid}" + os.makedirs(path) + sscount=1 + for seconds in random.sample(range(int(float(duration))), int(row*col)): + img = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=4)) + genss = subprocess.run(["ffmpeg", "-hide_banner", "-ss", f"{seconds}", "-i", f"{link}", "-frames:v", "1", "-q:v", "2", "-y", f"{path}/{img}.png"], capture_output=True) + sscount+=1 + img_list = os.listdir(path) + images = [Image.open(fp) for fp in [os.path.join(path, file) for file in img_list]] + widths, heights = zip(*(i.size for i in images)) + max_width = max(widths) + max_height = max(heights) + canvas_width = max_width*row + canvas_height = max_height*col + canvas = Image.new(mode="RGB", size=(canvas_width, canvas_height), color=(0, 0, 0)) + tile_count=0 + for j in range(0, canvas_height - 1, max_height): + for i in range(0, canvas_width - 1, max_width): + im = Image.open(f'{path}/{img_list[tile_count]}') + canvas.paste(im, box=(i, j)) + tile_count+=1 + canvas_exp = ImageOps.expand(canvas, border=(0,int(canvas_height/6.5),0,0), fill=(0, 0, 0)) + draw = ImageDraw.Draw(canvas_exp) + text = f"{name}\nSize: {size}\nDuration: {durationhms}\nDimension: {max_width}x{max_height}" + font = ImageFont.truetype(font="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", size=int(canvas_height/30)) + draw.text((30,10), text=text, fill=(255, 255, 255), font=font) + collage_path = f"{path}/collage" + os.makedirs(collage_path) + img = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=4)) + canvas_res = canvas_exp.resize(size=(max_width, max_height)) + canvas_res.save(f"{collage_path}/{img}.png") + img_link = slowpics_collection(collage_path) + result = "" + result += f"Name: {name}" + result += f"\nSize: {size}" + result += f"\nType: {mime_type}" + button = ButtonMaker() + button.build_button("VIEW COLLAGE 🗂️", f"{img_link}") + clean_download(path) + deleteMessage(context.bot, msg) + sendMessage(result, context.bot, update.message, button.build_menu(1)) + except KeyError: + deleteMessage(context.bot, msg) + err = "Invalid link" + LOGGER.error(str(err)) + return sendMessage(str(err), context.bot, update.message) + except Exception as err: + deleteMessage(context.bot, msg) + LOGGER.error(str(err)) + return sendMessage(str(err), context.bot, update.message) + else: + sendMessage("Send a link along with command", context.bot, update.message) + +collage_handler = CommandHandler(BotCommands.CollageCommand, collageNode, + filters=CustomFilters.authorized_user | CustomFilters.authorized_chat) +dispatcher.add_handler(collage_handler) diff --git a/bot/modules/frames.py b/bot/modules/frames.py new file mode 100644 index 00000000..82e26208 --- /dev/null +++ b/bot/modules/frames.py @@ -0,0 +1,126 @@ +import mimetypes +import os +import random +import requests +import string +import subprocess + +from telegram.ext import CommandHandler +from urllib.parse import unquote_plus + +from bot import LOGGER, DOWNLOAD_DIR, dispatcher +from bot.helper.drive_utils.gdriveTools import GoogleDriveHelper +from bot.helper.ext_utils.bot_utils import new_thread, get_readable_file_size, slowpics_collection, is_url, is_gdrive_link +from bot.helper.ext_utils.exceptions import DDLExceptionHandler +from bot.helper.ext_utils.fs_utils import clean_download +from bot.helper.telegram_helper.message_utils import sendMessage, deleteMessage +from bot.helper.telegram_helper.bot_commands import BotCommands +from bot.helper.telegram_helper.button_builder import ButtonMaker +from bot.helper.telegram_helper.filters import CustomFilters + +@new_thread +def framesNode(update, context): + args = update.message.text.split() + reply_to = update.message.reply_to_message + link = '' + frames = 5 + if len(args) > 1: + link = args[1].strip() + try: + frames = int(args[2]) + except (IndexError, ValueError): + pass + if reply_to: + link = reply_to.text.split(maxsplit=1)[0].strip() + try: + frames = int(args[1]) + except (IndexError, ValueError): + pass + if frames > 10: + frames = 10 + if is_url(link): + msg = sendMessage(f"Getting {frames} frames: {link}", context.bot, update.message) + LOGGER.info(f"Getting {frames} frames: {link}") + if is_gdrive_link(link): + try: + gd = GoogleDriveHelper() + res, file_id, access_token, name, size, mime_type = gd.fileinfo(link) + if res != "": + deleteMessage(context.bot, msg) + return sendMessage(res, context.bot, update.message) + if mime_type == "application/vnd.google-apps.folder": + raise DDLExceptionHandler("Folder is not supported") + file_dl = f"https://www.googleapis.com/drive/v3/files/{file_id}\?supportsAllDrives\=true\&alt\=media" + header = f"Authorization: Bearer {access_token}" + out = subprocess.run(f"ffprobe -headers '{header}' -i {file_dl} -show_entries format=duration -v error -of csv=p=0", capture_output=True, shell=True) + stderr = out.stderr.decode('utf-8') + if "403 Forbidden" in stderr: + raise DDLExceptionHandler("Download quota exceeded") + duration = out.stdout.decode('utf-8') + if duration == '': + raise ValueError("Unsupported media file") + uid = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=12)) + path = f"{DOWNLOAD_DIR}{uid}" + os.makedirs(path) + for seconds in random.sample(range(int(float(duration))), int(f"{frames}")): + img = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=3)) + genss = subprocess.run(f"ffmpeg -headers '{header}' -hide_banner -ss {seconds} -i {file_dl} -frames:v 1 -q:v 2 -y {path}/{img}.png", capture_output=True, shell=True) + if "403 Forbidden" in genss.stderr.decode('utf-8'): + raise DDLExceptionHandler("Download quota exceeded") + img_link = slowpics_collection(path) + result = "" + result += f"Name: {name}" + result += f"\nSize: {size}" + result += f"\nType: {mime_type}" + button = ButtonMaker() + button.build_button("VIEW FRAMES 🗂️", f"{img_link}") + clean_download(path) + deleteMessage(context.bot, msg) + sendMessage(result, context.bot, update.message, button.build_menu(1)) + except Exception as err: + deleteMessage(context.bot, msg) + LOGGER.error(str(err)) + return sendMessage(str(err), context.bot, update.message) + else: + try: + res = requests.head(link, stream=True) + name = unquote_plus(link).rsplit('/', 1)[-1] + size = get_readable_file_size(int(res.headers["Content-Length"].strip())) + mime_type = res.headers.get("Content-Type", mimetypes.guess_type(name)).rsplit(";", 1)[0] + out = subprocess.run(["ffprobe", "-i", f"{link}", "-show_entries", "format=duration", "-v", "quiet", "-of", "csv=p=0"], capture_output=True) + duration = out.stdout.decode('utf-8') + if duration == '': + raise ValueError("Unsupported media file") + uid = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=12)) + path = f"{DOWNLOAD_DIR}{uid}" + os.makedirs(path) + sscount=1 + for seconds in random.sample(range(int(float(duration))), int(f"{frames}")): + img = ''.join(random.SystemRandom().choices(string.ascii_letters + string.digits, k=4)) + genss = subprocess.run(["ffmpeg", "-hide_banner", "-ss", f"{seconds}", "-i", f"{link}", "-frames:v", "1", "-q:v", "2", "-y", f"{path}/{img}.png"], capture_output=True) + sscount+=1 + img_link = slowpics_collection(path) + result = "" + result += f"Name: {name}" + result += f"\nSize: {size}" + result += f"\nType: {mime_type}" + button = ButtonMaker() + button.build_button("VIEW FRAMES 🗂️", f"{img_link}") + clean_download(path) + deleteMessage(context.bot, msg) + sendMessage(result, context.bot, update.message, button.build_menu(1)) + except KeyError: + deleteMessage(context.bot, msg) + err = "Invalid link" + LOGGER.error(str(err)) + return sendMessage(str(err), context.bot, update.message) + except Exception as err: + deleteMessage(context.bot, msg) + LOGGER.error(str(err)) + return sendMessage(str(err), context.bot, update.message) + else: + sendMessage("Send a link along with command", context.bot, update.message) + +frames_handler = CommandHandler(BotCommands.FramesCommand, framesNode, + filters=CustomFilters.authorized_user | CustomFilters.authorized_chat) +dispatcher.add_handler(frames_handler) diff --git a/bot/modules/mediainfo.py b/bot/modules/mediainfo.py new file mode 100644 index 00000000..b035d3cd --- /dev/null +++ b/bot/modules/mediainfo.py @@ -0,0 +1,98 @@ +import mimetypes +import requests +import subprocess + +from telegram.ext import CommandHandler +from urllib.parse import unquote_plus + +from bot import LOGGER, TELEGRAPH, dispatcher +from bot.helper.drive_utils.gdriveTools import GoogleDriveHelper +from bot.helper.ext_utils.bot_utils import new_thread, get_readable_file_size, is_url, is_gdrive_link +from bot.helper.ext_utils.exceptions import DDLExceptionHandler +from bot.helper.telegram_helper.message_utils import sendMessage, deleteMessage +from bot.helper.telegram_helper.bot_commands import BotCommands +from bot.helper.telegram_helper.button_builder import ButtonMaker +from bot.helper.telegram_helper.filters import CustomFilters + +@new_thread +def mediainfoNode(update, context): + reply_to = update.message.reply_to_message + link = '' + if len(context.args) == 1: + link = context.args[0] + if reply_to: + link = reply_to.text.split(maxsplit=1)[0].strip() + if is_url(link): + msg = sendMessage(f"Getting mediainfo: {link}", context.bot, update.message) + LOGGER.info(f"Getting mediainfo: {link}") + if is_gdrive_link(link): + try: + gd = GoogleDriveHelper() + res, file_id, access_token, name, size, mime_type = gd.fileinfo(link) + if res != "": + deleteMessage(context.bot, msg) + return sendMessage(res, context.bot, update.message) + if mime_type == "application/vnd.google-apps.folder": + raise DDLExceptionHandler("Folder is not supported") + file_dl = f"https://www.googleapis.com/drive/v3/files/{file_id}\?supportsAllDrives\=true\&alt\=media" + header = f"--file_curl=HttpHeader,Authorization: Bearer {access_token}" + out = subprocess.run(f"mediainfo '{header}' {file_dl}", capture_output=True, shell=True) + stderr = out.stderr.decode('utf-8') + if "downloadQuotaExceeded" in stderr or "cannotDownloadFile" in stderr: + raise DDLExceptionHandler("Download quota exceeded") + stdout = out.stdout.decode('utf-8') + metadata = stdout.replace(file_dl.replace("\\", ""), name) + page = TELEGRAPH[0].create_page( + title='SearchX Mediainfo', + author_name='Levi', + author_url='https://t.me/l3v11', + html_content=f'
{metadata}
')['path'] + result = "" + result += f"Name: {name}" + result += f"\nSize: {size}" + result += f"\nType: {mime_type}" + button = ButtonMaker() + button.build_button("VIEW MEDIAINFO 🗂️", f"https://graph.org/{page}") + deleteMessage(context.bot, msg) + sendMessage(result, context.bot, update.message, button.build_menu(1)) + except Exception as err: + deleteMessage(context.bot, msg) + LOGGER.error(str(err)) + return sendMessage(str(err), context.bot, update.message) + else: + try: + res = requests.head(link, stream=True) + name = unquote_plus(link).rsplit('/', 1)[-1] + size = get_readable_file_size(int(res.headers["Content-Length"].strip())) + mime_type = res.headers.get("Content-Type", mimetypes.guess_type(name)).rsplit(";", 1)[0] + out = subprocess.run(["mediainfo", f"{link}"], capture_output=True) + stdout = out.stdout.decode('utf-8') + metadata = stdout.replace(link, name) + page = TELEGRAPH[0].create_page( + title='SearchX Mediainfo', + author_name='Levi', + author_url='https://t.me/l3v11', + html_content=f'
{metadata}
')['path'] + result = "" + result += f"Name: {name}" + result += f"\nSize: {size}" + result += f"\nType: {mime_type}" + button = ButtonMaker() + button.build_button("VIEW MEDIAINFO 🗂️", f"https://graph.org/{page}") + deleteMessage(context.bot, msg) + sendMessage(result, context.bot, update.message, button.build_menu(1)) + except KeyError: + deleteMessage(context.bot, msg) + err = "Invalid link" + LOGGER.error(str(err)) + return sendMessage(str(err), context.bot, update.message) + except Exception as err: + deleteMessage(context.bot, msg) + LOGGER.error(str(err)) + return sendMessage(str(err), context.bot, update.message) + else: + sendMessage("Send a link along with command", context.bot, update.message) + +mediainfo_handler = CommandHandler(BotCommands.MediainfoCommand, mediainfoNode, + filters=CustomFilters.authorized_user | CustomFilters.authorized_chat) +dispatcher.add_handler(mediainfo_handler) diff --git a/requirements.txt b/requirements.txt index 1d5ac517..18bab810 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,11 +1,13 @@ dnspython google-api-python-client google-auth-oauthlib +pillow psutil pymongo python-dotenv python-magic python-telegram-bot==13.15 requests +requests-toolbelt telegraph tenacity