async def ytdl_btn_k(message: Message): i_m_sefg = await message.edit_text("processing") # LOGGER.info(message) # extract link from message dl_url, cf_name, yt_dl_user_name, yt_dl_pass_word = await extract_link( message.reply_to_message, "YTDL" ) LOGGER.info(dl_url) LOGGER.info(cf_name) if dl_url is not None: current_user_id = message.reply_to_message.from_user.id # create an unique directory user_working_dir = os.path.join( DOWNLOAD_LOCATION, str(current_user_id), str(message.reply_to_message.message_id) ) # create download directory, if not exist if not os.path.isdir(user_working_dir): os.makedirs(user_working_dir) await i_m_sefg.edit_text("extracting links") # list the formats, and display in button markup formats thumb_image, text_message, reply_markup = await extract_youtube_dl_formats( dl_url, # cf_name, yt_dl_user_name, yt_dl_pass_word, user_working_dir ) await i_m_sefg.edit_text( text=text_message, reply_markup=reply_markup ) else: await i_m_sefg.delete()
async def upload_document_f(client, message): imsegd = await message.reply_text(Loilacaztion.PROCESSING) if " " in message.text: recvd_command, local_file_name = message.text.split(" ", 1) recvd_response = await upload_to_tg(imsegd, local_file_name, message.from_user.id, {}) LOGGER.info(recvd_response) await imsegd.delete()
async def status_message_f(client, message): aria_i_p = await aria_start() # Show All Downloads downloads = aria_i_p.get_downloads() # DOWNLOAD_ICON = "📥" UPLOAD_ICON = "📤" # msg = "" for download in downloads: downloading_dir_name = "NA" try: downloading_dir_name = str(download.name) except: pass total_length_size = str(download.total_length_string()) progress_percent_string = str(download.progress_string()) down_speed_string = str(download.download_speed_string()) up_speed_string = str(download.upload_speed_string()) download_current_status = str(download.status) e_t_a = str(download.eta_string()) current_gid = str(download.gid) # msg += f"<u>{downloading_dir_name}</u>" msg += " | " msg += f"{total_length_size}" msg += " | " msg += f"{progress_percent_string}" msg += " | " msg += f"{DOWNLOAD_ICON} {down_speed_string}" msg += " | " msg += f"{UPLOAD_ICON} {up_speed_string}" msg += " | " msg += f"{e_t_a}" msg += " | " msg += f"{download_current_status}" msg += " | " msg += f"<code>{Commandi.CANCEL} {current_gid}</code>" msg += " | " msg += "\n\n" LOGGER.info(msg) if msg == "": msg = Loilacaztion.NO_TOR_STATUS currentTime = time_formatter((time.time() - BOT_START_TIME)) total, used, free = shutil.disk_usage(".") total = humanbytes(total) used = humanbytes(used) free = humanbytes(free) ms_g = f"<b>Bot Uptime</b>: <code>{currentTime}</code>\n" \ f"<b>Total disk space</b>: <code>{total}</code>\n" \ f"<b>Used</b>: <code>{used}</code>\n" \ f"<b>Free</b>: <code>{free}</code>\n" msg = ms_g + "\n" + msg await message.reply_text(msg, quote=True)
async def fake_etairporpa_call(aria_instance, incoming_link, c_file_name, sent_message_to_update_tg_p, r_clone_header_xedni): # TODO: duplicate code -_- if incoming_link.lower().startswith("magnet:"): sagtus, err_message = add_magnet(aria_instance, incoming_link, c_file_name) elif os.path.isfile(incoming_link) and incoming_link.lower().endswith( ".torrent"): sagtus, err_message = add_torrent(aria_instance, incoming_link) else: sagtus, err_message = add_url(aria_instance, incoming_link, c_file_name) if not sagtus: return sagtus, err_message LOGGER.info(err_message) # https://stackoverflow.com/a/58213653/4723940 await check_progress_for_dl(aria_instance, err_message, sent_message_to_update_tg_p, None) has_metadata = aria_instance.client.tell_status(err_message, ["followedBy"]) if has_metadata: err_message = has_metadata["followedBy"][0] await check_progress_for_dl(aria_instance, err_message, sent_message_to_update_tg_p, None) await asyncio.sleep(1) file = aria_instance.get_download(err_message) to_upload_file = file.name # -_- r_clone_conf_file = await get_r_clone_config( R_CLONE_CONF_URI, sent_message_to_update_tg_p._client) if r_clone_conf_file is not None: # how? even :\ config = configparser.ConfigParser() config.read(r_clone_conf_file) remote_names = config.sections() try: required_remote = remote_names[r_clone_header_xedni] except IndexError: return False, "maybe a bug, but index seems not valid" remote_file_id = await copy_via_rclone( to_upload_file, required_remote, R_CLONE_DEST, # rclone destination folder r_clone_conf_file) # temporary hard coded id for Google Drive only. :\ # TODO await sent_message_to_update_tg_p.reply_text( "files might be uploaded in the desired remote " "please check Logs for any errors" f"\n\nhttps://drive.google.com/open?id={remote_file_id}") return True, None
async def leech_btn_k(message: Message, cb_data: str): # get link from the incoming message dl_url, cf_name, _, _ = await extract_link( message.reply_to_message, "LEECH" ) LOGGER.info(dl_url) LOGGER.info(cf_name) current_user_id = message.reply_to_message.from_user.id # create an unique directory new_download_location = os.path.join( DOWNLOAD_LOCATION, str(current_user_id), str(message.reply_to_message.message_id) ) # create download directory, if not exist if not os.path.isdir(new_download_location): os.makedirs(new_download_location) if dl_url is not None: await message.edit_text("extracting links") # start the aria2c daemon aria_i_p = await aria_start() LOGGER.info(aria_i_p) if "_" in cb_data: await message.edit_text("trying to download") # try to download the "link" sagtus, err_message = await fake_etairporpa_call( aria_i_p, dl_url, new_download_location, message, int(cb_data.split("_")[2]) # maybe IndexError / ValueError might occur, # we don't know, yet!! ) if not sagtus: # if FAILED, display the error message await message.edit_text(err_message) else: is_zip = False if "a" in cb_data: is_zip = True await message.edit_text("trying to download") # try to download the "link" sagtus, err_message = await call_apropriate_function( aria_i_p, dl_url, new_download_location, message, is_zip ) if not sagtus: # if FAILED, display the error message await message.edit_text(err_message)
async def cancel_message_f(client, message): if len(message.command) > 1: # /cancel command i_m_s_e_g = await message.reply_text(Loilacaztion.PROCESSING, quote=True) aria_i_p = await aria_start() g_id = message.command[1].strip() LOGGER.info(g_id) try: downloads = aria_i_p.get_download(g_id) LOGGER.info(downloads) LOGGER.info(downloads.remove(force=True, files=True)) await i_m_s_e_g.edit_text(Loilacaztion.TOR_CANCELLED) except Exception as e: LOGGER.warn(str(e)) await i_m_s_e_g.edit_text(Loilacaztion.TOR_CANCEL_FAILED) else: await message.delete()
async def aria_start(): aria2_daemon_start_cmd = [] # start the daemon, aria2c command aria2_daemon_start_cmd.append("aria2c") # aria2_daemon_start_cmd.append("--allow-overwrite=true") aria2_daemon_start_cmd.append("--daemon=true") # aria2_daemon_start_cmd.append(f"--dir={DOWNLOAD_LOCATION}") # TODO: this does not work, need to investigate this. # but for now, https://t.me/TrollVoiceBot?start=858 # maybe, :\ but https://t.me/c/1374712761/1142 aria2_daemon_start_cmd.append("--enable-rpc") aria2_daemon_start_cmd.append("--follow-torrent=mem") aria2_daemon_start_cmd.append("--max-connection-per-server=10") aria2_daemon_start_cmd.append("--min-split-size=10M") aria2_daemon_start_cmd.append("--rpc-listen-all=false") aria2_daemon_start_cmd.append(f"--rpc-listen-port={ARIA_TWO_STARTED_PORT}") aria2_daemon_start_cmd.append("--rpc-max-request-size=1024M") aria2_daemon_start_cmd.append("--seed-ratio=0.0") aria2_daemon_start_cmd.append("--seed-time=1") aria2_daemon_start_cmd.append("--split=10") aria2_daemon_start_cmd.append(f"--bt-stop-timeout={MAX_TIME_TO_WAIT_FOR_TORRENTS_TO_START}") # LOGGER.info(aria2_daemon_start_cmd) # process = await asyncio.create_subprocess_exec( *aria2_daemon_start_cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) stdout, stderr = await process.communicate() LOGGER.info(stdout) LOGGER.info(stderr) aria2 = aria2p.API( aria2p.Client( host="http://localhost", port=ARIA_TWO_STARTED_PORT, secret="" ) ) return aria2
async def extract_youtube_dl_formats(url, yt_dl_user_name, yt_dl_pass_word, user_working_dir): command_to_exec = [ "youtube-dl", "--no-warnings", "--youtube-skip-dash-manifest", "-j", url ] if "hotstar" in url: command_to_exec.append("--geo-bypass-country") command_to_exec.append("IN") # if yt_dl_user_name is not None: command_to_exec.append("--username") command_to_exec.append(yt_dl_user_name) if yt_dl_pass_word is not None: command_to_exec.append("--password") command_to_exec.append(yt_dl_pass_word) LOGGER.info(command_to_exec) process = await asyncio.create_subprocess_exec( *command_to_exec, # stdout must a pipe to be accessible as process.stdout stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) # Wait for the subprocess to finish stdout, stderr = await process.communicate() e_response = stderr.decode().strip() # LOGGER.info(e_response) t_response = stdout.decode().strip() # LOGGER.info(t_response) # https://github.com/rg3/youtube-dl/issues/2630#issuecomment-38635239 if e_response: # logger.warn("Status : FAIL", exc.returncode, exc.output) error_message = e_response.replace( "please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see https://yt-dl.org/update on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.", "") return None, error_message, None if t_response: # logger.info(t_response) x_reponse = t_response response_json = [] if "\n" in x_reponse: for yu_r in x_reponse.split("\n"): response_json.append(json.loads(yu_r)) else: response_json.append(json.loads(x_reponse)) # response_json = json.loads(x_reponse) save_ytdl_json_path = user_working_dir + \ "/" + str("ytdleech") + ".json" with open(save_ytdl_json_path, "w", encoding="utf8") as outfile: json.dump(response_json, outfile, ensure_ascii=False) # logger.info(response_json) inline_keyboard = [] # thumb_image = DEF_THUMB_NAIL_VID_S # for current_r_json in response_json: # LOGGER.info(current_r_json) # thumb_image = current_r_json.get("thumbnails", None) # LOGGER.info(thumb_image) if thumb_image is not None: # YouTube acts weirdly, # and not in the same way as Telegram thumb_image = thumb_image[-1]["url"] if thumb_image is None: thumb_image = DEF_THUMB_NAIL_VID_S duration = None if "duration" in current_r_json: duration = current_r_json["duration"] if "formats" in current_r_json: for formats in current_r_json["formats"]: format_id = formats.get("format_id") format_string = formats.get("format_note") if format_string is None: format_string = formats.get("format") # don't display formats, without audio # https://t.me/c/1434259219/269937 if "DASH" in format_string.upper(): continue format_ext = formats.get("ext") approx_file_size = "" if "filesize" in formats: approx_file_size = humanbytes(formats["filesize"]) n_ue_sc = bool("video only" in format_string) scneu = "DL" if not n_ue_sc else "XM" dipslay_str_uon = " " + format_string + " (" + format_ext.upper( ) + ") " + approx_file_size + " " cb_string_video = "{}|{}|{}|{}".format( "video", format_id, format_ext, scneu) ikeyboard = [] if "drive.google.com" in url: if format_id == "source": ikeyboard = [ InlineKeyboardButton( dipslay_str_uon, callback_data=( cb_string_video).encode("UTF-8")) ] else: if format_string is not None and not "audio only" in format_string: ikeyboard = [ InlineKeyboardButton( dipslay_str_uon, callback_data=( cb_string_video).encode("UTF-8")) ] else: # special weird case :\ ikeyboard = [ InlineKeyboardButton( "SVideo [" + "] ( " + approx_file_size + " )", callback_data=( cb_string_video).encode("UTF-8")) ] inline_keyboard.append(ikeyboard) if duration is not None: inline_keyboard.append([ InlineKeyboardButton("MP3 (64 kbps)", callback_data="audio|64k|mp3|_"), InlineKeyboardButton("MP3 (128 kbps)", callback_data="audio|128k|mp3|_") ]) inline_keyboard.append([ InlineKeyboardButton("MP3 (320 kbps)", callback_data="audio|320k|mp3|_") ]) else: format_id = current_r_json["format_id"] format_ext = current_r_json["ext"] cb_string_video = "{}|{}|{}|{}".format("video", format_id, format_ext, "DL") inline_keyboard.append([ InlineKeyboardButton( "SVideo", callback_data=(cb_string_video).encode("UTF-8")) ]) # TODO: :\ break reply_markup = InlineKeyboardMarkup(inline_keyboard) # LOGGER.info(reply_markup) succss_mesg = ( "Select the desired format: 👇\n" "<u>mentioned</u> <i>file size might be approximate</i>") return thumb_image, succss_mesg, reply_markup
async def check_progress_for_dl(aria2, gid, event, previous_message): try: file = aria2.get_download(gid) complete = file.is_complete if not complete: if not file.error_message: msg = "" # sometimes, this weird https://t.me/c/1220993104/392975 # error creeps up # TODO: temporary workaround downloading_dir_name = "N/A" try: # another derp -_- # https://t.me/c/1220993104/423318 downloading_dir_name = str(file.name) except: pass # msg = f"\nDownloading File: <code>{downloading_dir_name}</code>" msg += f"\nSpeed: {file.download_speed_string()} 🔽 / {file.upload_speed_string()} 🔼" msg += f"\nProgress: {file.progress_string()}" msg += f"\nTotal Size: {file.total_length_string()}" msg += f"\n<b>Info:</b>| P: {file.connections} |" if file.seeder is False: """https://t.me/c/1220993104/670177""" msg += f"| S: {file.num_seeders} |" # msg += f"\nStatus: {file.status}" msg += f"\nETA: {file.eta_string()}" msg += f"\n<code>/cancel {gid}</code>" # LOGGER.info(msg) if msg != previous_message: await event.edit(msg) previous_message = msg else: msg = file.error_message await event.edit(f"<code>{msg}</code>") return False await asyncio.sleep(EDIT_SLEEP_TIME_OUT) return await check_progress_for_dl(aria2, gid, event, previous_message) else: await event.edit( f"File Downloaded Successfully: <code>{file.name}</code>") return True except aria2p.client.ClientException: pass except MessageNotModified: pass except FloodWait as e: await asyncio.sleep(e.x) except RecursionError: file.remove(force=True) await event.edit("Download Auto Canceled :\n\n" "Your Torrent/Link {} is Dead.".format(file.name)) return False except Exception as e: LOGGER.info(str(e)) if " not found" in str(e) or "'file'" in str(e): await event.edit("Download Canceled :\n<code>{}</code>".format( file.name)) return False else: LOGGER.info(str(e)) await event.edit( "<u>error</u> :\n<code>{}</code> \n\n#error".format(str(e))) return False
async def call_apropriate_function(aria_instance, incoming_link, c_file_name, sent_message_to_update_tg_p, is_zip, force_doc=False, cfn=None): if incoming_link.lower().startswith("magnet:"): sagtus, err_message = add_magnet(aria_instance, incoming_link, c_file_name) elif os.path.isfile(incoming_link) and incoming_link.lower().endswith( ".torrent"): sagtus, err_message = add_torrent(aria_instance, incoming_link) else: sagtus, err_message = add_url(aria_instance, incoming_link, c_file_name) if not sagtus: return sagtus, err_message LOGGER.info(err_message) # https://stackoverflow.com/a/58213653/4723940 await check_progress_for_dl(aria_instance, err_message, sent_message_to_update_tg_p, None) has_metadata = aria_instance.client.tell_status(err_message, ["followedBy"]) if has_metadata: err_message = has_metadata["followedBy"][0] await check_progress_for_dl(aria_instance, err_message, sent_message_to_update_tg_p, None) await asyncio.sleep(1) file = aria_instance.get_download(err_message) to_upload_file = file.name """os.path.join( c_file_name, file.name )""" # if is_zip: # first check if current free space allows this # ref: https://github.com/out386/aria-telegram-mirror-bot/blob/master/src/download_tools/aria-tools.ts#L194 # archive the contents check_if_file = await create_archive(to_upload_file) if check_if_file is not None: to_upload_file = check_if_file # response = {} LOGGER.info(response) user_id = sent_message_to_update_tg_p.reply_to_message.from_user.id final_response = await upload_to_tg(sent_message_to_update_tg_p, to_upload_file, user_id, response, force_doc=force_doc, cfn=cfn) LOGGER.info(final_response) message_to_send = "" for key_f_res_se in final_response: local_file_name = key_f_res_se message_id = final_response[key_f_res_se] channel_id = str(sent_message_to_update_tg_p.chat.id)[4:] private_link = f"https://t.me/c/{channel_id}/{message_id}" message_to_send += "👉 <a href='" message_to_send += private_link message_to_send += "'>" message_to_send += local_file_name message_to_send += "</a>" message_to_send += "\n" if message_to_send != "": mention_req_user = f"<a href='tg://user?id={user_id}'>Your Requested Files</a>\n\n" message_to_send = mention_req_user + message_to_send message_to_send = message_to_send + "\n\n" + "#uploads" else: message_to_send = "<i>FAILED</i> to upload files. 😞😞" # also clear the aria2 downloads try: file.remove(force=True, files=True) except: LOGGER.exception("faield to rem") await sent_message_to_update_tg_p.reply_to_message.reply_text( text=message_to_send, quote=True, disable_web_page_preview=True) return True, None