async def send_file_to_dustbin(file_message: Message, media_type: str, url: str, f_type: str): global file_link fd_msg = await file_message.copy(chat_id=Common().bot_dustbin) file_link = f"https://{Common().web_fqdn}/stream/{fd_msg.message_id}" if Common().on_heroku else \ f"http://{Common().web_fqdn}:{Common().web_port}/stream/{fd_msg.message_id}" await file_message.edit_reply_markup( reply_markup=InlineKeyboardMarkup([[ InlineKeyboardButton(text=f"{emoji.ROCKET} Streaming Link", url=file_link) ]])) if f_type != "bytesIO" and url != "": if media_type == "video": await MegaFiles().insert_new_files( file_name=fd_msg.video.file_name, msg_id=fd_msg.message_id, chat_id=fd_msg.chat.id, file_type=fd_msg.video.mime_type, url=url) elif media_type == "audio": await MegaFiles().insert_new_files( file_name=fd_msg.audio.file_name, msg_id=fd_msg.message_id, chat_id=fd_msg.chat.id, file_type=fd_msg.audio.mime_type, url=url) else: await MegaFiles().insert_new_files( file_name=fd_msg.document.file_name, msg_id=fd_msg.message_id, chat_id=fd_msg.chat.id, file_type=fd_msg.document.mime_type, url=url)
async def send_file_to_dustbin(file_message: Message, media_type: str, url: str): if media_type == "video": fd_msg = await file_message.forward( chat_id=Common().bot_dustbin, as_copy=True ) await MegaFiles().insert_new_files( filed_id=fd_msg.video.file_id, file_name=fd_msg.video.file_name, msg_id=fd_msg.message_id, chat_id=fd_msg.chat.id, file_type=fd_msg.video.mime_type, url=url ) else: fd_msg = await file_message.forward( chat_id=Common().bot_dustbin, as_copy=True ) await MegaFiles().insert_new_files( filed_id=fd_msg.document.file_id, file_name=fd_msg.document.file_name, msg_id=fd_msg.message_id, chat_id=fd_msg.chat.id, file_type=fd_msg.document.mime_type, url=url )
async def new_message_dl_handler(c: Client, m: Message): await MegaUsers().insert_user(m.from_user.id) me = await c.get_me() regex = re.compile( r'^(?:http|ftp)s?://' # http:// or https:// r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain... r'localhost|' # localhost... r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip r'(?::\d+)?' # optional port r'(?:/?|[/?]\S+)$', re.IGNORECASE) if re.match(regex, m.text) or m.text.startswith("magnet"): url_count = await MegaFiles().count_files_by_url(m.text) if url_count == 0 and not m.text.startswith("magnet"): if Common().seedr_username is not None: await url_process(m) else: await m.reply_text( "Well! I do not know how to download torrents unless you connect me to Seedr" ) elif url_count == 0 and m.text.startswith("magnet"): if Common().seedr_username is not None: await call_seedr_download(m, "magnet") else: await m.reply_text( "Well! I do not know how to download torrents unless you connect me to Seedr" ) elif m.text.startswith("magnet"): url_details = await MegaFiles().get_file_by_url(m.text) files = [ f"<a href='http://t.me/{me.username}?start=plf-{file['file_id']}'>{file['file_name']}" \ f" - {file['file_type']}</a>" for file in url_details ] files_msg_formatted = '\n'.join(files) await m.reply_text( f"I also do have the following files that were uploaded earlier with the same url:\n" f"{files_msg_formatted}", disable_web_page_preview=True) await url_process(m) else: url_details = await MegaFiles().get_file_by_url(m.text) files = [ f"<a href='http://t.me/{me.username}" \ f"?start=plf-{file['file_id']}'>{file['file_name']} - {file['file_type']}</a>" for file in url_details ] files_msg_formatted = '\n'.join(files) await m.reply_text( f"I also do have the following files that were uploaded earlier with the same url:\n" f"{files_msg_formatted}", disable_web_page_preview=True) await url_process(m)
async def main(): await MegaDLBot.start() runner = web.AppRunner(await web_server()) await runner.setup() bind_address = "0.0.0.0" if Common().is_env else Common().web_fqdn await web.TCPSite(runner, bind_address, Common().web_port).start() logging.info(f"Web Server Started at: {bind_address}:{Common().web_port}") await idle()
async def main(): await MegaDLBot.start() runner = web.AppRunner(await web_server()) await runner.setup() await web.TCPSite(runner, Common().web_bind_address, Common().web_port).start() logging.info( f"Web Server Started at: {Common().web_bind_address}:{Common().web_port} - FQDN: " f"{Common().web_fqdn}") await idle()
def __init__(self): DB_USERNAME = Common().db_username DB_PASSWORD = Common().db_password if DB_USERNAME and DB_PASSWORD: connection_string = f"mongodb://{Common().db_username}:{quote(Common().db_password)}@{Common().db_host}" self.db_client = pymongo.MongoClient(connection_string) else: self.db_client = pymongo.MongoClient(Common().db_host, username=DB_USERNAME, password=DB_PASSWORD) self.db = self.db_client[Common().db_name]
async def extract(msg: Message, extraction_type: str): ack_message = await msg.reply_text( "Trying to download the file to local!" ) temp_dir = os.path.join(Common().working_dir, f"{msg.chat.id}+{msg.message_id}") if not os.path.exists(temp_dir): os.mkdir(temp_dir) ytdl_options = {} if extraction_type == "audio": ytdl_options = { 'format': 'bestaudio/best', 'noplaylist': 'true', 'outtmpl': f'{temp_dir}/%(title)s.%(ext)s', 'progress_hooks': [YTdl().progress_hooks], 'ignoreerrors': 'true', 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192', }], } elif extraction_type == "video": ytdl_options = { 'format': 'bestvideo[height<=480][ext=mp4]+bestaudio[height<=480][ext=m4a]/best', 'noplaylist': 'true', 'outtmpl': f'{temp_dir}/%(title)s.%(ext)s', 'progress_hooks': [YTdl().progress_hooks], 'ignoreerrors': 'true', } yt_progress_updates[f"{msg.chat.id}{msg.message_id}"] = { "current": 0, "total": 0, "file_name": "", "last_update": time.time() } loop = asyncio.get_event_loop() yt_process = loop.run_in_executor(None, YTdl().ytdl_download, ytdl_options, msg.text) yt_progress = await yt_process while True: if yt_progress is True: temp_file = yt_progress_updates[f"{msg.chat.id}{msg.message_id}"]["file_name"] if extraction_type == "audio": file_name = os.path.basename(temp_file) pre, _ = os.path.splitext(file_name) temp_file = os.path.join(temp_dir, f"{pre}.mp3") await UploadFiles().upload_file(temp_file, ack_message, msg.text, "other") break else: await asyncio.sleep(1) if (time.time() - yt_progress_updates[f"{msg.chat.id}{msg.message_id}"]["last_update"]) > 5: await ack_message.edit_text( f"Downloading: {yt_progress_updates[f'{msg.chat.id}{msg.message_id}']['current']} of " f"{yt_progress_updates[f'{msg.chat.id}{msg.message_id}']['total']}" ) yt_progress_updates[f"{msg.chat.id}{msg.message_id}"]["last_update"] = time.time()
def __init__(self): self.db_client = pymongo.MongoClient( f"mongodb://" f"{Common().db_username}:{Common().db_password}@{Common().db_host}" ) self.db = self.db_client[Common().db_name]
async def get_media_info(file: str): neko_endpoint = "https://nekobin.com/api/documents" process_cmd = [ "ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", file ] process = await asyncio.create_subprocess_exec( *process_cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) data, err = await process.communicate() m_info = json.loads(data.decode("utf-8").rstrip()) if m_info is None: return False else: temp_file = os.path.join(Common().working_dir, f"{secrets.token_hex(2)}.txt") async with aiofiles.open(temp_file, mode="w") as m_file: await m_file.write(str(json.dumps(m_info, indent=2))) neko_link = "" async with aiohttp.ClientSession() as nekoSession: payload = {"content": str(json.dumps(m_info, indent=2))} async with nekoSession.post(neko_endpoint, data=payload) as resp: neko_link = f"https://nekobin.com/{(await resp.json())['result']['key']}.py" return temp_file, neko_link
async def get_media_info(file: str): process_cmd = [ "ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", file ] process = await asyncio.create_subprocess_exec( *process_cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) data, err = await process.communicate() m_info = json.loads(data.decode("utf-8").rstrip()) if m_info is None: return False else: temp_file = os.path.join(Common().working_dir, f"{secrets.token_hex(2)}.txt") async with aiofiles.open(temp_file, mode="w") as m_file: await m_file.write(str(json.dumps(m_info, indent=2))) neko_link = await Nekobin().nekofy( str(json.dumps(m_info, indent=2))) return temp_file, neko_link
def __init__(self): """ Interacts with Seedr user their API for torrent-ing. functions: add_url: Add a torrent file using a magnet/link. Returns with the json response from the endpoint. get_torrent_details: returns with a json response that contains the details of a torrent that was added using add_url method. get_folder: returns with a json response that contains the list of folder contents and its details. delete_folder: removes a specific folder from seedr using its folder_id download_folder: download the folder and its content as a compressed file from seedr and finally start the uploading process to telegram or otherwise extracting process. uncompress_upload: extract and start uploading process to telegram for the contents of the compressed file that was downloaded using download_folder. """ self.web_dav = "https://www.seedr.cc/rest" self.username = Common().seedr_username self.password = Common().seedr_password
async def root_route_handler(request): bot_details = await MegaDLBot.get_me() return web.json_response({ "status": "running", "server_permission": "Limited" if len(Common().allowed_users) > 0 else "Open", "bot_associated_w": bot_details.username })
async def download_folder(self, folder_id: str, ack_message: Message, org_message: Message, upload_type: str): endpoint = f"{self.web_dav}/folder/{folder_id}/download" user_details = await MegaUsers().get_user(org_message.chat.id) temp_dir = os.path.join(Common().working_dir, secrets.token_hex(2)) if not os.path.exists(temp_dir): os.mkdir(temp_dir) folder_details = await self.get_folder(folder_id, org_message.chat.id) dl_folder_name = f"{folder_details['name']}.zip" dl_compressed_file = os.path.join(temp_dir, dl_folder_name) await ack_message.edit_reply_markup(None) seedr_status_progress[ f"{ack_message.chat.id}{ack_message.message_id}"] = { "last_updated": time.time() } async with aiohttp.ClientSession() as seedr_session: async with seedr_session.get( url=endpoint, auth=aiohttp.BasicAuth( user_details["seedr_username"], user_details["seedr_passwd"])) as resp: async with aiofiles.open(dl_compressed_file, mode="wb") as fd: downloaded = 0 async for chunk in resp.content.iter_any(): downloaded += len(chunk) await fd.write(chunk) if (time.time() - seedr_status_progress[ f"{ack_message.chat.id}{ack_message.message_id}"] ["last_updated"]) > 5: try: await ack_message.edit_text( f"Downloading file to local: {size.format_size(downloaded, binary=True)}" ) seedr_status_progress[ f"{ack_message.chat.id}{ack_message.message_id}"][ "last_updated"] = time.time() except MessageNotModified as e: logging.error(e) if upload_type != "compressed": await UploadFiles().upload_file(dl_compressed_file, ack_message, org_message.text, "other", "disk", "") else: await self.uncompress_upload(dl_compressed_file, ack_message, org_message)
async def media_receive_handler(c: Client, m: Message): user_settings = await MegaUsers().get_user(m.from_user.id) if "f_rename_type" not in user_settings: await MegaUsers().update_file_rename_settings(m.from_user.id, "disk") fd_msg = await m.copy(chat_id=Common().bot_dustbin) file_link = f"https://{Common().web_fqdn}/{fd_msg.message_id}" if Common().on_heroku else \ f"http://{Common().web_fqdn}:{Common().web_port}/{fd_msg.message_id}" await m.reply_text( text="What would you like to do with this file?", reply_markup=InlineKeyboardMarkup( [[ InlineKeyboardButton(text=f"{emoji.ROCKET} Streaming Link", url=file_link) ], [ InlineKeyboardButton( text=f"{emoji.PEN} Rename File", callback_data=f"prflrn_{m.chat.id}_{m.message_id}") ]]))
def __init__(self): if Common().is_atlas: self.db_client = pymongo.MongoClient(Common().db_host, ) else: self.db_client = pymongo.MongoClient(Common().db_host, username=Common().db_username, password=Common().db_password) self.db = self.db_client[Common().db_name]
async def cap_screens(msg: Message): link = msg.text duration_process_cmd = [ "ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries", "stream=duration", "-of", "default=noprint_wrappers=1:nokey=1", link ] process = await asyncio.create_subprocess_exec( *duration_process_cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) duration, _ = await process.communicate() duration_int = int(float(duration.decode("utf-8").rstrip())) tmp_dir = os.path.join(pathlib.Path().absolute(), Common().working_dir, secrets.token_hex(2)) if not os.path.exists(tmp_dir): os.mkdir(tmp_dir) for x in range(4): shot_duration = int(duration_int * ((x + 1) / 5)) tmp_file = os.path.join(tmp_dir, f"{secrets.token_hex(2)}.jpg") screen_cap_process_cmd = [ "ffmpeg", "-ss", f"{shot_duration}", "-i", link, "-vframes", "1", "-q:v", "2", tmp_file ] screen_process = await asyncio.create_subprocess_exec( *screen_cap_process_cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) _, __ = await screen_process.communicate() if os.path.isfile(tmp_file): await msg.reply_photo( photo=tmp_file, caption=f"Screen capture at {shot_duration} second.") try: shutil.rmtree(tmp_dir) except Exception as e: logging.error(e)
async def media_streamer(request, message_id: int): range_header = request.headers.get('Range', 0) media_msg = await MegaDLBot.get_messages(Common().bot_dustbin, message_id) file_properties = await TGCustomYield().generate_file_properties(media_msg) file_size = file_properties.file_size if range_header: from_bytes, until_bytes = range_header.replace('bytes=', '').split('-') from_bytes = int(from_bytes) until_bytes = int(until_bytes) if until_bytes else file_size else: from_bytes = request.http_range.start or 0 until_bytes = request.http_range.stop or file_size req_length = until_bytes - from_bytes new_chunk_size = await chunk_size(req_length) offset = await offset_fix(from_bytes, new_chunk_size) first_part_cut = from_bytes - offset last_part_cut = (until_bytes % new_chunk_size) + 1 part_count = math.ceil(req_length / new_chunk_size) body = TGCustomYield().yield_file(media_msg, offset, first_part_cut, last_part_cut, part_count, new_chunk_size) file_name = file_properties.file_name if file_properties.file_name \ else f"{secrets.token_hex(2)}.jpeg" mime_type = file_properties.mime_type if file_properties.mime_type \ else f"{mimetypes.guess_type(file_name)}" return_resp = web.Response( status=206 if range_header else 200, body=body, headers={ "Content-Type": mime_type, "Content-Range": f"bytes {from_bytes}-{until_bytes}/{file_size}", "Content-Disposition": f'attachment; filename="{file_name}"', "Accept-Ranges": "bytes", }) if return_resp.status == 200: return_resp.headers.add("Content-Length", str(req_length)) return return_resp
async def extract_audio(msg: Message): # here what we basically do is, create a temp directory for the files to be downloaded, temp_dir = os.path.join(Common().working_dir, f"{secrets.token_hex(2)}") if not os.path.exists(temp_dir): os.mkdir(temp_dir) ack_message = await msg.reply_text( "Trying to download the file to local!" ) temp_file = os.path.join(temp_dir, f"{secrets.token_hex(2)}.mp3") ytdl_options = { 'format': 'bestaudio/best', 'noplaylist': 'true', 'outtmpl': temp_file, 'ignoreerrors': 'true', 'writethumbnail': True, } with youtube_dl.YoutubeDL(ytdl_options) as ydl: ydl.download([msg.text]) await UploadFiles().upload_file(temp_file, ack_message, msg.text)
async def extract(msg: Message, extraction_type: str): user_details = await MegaUsers().get_user(msg.chat.id) cookie_file_location = "" if "yt_cookie" in user_details: cookie_file_location = f"mega/{user_details['yt_cookie_location']}" if os.path.isfile(cookie_file_location) is not True: async with aiofiles.open(cookie_file_location, mode='wb') as key_file_aio: await key_file_aio.write( base64.decodebytes(user_details["yt_cookie"])) ack_message = await msg.reply_text( "Trying to download the file to local!") temp_dir = os.path.join(Common().working_dir, f"{msg.chat.id}+{msg.message_id}") if not os.path.exists(temp_dir): os.mkdir(temp_dir) ytdl_options = {} if extraction_type == "audio": ytdl_options = { 'format': 'bestaudio/best', 'noplaylist': 'true', 'outtmpl': f'{temp_dir}/%(title)s.%(ext)s', 'progress_hooks': [YTdl().progress_hooks], 'ignoreerrors': 'true', 'source_address': '0.0.0.0', 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '320' }], } if "yt_cookie" in user_details: ytdl_options = { 'format': 'bestaudio/best', 'noplaylist': 'true', 'outtmpl': f'{temp_dir}/%(title)s.%(ext)s', 'progress_hooks': [YTdl().progress_hooks], 'ignoreerrors': 'true', 'source_address': '0.0.0.0', 'cookiefile': cookie_file_location, 'postprocessors': [{ 'key': 'FFmpegExtractAudio', 'preferredcodec': 'mp3', 'preferredquality': '192', }], } elif extraction_type == "video": ytdl_options = { 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best', 'noplaylist': 'true', 'outtmpl': f'{temp_dir}/%(title)s.%(ext)s', 'progress_hooks': [YTdl().progress_hooks], 'ignoreerrors': 'true', 'source_address': '0.0.0.0' } if "yt_cookie" in user_details: ytdl_options = { 'format': 'bestvideo[height<=480][ext=mp4]+bestaudio[height<=480][ext=m4a]/best', 'noplaylist': 'true', 'outtmpl': f'{temp_dir}/%(title)s.%(ext)s', 'progress_hooks': [YTdl().progress_hooks], 'ignoreerrors': 'true', 'source_address': '0.0.0.0', 'cookiefile': cookie_file_location } yt_progress_updates[f"{msg.chat.id}{msg.message_id}"] = { "current": 0, "total": 0, "file_name": "", "last_update": time.time() } loop = asyncio.get_event_loop() yt_process = loop.run_in_executor(None, YTdl().ytdl_download, ytdl_options, msg.text) yt_progress = await yt_process while True: if yt_progress is True: temp_file = yt_progress_updates[ f"{msg.chat.id}{msg.message_id}"]["file_name"] if extraction_type == "audio": file_name = os.path.basename(temp_file) pre, _ = os.path.splitext(file_name) temp_file = os.path.join(temp_dir, f"{pre}.mp3") await UploadFiles().upload_file(temp_file, ack_message, msg.text, "other", "disk", "") break else: await asyncio.sleep(1) if (time.time() - yt_progress_updates[f"{msg.chat.id}{msg.message_id}"] ["last_update"]) > 5: await ack_message.edit_text( f"Downloading: {yt_progress_updates[f'{msg.chat.id}{msg.message_id}']['current']} of " f"{yt_progress_updates[f'{msg.chat.id}{msg.message_id}']['total']}" ) yt_progress_updates[f"{msg.chat.id}{msg.message_id}"][ "last_update"] = time.time()
async def url_process(m: Message): if m.text.startswith("magnet"): await m.reply_text( text="What would you like to do with this file?", reply_markup=InlineKeyboardMarkup( [ [InlineKeyboardButton(text=f"{emoji.MAGNET} Proceed with Download", callback_data=f"magnet_{m.chat.id}_{m.message_id}")] ] ) ) else: header_info = await Downloader.get_headers(m.text) file_type_raw = header_info.get("Content-Type") if "Content-Type" in header_info else "None/None" file_type_split = file_type_raw.split("/")[0] file_content_disposition = header_info.get("content-disposition") try: file_name_f_headers = re.findall("filename=(.+)", file_content_disposition)[0] if file_content_disposition else None except Exception as e: logging.error(e) file_name_f_headers = None file_ext_f_name = os.path.splitext(str(file_name_f_headers).replace('"', ""))[1] if header_info is None: await m.reply_text( f"I do not know the details of the file to download the file! {emoji.MAN_RAISING_HAND_DARK_SKIN_TONE}" ) elif (tldextract.extract(m.text)).domain != "youtube": file_size = header_info.get("Content-Length") if "Content-Length" in header_info else None if file_size is not None and int(file_size) > 2147483648: await m.reply_text( f"Well that file is bigger than I can upload to telegram! {emoji.MAN_SHRUGGING_DARK_SKIN_TONE}" ) else: inline_buttons = [ [ InlineKeyboardButton(text=f"{emoji.FLOPPY_DISK} Download", callback_data=f"download_{m.chat.id}_{m.message_id}"), InlineKeyboardButton(text=f"{emoji.PENCIL} Rename", callback_data=f"rename_{m.chat.id}_{m.message_id}") ] ] if file_type_split.lower() == "video": inline_buttons.append([ InlineKeyboardButton(text=f"{emoji.LIGHT_BULB} Media Info", callback_data=f"info_{m.chat.id}_{m.message_id}"), InlineKeyboardButton(text=f"{emoji.FRAMED_PICTURE} Screens", callback_data=f"screens_{m.chat.id}_{m.message_id}") ]) elif file_ext_f_name == ".torrent" and Common().seedr_username is not None: inline_buttons.append([ InlineKeyboardButton(text=f"{emoji.TORNADO} Download Torrent", callback_data=f"torrent_{m.chat.id}_{m.message_id}") ]) await m.reply_text( text="What would you like to do with this file?", reply_markup=InlineKeyboardMarkup(inline_buttons) ) elif (tldextract.extract(m.text)).domain == "youtube": inline_buttons = [ [ InlineKeyboardButton(text=f"{emoji.LOUDSPEAKER} Extract Audio", callback_data=f"ytaudio_{m.chat.id}_{m.message_id}"), InlineKeyboardButton(text=f"{emoji.VIDEOCASSETTE} Extract Video", callback_data=f"ytvid_{m.chat.id}_{m.message_id}") ], [ InlineKeyboardButton(text=f"{emoji.LIGHT_BULB} Media Info", callback_data=f"ytmd_{m.chat.id}_{m.message_id}") ] ] await m.reply_text( text="What would you like to do with this file?", reply_markup=InlineKeyboardMarkup(inline_buttons) )
def __init__(self): self.db_client = pymongo.MongoClient(f"{Common().db_url}") self.db = self.db_client[Common().db_name]
"""MegaDLBot Pyrogram Client.""" from pyrogram import Client from mega.common import Common if Common().is_env: MegaDLBot = Client(api_id=Common().tg_app_id, api_hash=Common().tg_api_key, session_name=Common().bot_session, bot_token=Common().bot_api_key, workers=200, workdir=Common().working_dir, plugins=dict(root="mega/telegram/plugins")) else: MegaDLBot = Client(session_name=Common().bot_session, bot_token=Common().bot_api_key, workers=200, workdir=Common().working_dir, config_file=Common().app_config_file)
def __init__(self): self.web_dav = "https://www.seedr.cc/rest" self.username = Common().seedr_username self.password = Common().seedr_password
from pyrogram import Client from mega.common import Common MegaDLBot = Client(session_name=Common().bot_session, bot_token=Common().bot_api_key, workers=200, workdir=Common().working_dir, config_file=Common().app_config_file)
async def call_seedr_download(msg: Message, torrent_type: str): if torrent_type == "magnet": ack_msg = await msg.reply_text("About to add the magnet link to seedr." ) tr_process = await SeedrAPI().add_url(msg.text, "magnet", msg.chat.id) else: ack_msg = await msg.reply_text("About to add the link to seedr.") tr_process = await SeedrAPI().add_url(msg.text, "other", msg.chat.id) if tr_process["result"] is True: try: while True: await asyncio.sleep(4) tr_progress = await SeedrAPI().get_torrent_details( tr_process["user_torrent_id"], msg.chat.id) if tr_progress["progress"] < 100: try: await ack_msg.edit_text( f"Uploading to Seedr: \n" f"Progress: {tr_progress['progress']}% | " f"Size: {size.format_size(tr_progress['size'], binary=True)}" ) except MessageNotModified as e: logging.error(e) else: await asyncio.sleep(10) tr_progress = await SeedrAPI().get_torrent_details( tr_process["user_torrent_id"], msg.chat.id) file_link = f"https://{Common().web_fqdn}/seedr/{msg.chat.id}/{str(tr_progress['folder_created'])}" if Common().on_heroku else \ f"http://{Common().web_fqdn}:{Common().web_port}/seedr/{msg.chat.id}/{str(tr_progress['folder_created'])}" await ack_msg.edit_text( f"How would you like to upload the contents?\n" f"Here is the Direct Link for the File: \n" f"{file_link}") await ack_msg.edit_reply_markup( InlineKeyboardMarkup([ [ InlineKeyboardButton( text=f"{emoji.PACKAGE} Compressed", callback_data= f"sdlc_{str(tr_progress['folder_created'])}" f"_{msg.chat.id}_{msg.message_id}" f"_{ack_msg.message_id}") ], [ InlineKeyboardButton( text=f"{emoji.CARD_FILE_BOX} UnCompressed", callback_data= f"unsd_{str(tr_progress['folder_created'])}" f"_{msg.chat.id}_{msg.message_id}" f"_{ack_msg.message_id}") ] ])) break except Exception as e: logging.error(e) else: try: error = tr_process['error'] except KeyError: error = None logging.error(error) await ack_msg.edit_text(f"An error occurred:\n<pre>{error}</pre>", parse_mode="html")