Exemple #1
0
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()
Exemple #3
0
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
Exemple #5
0
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()
Exemple #7
0
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