# Copyright (c) 2023 EDM115 import asyncio import concurrent.futures import os import re import shutil from fnmatch import fnmatch from time import time from urllib.parse import unquote from aiofiles import open as openfile from aiohttp import ClientSession, InvalidURL from pyrogram import Client from pyrogram.errors import ReplyMarkupTooLong from pyrogram.types import CallbackQuery import unzip_http from config import Config from unzipper import LOGGER, unzipperbot from unzipper.helpers.database import ( add_cancel_task, del_cancel_task, del_merge_task, del_thumb_db, get_cancel_task, get_maintenance, get_merge_task_message_id, get_ongoing_tasks, set_upload_mode, update_thumb, update_uploaded, upload_thumb, add_ongoing_task, del_ongoing_task, count_ongoing_tasks, ) from unzipper.helpers.unzip_help import ( TimeFormatter, extentions_list, humanbytes, progress_for_pyrogram, ) from .bot_data import ERROR_MSGS, Buttons, Messages from .commands import https_url_regex, get_stats from .ext_script.custom_thumbnail import silent_del from .ext_script.ext_helper import ( _test_with_7z_helper, extr_files, get_files, make_keyboard, make_keyboard_empty, merge_files, split_files, ) from .ext_script.up_helper import answer_query, get_size, send_file, send_url_logs from .ext_script.url_parser import gdrive_dl split_file_pattern = r"\.(?:z\d+|r\d{2})$" rar_file_pattern = r"\.part\d+\.rar$" telegram_url_pattern = r"(?:http[s]?:\/\/)?(?:www\.)?t\.me\/([a-zA-Z0-9_]+)\/(\d+)" async def download(url, path): try: async with ClientSession() as session, session.get(url, timeout=None, allow_redirects=True) as resp, openfile(path, mode="wb") as file: async for chunk in resp.content.iter_chunked(Config.CHUNK_SIZE): await file.write(chunk) await session.close() except InvalidURL: LOGGER.error(Messages.INVALID_URL) except: LOGGER.error(Messages.ERR_DL.format(url)) async def download_with_progress(url, path, message, unzip_bot): async with ClientSession() as session, session.get(url, timeout=None, allow_redirects=True) as resp, openfile(path, mode="wb") as file: total_size = int(resp.headers.get("Content-Length", 0)) current_size = 0 start_time = time() async for chunk in resp.content.iter_chunked(Config.CHUNK_SIZE): if message.from_user is not None and await get_cancel_task(message.from_user.id): await session.close() await message.edit(text=Messages.DL_STOPPED) await del_cancel_task(message.from_user.id) return False await file.write(chunk) current_size += len(chunk) await progress_for_pyrogram(current_size, total_size, Messages.DL_URL.format(url), message, start_time, unzip_bot) await session.close() def get_zip_http(url): rzf = unzip_http.RemoteZipFile(url) paths = rzf.namelist() return rzf, paths async def async_generator(iterable): for item in iterable: yield item # Callbacks @unzipperbot.on_callback_query() async def unzipper_cb(unzip_bot: Client, query: CallbackQuery): uid = query.from_user.id if uid != Config.BOT_OWNER: # skipcq: PTC-W0048 if await count_ongoing_tasks() >= Config.MAX_CONCURRENT_TASKS: ogtasks = await get_ongoing_tasks() if not any(ogtask["user_id"] == uid for ogtask in ogtasks): await unzip_bot.send_message( chat_id=uid, text=Messages.MAX_TASKS.format(Config.MAX_CONCURRENT_TASKS), ) return if uid != Config.BOT_OWNER and await get_maintenance(): await answer_query(query, Messages.MAINTENANCE_ON) return sent_files = 0 global log_msg if query.data == "megoinhome": await query.edit_message_text( text=Messages.START_TEXT.format(query.from_user.mention), reply_markup=Buttons.START_BUTTON, ) elif query.data == "helpcallback": await query.edit_message_text( text=Messages.HELP_TXT, reply_markup=Buttons.ME_GOIN_HOME ) elif query.data == "aboutcallback": await query.edit_message_text( text=Messages.ABOUT_TXT, reply_markup=Buttons.ME_GOIN_HOME, disable_web_page_preview=True, ) elif query.data == "donatecallback": await query.edit_message_text( text=Messages.DONATE_TEXT, reply_markup=Buttons.ME_GOIN_HOME, disable_web_page_preview=True, ) elif query.data.startswith("statscallback"): if query.data.endswith("refresh"): await query.edit_message_text(text=Messages.REFRESH_STATS) text_stats = await get_stats(query.from_user.id) await query.edit_message_text( text=text_stats, reply_markup=Buttons.REFRESH_BUTTON, ) elif query.data == "canceldownload": await add_cancel_task(query.from_user.id) elif query.data == "check_thumb": user_id = query.from_user.id thumb_location = Config.THUMB_LOCATION + "/" + str(user_id) + ".jpg" await unzip_bot.send_photo( chat_id=user_id, photo=thumb_location, caption=Messages.ACTUAL_THUMB ) await unzip_bot.delete_messages( chat_id=user_id, message_ids=query.message.id ) await unzip_bot.send_message( chat_id=user_id, text=Messages.EXISTING_THUMB, reply_markup=Buttons.THUMB_FINAL, ) elif query.data == "check_before_del": user_id = query.from_user.id thumb_location = Config.THUMB_LOCATION + "/" + str(user_id) + ".jpg" await unzip_bot.send_photo( chat_id=user_id, photo=thumb_location, caption=Messages.ACTUAL_THUMB ) await unzip_bot.delete_messages( chat_id=user_id, message_ids=query.message.id ) await unzip_bot.send_message( chat_id=user_id, text=Messages.DEL_CONFIRM_THUMB_2, reply_markup=Buttons.THUMB_DEL_2, ) elif query.data.startswith("save_thumb"): user_id = query.from_user.id replace = query.data.split("|")[1] if replace == "replace": await silent_del(user_id) thumb_location = Config.THUMB_LOCATION + "/" + str(user_id) + ".jpg" final_thumb = Config.THUMB_LOCATION + "/waiting_" + str(user_id) + ".jpg" try: os.rename(final_thumb, thumb_location) except: LOGGER.warning(Messages.ERROR_THUMB_RENAME) try: thumb_url = await upload_thumb(thumb_location) try: if thumb_url != -1 and re.match(https_url_regex, thumb_url): await update_thumb(query.from_user.id, thumb_url, force=True) except: LOGGER.error(Messages.ERROR_THUMB_UPDATE) except: LOGGER.error(Messages.ERROR_TELEGRAPH_UPLOAD) await answer_query(query, Messages.SAVED_THUMBNAIL) elif query.data == "del_thumb": user_id = query.from_user.id thumb_location = Config.THUMB_LOCATION + "/" + str(user_id) + ".jpg" try: await del_thumb_db(user_id) except Exception as e: LOGGER.error(Messages.ERROR_THUMB_DEL.format(e)) try: os.remove(thumb_location) except: pass await query.edit_message_text(text=Messages.DELETED_THUMB) elif query.data == "nope_thumb": user_id = query.from_user.id del_1 = Config.THUMB_LOCATION + "/not_resized_" + str(user_id) + ".jpg" del_2 = Config.THUMB_LOCATION + "/waiting_" + str(user_id) + ".jpg" try: os.remove(del_1) except: pass try: os.remove(del_2) except: pass await query.edit_message_text( text=Messages.CANCELLED_TXT.format(Messages.PROCESS_CANCELLED)) elif query.data.startswith("set_mode"): user_id = query.from_user.id mode = query.data.split("|")[1] await set_upload_mode(user_id, mode) await answer_query( query, Messages.CHANGED_UPLOAD_MODE_TXT.format(mode) ) elif query.data == "merge_this": user_id = query.from_user.id m_id = query.message.id start_time = time() await add_ongoing_task(user_id, start_time, "merge") s_id = await get_merge_task_message_id(user_id) merge_msg = await query.message.edit(Messages.PROCESSING_TASK) download_path = f"{Config.DOWNLOAD_LOCATION}/{user_id}/merge" if s_id and (m_id - s_id) > 1: files_array = list(range(s_id, m_id)) try: messages_array = await unzip_bot.get_messages(user_id, files_array) except Exception as e: LOGGER.error(Messages.ERROR_GET_MSG.format(e)) await answer_query(query, Messages.ERROR_TXT.format(e)) await del_ongoing_task(user_id) await del_merge_task(user_id) try: shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}") except: pass return length = len(messages_array) if not os.path.isdir(download_path): os.makedirs(download_path) rs_time = time() newarray = [] await merge_msg.edit(Messages.PROCESS_MSGS.format(length)) for message in messages_array: if message.document is None: pass else: if message.from_user.id == user_id: # avoid getting files from other users, tho idk why this could happen newarray.append(message) length = len(newarray) if length == 0: await answer_query(query, Messages.NO_MERGE_TASK) await del_ongoing_task(user_id) await del_merge_task(user_id) try: shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}") except: pass return i = 0 async_newarray = async_generator(newarray) async for message in async_newarray: i += 1 fname = message.document.file_name await message.forward(chat_id=Config.LOGS_CHANNEL) location = f"{download_path}/{fname}" s_time = time() await message.download( file_name=location, progress=progress_for_pyrogram, progress_args=( Messages.DL_FILES.format(i, length), merge_msg, s_time, unzip_bot, ), ) e_time = time() dltime = TimeFormatter(round(e_time - rs_time) * 1000) if dltime == "": dltime = "1 s" await merge_msg.edit(Messages.AFTER_OK_MERGE_DL_TXT.format(i, dltime)) await merge_msg.edit( text=Messages.CHOOSE_EXT_MODE_MERGE, reply_markup=Buttons.CHOOSE_E_F_M__BTNS, ) await del_merge_task(user_id) else: await answer_query(query, Messages.NO_MERGE_TASK) await del_ongoing_task(user_id) await del_merge_task(user_id) try: shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}") except: pass elif query.data.startswith("merged"): user_id = query.from_user.id download_path = f"{Config.DOWNLOAD_LOCATION}/{user_id}/merge" ext_files_dir = f"{Config.DOWNLOAD_LOCATION}/{user_id}/extracted" os.makedirs(ext_files_dir) try: files = await get_files(download_path) file = files[0] except IndexError: await answer_query(query, Messages.NO_MERGE_TASK) await del_ongoing_task(user_id) await del_merge_task(user_id) try: shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}") except: pass return splitted_data = query.data.split("|") log_msg = await unzip_bot.send_message( chat_id=Config.LOGS_CHANNEL, text=Messages.PROCESS_MERGE.format(user_id, ".".join(file.split("/")[-1].split(".")[:-1])), ) try: await query.message.edit(Messages.PROCESSING_TASK) except: pass if splitted_data[1] == "with_pass": password = await unzip_bot.ask( chat_id=query.message.chat.id, text=Messages.PLS_SEND_PASSWORD, ) ext_s_time = time() extractor = await merge_files( iinput=file, ooutput=ext_files_dir, password=password.text, ) ext_e_time = time() else: # Can't test the archive apparently ext_s_time = time() extractor = await merge_files(iinput=file, ooutput=ext_files_dir) ext_e_time = time() # Checks if there is an error happened while extracting the archive if any(err in extractor for err in ERROR_MSGS): try: await query.message.edit(Messages.EXT_FAILED_TXT) shutil.rmtree(ext_files_dir) shutil.rmtree(download_path) await del_ongoing_task(user_id) except: try: await query.message.delete() except: pass await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.EXT_FAILED_TXT ) shutil.rmtree(ext_files_dir) await del_ongoing_task(user_id) return # Check if user was dumb 😐 paths = await get_files(path=ext_files_dir) if not paths: await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.PASSWORD_PROTECTED, ) await answer_query( query, Messages.EXT_FAILED_TXT, unzip_client=unzip_bot ) shutil.rmtree(ext_files_dir) shutil.rmtree(download_path) await del_ongoing_task(user_id) return try: shutil.rmtree(download_path) except: pass # Upload extracted files extrtime = TimeFormatter(round(ext_e_time - ext_s_time) * 1000) if extrtime == "": extrtime = "1s" await answer_query( query, Messages.EXT_OK_TXT.format(extrtime), unzip_client=unzip_bot ) try: i_e_buttons = await make_keyboard( paths=paths, user_id=user_id, chat_id=query.message.chat.id, unziphttp=False ) try: await query.message.edit(Messages.SELECT_FILES, reply_markup=i_e_buttons) except ReplyMarkupTooLong: empty_buttons = await make_keyboard_empty( user_id=user_id, chat_id=query.message.chat.id, unziphttp=False ) await query.message.edit( Messages.UNABLE_GATHER_FILES, reply_markup=empty_buttons, ) except: try: await query.message.delete() i_e_buttons = await make_keyboard( paths=paths, user_id=user_id, chat_id=query.message.chat.id, unziphttp=False ) await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.SELECT_FILES, reply_markup=i_e_buttons, ) except: try: await query.message.delete() empty_buttons = await make_keyboard_empty( user_id=user_id, chat_id=query.message.chat.id, unziphttp=False ) await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.UNABLE_GATHER_FILES, reply_markup=empty_buttons, ) except: await answer_query( query, Messages.EXT_FAILED_TXT, unzip_client=unzip_bot ) shutil.rmtree(ext_files_dir) LOGGER.error(Messages.FATAL_ERROR) await del_ongoing_task(user_id) return elif query.data.startswith("extract_file"): user_id = query.from_user.id start_time = time() await add_ongoing_task(user_id, start_time, "extract") download_path = f"{Config.DOWNLOAD_LOCATION}/{user_id}" ext_files_dir = f"{download_path}/extracted" r_message = query.message.reply_to_message splitted_data = query.data.split("|") try: await query.message.edit(Messages.PROCESSING_TASK) except: pass log_msg = await unzip_bot.send_message( chat_id=Config.LOGS_CHANNEL, text=Messages.USER_QUERY.format(user_id) ) global archive_msg try: if splitted_data[1] == "url": url = r_message.text # Double check if not re.match(https_url_regex, url): await del_ongoing_task(user_id) await query.message.edit(Messages.INVALID_URL) return if re.match(telegram_url_pattern, url): r_message = await unzip_bot.get_messages( chat_id=url.split("/")[-2], message_ids=int(url.split("/")[-1]) ) splitted_data[1] = "tg_file" if splitted_data[1] == "url": s = ClientSession() if "drive.google.com" in url: url = await gdrive_dl(url) if url is None: await del_ongoing_task(user_id) await query.message.edit(Messages.INVALID_URL) return async with s as session: # Get the file size unzip_head = await session.head(url, allow_redirects=True) f_size = unzip_head.headers.get("content-length") u_file_size = f_size if f_size else "undefined" await log_msg.edit(Messages.LOG_TXT.format(user_id, url, u_file_size)) archive_msg = log_msg # Checks if file is an archive using content-type header unzip_resp = await session.get(url, timeout=None, allow_redirects=True) if "application/" not in unzip_resp.headers.get("content-type"): await del_ongoing_task(user_id) await query.message.edit(Messages.NOT_AN_ARCHIVE) return rfnamebro = unquote(url.split("/")[-1]) if unzip_resp.status == 200: # Makes download dir os.makedirs(download_path) s_time = time() fname = unquote(os.path.splitext(url)[1]) fext = fname.split(".")[-1].casefold() if ( splitted_data[2] not in ["thumb", "thumbrename"] and fext not in extentions_list["archive"] ): await del_ongoing_task(user_id) await query.message.edit(Messages.DEF_NOT_AN_ARCHIVE) try: shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}") except: pass return archive = f"{download_path}/archive_from_{user_id}{fname}" location = archive await answer_query( query, Messages.PROCESSING2, unzip_client=unzip_bot ) # HTTP server must send Accept-Ranges: bytes and Content-Length in headers if fext == "zip" and "accept-ranges" in unzip_resp.headers and "content-length" in unzip_resp.headers: try: loop = asyncio.get_event_loop() with concurrent.futures.ThreadPoolExecutor() as pool: rzf, paths = await loop.run_in_executor(pool, get_zip_http, url) try: i_e_buttons = await make_keyboard( paths=paths, user_id=user_id, chat_id=query.message.chat.id, unziphttp=True, rzfile=rzf, ) try: await query.message.edit( Messages.SELECT_FILES, reply_markup=i_e_buttons ) except ReplyMarkupTooLong: empty_buttons = await make_keyboard_empty( user_id=user_id, chat_id=query.message.chat.id, unziphttp=True, rzfile=rzf) await query.message.edit( Messages.UNABLE_GATHER_FILES, reply_markup=empty_buttons, ) except: try: await query.message.delete() i_e_buttons = await make_keyboard( paths=paths, user_id=user_id, chat_id=query.message.chat.id, unziphttp=True, rzfile=rzf, ) await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.SELECT_FILES, reply_markup=i_e_buttons, ) except: try: await query.message.delete() empty_buttons = await make_keyboard_empty( user_id=user_id, chat_id=query.message.chat.id, unziphttp=True, rzfile=rzf ) await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.UNABLE_GATHER_FILES, reply_markup=empty_buttons, ) except: pass except Exception as e: LOGGER.error(Messages.UNZIP_HTTP.format(url, e)) try: dled = await download_with_progress(url, archive, query.message, unzip_bot) except Exception as e: dled = False LOGGER.error(Messages.ERR_DL.format(e)) if isinstance(dled, bool) and not dled: return e_time = time() # Send copy in logs in case url has gone # paths = await get_files(path=archive) await send_url_logs( unzip_bot=unzip_bot, c_id=Config.LOGS_CHANNEL, doc_f=archive, source=url, message=query.message, ) else: await del_ongoing_task(user_id) await query.message.edit(Messages.CANT_DL_URL) try: shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}") except: pass return elif splitted_data[1] == "tg_file": if r_message.document is None: await del_ongoing_task(user_id) await query.message.edit(Messages.GIVE_ARCHIVE) return fname = r_message.document.file_name rfnamebro = fname archive_msg = await r_message.forward(chat_id=Config.LOGS_CHANNEL) await log_msg.edit(Messages.LOG_TXT.format( user_id, fname, humanbytes(r_message.document.file_size) )) # Checks if it's actually an archive # fext = (pathlib.Path(fname).suffix).casefold() if splitted_data[2] not in ["thumb", "thumbrename"]: fext = fname.split(".")[-1].casefold() if ( fnmatch(fext, extentions_list["split"][0]) or fext in extentions_list["split"] or bool(re.search(rar_file_pattern, fname)) ): await query.message.edit(Messages.ITS_SPLITTED) return if bool(re.search(split_file_pattern, fname)): await del_ongoing_task(user_id) await query.message.edit(Messages.SPL_RZ) return if fext not in extentions_list["archive"]: await del_ongoing_task(user_id) await query.message.edit(Messages.DEF_NOT_AN_ARCHIVE) return # Makes download dir os.makedirs(download_path) s_time = time() location = f"{download_path}/archive_from_{user_id}{os.path.splitext(fname)[1]}" archive = await r_message.download( file_name=location, progress=progress_for_pyrogram, progress_args=( Messages.TRY_DL, query.message, s_time, unzip_bot, ), ) e_time = time() else: await del_ongoing_task(user_id) await answer_query( query, Messages.QUERY_PARSE_ERR, answer_only=True, unzip_client=unzip_bot, ) return if splitted_data[2].startswith("thumb"): await query.message.edit(Messages.PROCESSING2) archive_name = location.split("/")[-1] if "rename" in splitted_data[2]: newname = await unzip_bot.ask( chat_id=user_id, text=Messages.GIVE_NEW_NAME.format(rfnamebro), ) renamed = location.replace(archive_name, newname.text) else: renamed = location.replace(archive_name, rfnamebro) try: os.rename(location, renamed) except OSError as e: await del_ongoing_task(user_id) LOGGER.error(e) return newfname = renamed.split("/")[-1] fsize = await get_size(renamed) if fsize <= Config.TG_MAX_SIZE: await send_file( unzip_bot=unzip_bot, c_id=user_id, doc_f=renamed, query=query, full_path=renamed, log_msg=log_msg, split=False, ) await query.message.delete() await del_ongoing_task(user_id) return shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{user_id}") await query.message.edit(Messages.SPLITTING.format(newfname)) splitteddir = f"{Config.DOWNLOAD_LOCATION}/splitted/{user_id}" os.makedirs(splitteddir) ooutput = f"{splitteddir}/{newfname}" if await (user_id): splittedfiles = await split_files(renamed, ooutput, Config.TG_PREMIUM_SIZE) else: splittedfiles = await split_files(renamed, ooutput, Config.TG_MAX_SIZE) if not splittedfiles: try: shutil.rmtree(splitteddir) except: pass await del_ongoing_task(user_id) await query.message.edit(Messages.ERR_SPLIT) return await query.message.edit(Messages.SEND_ALL_PARTS.format(newfname)) async_splittedfiles = async_generator(splittedfiles) async for file in async_splittedfiles: sent_files += 1 await send_file( unzip_bot=unzip_bot, c_id=user_id, doc_f=file, query=query, full_path=splitteddir, log_msg=log_msg, split=True, ) try: shutil.rmtree(splitteddir) shutil.rmtree(renamed.replace(newfname, "")) except: pass await del_ongoing_task(user_id) try: await query.message.edit( text=Messages.UPLOADED, reply_markup=Buttons.RATE_ME ) except: await unzip_bot.send_message( chat_id=user_id, text=Messages.UPLOADED, reply_markup=Buttons.RATE_ME ) return dltime = TimeFormatter(round(e_time - s_time) * 1000) if dltime == "": dltime = "1s" await answer_query( query, Messages.AFTER_OK_DL_TXT.format(dltime), unzip_client=unzip_bot ) # Attempt to fetch password protected archives if splitted_data[2] == "with_pass": password = await unzip_bot.ask( chat_id=query.message.chat.id, text=Messages.PLS_SEND_PASSWORD ) ext_s_time = time() extractor = await extr_files( path=ext_files_dir, archive_path=archive, password=password.text, ) ext_e_time = time() await archive_msg.reply(Messages.PASS_TXT.format(password.text)) else: ext_s_time = time() tested = await _test_with_7z_helper(archive) ext_t_time = time() testtime = TimeFormatter(round(ext_t_time - ext_s_time) * 1000) if testtime == "": testtime = "1s" await answer_query( query, Messages.AFTER_OK_TEST_TXT.format(testtime), unzip_client=unzip_bot ) if tested: extractor = await extr_files( path=ext_files_dir, archive_path=archive ) ext_e_time = time() else: extractor = "Error" ext_e_time = time() # Checks if there is an error happened while extracting the archive if any(err in extractor for err in ERROR_MSGS): try: await query.message.edit(Messages.EXT_FAILED_TXT) shutil.rmtree(ext_files_dir) await del_ongoing_task(user_id) await log_msg.reply(Messages.EXT_FAILED_TXT) return except: try: await query.message.delete() except: pass await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.EXT_FAILED_TXT ) shutil.rmtree(ext_files_dir) await del_ongoing_task(user_id) await archive_msg.reply(Messages.EXT_FAILED_TXT) return # Check if user was dumb 😐 paths = await get_files(path=ext_files_dir) if not paths: await archive_msg.reply(Messages.PASSWORD_PROTECTED) await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.PASSWORD_PROTECTED, ) await answer_query( query, Messages.EXT_FAILED_TXT, unzip_client=unzip_bot ) shutil.rmtree(ext_files_dir) await del_ongoing_task(user_id) return # Upload extracted files extrtime = TimeFormatter(round(ext_e_time - ext_s_time) * 1000) if extrtime == "": extrtime = "1s" await answer_query( query, Messages.EXT_OK_TXT.format(extrtime), unzip_client=unzip_bot ) try: i_e_buttons = await make_keyboard( paths=paths, user_id=user_id, chat_id=query.message.chat.id, unziphttp=False ) try: await query.message.edit(Messages.SELECT_FILES, reply_markup=i_e_buttons) except ReplyMarkupTooLong: empty_buttons = await make_keyboard_empty( user_id=user_id, chat_id=query.message.chat.id, unziphttp=False ) await query.message.edit( Messages.UNABLE_GATHER_FILES, reply_markup=empty_buttons, ) except: try: await query.message.delete() i_e_buttons = await make_keyboard( paths=paths, user_id=user_id, chat_id=query.message.chat.id, unziphttp=False ) await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.SELECT_FILES, reply_markup=i_e_buttons, ) except: try: await query.message.delete() empty_buttons = await make_keyboard_empty( user_id=user_id, chat_id=query.message.chat.id, unziphttp=False ) await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.UNABLE_GATHER_FILES, reply_markup=empty_buttons, ) except: await answer_query( query, Messages.EXT_FAILED_TXT, unzip_client=unzip_bot ) await archive_msg.reply(Messages.EXT_FAILED_TXT) shutil.rmtree(ext_files_dir) LOGGER.error(Messages.FATAL_ERROR) await del_ongoing_task(user_id) return except Exception as e: await del_ongoing_task(user_id) try: try: await query.message.edit(Messages.ERROR_TXT.format(e)) except: await unzip_bot.send_message( chat_id=query.message.chat.id, text=Messages.ERROR_TXT.format(e)) await archive_msg.reply(Messages.ERROR_TXT.format(e)) shutil.rmtree(ext_files_dir) try: await ClientSession().close() except: pass LOGGER.error(e) except Exception as err: LOGGER.error(err) await archive_msg.reply(err) elif query.data.startswith("ext_f"): LOGGER.info(query.data) user_id = query.from_user.id spl_data = query.data.split("|") file_path = f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}/extracted" try: urled = spl_data[4] if isinstance(spl_data[4], bool) else False except: urled = False if urled: paths = spl_data[5].namelist() else: paths = await get_files(path=file_path) if not paths and not urled: if os.path.isdir(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}"): shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}") await del_ongoing_task(user_id) await query.message.edit( text=Messages.NO_FILE_LEFT, reply_markup=Buttons.RATE_ME ) return LOGGER.info("ext_f paths : " + str(paths)) try: await query.answer(Messages.SENDING_FILE) except: pass sent_files += 1 if urled: file = spl_data[5].open(paths[int(spl_data[3])]) else: file = paths[int(spl_data[3])] fsize = await get_size(file) split = False if fsize <= Config.TG_MAX_SIZE: await send_file( unzip_bot=unzip_bot, c_id=spl_data[2], doc_f=file, query=query, full_path=f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}", log_msg=log_msg, split=False, ) else: split = True if split: fname = file.split('/')[-1] smessage = await unzip_bot.send_message( chat_id=user_id, text=Messages.SPLITTING.format(fname) ) splitteddir = f"{Config.DOWNLOAD_LOCATION}/splitted/{user_id}" os.makedirs(splitteddir) ooutput = f"{splitteddir}/{fname}" splittedfiles = await split_files(file, ooutput, Config.TG_MAX_SIZE) LOGGER.info(splittedfiles) if not splittedfiles: try: shutil.rmtree(splitteddir) except: pass await del_ongoing_task(user_id) await smessage.edit(Messages.ERR_SPLIT) return await smessage.edit(Messages.SEND_ALL_PARTS.format(fname)) async_splittedfiles = async_generator(splittedfiles) async for file in async_splittedfiles: sent_files += 1 await send_file( unzip_bot=unzip_bot, c_id=user_id, doc_f=file, query=query, full_path=splitteddir, log_msg=log_msg, split=True, ) try: shutil.rmtree(splitteddir) os.remove(file) except: pass try: await smessage.delete() except: pass await query.message.edit(Messages.REFRESHING) if urled: rpaths = paths.remove(paths[int(spl_data[3])]) else: rpaths = await get_files(path=file_path) if not rpaths: try: shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}") except: pass await del_ongoing_task(user_id) await query.message.edit( text=Messages.NO_FILE_LEFT, reply_markup=Buttons.RATE_ME ) return if urled: try: i_e_buttons = await make_keyboard( paths=rpaths, user_id=query.from_user.id, chat_id=query.message.chat.id, unziphttp=True, rzfile=spl_data[5], ) await query.message.edit(Messages.SELECT_FILES, reply_markup=i_e_buttons) except ReplyMarkupTooLong: empty_buttons = await make_keyboard_empty( user_id=user_id, chat_id=query.message.chat.id, unziphttp=True, rzfile=spl_data[5] ) await query.message.edit( Messages.UNABLE_GATHER_FILES, reply_markup=empty_buttons, ) else: try: i_e_buttons = await make_keyboard( paths=rpaths, user_id=query.from_user.id, chat_id=query.message.chat.id, unziphttp=False ) await query.message.edit(Messages.SELECT_FILES, reply_markup=i_e_buttons) except ReplyMarkupTooLong: empty_buttons = await make_keyboard_empty( user_id=user_id, chat_id=query.message.chat.id, unziphttp=False ) await query.message.edit( Messages.UNABLE_GATHER_FILES, reply_markup=empty_buttons, ) await update_uploaded(user_id, upload_count=sent_files) elif query.data.startswith("ext_a"): LOGGER.info(query.data) user_id = query.from_user.id spl_data = query.data.split("|") file_path = f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}/extracted" try: urled = spl_data[4] if isinstance(spl_data[3], bool) else False except: urled = False if urled: paths = spl_data[4].namelist() else: paths = await get_files(path=file_path) LOGGER.info("ext_a paths : " + str(paths)) if not paths and not urled: try: shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}") except: pass await del_ongoing_task(user_id) await query.message.edit( text=Messages.NO_FILE_LEFT, reply_markup=Buttons.RATE_ME ) return await query.message.edit(Messages.SEND_ALL_FILES) async_paths = async_generator(paths) async for file in async_paths: sent_files += 1 if urled: file = spl_data[4].open(file) fsize = Config.TG_MAX_SIZE + 1 # secutity as we can't retrieve the file size from URL else: fsize = await get_size(file) split = False if fsize <= Config.TG_MAX_SIZE: await send_file( unzip_bot=unzip_bot, c_id=spl_data[2], doc_f=file, query=query, full_path=f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}", log_msg=log_msg, split=False, ) else: split = True if split: fname = file.split('/')[-1] smessage = await unzip_bot.send_message( chat_id=user_id, text=Messages.SPLITTING.format(fname) ) splitteddir = f"{Config.DOWNLOAD_LOCATION}/splitted/{user_id}" os.makedirs(splitteddir) ooutput = f"{splitteddir}/{fname}" splittedfiles = await split_files(file, ooutput, Config.TG_MAX_SIZE) LOGGER.info(splittedfiles) if not splittedfiles: try: shutil.rmtree(splitteddir) except: pass await del_ongoing_task(user_id) await smessage.edit(Messages.ERR_SPLIT) return await smessage.edit(Messages.SEND_ALL_PARTS.format(fname)) async_splittedfiles = async_generator(splittedfiles) async for file in async_splittedfiles: sent_files += 1 await send_file( unzip_bot=unzip_bot, c_id=user_id, doc_f=file, query=query, full_path=splitteddir, log_msg=log_msg, split=True, ) try: shutil.rmtree(splitteddir) except: pass try: await smessage.delete() except: pass await query.message.edit( text=Messages.UPLOADED, reply_markup=Buttons.RATE_ME ) await log_msg.reply(Messages.HOW_MANY_UPLOADED.format(sent_files)) await update_uploaded(user_id, upload_count=sent_files) await del_ongoing_task(user_id) try: shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{spl_data[1]}") except Exception as e: await query.message.edit(Messages.ERROR_TXT.format(e)) await archive_msg.reply(Messages.ERROR_TXT.format(e)) elif query.data == "cancel_dis": uid = query.from_user.id await del_ongoing_task(uid) await del_merge_task(uid) try: await query.message.edit(Messages.CANCELLED_TXT.format(Messages.PROCESS_CANCELLED)) shutil.rmtree(f"{Config.DOWNLOAD_LOCATION}/{uid}") await update_uploaded( user_id=uid, upload_count=sent_files ) try: await log_msg.reply(Messages.HOW_MANY_UPLOADED.format(sent_files)) except: return except: await unzip_bot.send_message( chat_id=uid, text=Messages.CANCELLED_TXT.format(Messages.PROCESS_CANCELLED) ) return elif query.data == "nobully": await query.message.edit(Messages.CANCELLED)