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 copy_via_rclone(src: str, remote_name: str, remote_dir: str, conf_file: str):
    if os.path.isdir(src):
        remote_dir = f"{remote_dir}/{src}"
    command_to_exec = [
        "rclone",
        "move",
        src,
        f"{remote_name}:{remote_dir}",
        f"--config={conf_file}",
        "--fast-list",
        "--transfers",
        "18",
        "--checkers",
        "10",
        "--drive-chunk-size",
        "64M",
    ]
    LOGGER(__name__).info(command_to_exec)
    t_response, e_response = await run_command(command_to_exec)
    # Wait for the subprocess to finish
    LOGGER(__name__).info(e_response)
    LOGGER(__name__).info(t_response)
    # https://github.com/rg3/youtube-dl/issues/2630#issuecomment-38635239
    remote_file_link = await r_clone_extract_link_s(
        re.escape(src), remote_name, remote_dir, conf_file
    )
    LOGGER(__name__).info(remote_file_link)
    return remote_file_link
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 #4
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 #6
0
async def incoming_youtube_dl_f(client, message):
    """/ytdl command"""
    i_m_sefg = await message.reply_text("processing", quote=True)
    # LOGGER.info(message)
    if not message.reply_to_message:
        await i_m_sefg.edit_text(
            "No ytdl links to download\n"
            f"Reply <code>/{Command.YTDL}</code> to a ytdl link")
        return
    # 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(__name__).info(f"extracted /ytdl links {dl_url}")
    # LOGGER.info(cf_name)
    if dl_url is not None:
        current_user_id = message.from_user.id
        # create an unique directory
        user_working_dir = os.path.join(
            Config.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)
        LOGGER(__name__).info("fetching youtube_dl formats")
        # 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,
        )
        if thumb_image is not None:
            thumb_image = await fetch_thumbnail(thumb_image, user_working_dir)
            await message.reply_photo(
                photo=thumb_image,
                quote=True,
                caption=text_message,
                reply_to_message_id=message.reply_to_message.message_id,
                reply_markup=reply_markup,
            )
            os.remove(thumb_image)
            await i_m_sefg.delete()
        else:
            await i_m_sefg.edit_text(text=text_message,
                                     reply_markup=reply_markup)
async def r_clone_extract_link_s(
    src_file_name: str, remote_name: str, remote_dir: str, conf_file: str
):
    # TODO: Need to fix file linking for individual files
    command_to_exec = [
        "rclone",
        "link",
        f"{remote_name}:{remote_dir}",
        f"--config={conf_file}",
    ]
    LOGGER(__name__).info(command_to_exec)
    t_response, e_response = await run_command(command_to_exec)
    # Wait for the subprocess to finish
    LOGGER(__name__).info(e_response)
    LOGGER(__name__).info(t_response)
    return t_response
async def cancel_message_f(_, message):
    if len(message.command) > 1:
        # /cancel command
        i_m_s_e_g = await message.reply_text(String.PROCESSING, quote=True)
        g_id = message.command[1].strip()
        LOGGER(__name__).info(g_id)
        try:
            downloads = aria2.get_download(g_id)
            LOGGER(__name__).info(downloads)
            LOGGER(__name__).info(downloads.remove(force=True, files=True))
            await i_m_s_e_g.edit_text(String.TOR_CANCELLED)
        except Exception as e:
            LOGGER(__name__).info(str(e))
            await i_m_s_e_g.edit_text(String.TOR_CANCEL_FAILED)
    else:
        await message.delete()
Exemple #9
0
async def leech_commandi_f(client, message):
    m_ = await message.reply_text("checking", quote=True)
    m_sgra = " ".join(message.command[1:])
    if not message.reply_to_message:
        await m_.edit_text("No URIs to download\n"
                           f"Reply <code>/{Command.LEECH}</code> to an URI")
        return
    # get link from the incoming message
    dl_url, cf_name, _, _ = await extract_link(message.reply_to_message,
                                               "LEECH")
    LOGGER(__name__).info(f"extracted /leech links {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
        new_download_location = os.path.join(
            Config.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 "_" in m_sgra:
            LOGGER(__name__).info("rclone upload mode")
            # try to download the "link"
            sagtus, err_message = await fake_etairporpa_call(
                aria2, dl_url, new_download_location, m_,
                int(m_sgra.split("_")[2])
                # maybe IndexError / ValueError might occur,
                # we don't know, yet!!
            )
        else:
            is_zip = False
            if "a" in m_sgra:
                is_zip = True
            LOGGER(__name__).info("tg upload mode")
            # try to download the "link"
            sagtus, err_message = await call_apropriate_function(
                aria2, dl_url, new_download_location, m_, is_zip)
        if not sagtus:
            # if FAILED, display the error message
            await m_.edit_text(err_message)
Exemple #10
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(__name__).info(f"extracted /leech links {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(
        Config.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:
        if "_" in cb_data:
            LOGGER(__name__).info("rclone upload mode")
            # try to download the "link"
            sagtus, err_message = await fake_etairporpa_call(
                aria2,
                dl_url,
                new_download_location,
                message,
                int(cb_data.split("_")[2])
                # maybe IndexError / ValueError might occur,
                # we don't know, yet!!
            )
        else:
            is_zip = False
            if "a" in cb_data:
                is_zip = True
            LOGGER(__name__).info("tg upload mode")
            # try to download the "link"
            sagtus, err_message = await call_apropriate_function(
                aria2, dl_url, new_download_location, message, is_zip
            )
        if not sagtus:
            # if FAILED, display the error message
            await message.edit_text(err_message)
Exemple #11
0
async def create_archive(input_path):
    base_dir_name = PurePath(input_path).name[-249:]
    # nothing just 256 - 7 (.tar.gz), btw caption limit is 1024
    compressed_file_name = f"{base_dir_name}.tar.gz"
    # fix for https://t.me/c/1434259219/13344
    cmd_create_archive = [
        "tar",
        "-zcvf",
        compressed_file_name,
        f"{input_path}",
    ]
    LOGGER(__name__).info(cmd_create_archive)
    _, error = await run_command(cmd_create_archive)
    if error:
        LOGGER(__name__).info(error)
    # Wait for the subprocess to finish
    _path = Path(input_path)
    if _path.is_dir():
        shutil.rmtree(_path)
    elif _path.is_file():
        _path.unlink()
    return compressed_file_name if Path(
        compressed_file_name).exists() else None
async def get_r_clone_config(message_link: str, py_client: Client) -> Optional[str]:
    config_path = os.path.join(os.getcwd(), ".config", "rclone", "rclone.conf")
    if os.path.exists(config_path):
        return config_path
    splited_uri = message_link.split("/")
    chat_id, message_id = None, None
    if len(splited_uri) == 6 and splited_uri[3] == "c":
        chat_id, message_id = int(splited_uri[4]), int(splited_uri[5])
    try:
        conf_mesg = await py_client.get_messages(
            chat_id=chat_id, message_ids=message_id
        )
    except ChannelInvalid:
        LOGGER(__name__).info("invalid RClone config URL. this is NOT an ERROR")
        return None
    return await py_client.download_media(message=conf_mesg, file_name=config_path)
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 upload_document_f(_, message):
    imsegd = await message.reply_text(String.PROCESSING)
    if " " not in message.text:
        await imsegd.edit_text(
            f"<code>/{Command.UPLOAD}</code> <i>File/Directory path to upload</i>"
        )
        return
    else:
        _, local_file_name = message.text.split(" ", 1)
        if not os.path.exists(local_file_name):
            await imsegd.edit_text(
                f"Unable to find the path; <i>{local_file_name}</i>")
            return
        else:
            recvd_response = await upload_to_tg(imsegd, local_file_name,
                                                message.from_user.id, {})
            LOGGER(__name__).info(recvd_response)
            await imsegd.edit_text(
                f"<a href='tg://user?id={message.from_user.id}'>Upload completed</a>"
            )
Exemple #15
0
async def button(bot, update: CallbackQuery):
    LOGGER(__name__).info(update)
    if not update.message.reply_to_message:
        await update.answer(text=String.TGD_YTLD_STOOPID_DRUSER,
                            show_alert=True)
        return

    if update.from_user.id != update.message.reply_to_message.from_user.id:
        return

    await update.answer()
    cb_data = update.data

    if cb_data.startswith("leech"):
        await leech_btn_k(update.message, cb_data)

    elif cb_data.startswith("ytdl"):
        await ytdl_btn_k(update.message)

    elif "|" in cb_data:
        await youtube_dl_call_back(bot, update)
Exemple #16
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 youtube_dl_call_back(bot, update):
    # LOGGER.info(update)
    cb_data = update.data
    # youtube_dl extractors
    tg_send_type, extractor_key, youtube_dl_format, av_codec = cb_data.split(
        "|")
    #
    current_user_id = update.message.reply_to_message.from_user.id
    current_message = update.message.reply_to_message
    current_message_id = current_message.message_id
    current_touched_user_id = update.from_user.id

    user_working_dir = os.path.join(
        Config.DOWNLOAD_LOCATION,
        str(current_user_id),
        str(update.message.reply_to_message.message_id),
    )
    # create download directory, if not exist
    if not os.path.isdir(user_working_dir):
        await bot.delete_messages(
            chat_id=update.message.chat.id,
            message_ids=[
                update.message.message_id,
                update.message.reply_to_message.message_id,
            ],
            revoke=True,
        )
        return

    youtube_dl_url, cf_name, yt_dl_user_name, yt_dl_pass_word = await extract_link(
        current_message, "YTDL")
    LOGGER(__name__).info(youtube_dl_url)
    #
    custom_file_name = "%(title)s.%(ext)s"
    # Assign custom filename if specified
    if cf_name:
        custom_file_name = f"{cf_name}.%(ext)s"
    # https://superuser.com/a/994060
    # LOGGER.info(custom_file_name)
    #
    await update.message.edit_caption(caption="trying to download")
    tmp_directory_for_each_user = user_working_dir
    download_directory = tmp_directory_for_each_user
    download_directory = os.path.join(tmp_directory_for_each_user,
                                      custom_file_name)
    ytdl_opts = {
        "outtmpl": download_directory,
        "ignoreerrors": True,
        "nooverwrites": True,
        "continuedl": True,
        "noplaylist": True,
        # "max_filesize": Config.MAX_FILE_SIZE,
    }
    if yt_dl_user_name and yt_dl_pass_word:
        ytdl_opts.update({
            "username": yt_dl_user_name,
            "password": yt_dl_pass_word,
        })
    if extractor_key == "HotStar":
        ytdl_opts.update({
            "geo_bypass_country": "IN",
        })
    if tg_send_type == "audio":
        ytdl_opts.update({
            "format":
            "bestaudio/best",
            "postprocessors": [
                {
                    "key": "FFmpegExtractAudio",
                    "preferredcodec": av_codec,
                    "preferredquality": youtube_dl_format,
                },
                {
                    "key": "FFmpegMetadata"
                },
            ],
        })
    elif tg_send_type == "video":
        # recreating commit 20b0ef4 in a confusing way
        final_format = youtube_dl_format
        # GDrive check, it doesn't accept "bestaudio" value
        # so its no need to append or do a condition check
        if extractor_key == "Youtube" and av_codec == "none":
            final_format = f"{youtube_dl_format}+bestaudio"
        ytdl_opts.update({
            "format": final_format,
            "postprocessors": [{
                "key": "FFmpegMetadata"
            }],
        })
    elif tg_send_type == "generic":
        ytdl_opts.update({
            "format": youtube_dl_format,
        })

    start = datetime.now()
    try:
        info = await yt_extract_info(
            video_url=youtube_dl_url,
            download=True,
            ytdl_opts=ytdl_opts,
            ie_key=extractor_key,
        )
    except yt_dlp.utils.DownloadError as ytdl_error:
        await update.message.edit_caption(caption=str(ytdl_error))
        return False, None
    if info:
        end_one = datetime.now()
        time_taken_for_download = (end_one - start).seconds
        dir_contents = len(os.listdir(tmp_directory_for_each_user))
        # dir_contents.sort()
        await update.message.edit_caption(
            caption=
            f"Download completed in {time_formatter(time_taken_for_download)}"
            f"\nfound {dir_contents} file(s)")
        user_id = update.from_user.id
        #
        final_response = await upload_to_tg(
            update.message,
            tmp_directory_for_each_user,
            user_id,
            {},
            True,
            cf_name or info.get("title", ""),
        )

        LOGGER(__name__).info(final_response)
        #
        try:
            shutil.rmtree(tmp_directory_for_each_user)
        except OSError:
            pass
async def upload_single_file(message, local_file_path, caption_str, from_user,
                             edit_media):
    await asyncio.sleep(Config.EDIT_SLEEP_TIME_OUT)
    start_time = time.time()
    #
    thumbnail_location = os.path.join(Config.DOWNLOAD_LOCATION, "thumbnails",
                                      str(from_user) + ".jpg")
    LOGGER(__name__).info(thumbnail_location)
    #
    message_for_progress_display = message
    file_name = os.path.basename(local_file_path)
    if not edit_media:
        message_for_progress_display = await message.reply_text(
            f"starting upload of {file_name}")
    thumb_image_path = None
    file_type = magic.from_file(local_file_path, mime=True)
    if file_type.startswith("video/"):
        metadata = extractMetadata(createParser(local_file_path))
        duration = 0
        if metadata.has("duration"):
            duration = metadata.get("duration").seconds
        #
        width = 0
        height = 0
        if os.path.exists(thumbnail_location):
            thumb_image_path = await copy_file(
                thumbnail_location,
                os.path.dirname(os.path.abspath(local_file_path)))
        else:
            thumb_image_path = await take_screen_shot(
                local_file_path,
                os.path.dirname(os.path.abspath(local_file_path)),
                (duration / 2),
            )
            # get the correct width, height, and duration for videos greater than 10MB
            if os.path.exists(thumb_image_path):
                metadata = extractMetadata(createParser(thumb_image_path))
                if metadata.has("width"):
                    width = metadata.get("width")
                if metadata.has("height"):
                    height = metadata.get("height")
                # resize image
                # ref: https://t.me/PyrogramChat/44663
                # https://stackoverflow.com/a/21669827/4723940
                Image.open(thumb_image_path).convert("RGB").save(
                    thumb_image_path)
                img = Image.open(thumb_image_path)
                # https://stackoverflow.com/a/37631799/4723940
                img.resize((320, height))
                img.save(thumb_image_path, "JPEG")
                # https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#create-thumbnails
        #
        thumb = None
        if thumb_image_path is not None and os.path.isfile(thumb_image_path):
            thumb = thumb_image_path
        # send video
        if edit_media and message.photo:
            sent_message = await message.edit_media(media=InputMediaVideo(
                media=local_file_path,
                thumb=thumb,
                caption=caption_str,
                parse_mode="html",
                width=width,
                height=height,
                duration=duration,
                supports_streaming=True,
            )
                                                    # quote=True,
                                                    )
        else:
            sent_message = await message.reply_video(
                video=local_file_path,
                # quote=True,
                caption=caption_str,
                parse_mode="html",
                duration=duration,
                width=width,
                height=height,
                thumb=thumb,
                supports_streaming=True,
                disable_notification=True,
                # reply_to_message_id=message.reply_to_message.message_id,
                progress=progress_for_pyrogram,
                progress_args=(
                    file_name,
                    message_for_progress_display,
                    start_time,
                ),
            )
    elif file_type.startswith("audio/"):
        metadata = extractMetadata(createParser(local_file_path))
        duration = 0
        title = ""
        artist = ""
        if metadata.has("duration"):
            duration = metadata.get("duration").seconds
        if metadata.has("title"):
            title = metadata.get("title")
        if metadata.has("artist"):
            artist = metadata.get("artist")
        if os.path.isfile(thumbnail_location):
            thumb_image_path = await copy_file(
                thumbnail_location,
                os.path.dirname(os.path.abspath(local_file_path)))
        thumb = None
        if thumb_image_path is not None and os.path.isfile(thumb_image_path):
            thumb = thumb_image_path
        # send audio
        if edit_media and message.photo:
            sent_message = await message.edit_media(media=InputMediaAudio(
                media=local_file_path,
                thumb=thumb,
                caption=caption_str,
                parse_mode="html",
                duration=duration,
                performer=artist,
                title=title,
            )
                                                    # quote=True,
                                                    )
        else:
            sent_message = await message.reply_audio(
                audio=local_file_path,
                # quote=True,
                caption=caption_str,
                parse_mode="html",
                duration=duration,
                performer=artist,
                title=title,
                thumb=thumb,
                disable_notification=True,
                # reply_to_message_id=message.reply_to_message.message_id,
                progress=progress_for_pyrogram,
                progress_args=(
                    file_name,
                    message_for_progress_display,
                    start_time,
                ),
            )
    else:
        if os.path.isfile(thumbnail_location):
            thumb_image_path = await copy_file(
                thumbnail_location,
                os.path.dirname(os.path.abspath(local_file_path)))
        # if a file, don't upload "thumb"
        # this "diff" is a major derp -_- 😔😭😭
        thumb = None
        if thumb_image_path is not None and os.path.isfile(thumb_image_path):
            thumb = thumb_image_path
        #
        # send document
        if edit_media and message.photo:
            sent_message = await message.edit_media(media=InputMediaDocument(
                media=local_file_path,
                thumb=thumb,
                caption=caption_str,
                parse_mode="html",
            )
                                                    # quote=True,
                                                    )
        else:
            sent_message = await message.reply_document(
                document=local_file_path,
                # quote=True,
                thumb=thumb,
                caption=caption_str,
                parse_mode="html",
                disable_notification=True,
                # reply_to_message_id=message.reply_to_message.message_id,
                progress=progress_for_pyrogram,
                progress_args=(
                    file_name,
                    message_for_progress_display,
                    start_time,
                ),
            )
    if thumb is not None:
        os.remove(thumb)
    if message.message_id != message_for_progress_display.message_id:
        await message_for_progress_display.delete()
    os.remove(local_file_path)
    return sent_message
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
Exemple #20
0
async def split_large_files(input_file):
    file = Path(input_file)
    base_path = PurePath(file.resolve())
    # create a new download directory
    temp_dir = PurePath(tempfile.mkdtemp(dir=base_path.parent))

    file_type = magic.from_file(input_file, mime=True)
    if Config.SPLIT_ALGORITHM.lower() != "rar" and file_type.startswith(
            "video/"):
        # handle video / audio files here
        metadata = extractMetadata(createParser(input_file))
        duration = metadata.get("duration").seconds if metadata.has(
            "duration") else 0
        LOGGER(__name__).info(duration)

        # proprietary logic to get the seconds to trim (at)
        file_size = file.stat().st_size
        LOGGER(__name__).info(file_size)
        minimum_duration = (duration / file_size) * Config.MAX_SPLIT_SIZE
        # casting to int cuz float Time Stamp can cause errors
        minimum_duration = int(minimum_duration)
        LOGGER(__name__).info(minimum_duration)
        # END: proprietary

        start_time = 0
        end_time = minimum_duration

        i = 0
        flag = False

        while end_time <= duration:
            LOGGER(__name__).info(i)
            # file name generate
            parted_file_name = (
                f"{str(base_path.stem)}_PART_{str(i).zfill(2)}{str(base_path.suffix)}"
            )
            # [.stem] is for final path component without suffix
            # "Example.mp4" --> "Example_PART_00.mp4"

            output_path = temp_dir / parted_file_name
            cmd_split_video = [
                "ffmpeg",
                "-i",
                input_file,
                "-ss",
                str(start_time),
                "-to",
                str(end_time),
                "-async",
                "1",
                "-strict",
                "-2",
                "-c",
                "copy",
                output_path,
            ]
            LOGGER(__name__).info(cmd_split_video)
            await run_command(cmd_split_video)
            LOGGER(__name__).info(
                f"Start time {start_time}, End time {end_time}, Itr {i}")

            # adding offset of 3 seconds to ensure smooth playback
            start_time = end_time - 3
            end_time += minimum_duration
            i += 1

            if (end_time > duration) and not flag:
                end_time = duration
                flag = True
            elif flag:
                break

    elif Config.SPLIT_ALGORITHM.lower() == "split":
        # handle normal files here
        output_path = temp_dir / f"{base_path.name}."
        cmd_create_split = [
            "split",
            "--numeric-suffixes=1",
            "--suffix-length=3",
            f"--bytes={Config.MAX_SPLIT_SIZE}",
            input_file,
            output_path,
        ]
        LOGGER(__name__).info(cmd_create_split)
        await run_command(cmd_create_split)
    elif Config.SPLIT_ALGORITHM.lower() == "rar":
        output_path = temp_dir / base_path.stem
        cmd_create_rar = [
            "rar",
            "a",
            f"-v{Config.MAX_SPLIT_SIZE}b",
            "-m0",
            output_path,
            input_file,
        ]
        LOGGER(__name__).info(cmd_create_rar)
        await run_command(cmd_create_rar)

    file.unlink()  # Remove input_file
    return temp_dir
async def upload_to_tg(
    message,
    local_file_name,
    from_user,
    dict_contatining_uploaded_files,
    edit_media=False,
    custom_caption=None,
):
    LOGGER(__name__).info(local_file_name)
    base_file_name = os.path.basename(local_file_name)
    caption_str = custom_caption
    if not caption_str or not edit_media:
        LOGGER(__name__).info("fall-back to default file_name")
        caption_str = "<code>"
        caption_str += base_file_name
        caption_str += "</code>"
    # caption_str += "\n\n"
    # caption_str += "<a href='tg://user?id="
    # caption_str += str(from_user)
    # caption_str += "'>"
    # caption_str += "Here is the file to the link you sent"
    # caption_str += "</a>"
    if os.path.isdir(local_file_name):
        directory_contents = os.listdir(local_file_name)
        directory_contents.sort()
        # number_of_files = len(directory_contents)
        LOGGER(__name__).info(directory_contents)
        new_m_esg = message
        if not message.photo:
            new_m_esg = await message.reply_text(
                "Found {} files".format(len(directory_contents)),
                quote=True
                # reply_to_message_id=message.message_id
            )
        for single_file in directory_contents:
            # recursion: will this FAIL somewhere?
            file_path = os.path.join(local_file_name, single_file)
            if not os.path.exists(file_path):
                continue
            await upload_to_tg(
                new_m_esg,
                file_path,
                from_user,
                dict_contatining_uploaded_files,
                edit_media,
                caption_str,
            )
    elif os.path.getsize(local_file_name) > Config.MAX_FILE_SIZE:
        LOGGER(__name__).info("TODO")
        d_f_s = humanbytes(os.path.getsize(local_file_name))
        i_m_s_g = await message.reply_text(
            "Telegram does not support uploading this file.\n"
            f"Detected File Size: {d_f_s} 😡\n"
            "\n🤖 trying to split the files 🌝🌝🌚")
        splitted_dir = await split_large_files(local_file_name)
        totlaa_sleif = os.listdir(splitted_dir)
        totlaa_sleif.sort()
        number_of_files = len(totlaa_sleif)
        LOGGER(__name__).info(totlaa_sleif)
        ba_se_file_name = os.path.basename(local_file_name)
        await i_m_s_g.edit_text(
            f"Detected File Size: {d_f_s} 😡\n"
            f"<code>{ba_se_file_name}</code> splitted into {number_of_files} files.\n"
            "trying to upload to Telegram, now ...")
        for le_file in totlaa_sleif:
            # recursion: will this FAIL somewhere?
            file_path = os.path.join(splitted_dir, le_file)
            if not os.path.isfile(file_path):
                continue
            await upload_to_tg(
                message,
                file_path,
                from_user,
                dict_contatining_uploaded_files,
            )
    else:
        sent_message = None
        if os.path.isfile(local_file_name):
            sent_message = await upload_single_file(message, local_file_name,
                                                    caption_str, from_user,
                                                    edit_media)
        if sent_message is not None:
            dict_contatining_uploaded_files[os.path.basename(
                local_file_name)] = sent_message.message_id
    # await message.delete()
    return dict_contatining_uploaded_files
async def extract_link(message, type_o_request):
    custom_file_name = None
    url = None
    youtube_dl_username = None
    youtube_dl_password = None

    if message is None:
        url = None
        custom_file_name = None

    elif message.text is not None:
        if message.text.lower().startswith("magnet:"):
            url = message.text.strip()

        elif "|" in message.text:
            url_parts = message.text.split("|")
            if len(url_parts) == 2:
                url = url_parts[0]
                custom_file_name = url_parts[1]
            elif len(url_parts) == 4:
                url = url_parts[0]
                custom_file_name = url_parts[1]
                youtube_dl_username = url_parts[2]
                youtube_dl_password = url_parts[3]

        elif message.entities is not None:
            url = extract_url_from_entity(message.entities, message.text)

        else:
            url = message.text.strip()

    elif message.document is not None:
        if message.document.file_name.lower().endswith(".torrent"):
            url = await message.download()
            custom_file_name = message.caption

    elif message.caption is not None:
        if "|" in message.caption:
            url_parts = message.caption.split("|")
            if len(url_parts) == 2:
                url = url_parts[0]
                custom_file_name = url_parts[1]
            elif len(url_parts) == 4:
                url = url_parts[0]
                custom_file_name = url_parts[1]
                youtube_dl_username = url_parts[2]
                youtube_dl_password = url_parts[3]

        elif message.caption_entities is not None:
            url = extract_url_from_entity(message.caption_entities,
                                          message.caption)

        else:
            url = message.caption.strip()

    elif message.entities is not None:
        url = message.text

    # trim blank spaces from the URL
    # might have some issues with #45
    if url is not None:
        url = url.strip()
    if custom_file_name is not None:
        custom_file_name = custom_file_name.strip()
    # https://stackoverflow.com/a/761825/4723940
    if youtube_dl_username is not None:
        youtube_dl_username = youtube_dl_username.strip()
    if youtube_dl_password is not None:
        youtube_dl_password = youtube_dl_password.strip()

    # additional conditional check,
    # here to FILTER out BAD URLs
    LOGGER(__name__).info(Config.TG_OFFENSIVE_API)
    if Config.TG_OFFENSIVE_API is not None:
        try:
            async with aiohttp.ClientSession() as session:
                api_url = Config.TG_OFFENSIVE_API.format(i=url,
                                                         m=custom_file_name,
                                                         t=type_o_request)
                LOGGER(__name__).info(api_url)
                async with session.get(api_url) as resp:
                    suats = int(resp.status)
                    err = await resp.text()
                    if suats != 200:
                        url = None
                        custom_file_name = err
        except:
            # this might occur in case of a BAD API URL,
            # who knows? :\
            pass

    return url, custom_file_name, youtube_dl_username, youtube_dl_password
Exemple #23
0
 async def stop(self, *args):
     await super().stop()
     shutil.rmtree(DOWNLOAD_LOCATION, ignore_errors=True)
     LOGGER(__name__).info("PublicLeechGroup stopped. Bye.")
Exemple #24
0
    async def start(self):
        await super().start()
        usr_bot_me = await self.get_me()

        # create download directory, if not exist
        if not os.path.isdir(DOWNLOAD_LOCATION):
            os.makedirs(DOWNLOAD_LOCATION)

        LOGGER(__name__).info("@PublicLeechGroup, trying to add handlers")
        # PURGE command
        self.add_handler(
            MessageHandler(incoming_purge_message_f,
                           filters=filters.command([Commandi.PURGE])
                           & filters.chat(chats=AUTH_CHANNEL)))

        # STATUS command
        self.add_handler(
            MessageHandler(status_message_f,
                           filters=filters.command([Commandi.STATUS])
                           & filters.chat(chats=AUTH_CHANNEL)))

        # CANCEL command
        self.add_handler(
            MessageHandler(cancel_message_f,
                           filters=filters.command([Commandi.CANCEL])
                           & filters.chat(chats=AUTH_CHANNEL)))

        if not SHOULD_USE_BUTTONS:
            LOGGER(__name__).info("using COMMANDi mode")
            # LEECH command
            self.add_handler(
                MessageHandler(leech_commandi_f,
                               filters=filters.command([Commandi.LEECH])
                               & filters.chat(chats=AUTH_CHANNEL)))

            # YTDL command
            self.add_handler(
                MessageHandler(incoming_youtube_dl_f,
                               filters=filters.command([Commandi.YTDL])
                               & filters.chat(chats=AUTH_CHANNEL)))
        else:
            LOGGER(__name__).info("using BUTTONS mode")
            # all messages filter
            # in the AUTH_CHANNELs
            self.add_handler(
                MessageHandler(incoming_message_f,
                               filters=message_fliter
                               & filters.chat(chats=AUTH_CHANNEL)))

        # button is LEGACY command to handle
        # the OLD YTDL buttons,
        # and also the new SUB buttons
        self.add_handler(CallbackQueryHandler(button))

        if DIS_ABLE_ST_GFC_COMMAND_I:
            self.add_handler(
                MessageHandler(exec_message_f,
                               filters=filters.command([Commandi.EXEC])
                               & filters.user(users=SUDO_USERS)))

            self.add_handler(
                MessageHandler(eval_message_f,
                               filters=filters.command([Commandi.EVAL])
                               & filters.user(users=SUDO_USERS)))

            # MEMEs COMMANDs
            self.add_handler(
                MessageHandler(upload_document_f,
                               filters=filters.command([Commandi.UPLOAD])
                               & filters.user(users=SUDO_USERS)))

        # HELP command
        self.add_handler(
            MessageHandler(help_message_f,
                           filters=filters.command([Commandi.HELP])
                           & filters.chat(chats=AUTH_CHANNEL)))

        # not AUTH CHANNEL users
        self.add_handler(
            MessageHandler(new_join_f,
                           filters=~filters.chat(chats=AUTH_CHANNEL)))

        # welcome MESSAGE
        self.add_handler(
            MessageHandler(help_message_f,
                           filters=filters.chat(chats=AUTH_CHANNEL)
                           & filters.new_chat_members))

        # savethumbnail COMMAND
        self.add_handler(
            MessageHandler(save_thumb_nail,
                           filters=filters.command([Commandi.SAVETHUMBNAIL])
                           & filters.chat(chats=AUTH_CHANNEL)))

        # clearthumbnail COMMAND
        self.add_handler(
            MessageHandler(clear_thumb_nail,
                           filters=filters.command([Commandi.CLEARTHUMBNAIL])
                           & filters.chat(chats=AUTH_CHANNEL)))

        # an probably easy way to get RClone CONF URI
        self.add_handler(
            MessageHandler(
                save_rclone_conf_f,
                filters=filters.command([Commandi.GET_RCLONE_CONF_URI])
                & filters.user(users=SUDO_USERS)))

        # Telegram command to upload LOG files
        self.add_handler(
            MessageHandler(upload_log_file,
                           filters=filters.command([Commandi.UPLOAD_LOG_FILE])
                           & filters.user(users=SUDO_USERS)))

        LOGGER(__name__).info(
            f"@{usr_bot_me.username} based on Pyrogram v{__version__} ")
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Affero General Public License for more details.

#  You should have received a copy of the GNU Affero General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.

import aria2p
import asyncio
import configparser
import os
from pyrogram.errors import (MessageNotModified, FloodWait)
from publicleechgroup import (LOGGER)
LOGGER = LOGGER(__name__)
from publicleechgroup.helper_funcs.upload_to_tg import upload_to_tg
from publicleechgroup.helper_funcs.create_compressed_archive import create_archive

from publicleechgroup import (ARIA_TWO_STARTED_PORT,
                              MAX_TIME_TO_WAIT_FOR_TORRENTS_TO_START,
                              AUTH_CHANNEL, DOWNLOAD_LOCATION,
                              EDIT_SLEEP_TIME_OUT, R_CLONE_CONF_URI,
                              R_CLONE_DEST)
from publicleechgroup.helper_funcs.r_clone import (get_r_clone_config,
                                                   copy_via_rclone)


async def aria_start():
    aria2_daemon_start_cmd = []
    # start the daemon, aria2c command
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