Example #1
0
async def reverse(bot: Amime, message: Message):
    reply = message.reply_to_message
    lang = message._lang

    if reply.from_user.id == bot.me.id:
        return

    if not reply.media:
        await message.reply_text(lang.media_not_found_text)
        return

    media = (reply.photo or reply.sticker or reply.animation or reply.document
             or reply.video)

    if isinstance(media, (Document, Video)):
        if bool(media.thumbs) and len(media.thumbs) > 0:
            media = media.thumbs[0]
        else:
            return

    sent = await message.reply_photo("https://i.imgur.com/m0N2pFc.jpg",
                                     caption=lang.searching_media_text)

    path = await bot.download_media(media)

    async with httpx.AsyncClient(http2=True) as client:
        try:
            response = await client.post(
                "https://www.google.com/searchbyimage/upload",
                files=dict(
                    encoded_image=(os.path.basename(path), open(path, "rb")),
                    image_content="",
                ),
                timeout=20.0,
                allow_redirects=False,
            )
        except httpx.TimeoutException:
            await sent.edit_text(lang.timed_out_text)
            return

        if response.status_code == 400:
            await sent.edit_text(lang.api_overuse_text)
            return

        url = response.headers["Location"]

        opener = urllib.request.build_opener()

        source = opener.open(f"{url}&hl=en").read()
        soup = bs4.BeautifulSoup(source, "html.parser")

        results = {
            "similar_images": None,
            "override": None,
            "best_guess": None,
        }

        try:
            for bess in soup.findAll("a", {"class": "PBorbe"}):
                results["override"] = f"https://www.google.com{bess['href']}"
        except BaseException:
            pass

        for similar_image in soup.findAll("input", {"clas": "gLFyf"}):
            results[
                "similar_images"] = f"https://www.google.com/search?tbm=isch&q={urllib.parse.quote_plus(similar_image['value'])}"

        for best_guess in soup.findAll("div", {"class": "r5a77d"}):
            results["best_guess"] = best_guess.get_text()

        guess = results["best_guess"]

        page_url = None
        if results["override"] is not None:
            page_url = results["override"]
        else:
            page_url = results["similar_images"]

        if guess is None and page_url is None:
            await sent.edit_text(lang.no_results_text)
            return

        single = opener.open(page_url).read().decode()

        images = []
        count = 0
        for image in re.findall(
                r"^,\[\"(.*[.png|.jpg|.jpeg])\",[0-9]+,[0-9]+\]$", single,
                re.I | re.M):
            count += 1
            images.append(image)
            if count >= 5:
                break

        if len(images) == 0:
            await sent.edit_text(lang.no_results_text)
            return

        await sent.reply_media_group(
            media=[InputMediaPhoto(image) for image in images])
        await sent.edit_text(
            lang.search_results_text.format(
                query=f"<a href='{url}'>{guess}</a>"),
            disable_web_page_preview=True,
        )

        await client.aclose()

    os.remove(path)
Example #2
0
async def ytdl_callback(_, c_q: CallbackQuery):
    choosen_btn = c_q.matches[0].group(1)
    data_key = c_q.matches[0].group(2)
    page = c_q.matches[0].group(3)
    if os.path.exists(PATH):
        with open(PATH) as f:
            view_data = ujson.load(f)
        search_data = view_data.get(data_key)
        total = len(search_data)
    else:
        return await c_q.answer(
            "Search data doesn't exists anymore, please perform search again ...",
            show_alert=True,
        )
    if choosen_btn == "back":
        index = int(page) - 1
        del_back = index == 1
        await c_q.answer()
        back_vid = search_data.get(str(index))
        await c_q.edit_message_media(
            media=(
                InputMediaPhoto(
                    media=back_vid.get("thumb"),
                    caption=back_vid.get("message"),
                )
            ),
            reply_markup=yt_search_btns(
                del_back=del_back,
                data_key=data_key,
                page=index,
                vid=back_vid.get("video_id"),
                total=total,
            ),
        )
    elif choosen_btn == "next":
        index = int(page) + 1
        if index > total:
            return await c_q.answer("That's All Folks !", show_alert=True)
        await c_q.answer()
        front_vid = search_data.get(str(index))
        await c_q.edit_message_media(
            media=(
                InputMediaPhoto(
                    media=front_vid.get("thumb"),
                    caption=front_vid.get("message"),
                )
            ),
            reply_markup=yt_search_btns(
                data_key=data_key,
                page=index,
                vid=front_vid.get("video_id"),
                total=total,
            ),
        )
    elif choosen_btn == "listall":
        await c_q.answer("View Changed to:  📜  List", show_alert=False)
        list_res = ""
        for vid_s in search_data:
            list_res += search_data.get(vid_s).get("list_view")
        telegraph = post_to_telegraph(
            a_title=f"Showing {total} youtube video results for the given query ...",
            content=list_res,
        )
        await c_q.edit_message_media(
            media=(
                InputMediaPhoto(
                    media=search_data.get("1").get("thumb"),
                )
            ),
            reply_markup=InlineKeyboardMarkup(
                [
                    [
                        InlineKeyboardButton(
                            "↗️  Click To Open",
                            url=telegraph,
                        )
                    ],
                    [
                        InlineKeyboardButton(
                            "📰  Detailed View",
                            callback_data=f"ytdl_detail_{data_key}_{page}",
                        )
                    ],
                ]
            ),
        )
    else:  # Detailed
        index = 1
        await c_q.answer("View Changed to:  📰  Detailed", show_alert=False)
        first = search_data.get(str(index))
        await c_q.edit_message_media(
            media=(
                InputMediaPhoto(
                    media=first.get("thumb"),
                    caption=first.get("message"),
                )
            ),
            reply_markup=yt_search_btns(
                del_back=True,
                data_key=data_key,
                page=index,
                vid=first.get("video_id"),
                total=total,
            ),
        )
async def youtube_dl_call_back(bot, update):
    cb_data = update.data
    tg_send_type, youtube_dl_format, youtube_dl_ext = cb_data.split("|")
    thumb_image_path = Config.DOWNLOAD_LOCATION + \
        "/" + str(update.from_user.id) + ".jpg"

    save_ytdl_json_path = Config.DOWNLOAD_LOCATION + \
        "/" + str(update.from_user.id) + ".json"
    try:
        with open(save_ytdl_json_path, "r", encoding="utf8") as f:
            response_json = json.load(f)
    except (FileNotFoundError) as e:
        await bot.delete_messages(chat_id=update.message.chat.id,
                                  message_ids=update.message.message_id,
                                  revoke=True)
        return False
    youtube_dl_url = update.message.reply_to_message.text
    custom_file_name = str(response_json.get("title")) + \
        "_" + youtube_dl_format + "." + youtube_dl_ext
    youtube_dl_username = None
    youtube_dl_password = None
    if "|" in youtube_dl_url:
        url_parts = youtube_dl_url.split("|")
        if len(url_parts) == 2:
            youtube_dl_url = url_parts[0]
            custom_file_name = url_parts[1]
        elif len(url_parts) == 4:
            youtube_dl_url = url_parts[0]
            custom_file_name = url_parts[1]
            youtube_dl_username = url_parts[2]
            youtube_dl_password = url_parts[3]
        else:
            for entity in update.message.reply_to_message.entities:
                if entity.type == "text_link":
                    youtube_dl_url = entity.url
                elif entity.type == "url":
                    o = entity.offset
                    l = entity.length
                    youtube_dl_url = youtube_dl_url[o:o + l]
        if youtube_dl_url is not None:
            youtube_dl_url = youtube_dl_url.strip()
        if custom_file_name is not None:
            custom_file_name = custom_file_name.strip()
        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()

    else:
        for entity in update.message.reply_to_message.entities:
            if entity.type == "text_link":
                youtube_dl_url = entity.url
            elif entity.type == "url":
                o = entity.offset
                l = entity.length
                youtube_dl_url = youtube_dl_url[o:o + l]
    await bot.edit_message_text(text=Translation.DOWNLOAD_START,
                                chat_id=update.message.chat.id,
                                message_id=update.message.message_id)
    description = Translation.CUSTOM_CAPTION_UL_FILE
    if "fulltitle" in response_json:
        description = response_json["fulltitle"][0:1021]
    tmp_directory_for_each_user = Config.DOWNLOAD_LOCATION + "/" + str(
        update.from_user.id)
    if not os.path.isdir(tmp_directory_for_each_user):
        os.makedirs(tmp_directory_for_each_user)
    download_directory = tmp_directory_for_each_user + "/" + custom_file_name
    command_to_exec = []
    if tg_send_type == "audio":
        command_to_exec = [
            "youtube-dl", "-c", "--max-filesize",
            str(Config.TG_MAX_FILE_SIZE), "--prefer-ffmpeg", "--extract-audio",
            "--audio-format", youtube_dl_ext, "--audio-quality",
            youtube_dl_format, youtube_dl_url, "-o", download_directory
        ]
    else:
        minus_f_format = youtube_dl_format
        if "youtu" in youtube_dl_url:
            minus_f_format = youtube_dl_format + "+bestaudio"
        command_to_exec = [
            "youtube-dl", "-c", "--max-filesize",
            str(Config.TG_MAX_FILE_SIZE), "--embed-subs", "-f", minus_f_format,
            "--hls-prefer-ffmpeg", youtube_dl_url, "-o", download_directory
        ]
    if Config.HTTP_PROXY != "":
        command_to_exec.append("--proxy")
        command_to_exec.append(Config.HTTP_PROXY)
    if youtube_dl_username is not None:
        command_to_exec.append("--username")
        command_to_exec.append(youtube_dl_username)
    if youtube_dl_password is not None:
        command_to_exec.append("--password")
        command_to_exec.append(youtube_dl_password)
    command_to_exec.append("--no-warnings")
    if "hotstar" in youtube_dl_url:
        command_to_exec.append("--geo-bypass-country")
        command_to_exec.append("IN")

    start = datetime.now()
    process = await asyncio.create_subprocess_exec(
        *command_to_exec,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE,
    )
    stdout, stderr = await process.communicate()
    e_response = stderr.decode().strip()
    t_response = stdout.decode().strip()
    # logger.info(e_response)
    # logger.info(t_response)
    ad_string_to_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."
    if e_response and ad_string_to_replace in e_response:
        error_message = e_response.replace(ad_string_to_replace, "")
        await bot.edit_message_text(chat_id=update.message.chat.id,
                                    message_id=update.message.message_id,
                                    text=error_message)
        return False
    if t_response:
        try:
            os.remove(save_ytdl_json_path)
        except:
            pass
        end_one = datetime.now()
        time_taken_for_download = (end_one - start).seconds
        file_size = Config.TG_MAX_FILE_SIZE + 1
        try:
            file_size = os.stat(download_directory).st_size
        except FileNotFoundError as exc:
            try:
                download_directory = os.path.splitext(
                    download_directory)[0] + "." + "mkv"
                file_size = os.stat(download_directory).st_size
            except Exception as e:
                await bot.edit_message_text(
                    chat_id=update.message.chat.id,
                    text="Some errors occured while downloading video!",
                    message_id=update.message.message_id)
                logger.info("FnF error - " + str(e))
                return
        if file_size > Config.TG_MAX_FILE_SIZE:
            await bot.edit_message_text(
                chat_id=update.message.chat.id,
                text=Translation.RCHD_TG_API_LIMIT.format(
                    time_taken_for_download, humanbytes(file_size)),
                message_id=update.message.message_id)
        else:
            if Config.SCREENSHOTS:
                is_w_f = False
                images = await generate_screen_shots(
                    download_directory, tmp_directory_for_each_user, is_w_f,
                    Config.DEF_WATER_MARK_FILE, 300, 9)
            try:
                await bot.edit_message_text(
                    text=Translation.UPLOAD_START,
                    chat_id=update.message.chat.id,
                    message_id=update.message.message_id)
            except:
                pass
            # get the correct width, height, and duration for videos greater than 10MB
            width = 0
            height = 0
            duration = 0
            if tg_send_type != "file":
                metadata = extractMetadata(createParser(download_directory))
                if metadata is not None:
                    if metadata.has("duration"):
                        duration = metadata.get('duration').seconds

            if os.path.exists(thumb_image_path):
                width = 0
                height = 0
                metadata = extractMetadata(createParser(thumb_image_path))
                if metadata.has("width"):
                    width = metadata.get("width")
                if metadata.has("height"):
                    height = metadata.get("height")
                if tg_send_type == "vm":
                    height = width
                Image.open(thumb_image_path).convert("RGB").save(
                    thumb_image_path)
                img = Image.open(thumb_image_path)
                if tg_send_type == "file":
                    img.resize((320, height))
                else:
                    img.resize((90, height))
                img.save(thumb_image_path, "JPEG")
            else:
                thumb_image_path = None

            start_time = time.time()
            if tg_send_type == "audio":
                await update.message.reply_to_message.reply_chat_action(
                    "upload_audio")
                await bot.send_audio(
                    chat_id=update.message.chat.id,
                    audio=download_directory,
                    caption=description,
                    parse_mode="HTML",
                    duration=duration,
                    # performer=response_json["uploader"],
                    # title=response_json["title"],
                    reply_markup=InlineKeyboardMarkup([[
                        InlineKeyboardButton(
                            'Join Channel',
                            url='https://telegram.me/David_Botz')
                    ]]),
                    thumb=thumb_image_path,
                    progress=progress_for_pyrogram,
                    progress_args=(Translation.UPLOAD_START, update.message,
                                   start_time))
            elif tg_send_type == "file":
                await update.message.reply_to_message.reply_chat_action(
                    "upload_document")
                await bot.send_document(
                    chat_id=update.message.chat.id,
                    document=download_directory,
                    thumb=thumb_image_path,
                    caption=description,
                    parse_mode="HTML",
                    reply_markup=InlineKeyboardMarkup([[
                        InlineKeyboardButton(
                            'Join Channel',
                            url='https://telegram.me/David_Botz')
                    ]]),
                    reply_to_message_id=update.message.reply_to_message.
                    message_id,
                    progress=progress_for_pyrogram,
                    progress_args=(Translation.UPLOAD_START, update.message,
                                   start_time))
            elif tg_send_type == "vm":
                await update.message.reply_to_message.reply_chat_action(
                    "upload_video_note")

                await bot.send_video_note(
                    chat_id=update.message.chat.id,
                    video_note=download_directory,
                    duration=duration,
                    length=width,
                    thumb=thumb_image_path,
                    reply_to_message_id=update.message.reply_to_message.
                    message_id,
                    progress=progress_for_pyrogram,
                    progress_args=(Translation.UPLOAD_START, update.message,
                                   start_time))
            elif tg_send_type == "video":
                await update.message.reply_to_message.reply_chat_action(
                    "upload_video")
                await bot.send_video(
                    chat_id=update.message.chat.id,
                    video=download_directory,
                    caption=description,
                    parse_mode="HTML",
                    duration=duration,
                    width=width,
                    height=height,
                    supports_streaming=True,
                    reply_markup=InlineKeyboardMarkup([[
                        InlineKeyboardButton(
                            'Join Channel',
                            url='https://telegram.me/David_Botz')
                    ]]),
                    thumb=thumb_image_path,
                    reply_to_message_id=update.message.reply_to_message.
                    message_id,
                    progress=progress_for_pyrogram,
                    progress_args=(Translation.UPLOAD_START, update.message,
                                   start_time))
            else:
                logger.info("Did this happen? :\\")
            end_two = datetime.now()
            time_taken_for_upload = (end_two - end_one).seconds

            media_album_p = []
            if Config.SCREENSHOTS:
                if images is not None:
                    i = 0
                    caption = ""
                    if is_w_f:
                        caption = ""
                    for image in images:
                        if os.path.exists(image):
                            if i == 0:
                                media_album_p.append(
                                    InputMediaPhoto(media=image,
                                                    caption=caption,
                                                    parse_mode="html"))
                            else:
                                media_album_p.append(
                                    InputMediaPhoto(media=image))
                            i = i + 1
                    await bot.send_media_group(
                        chat_id=update.message.chat.id,
                        disable_notification=True,
                        reply_to_message_id=update.message.message_id,
                        media=media_album_p)
            try:
                shutil.rmtree(tmp_directory_for_each_user)
            except:
                pass
            try:
                os.remove(thumb_image_path)
            except:
                pass
            await bot.edit_message_text(
                text=Translation.AFTER_SUCCESSFUL_UPLOAD_MSG_WITH_TS.format(
                    time_taken_for_download, time_taken_for_upload),
                chat_id=update.message.chat.id,
                message_id=update.message.message_id,
                disable_web_page_preview=True)
Example #4
0
async def whatanime(c: Korone, m: Message):
    if not m.reply_to_message.media:
        await m.reply_text("Nenhuma mídia encontrada!")
        return

    media = (
        m.reply_to_message.photo
        or m.reply_to_message.sticker
        or m.reply_to_message.animation
        or m.reply_to_message.video
        or m.reply_to_message.document
    )

    if isinstance(media, (Document, Video)):
        if bool(media.thumbs) and len(media.thumbs) > 0:
            media = media.thumbs[0]

        elif (
            isinstance(media, Video)
            and bool(media.duration)
            and ((media.duration) > (1 * 60 + 30))
        ):
            return

    sent = await m.reply_photo(
        "https://telegra.ph/file/4b479327f02d097a23344.png",
        caption="Procurando informações no AniList...",
    )

    tempdir = tempfile.mkdtemp()
    path = await c.download_media(media, file_name=os.path.join(tempdir, "whatanime"))

    try:
        r = await http.post(
            "https://api.trace.moe/search?anilistInfo&cutBorders",
            files={"image": open(path, "rb")},
        )
    except TimeoutException:
        shutil.rmtree(tempdir)
        await sent.edit("A pesquisa excedeu o tempo limite...")
        return

    shutil.rmtree(tempdir)

    if r.status_code != 200:
        await sent.edit(
            f"<b>Error:</b> <code>{r.status_code}</code>! Tente novamente mais tarde."
        )
        return

    results = r.json()["result"]
    if len(results) == 0:
        await sent.edit("Nenhum resultado foi encontrado!")
        return

    result = results[0]
    anilist_id = result["anilist"]["id"]
    title_native = result["anilist"]["title"]["native"]
    title_romaji = result["anilist"]["title"]["romaji"]
    is_adult = result["anilist"]["isAdult"]
    synonyms = result["anilist"]["synonyms"]
    episode = result["episode"]

    text = f"<b>{title_romaji}</b>"
    if bool(title_native):
        text += f" (<code>{title_native}</code>)"
    text += "\n"
    text += f"<b>ID:</b> <code>{anilist_id}</code>\n"
    if bool(episode):
        text += f"\n<b>Episódio:</b> <code>{episode}</code>"
    if bool(synonyms):
        text += f"\n<b>Sinônimos:</b> {', '.join(str(x) for x in synonyms)}"
    if bool(is_adult):
        text += "\n<b>Adulto:</b> <code>Sim</code>"
    percent = round(result["similarity"] * 100, 2)
    text += f"\n<b>Similaridade:</b> <code>{percent}%</code>"

    keyboard = [[("Mais informações", f"https://anilist.co/anime/{anilist_id}", "url")]]

    await sent.edit_media(
        InputMediaPhoto(
            f"https://img.anili.st/media/{anilist_id}",
            text,
        ),
        reply_markup=c.ikb(keyboard),
    )

    video = result["video"]
    from_time = str(timedelta(seconds=result["from"])).split(".", 1)[0].rjust(8, "0")
    to_time = str(timedelta(seconds=result["to"])).split(".", 1)[0].rjust(8, "0")
    if video is not None:
        file_name = result["filename"]

        try:
            await c.send_video(
                chat_id=m.chat.id,
                video=video + "&size=l",
                width=1280,
                height=720,
                caption=(
                    f"<code>{file_name}</code>\n\n"
                    f"<code>{from_time}</code> - <code>{to_time}</code>"
                ),
                reply_to_message_id=m.message_id,
            )
        except BadRequest:
            return
Example #5
0
async def reverseing(client, message):
    pablo = await edit_or_reply(message, "`Searching For The Image.....`")
    if not message.reply_to_message or not message.reply_to_message.photo:
        await pablo.edit("Reply to A image...")
        return
    imoge = await message.reply_to_message.download()
    try:
        image = Image.open(imoge)
    except OSError:
        return
    name = "okgoogle.png"
    image.save(name, "PNG")
    image.close()
    searchUrl = "https://www.google.com/searchbyimage/upload"
    multipart = {
        "encoded_image": (name, open(name, "rb")),
        "image_content": ""
    }
    response = requests.post(searchUrl, files=multipart, allow_redirects=False)
    fetchUrl = response.headers["Location"]
    if response != 400:
        await pablo.edit("`Image successfully uploaded to Google. Maybe.`"
                         "\n`Parsing source now. Maybe.`")
    else:
        await pablo.edit("`Google told me to f**k off.`")
        return

    os.remove(name)
    match = await ParseSauce(fetchUrl + "&preferences?hl=en&fg=1#languages")
    guess = match["best_guess"]
    imgspage = match["similar_images"]

    if guess and imgspage:
        await pablo.edit(
            f"[{guess}]({fetchUrl})\n\n`Looking for this Image...`")
    else:
        await pablo.edit("`Can't find this piece of shit.`")
        return
    lim = findall(r"lim=\d+", guess)
    try:
        lim = lim[0]
        lim = lim.replace("lim=", "")
        guess = guess.replace("lim=" + lim[0], "")
    except IndexError:
        lim = 5
    response = googleimagesdownload()

    arguments = {
        "keywords": guess,
        "silent_mode": True,
        "limit": lim,
        "format": "jpg",
        "no_directory": "no_directory",
    }
    paths = response.download(arguments)
    lst = paths[0][guess]
    await pablo.edit(
        f"[{guess}]({fetchUrl})\n\n[Visually similar images]({imgspage})")
    Beast = []
    for x in lst:
        try:
            Beast.append(InputMediaPhoto(f"{x}"))
        except:
            pass
    await client.send_media_group(message.chat.id, media=Beast)
    shutil.rmtree(os.path.dirname(os.path.abspath(lst[0])))
async def youtube_dl_call_back(bot, update):
    cb_data = update.data
    # youtube_dl extractors
    tg_send_type, youtube_dl_format, youtube_dl_ext = cb_data.split("|")
    thumb_image_path = Config.DOWNLOAD_LOCATION + \
        "/" + str(update.from_user.id) + ".jpg"
    save_ytdl_json_path = Config.DOWNLOAD_LOCATION + \
        "/" + str(update.from_user.id) + ".json"
    try:
        with open(save_ytdl_json_path, "r", encoding="utf8") as f:
            response_json = json.load(f)
    except (FileNotFoundError) as e:
        await bot.delete_messages(
            chat_id=update.message.chat.id,
            message_ids=update.message.message_id,
            revoke=True
        )
        return False
    youtube_dl_url = update.message.reply_to_message.text
    custom_file_name = str(response_json.get("title")) + \
        "_" + youtube_dl_format + "." + youtube_dl_ext
    youtube_dl_username = None
    youtube_dl_password = None
    if "|" in youtube_dl_url:
        url_parts = youtube_dl_url.split("|")
        if len(url_parts) == 2:
            youtube_dl_url = url_parts[0]
            custom_file_name = url_parts[1]
        elif len(url_parts) == 4:
            youtube_dl_url = url_parts[0]
            custom_file_name = url_parts[1]
            youtube_dl_username = url_parts[2]
            youtube_dl_password = url_parts[3]
        else:
            for entity in update.message.reply_to_message.entities:
                if entity.type == "text_link":
                    youtube_dl_url = entity.url
                elif entity.type == "url":
                    o = entity.offset
                    l = entity.length
                    youtube_dl_url = youtube_dl_url[o:o + l]
        if youtube_dl_url is not None:
            youtube_dl_url = youtube_dl_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()
        logger.info(youtube_dl_url)
        logger.info(custom_file_name)
    else:
        for entity in update.message.reply_to_message.entities:
            if entity.type == "text_link":
                youtube_dl_url = entity.url
            elif entity.type == "url":
                o = entity.offset
                l = entity.length
                youtube_dl_url = youtube_dl_url[o:o + l]
    await bot.edit_message_text(
        text=Translation.DOWNLOAD_START,
        chat_id=update.message.chat.id,
        message_id=update.message.message_id
    )
    description = Translation.CUSTOM_CAPTION_UL_FILE
    if "fulltitle" in response_json:
        description = response_json["fulltitle"][0:1021]
        # escape Markdown and special characters
    tmp_directory_for_each_user = Config.DOWNLOAD_LOCATION + "/" + str(update.from_user.id)
    if not os.path.isdir(tmp_directory_for_each_user):
        os.makedirs(tmp_directory_for_each_user)
    download_directory = tmp_directory_for_each_user + "/" + custom_file_name
    command_to_exec = []
    if tg_send_type == "audio":
        command_to_exec = [
            "youtube-dl",
            "-c",
            "--max-filesize", str(Config.TG_MAX_FILE_SIZE),
            "--prefer-ffmpeg",
            "--extract-audio",
            "--audio-format", youtube_dl_ext,
            "--audio-quality", youtube_dl_format,
            youtube_dl_url,
            "-o", download_directory
        ]
    else:
        # command_to_exec = ["youtube-dl", "-f", youtube_dl_format, "--hls-prefer-ffmpeg", "--recode-video", "mp4", "-k", youtube_dl_url, "-o", download_directory]
        minus_f_format = youtube_dl_format
        if "youtu" in youtube_dl_url:
            minus_f_format = youtube_dl_format + "+bestaudio"
        command_to_exec = [
            "youtube-dl",
            "-c",
            "--max-filesize", str(Config.TG_MAX_FILE_SIZE),
            "--embed-subs",
            "-f", minus_f_format,
            "--hls-prefer-ffmpeg", youtube_dl_url,
            "-o", download_directory
        ]
    if Config.HTTP_PROXY != "":
        command_to_exec.append("--proxy")
        command_to_exec.append(Config.HTTP_PROXY)
    if youtube_dl_username is not None:
        command_to_exec.append("--username")
        command_to_exec.append(youtube_dl_username)
    if youtube_dl_password is not None:
        command_to_exec.append("--password")
        command_to_exec.append(youtube_dl_password)
    command_to_exec.append("--no-warnings")
    # command_to_exec.append("--quiet")
    logger.info(command_to_exec)
    start = datetime.now()
    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()
    t_response = stdout.decode().strip()
    logger.info(e_response)
    logger.info(t_response)
    ad_string_to_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."
    if e_response and ad_string_to_replace in e_response:
        error_message = e_response.replace(ad_string_to_replace, "")
        await bot.edit_message_text(
            chat_id=update.message.chat.id,
            message_id=update.message.message_id,
            text=error_message
        )
        return False
    if t_response:
        # logger.info(t_response)
        os.remove(save_ytdl_json_path)
        end_one = datetime.now()
        time_taken_for_download = (end_one -start).seconds
        file_size = Config.TG_MAX_FILE_SIZE + 1
        try:
            file_size = os.stat(download_directory).st_size
        except FileNotFoundError as exc:
            download_directory = os.path.splitext(download_directory)[0] + "." + "mkv"
            # https://stackoverflow.com/a/678242/4723940
            file_size = os.stat(download_directory).st_size
        if file_size > Config.TG_MAX_FILE_SIZE:
            await bot.edit_message_text(
                chat_id=update.message.chat.id,
                text=Translation.RCHD_TG_API_LIMIT.format(time_taken_for_download, humanbytes(file_size)),
                message_id=update.message.message_id
            )
        else:
            is_w_f = False
            images = await generate_screen_shots(
                download_directory,
                tmp_directory_for_each_user,
                is_w_f,
                Config.DEF_WATER_MARK_FILE,
                300,
                9
            )
            logger.info(images)
            await bot.edit_message_text(
                text=Translation.UPLOAD_START,
                chat_id=update.message.chat.id,
                message_id=update.message.message_id
            )
            # get the correct width, height, and duration for videos greater than 10MB
            # ref: message from @BotSupport
            width = 0
            height = 0
            duration = 0
            if tg_send_type != "file":
                metadata = extractMetadata(createParser(download_directory))
                if metadata is not None:
                    if metadata.has("duration"):
                        duration = metadata.get('duration').seconds
            # get the correct width, height, and duration for videos greater than 10MB
            if os.path.exists(thumb_image_path):
                width = 0
                height = 0
                metadata = extractMetadata(createParser(thumb_image_path))
                if metadata.has("width"):
                    width = metadata.get("width")
                if metadata.has("height"):
                    height = metadata.get("height")
                if tg_send_type == "vm":
                    height = width
                # 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.thumbnail((90, 90))
                if tg_send_type == "file":
                    img.resize((320, height))
                else:
                    img.resize((90, height))
                img.save(thumb_image_path, "JPEG")
                # https://pillow.readthedocs.io/en/3.1.x/reference/Image.html#create-thumbnails
                
            else:
                thumb_image_path = None
            start_time = time.time()
            # try to upload file
            if tg_send_type == "audio":
                await bot.send_audio(
                    chat_id=update.message.chat.id,
                    audio=download_directory,
                    caption=description,
                    parse_mode="HTML",
                    duration=duration,
                    # performer=response_json["uploader"],
                    # title=response_json["title"],
                    # reply_markup=reply_markup,
                    thumb=thumb_image_path,
                    reply_to_message_id=update.message.reply_to_message.message_id,
                    progress=progress_for_pyrogram,
                    progress_args=(
                        Translation.UPLOAD_START,
                        update.message,
                        start_time
                    )
                )
            elif tg_send_type == "file":
                await bot.send_document(
                    chat_id=update.message.chat.id,
                    document=download_directory,
                    thumb=thumb_image_path,
                    caption=description,
                    parse_mode="HTML",
                    # reply_markup=reply_markup,
                    reply_to_message_id=update.message.reply_to_message.message_id,
                    progress=progress_for_pyrogram,
                    progress_args=(
                        Translation.UPLOAD_START,
                        update.message,
                        start_time
                    )
                )
            elif tg_send_type == "vm":
                await bot.send_video_note(
                    chat_id=update.message.chat.id,
                    video_note=download_directory,
                    duration=duration,
                    length=width,
                    thumb=thumb_image_path,
                    reply_to_message_id=update.message.reply_to_message.message_id,
                    progress=progress_for_pyrogram,
                    progress_args=(
                        Translation.UPLOAD_START,
                        update.message,
                        start_time
                    )
                )
            elif tg_send_type == "video":
                await bot.send_video(
                    chat_id=update.message.chat.id,
                    video=download_directory,
                    caption=description,
                    parse_mode="HTML",
                    duration=duration,
                    width=width,
                    height=height,
                    supports_streaming=True,
                    # reply_markup=reply_markup,
                    thumb=thumb_image_path,
                    reply_to_message_id=update.message.reply_to_message.message_id,
                    progress=progress_for_pyrogram,
                    progress_args=(
                        Translation.UPLOAD_START,
                        update.message,
                        start_time
                    )
                )
            else:
                logger.info("Did this happen? :\\")
            end_two = datetime.now()
            time_taken_for_upload = (end_two - end_one).seconds
            #
            media_album_p = []
            if images is not None:
                i = 0
                caption = "© @TGBotsZ"
                if is_w_f:
                    caption = "/upgrade to Plan D to remove the watermark\n© @AnyDLBot"
                for image in images:
                    if os.path.exists(str(image)):
                        if i == 0:
                            media_album_p.append(
                                InputMediaPhoto(
                                    media=image,
                                    caption=caption,
                                    parse_mode="html"
                                )
                            )
                        else:
                            media_album_p.append(
                                InputMediaPhoto(
                                    media=image
                                )
                            )
                        i = i + 1
            await bot.send_media_group(
                chat_id=update.message.chat.id,
                disable_notification=True,
                reply_to_message_id=update.message.message_id,
                media=media_album_p
            )
            #
            try:
                shutil.rmtree(tmp_directory_for_each_user)
                os.remove(thumb_image_path)
            except:
                pass
            await bot.edit_message_text(
                text=Translation.AFTER_SUCCESSFUL_UPLOAD_MSG_WITH_TS.format(time_taken_for_download, time_taken_for_upload),
                chat_id=update.message.chat.id,
                message_id=update.message.message_id,
                disable_web_page_preview=True
            )
def reverse(message):
    photo = 'reverse.png'
    if path.isfile(photo):
        remove(photo)

    reverse = message.reply_to_message
    revfile = None
    if reverse and reverse.media:
        revfile = download_media_wc(reverse, photo)
    else:
        edit(message, f'`{get_translation("reverseUsage")}`')
        return

    if photo:
        edit(message, f'`{get_translation("processing")}`')
        try:
            image = Image.open(revfile)
        except OSError:
            edit(message, f'`{get_translation("reverseError")}`')
            return
        image.save(photo, 'PNG')
        image.close()
        # https://stackoverflow.com/questions/23270175/google-reverse-image-search-using-post-request#28792943
        searchUrl = 'https://www.google.com/searchbyimage/upload'
        multipart = {
            'encoded_image': (photo, open(photo, 'rb')),
            'image_content': ''
        }
        response = post(searchUrl, files=multipart, allow_redirects=False)
        fetchUrl = response.headers['Location']

        if response != 400:
            edit(message, f'`{get_translation("reverseProcess")}`')
        else:
            edit(message, f'`{get_translation("reverseGoogle")}`')
            return

        remove(photo)
        match = ParseSauce(fetchUrl + '&preferences?hl=en&fg=1#languages')
        guess = match['best_guess']
        imgspage = match['similar_images']

        if guess and imgspage:
            edit(message,
                 get_translation("reverseResult", [guess, fetchUrl, '`']))
        else:
            edit(message, f'`{get_translation("reverseError2")}`')
            return

        msg = extract_args(message)
        if len(msg) > 1 and msg.isdigit():
            lim = msg
        else:
            lim = 3
        images = scam(match, lim)
        yeet = []
        for i in range(len(images)):
            k = get(images[i])
            n = f'reverse_{i}.png'
            file = open(n, 'wb')
            file.write(k.content)
            file.close()
            yeet.append(InputMediaPhoto(n))
        reply_doc(message, yeet)
        edit(message,
             get_translation("reverseResult", [guess, fetchUrl, imgspage]))
Example #8
0
async def reverse_image_search(_, message: Message):
    if not message.reply_to_message:
        return await message.reply_text(
            "Reply to a message to reverse search it.")
    reply = message.reply_to_message
    if (not reply.document and not reply.photo and not reply.sticker
            and not reply.animation and not reply.video):
        return await message.reply_text(
            "Reply to an image/document/sticker/animation to reverse search it."
        )
    m = await message.reply_text("Searching...")
    file_id = get_file_id_from_message(reply)
    if not file_id:
        return await m.edit("Can't reverse that")
    image = await app.download_media(file_id, f"{randint(1000, 10000)}.jpg")
    async with aiofiles.open(image, "rb") as f:
        if image:
            search_url = "http://www.google.com/searchbyimage/upload"
            multipart = {
                "encoded_image": (image, await f.read()),
                "image_content": "",
            }

            def post_non_blocking():
                return requests.post(search_url,
                                     files=multipart,
                                     allow_redirects=False)

            loop = get_running_loop()
            response = await loop.run_in_executor(None, post_non_blocking)
            location = response.headers.get("Location")
            os.remove(image)
        else:
            return await m.edit("Something wrong happened.")
    headers = {
        "User-Agent":
        "Mozilla/5.0 (X11; Linux x86_64; rv:58.0) Gecko/20100101 Firefox/58.0"
    }

    try:
        soup = await get_soup(location, headers=headers)
        div = soup.find_all("div", {"class": "r5a77d"})[0]
        text = div.find("a").text
        text = f"**Result**: [{text}]({location})"
    except Exception:
        return await m.edit(
            f"**Result**: [Link]({location})",
            disable_web_page_preview=True,
        )

    # Pass if no images detected
    try:
        url = "https://google.com" + soup.find_all(
            "a", {"class": "ekf0x hSQtef"})[0].get("href")

        soup = await get_soup(url, headers=headers)

        media = []
        for img in soup.find_all("img"):
            if len(media) == 2:
                break

            if img.get("src"):
                img = img.get("src")
                if "image/gif" in img:
                    continue

                img = BytesIO(b64decode(img))
                img.name = "img.png"
                media.append(img)
            elif img.get("data-src"):
                img = img.get("data-src")
                media.append(img)

        # Cache images, so we can use file_ids
        tasks = [app.send_photo(MESSAGE_DUMP_CHAT, img) for img in media]
        messages = await gather(*tasks)

        await message.reply_media_group([
            InputMediaPhoto(
                i.photo.file_id,
                caption=text,
            ) for i in messages
        ])
    except Exception:
        pass

    await m.edit(
        text,
        disable_web_page_preview=True,
    )
    async def screenshot_fn(self, c, m):
        chat_id = m.from_user.id
        if c.CURRENT_PROCESSES.get(chat_id,
                                   0) == Config.MAX_PROCESSES_PER_USER:
            await m.answer(
                'You have reached the maximum parallel processes! Try again after one of them finishes.',
                show_alert=True)
            return

        await m.answer()
        if not c.CURRENT_PROCESSES.get(chat_id):
            c.CURRENT_PROCESSES[chat_id] = 0
        c.CURRENT_PROCESSES[chat_id] += 1

        _, num_screenshots = m.data.split('+')
        num_screenshots = int(num_screenshots)
        media_msg = m.message.reply_to_message
        if media_msg.empty:
            await m.edit_message_text(
                text=
                'Why did you delete the file 😠, Now i cannot help you 😒.'
            )
            c.CURRENT_PROCESSES[chat_id] -= 1
            return

        uid = str(uuid.uuid4())
        output_folder = Config.SCRST_OP_FLDR.joinpath(uid)
        os.makedirs(output_folder, exist_ok=True)

        if Config.TRACK_CHANNEL:
            tr_msg = await media_msg.forward(Config.TRACK_CHANNEL)
            await tr_msg.reply_text(f"User id: `{chat_id}`")

        try:
            async with timeout(Config.TIMEOUT) as cm:
                start_time = time.time()

                await m.edit_message_text(
                    text='Processing your request, Please wait! 😴')

                if media_msg.media:
                    file_link = self.generate_stream_link(media_msg)
                else:
                    file_link = media_msg.text

                await m.edit_message_text(text='😀 Generating screenshots!')

                duration = await self.get_duration(file_link)
                if isinstance(duration, str):
                    await m.edit_message_text(
                        text="😟 Sorry! I cannot open the file.")
                    l = await media_msg.forward(Config.LOG_CHANNEL)
                    await l.reply_text(
                        f'stream link : {file_link}\n\nRequested screenshots: {num_screenshots}.\n\n{duration}',
                        True)
                    c.CURRENT_PROCESSES[chat_id] -= 1
                    shutil.rmtree(output_folder, ignore_errors=True)
                    return

                log.info(
                    f"Generating {num_screenshots} screenshots from location: {file_link} for {chat_id}"
                )

                reduced_sec = duration - int(duration * 2 / 100)
                screenshots = []
                watermark = await c.db.get_watermark_text(chat_id)
                as_file = await c.db.is_as_file(chat_id)
                screenshot_mode = await c.db.get_screenshot_mode(chat_id)
                ffmpeg_errors = ''
                if watermark:
                    watermark_color_code = await c.db.get_watermark_color(
                        chat_id)
                    watermark_color = Config.COLORS[watermark_color_code]
                    watermark_position = await c.db.get_watermark_position(
                        chat_id)
                    font_size = await c.db.get_font_size(chat_id)
                    width, height = await self.get_dimentions(file_link)
                    fontsize = int((math.sqrt(width**2 + height**2) / 1388.0) *
                                   Config.FONT_SIZES[font_size])
                    x_pos, y_pos = self.get_watermark_coordinates(
                        watermark_position, width, height)
                    watermark_options = f'drawtext=fontcolor={watermark_color}:fontsize={fontsize}:x={x_pos}:y={y_pos}:text={watermark}, scale=1280:-1'

                if screenshot_mode == 0:
                    screenshot_secs = [
                        int(reduced_sec / num_screenshots) * i
                        for i in range(1, 1 + num_screenshots)
                    ]
                else:
                    screenshot_secs = [
                        self.get_random_start_at(reduced_sec)
                        for i in range(1, 1 + num_screenshots)
                    ]

                for i, sec in enumerate(screenshot_secs):
                    thumbnail_template = output_folder.joinpath(f'{i+1}.png')
                    ffmpeg_cmd = [
                        'ffmpeg', '-headers', f'IAM:{Config.IAM_HEADER}',
                        '-hide_banner', '-ss',
                        str(sec), '-i', file_link, '-vf'
                    ]
                    if watermark:
                        ffmpeg_cmd.append(watermark_options)
                    else:
                        ffmpeg_cmd.append('scale=1280:-1')
                    ffmpeg_cmd += [
                        '-y', '-vframes', '1',
                        str(thumbnail_template)
                    ]

                    log.debug(ffmpeg_cmd)
                    output = await self.run_subprocess(ffmpeg_cmd)
                    log.debug(output)
                    await m.edit_message_text(
                        text=f'😀 `{i+1}` of `{num_screenshots}` generated!')
                    if thumbnail_template.exists():
                        if as_file:
                            screenshots.append({
                                'document':
                                str(thumbnail_template),
                                'caption':
                                f"ScreenShot at {datetime.timedelta(seconds=sec)}"
                            })
                        else:
                            screenshots.append(
                                InputMediaPhoto(
                                    str(thumbnail_template),
                                    caption=
                                    f"ScreenShot at {datetime.timedelta(seconds=sec)}"
                                ))
                        continue
                    ffmpeg_errors += output[0].decode(
                    ) + '\n' + output[1].decode() + '\n\n'

                if not screenshots:
                    await m.edit_message_text(
                        text=
                        '😟 Sorry! Screenshot generation failed possibly due to some infrastructure failure 😥.'
                    )
                    l = await media_msg.forward(Config.LOG_CHANNEL)
                    if ffmpeg_errors:
                        error_file = io.BytesIO()
                        error_file.name = f"{uid}-errors.txt"
                        error_file.write(ffmpeg_errors.encode())
                        await l.reply_document(
                            error_file,
                            caption=
                            f"stream link : {file_link}\n\n{num_screenshots} screenshots where requested and Screen shots where not generated."
                        )
                    else:
                        await l.reply_text(
                            f'stream link : {file_link}\n\n{num_screenshots} screenshots where requested and Screen shots where not generated.',
                            True)
                    c.CURRENT_PROCESSES[chat_id] -= 1
                    shutil.rmtree(output_folder, ignore_errors=True)
                    return

                await m.edit_message_text(
                    text=
                    f'🤓 You requested {num_screenshots} screenshots and {len(screenshots)} screenshots generated, Now starting to upload!'
                )

                await media_msg.reply_chat_action("upload_photo")

                if as_file:
                    aws = [
                        media_msg.reply_document(quote=True, **photo)
                        for photo in screenshots
                    ]
                    await asyncio.gather(*aws)
                else:
                    await media_msg.reply_media_group(screenshots, True)
                await m.edit_message_text(
                    text=
                    f'Successfully completed process in {datetime.timedelta(seconds=int(time.time()-start_time))}\n\nIf You find me helpful, please rate me [here](tg://resolve?domain=botsarchive&post=1206),'
                )
        except (asyncio.TimeoutError, asyncio.CancelledError):
            await m.edit_message_text(
                text=
                '😟 Sorry! Video trimming failed due to timeout. Your process was taking too long to complete, hence cancelled'
            )
        except Exception as e:
            log.error(e, exc_info=True)
            await m.edit_message_text(
                text=
                '😟 Sorry! Screenshot generation failed possibly due to some infrastructure failure 😥.'
            )

            l = await media_msg.forward(Config.LOG_CHANNEL)
            await l.reply_text(
                f'{num_screenshots} screenshots where requested and some error occoured\n\n{traceback.format_exc()}',
                True)
        finally:
            c.CURRENT_PROCESSES[chat_id] -= 1
            shutil.rmtree(output_folder, ignore_errors=True)
Example #10
0
async def primary_task(client: Client, msg: Message, queue=[]) -> None:
    _pid = randint(100, 999)
    link = msg.reply_to_message.text
    queue.append(link)
    LOGGER.debug(f'WEB_SCRS:{_pid} --> new request >> processing settings')
    if len(queue) > 2:
        await msg.edit("<b>You are in the queue wait for a bit ;)</b>")
        while len(queue) > 2:
            await asyncio.sleep(2)
    random_message = await msg.edit(text='<b><i>processing...</b></i>')
    printer = await settings_parser(link, msg.reply_markup.inline_keyboard,
                                    _pid)
    # logging the request into a specific group or channel
    try:
        log = int(os.environ["LOG_GROUP"])
        LOGGER.debug(
            f'WEB_SCRS:{printer.PID} --> LOG GROUP FOUND >> sending log')
        await client.send_message(
            log, f'```{msg.chat.username}```\n{printer.__str__()}')
    except Exception as e:
        LOGGER.debug(f'WEB_SCRS:{printer.PID} --> LOGGING FAILED >> {e}')
    await random_message.edit(text='<b><i>rendering.</b></i>')
    # await browser.close()
    try:
        out = io.BytesIO(await screenshot_driver(printer))
        out.name = printer.name
    except Exception as e:
        await random_message.edit(f'<b>{e}</b>')
        queue.remove(link)
        return
    await random_message.edit(text='<b><i>rendering..</b></i>')
    if printer.split and printer.fullpage:
        LOGGER.debug(
            f'WEB_SCRS:{printer.PID} --> split setting detected -> spliting images'
        )
        await random_message.edit(text='<b><i>spliting images...</b></i>')
        location_of_image = await split_func(out, printer.type)
        LOGGER.debug(f'WEB_SCRS:{printer.PID} --> image splited successfully')
        # spliting finished
        if len(location_of_image) > 10:
            LOGGER.debug(
                f'WEB_SCRS:{printer.PID} --> found split pieces more than 10 >> zipping file'
            )
            await random_message.edit(
                text='<b>detected images more than 10\n\n<i>Zipping...</i></b>'
            )
            await asyncio.sleep(0.1)
            # zipping if length is too high
            zipped_file = await zipper(location_of_image)
            LOGGER.debug(
                f'WEB_SCRS:{printer.PID} --> zipping completed >> sending file'
            )
            #  finished zipping and sending the zipped file as document
            out = zipped_file
        else:
            # sending as media group if files are not too long
            # pyrogram doesnt support InputMediaPhotot to use BytesIO
            # until its added to the library going for temporary fix
            # starting folder creartion with message id
            if not os.path.isdir('./FILES'):
                LOGGER.debug(
                    f'WEB_SCRS:{printer.PID} --> ./FILES folder not found >> creating new '
                )
                os.mkdir('./FILES')
            location = f"./FILES/{str(msg.chat.id)}/{str(msg.message_id)}"
            if not os.path.isdir(location):
                LOGGER.debug(
                    f'WEB_SCRS:{printer.PID} --> user folder not found >> creating {location}'
                )
                os.makedirs(location)
            LOGGER.debug(
                f'WEB_SCRS:{printer.PID} --> sending split pieces as media group'
            )
            for byte_objects in location_of_image:
                with open(f'{location}/{byte_objects.name}', 'wb') as writer:
                    writer.write(byte_objects.getvalue())
                byte_objects.close()
            await random_message.edit(text='<b><i>uploading...</b></i>')
            location_to_send = []
            for count, images in enumerate(location_of_image, start=1):
                location_to_send.append(
                    InputMediaPhoto(media=f'{location}/{images.name}',
                                    caption=str(count)))
            # sending 10 at a time
            await client.send_chat_action(msg.chat.id, "upload_photo")
            await client.send_media_group(media=location_to_send,
                                          chat_id=msg.chat.id,
                                          disable_notification=True)
            shutil.rmtree(location)
            LOGGER.debug(
                f'WEB_SCRS:{printer.PID} --> mediagroup send successfully >> request statisfied'
            )
            queue.remove(link)
            return
    if not printer.fullpage and not printer.type == 'pdf':
        LOGGER.debug(
            f'WEB_SCRS:{printer.PID} --> split setting not found >> sending directly'
        )
        await random_message.edit(text='<b><i>uploading...</b></i>')
        await client.send_chat_action(msg.chat.id, "upload_photo")
        await client.send_photo(photo=out, chat_id=msg.chat.id)
        LOGGER.info(
            f'WEB_SCRS:{printer.PID} --> photo send successfully >> request statisfied'
        )
    if (printer.type == 'pdf' or printer.fullpage):
        await client.send_chat_action(msg.chat.id, "upload_document")
        await client.send_document(document=out, chat_id=msg.chat.id)
        LOGGER.debug(
            f'WEB_SCRS:{printer.PID} --> document send successfully >> request statisfied'
        )
    await random_message.delete()
    queue.remove(link)
async def cb_(client, callback_query, retry=False):
    cb_data = callback_query.data
    msg = callback_query.message
    if (cb_data == "render"
            or cb_data == 'cancel' or cb_data == 'statics'):
        pass
    else:
        # cause @Spechide said so
        await client.answer_callback_query(
            callback_query.id,
        )
    if cb_data == "render":
        await client.answer_callback_query(
            callback_query.id,
            text='Processing your request..!'
        )
        LOGGER.debug('WEB_SCRS --> new request >> processing settings')
        random_message = await msg.edit(text='<b><i>Processing...</b></i>')
        link = msg.reply_to_message.text
        # starting to recognize settings
        background, split, resolution = False, False, False
        for_logging = ""
        for settings in msg.reply_markup.inline_keyboard:
            if "Format" in settings[0].text:
                format = settings[0].text.split('-', 1)[1].strip()
            if "Page" in settings[0].text:
                page = settings[0].text.split('-', 1)[1].strip()
                page_value = True if 'Full' in page else False
            if "Split" in settings[0].text:
                split_boolean = settings[0].text.split('-', 1)[1].strip()
                split = True if 'Yes' in split_boolean else False
            if "wait" in settings[0].text:
                timer = settings[0].text.split('|', 1)[1].strip().strip('s')
                background = False if 'default' in timer else True
            if "resolution" in settings[0].text:
                resolution = settings[0].text.split('|', 1)[1].strip()
            for_logging += settings[0].text + '\n'
        LOGGER.debug(f'WEB_SCRS --> setting confirmation >> ({format}|{page})')
        # logging the request into a specific group or channel
        try:
            LOGGING_GROUP = int(os.environ["LOG_GROUP"])
            LOGGER.debug('WEB_SCRS --> LOG GROUP FOUND >> sending log')
            await client.send_message(
                chat_id=LOGGING_GROUP,
                text=format_for_logging.format(
                    name=msg.chat.first_name,
                    user=msg.chat.username,
                    link=link,
                    settings=for_logging
                    ),
                disable_web_page_preview=True
            )
        except Exception as e:
            LOGGER.debug(f'WEB_SCRS --> LOGGING FAILED >> {e}')
        # opening chrome bin
        try:
            LOGGER.debug('WEB_SCRS --> launching chrome')
            browser = await launch(
                headless=True,
                executablePath=EXEC_PATH
                )
            LOGGER.debug('WEB_SCRS --> fetching received link')
            page = await browser.newPage()
            await page.goto(link)
            LOGGER.debug('WEB_SCRS --> link fetched successfully')
            await asyncio.sleep(2)
            # implementing the settings
            await random_message.edit(text='<b><i>Rendering</b></i>')
            LOGGER.debug('WEB_SCRS --> configuring resolution settings')
            if format == 'jpeg' or format == 'PNG':
                LOGGER.debug('WEB_SCRS --> rendering as photo >> request statisfied')
                arguments_for_photo = {}
                # configuring resolution
                if resolution:
                    if '1280' in resolution:
                        res = {'width': 1280, 'height': 720}
                    elif '2560' in resolution:
                        res = {'width': 2560, 'height': 1440}
                    elif '640' in resolution:
                        res = {'width': 640, 'height': 480}
                    else:
                        res = {'width': 800, 'height': 600}
                    await page.setViewport(res)
                # configure btw Partial/fullpage
                LOGGER.debug('WEB_SCRS --> configuring pagesize settings')
                if page_value:
                    arguments_for_photo['fullPage'] = True
                await random_message.edit(text='<b><i>Rendering.</b></i>')
                # naming for the output file
                LOGGER.debug('WEB_SCRS --> configuring output file')
                if format == 'jpeg':
                    out_filename = '@Webs.ScreenCapture.JPEG'
                    arguments_for_photo['type'] = 'jpeg'
                if format == 'PNG':
                    out_filename = '@Webs.ScreenCapture.PNG'
                    arguments_for_photo['type'] = 'png'
                await random_message.edit(text='<b><i>Rendering...</b></i>')
                if background:
                    await asyncio.sleep(3)
                # taking screenshot and closing the browser
                LOGGER.debug('WEB_SCRS --> taking screenshot using bin')
                bytesfile = await page.screenshot(arguments_for_photo)
                LOGGER.debug('WEB_SCRS --> closing chrome binary')
                await browser.close()
                LOGGER.debug('WEB_SCRS --> chrome bin closed successfully')
                # spliting the image
                with io.BytesIO(bytesfile) as out:
                    out.name = out_filename
                    if split and page_value:
                        LOGGER.debug('WEB_SCRS --> split setting detected -> spliting images')
                        await random_message.edit(text='<b><i>Spliting Images...</b></i>')
                        # https://stackoverflow.com/questions/25705773/image-cropping-tool-python
                        Image.MAX_IMAGE_PIXELS = None
                        # https://coderwall.com/p/ovlnwa/use-python-and-pil-to-slice-an-image-vertically
                        location_of_image = []
                        img = Image.open(out)
                        width, height = img.size
                        upper, left, count, slice_size = 0, 0, 1, 800
                        slices = int(math.ceil(height/slice_size))
                        for _ in range(slices):
                            # if we are at the end, set the lower bound to be the bottom of the image
                            if count == slices:
                                lower = height
                            else:
                                lower = int(count * slice_size)
                            bbox = (left, upper, width, lower)
                            working_slice = img.crop(bbox)
                            upper += slice_size
                            # saving = the slice
                            if 'jpeg' in format:
                                location_to_save_slice = f'@Webs.ScreenCapture-{str(count)}.jpeg'
                            else:
                                location_to_save_slice = f'@Webs.ScreenCapture-{str(count)}.png'
                            split_out = io.BytesIO()
                            split_out.name = location_to_save_slice
                            working_slice.save(fp=split_out, format=arguments_for_photo['type'])
                            location_of_image.append(split_out)
                            count += 1
                        LOGGER.debug(f'WEB_SCRS --> image splited successfully >> total piece({count})')
                        out.close()
                        # spliting finished
                        if len(location_of_image) > 20:
                            LOGGER.debug('WEB_SCRS --> found split pieces more than 20 >> zipping file')
                            await random_message.edit(text='<b>detected images more than 20\n\n<i>Zipping...</i></b>')
                            await asyncio.sleep(1)
                            # zipping if length is too high
                            # https://stackoverflow.com/a/44946732/13033981
                            zipped_file = io.BytesIO()
                            with ZipFile(zipped_file, 'w') as zipper:
                                for files in location_of_image:
                                    zipper.writestr(files.name, files.getvalue())
                                    files.close()
                            zipped_file.name = "@Webs-Screenshot.zip"
                            LOGGER.debug('WEB_SCRS --> zipping completed >> sending file')
                            #  finished zipping and sending the zipped file as document
                            await random_message.edit(text='<b><i>Uploading...</b></i>')
                            await client.send_chat_action(
                                msg.chat.id,
                                "upload_document"
                                )
                            await client.send_document(
                                document=zipped_file,
                                chat_id=msg.chat.id,
                                reply_to_message_id=msg.reply_to_message.message_id
                                )
                            LOGGER.debug('WEB_SCRS --> file send successfully >> request statisfied')
                            zipped_file.close()
                        # sending as media group if files are not too long
                        # pyrogram doesnt support InputMediaPhotot to use BytesIO
                        # until its added to the library going for temporary fix
                        else:
                            # starting folder creartion with message id
                            if not os.path.isdir('./FILES'):
                                LOGGER.debug('WEB_SCRS --> ./FILES folder not found >> creating new ')
                                os.mkdir('./FILES')
                            location = f"./FILES/{str(msg.chat.id)}/{str(msg.message_id)}"
                            if not os.path.isdir(location):
                                LOGGER.debug(f'WEB_SCRS --> user folder not found >> creating {location}')
                                os.makedirs(location)
                            LOGGER.debug('WEB_SCRS --> sending split pieces as media group')
                            for byte_objects in location_of_image:
                                with open(f'{location}/{byte_objects.name}', 'wb') as writer:
                                    writer.write(byte_objects.getvalue())
                                byte_objects.close()
                            await random_message.edit(text='<b><i>Uploading...</b></i>')
                            location_to_send = []
                            for count, images in enumerate(location_of_image, start=1):
                                location_to_send.append(InputMediaPhoto(
                                    media=f'{location}/{images.name}',
                                    caption=str(count)
                                    ))
                            sent_so_far = 0
                            # sending 10 at a time
                            while sent_so_far <= len(location_to_send):
                                await client.send_chat_action(
                                    msg.chat.id,
                                    "upload_photo"
                                    )
                                await client.send_media_group(
                                    media=location_to_send[sent_so_far:sent_so_far+10],
                                    chat_id=msg.chat.id,
                                    reply_to_message_id=msg.reply_to_message.message_id,
                                    disable_notification=True
                                    )
                                sent_so_far += 10
                                await asyncio.sleep(0.5)
                            shutil.rmtree(location)
                            LOGGER.debug('WEB_SCRS --> mediagroup send successfully >> request statisfied')
                        # closing every Bytesio to save memory
                        [x.close() for x in location_of_image]
                    # if split is not selected
                    else:
                        LOGGER.debug('WEB_SCRS --> split setting not found >> sending directly')
                        await random_message.edit(text='<b><i>Uploading...</b></i>')
                        if not page_value:
                            await client.send_chat_action(
                                msg.chat.id,
                                "upload_photo"
                                )
                            await client.send_photo(
                                photo=out,
                                chat_id=msg.chat.id,
                                reply_to_message_id=msg.reply_to_message.message_id
                                )
                            LOGGER.debug('WEB_SCRS --> photo send successfully >> request statisfied')
                        else:
                            await client.send_chat_action(
                                msg.chat.id,
                                "upload_document"
                                )
                            await client.send_document(
                                document=out,
                                chat_id=msg.chat.id,
                                reply_to_message_id=msg.reply_to_message.message_id
                                )
                            LOGGER.debug('WEB_SCRS --> document send successfully >> request statisfied')
                await asyncio.sleep(1)
                await random_message.delete()
                out.close()
            # configuring pdf settings
            else:
                LOGGER.debug('WEB_SCRS --> rendering as PDF >> processing settings')
                await random_message.edit(text='<b><i>Rendering.</b></i>')
                arguments_for_pdf = {}
                if resolution:
                    if '1280' in resolution:
                        arguments_for_pdf = {'width': 1280, 'height': 720}
                    elif '2560' in resolution:
                        # cause asked by <ll>//𝚂𝚊𝚢𝚊𝚗𝚝𝚑//<ll>
                        arguments_for_pdf = {'width': 2560, 'height': 1440}
                    elif '640' in resolution:
                        arguments_for_pdf = {'width': 640, 'height': 480}
                    else:
                        arguments_for_pdf = {'width': 800, 'height': 600}
                arguments_for_pdf['format'] = 'Letter'
                arguments_for_pdf['displayHeaderFooter'] = True
                arguments_for_pdf['margin'] = {"bottom": 70, "left": 25, "right": 35, "top": 40}
                await page.emulateMedia('screen')
                if not page_value:
                    arguments_for_pdf['pageRanges'] = '1-2'
                LOGGER.debug('WEB_SCRS --> configuration successfull >> waiting to render')
                if background:
                    await random_message.edit(text='<b><i>Rendering..</b></i>')
                    await asyncio.sleep(3)
                    arguments_for_pdf['printBackground'] = True
                await random_message.edit(text='<b><i>Rendering...</b></i>')
                LOGGER.debug('WEB_SCRS --> rendering pdf')
                bytes_pdf = await page.pdf(arguments_for_pdf)
                await browser.close()
                LOGGER.debug('WEB_SCRS --> PDF rendered >> closing bin')
                await random_message.edit(text='<b><i>Uploading...</b></i>')
                await client.send_chat_action(
                        msg.chat.id,
                        "upload_document"
                        )
                with io.BytesIO(bytes_pdf) as out:
                    out.name = "@Webs.ScreenCapture.pdf"
                    await client.send_document(
                            document=out,
                            chat_id=msg.chat.id,
                            reply_to_message_id=msg.reply_to_message.message_id
                            )
                LOGGER.debug('WEB_SCRS --> PDF document send successfully >> request statisfied')
                await random_message.delete()
                await asyncio.sleep(1)
        except errors.PageError:
            LOGGER.debug('WEB_SCRS --> request failed -> Excepted PageError >> invalid link')
            await msg.edit(text='Not a valid link 😓🤔')
            await browser.close()
            return
        except BadStatusLine:
            await browser.close()
            if not retry:
                LOGGER.debug('WEB_SCRS --> request failed -> Excepted BadStatusLine >> retrying...')
                await msg.edit("<b>Site Error\nRetrying....</b>")
                await asyncio.sleep(4)
                await cb_(client, callback_query, retry=True)
            elif retry:
                LOGGER.debug('WEB_SCRS --> request failed -> Excepted BadStatusLine >> max retry exceeded')
                await msg.edit("<b>Soory the site is not responding</b>")
                return False
        except ModuleNotFoundError as e:
            await browser.close()
            LOGGER.debug(f'WEB_SCRS --> request failed -> Excepted {e}')
            await msg.reply_to_message.reply_text(
                f'''something went wrong\n
<b>reason:</b>\n\n<code>{e}</code>\n
<i>do a anonymous reporting to the developer
by tagging this message and use <code>/report</code> command</i>\n\n
retry if possible...''',
                quote=True
                )

    elif cb_data == "splits":
        if "PDF" not in msg.reply_markup.inline_keyboard[0][0].text:
            index_number = 1
        current_boolean = msg.reply_markup.inline_keyboard[index_number][0]
        boolean_to_change = 'Split - No' if "Yes" in current_boolean.text else 'Split - Yes'
        msg.reply_markup.inline_keyboard[index_number][0]['text'] = boolean_to_change
        await msg.edit(text='Choose the prefered settings', reply_markup=msg.reply_markup)

    elif cb_data == "page":
        if 'PDF' in msg.reply_markup.inline_keyboard[0][0].text:
            index_number = 1
        else:
            index_number = 2
        current_page = msg.reply_markup.inline_keyboard[index_number][0]
        page_to_change = "Page - Partial" if "Full" in current_page.text else "Page - Full"
        msg.reply_markup.inline_keyboard[index_number][0]['text'] = page_to_change
        await msg.edit(text='Choose the prefered settings', reply_markup=msg.reply_markup)

    elif cb_data == 'timer':
        current_time = msg.reply_markup.inline_keyboard[-4][0].text
        time_to_change = "wait for | BackgroundToLoad" if 'default' in current_time else "wait for | default"
        msg.reply_markup.inline_keyboard[-4][0]['text'] = time_to_change
        await msg.edit(text='Choose the prefered settings', reply_markup=msg.reply_markup)

    elif cb_data == 'options':
        current_option = msg.reply_markup.inline_keyboard[-3][0].text
        options_to_change = "hide additional options ˄" if 'show' in current_option else 'show additional options ˅'
        if 'hide' in options_to_change:
            msg.reply_markup.inline_keyboard.insert(
                -2,
                [InlineKeyboardButton(text="resolution | 800x600", callback_data='res')]
            )
            msg.reply_markup.inline_keyboard.insert(
                -2,
                [InlineKeyboardButton(text='wait for | default', callback_data="timer")],
            )
            msg.reply_markup.inline_keyboard.insert(
                -2,
                [InlineKeyboardButton(text='▫️ site statitics ▫️', callback_data="statics")],
            )
            if 'PDF' in msg.reply_markup.inline_keyboard[0][0].text:
                index_to_change = 2
            else:
                index_to_change = 3
            msg.reply_markup.inline_keyboard[index_to_change][0]['text'] = options_to_change

        else:
            for _ in range(3):
                msg.reply_markup.inline_keyboard.pop(-3)
            msg.reply_markup.inline_keyboard[-3][0]['text'] = options_to_change
        await msg.edit(text='Choose the prefered settings', reply_markup=msg.reply_markup)

    elif cb_data == "res":
        current_res = msg.reply_markup.inline_keyboard[-5][0].text
        if '800' in current_res:
            res_to_change = "resolution | 1280x720"
        elif '1280' in current_res:
            # cause asked by <ll>//𝚂𝚊𝚢𝚊𝚗𝚝𝚑//<ll>
            res_to_change = "resolution | 2560x1440"
        elif '2560' in current_res:
            res_to_change = "resolution | 640x480"
        else:
            res_to_change = "resolution | 800x600"
        msg.reply_markup.inline_keyboard[-5][0]['text'] = res_to_change
        await msg.edit(text='Choose the prefered settings', reply_markup=msg.reply_markup)

    elif cb_data == "format":
        current_format = msg.reply_markup.inline_keyboard[0][0]
        if 'PDF' in current_format.text:
            format_to_change = 'Format - PNG'
        elif 'PNG' in current_format.text:
            format_to_change = 'Format - jpeg'
        elif 'jpeg' in current_format.text:
            format_to_change = 'Format - PDF'
        msg.reply_markup.inline_keyboard[0][0]['text'] = format_to_change
        if "PNG" in format_to_change:
            msg.reply_markup.inline_keyboard.insert(
                1,
                [InlineKeyboardButton(text="Split - No", callback_data='splits')]
            )
        if 'PDF' in format_to_change:
            if "Split" in msg.reply_markup.inline_keyboard[1][0].text:
                msg.reply_markup.inline_keyboard.pop(1)
        await msg.edit(text='Choose the prefered settings', reply_markup=msg.reply_markup)

    elif cb_data == "cancel":
        await client.answer_callback_query(
            callback_query.id,
            text='Canceled your request..!'
        )
        await msg.delete()
    elif cb_data == 'statics':
        await client.answer_callback_query(
            callback_query.id,
            text='Soory this features is not implemented yet😫😢😬!',
            show_alert=True
        )
    elif cb_data == 'deleteno' or cb_data == 'deleteyes':
        if cb_data == 'deleteno':
            await msg.edit(text='process canceled')
            await asyncio.sleep(2)
            await msg.delete()
        else:
            await msg.edit(text='deleteing')
            try:
                shutil.rmtree('./FILES/')
            except Exception as e:
                await msg.edit(text=e)
            finally:
                await asyncio.sleep(2)
                await msg.delete()
Example #12
0
async def anime_scan(bot: Amime, message: Message):
    reply = message.reply_to_message
    lang = message._lang

    if reply.from_user.id == bot.me.id:
        return

    if not reply.media:
        await message.reply_text(lang.media_not_found_text)
        return

    media = (reply.photo or reply.sticker or reply.animation or reply.document
             or reply.video)

    if isinstance(media, (Document, Video)):
        if bool(media.thumbs) and len(media.thumbs) > 0:
            media = media.thumbs[0]
        else:
            return

    sent = await message.reply_photo("https://i.imgur.com/m0N2pFc.jpg",
                                     caption=lang.scanning_media_text)

    path = await bot.download_media(media)

    async with httpx.AsyncClient(http2=True) as client:
        try:
            response = await client.post(
                "https://api.trace.moe/search?anilistInfo&cutBorders",
                files=dict(image=open(path, "rb")),
                timeout=20.0,
            )
        except httpx.TimeoutException:
            await sent.edit_text(lang.timed_out_text)
            return

        if response.status_code == 200:
            pass
        elif response.status_code == 429:
            await sent.edit_text(lang.api_overuse_text)
            return
        else:
            await sent.edit_text(lang.api_down_text)
            return

        data = response.json()
        results = data["result"]
        if len(results) == 0:
            await sent.edit_text(lang.no_results_text)
            return

        result = results[0]

        video = result["video"]
        to_time = result["to"]
        episode = result["episode"]
        anilist_id = result["anilist"]["id"]
        file_name = result["filename"]
        from_time = result["from"]
        similarity = result["similarity"]
        title_native = result["anilist"]["title"]["native"]
        title_romaji = result["anilist"]["title"]["romaji"]

        text = f"<b>{title_romaji}</b>"
        if bool(title_native):
            text += f" (<code>{title_native}</code>)"
        text += "\n"
        text += f"\n<b>ID</b>: <code>{anilist_id}</code>"
        if episode is not None:
            text += f"\n<b>{lang.episode}</b>: <code>{episode}</code>"
        text += (
            f"\n<b>{lang.similarity}</b>: <code>{round(similarity * 100, 2)}%</code>"
        )

        sent = await sent.edit_media(
            InputMediaPhoto(
                f"https://img.anili.st/media/{anilist_id}",
                text,
            ),
            reply_markup=ikb([[
                (lang.view_more_button, f"anime {anilist_id}"),
            ]]),
        )

        if video is not None:
            try:
                sent_video = await sent.reply_video(
                    video,
                    caption=
                    f"<code>{file_name}</code>\n\n<code>{pendulum.from_timestamp(from_time).to_time_string()}</code> - <code>{pendulum.from_timestamp(to_time).to_time_string()}</code>",
                )

                keyboard = bki(sent.reply_markup)
                keyboard[0].append(("📹 Preview", sent_video.link, "url"))
                await sent.edit_reply_markup(reply_markup=ikb(keyboard), )
            except BaseException:
                pass

        await client.aclose()

    os.remove(path)
Example #13
0
async def events_callback(cli: Client, callback: CallbackQuery) -> None:
    if callback.data == "agenda":
        buttons = [{
            "格萊聽": "agenda_great",
            "天漾聽": "agenda_skyview",
        }, {
            "康定聽": "agenda_kd",
            "天悅聽": "agenda_ty",
            "萬大聽": "agenda_wd"
        }, {
            "Day 1": "agenda_Day1",
            "Day 2": "agenda_Day2"
        }, {
            "回主選單": "help"
        }]

        media = InputMediaPhoto("https://i.imgur.com/jDeodyc.jpg",
                                "議程總覽\n你想看哪個演講廳")

    elif callback.data == "agenda_great":
        buttons = [{
            "金融業如何迎擊數位戰場": "agenda_great_1A",
            "Breaking Samsung's Root": "agenda_great_2A"
        }, {
            "主動式資安防禦策略": "agenda_great_1B",
            "From LNK to RCE": "agenda_great_2B"
        }, {
            "如何兼顧疫情控制與隱私保護": "agenda_great_1C",
            "RE: 從零開始的 OOO DEF": "agenda_great_2C"
        }, {
            "疫情後資安人才培育的挑戰": "agenda_great_1D",
            "Development of Signaling Spoofing": "agenda_great_2D"
        }, {
            "人工智慧能否為人類指引": "agenda_great_1E",
            "How I Hacked Facebook Again!": "agenda_great_2E"
        }, {
            "回議程總覽": "agenda"
        }]

        media = InputMediaPhoto("https://i.imgur.com/7JFS5PL.png",
                                "格萊聽議程總覽\n請選擇 XXX")

    elif callback.data == "agenda_Day1":
        buttons = [{
            "11:00 - 11:50": "agenda_Day1A",
            "13:00 - 13:50": "agenda_Day1B",
        }, {
            "14:00 - 14:50": "agenda_Day1C",
        }, {
            "15:30 - 16:20": "agenda_Day1D",
            "16:30 - 17:20": "agenda_Day1E"
        }, {
            "回議程總覽": "agenda"
        }]

        media = InputMediaPhoto("https://i.imgur.com/SsAfqPg.png",
                                "Day 1 議程總覽\n請選擇時段")

    elif callback.data == "agenda_Day2":
        buttons = [{
            "09:20 - 10:10": "agenda_Day2A",
            "10:20 - 11:10": "agenda_Day2B",
        }, {
            "11:20 - 12:10": "agenda_Day2C",
        }, {
            "13:50 - 14:40": "agenda_Day2D",
            "14:50 - 15:40": "agenda_Day2E",
        }, {
            "回議程總覽": "agenda"
        }]

        media = InputMediaPhoto("https://i.imgur.com/T2WWUla.png",
                                "Day 2 議程總覽\n請選擇時段")

    elif callback.data == "agenda_Day1A":
        buttons = [{
            "金融業如何迎擊數位戰場的第一道烽火": "agenda_Day1A1",
            "通訊網路安全研究,從 GSM 到 5G NR": "agenda_Day1B2",
        }, {
            "練蠱大賽": "agenda_Day1C3",
        }, {
            "A Million Boluses: Discovery and Disclosure": "agenda_Day1D4",
            "IoT Hacking 101": "agenda_Day1E5"
        }, {
            "回 Day 1 議程": "agenda_Day1"
        }]

        media = InputMediaPhoto("https://i.imgur.com/IicQq8u.png",
                                "Day 1 上午 11:00 - 11:50 議程\n請選擇場次")

    elif callback.data in ["agenda_great_1A", "agenda_Day1A1"]:
        buttons = [{
            "Slido": "https://app.sli.do/event/ycm3yt5t",
            "議程共筆": "https://hackmd.io/FHbMehMSTsSq0aulU7GlKQ",
            "會場地圖": "map_13F",
        }, {
            "回到格萊聽": "agenda_great",
            "同時段議程": "agenda_Day1A",
        }]

        media = InputMediaPhoto(
            "https://i.imgur.com/WmTrCaK.png",
            "<b>[ HITCON 論壇 ] 金融業如何迎擊數位戰場的第一道烽火</b>\n\n 金融業是全國資安首當其衝的攻擊熱點,各單位的資安策略及措施,也非常適合各產業企業做為參考,有做為標竿的作用。本次探討的方向會針對「防禦機制的有效性評估」、「供應鏈安全」、「資安策略及預算投放」進行,以期透過這樣的討論讓聽眾知道金融機構資安的超前部署,增加民眾對資安的信心,也做為其他業者的表率。"
        )

    else:
        log.debug(f"Unknown callback {callback.data}")
        await cli.answer_callback_query(callback.id, f"尚未實作 {callback.data}")
        return

    keyboard = []
    for k in buttons:
        row = []
        for txt in k:
            if 'https://' in k[txt]:
                button = InlineKeyboardButton(text=txt, url=k[txt])
            else:
                button = InlineKeyboardButton(text=txt, callback_data=k[txt])
            row.append(button)
        keyboard.append(row)

    await cli.edit_message_media(callback.message.chat.id,
                                 callback.message.message_id,
                                 media=media,
                                 reply_markup=InlineKeyboardMarkup(keyboard))

    await cli.answer_callback_query(callback.id)
Example #14
0
async def open_stories(_, callback):
    username = callback.data.split(' ')[1]

    language = get_language(callback.from_user.id,
                            callback.from_user.language_code)

    key = f"{callback.message.chat.id}_{callback.message.message_id}"

    profile: Profile = cached_profiles.get(key)
    right_user_id = cached_ids.get(key)

    if profile is None or right_user_id is None:
        await callback.answer(get_message(language, "errors/no_cached_post"),
                              show_alert=True)
        await callback.edit_message_text("", reply_markup="")
        return

    if callback.from_user.id != right_user_id:
        await callback.answer(get_message(language, 'errors/wrong_id'),
                              show_alert=True)
        return

    iterator: StoriesIterator = cached_stories.get(key)

    if iterator is None:
        user = get_user_id(username)

        if "username" not in user:
            await callback.answer(get_message(language, "errors/fail"))
            return

        stories = _request_story(user["user_id"])

        if stories == "private_account":
            await callback.answer(
                get_message(language, "errors/private_account"))
            return

        if stories == "no_stories":
            await callback.answer(get_message(language, "errors/no_stories"))
            return

        iterator = StoriesIterator(stories, username)

        cached_stories[key] = iterator

    await callback.answer()

    story: Story = iterator.next(
    ) if iterator.index != -1 else iterator.collection[iterator.index]

    caption = format_date(story.taken_at)

    keyboard = create_keyboard_stories(iterator.username,
                                       len(iterator.collection),
                                       language,
                                       from_profile=True)

    media = InputMediaVideo(
        story.url
    ) if story.type_story == "mp4/video/boomerang" else InputMediaPhoto(
        story.url)
    media.caption = caption

    await callback.edit_message_media(media, reply_markup=keyboard)
Example #15
0
async def upload_to_tg(message: Message, dirname: str, post: Post) -> None:  # pylint: disable=R0912
    """ uploads downloaded post from local to telegram servers """
    pto = (".jpg", ".jpeg", ".png", ".bmp")
    vdo = (".mkv", ".mp4", ".webm")
    paths = []
    if post.typename == "GraphSidecar":
        # upload media group
        captioned = False
        media = []
        for path in natsorted(os.listdir(dirname)):
            ab_path = dirname + "/" + path
            paths.append(ab_path)
            if str(path).endswith(pto):
                if captioned:
                    media.append(InputMediaPhoto(media=ab_path))
                else:
                    media.append(
                        InputMediaPhoto(media=ab_path,
                                        caption=get_caption(post)[:1023]))
                    captioned = True
            elif str(path).endswith(vdo):
                if captioned:
                    media.append(InputMediaVideo(media=ab_path))
                else:
                    media.append(
                        InputMediaVideo(media=ab_path,
                                        caption=get_caption(post)[:1023]))
                    captioned = True
        if media:
            await message.client.send_media_group(message.chat.id, media)
            await message.client.send_media_group(Config.LOG_CHANNEL_ID, media)

    if post.typename == "GraphImage":
        # upload a photo
        for path in natsorted(os.listdir(dirname)):
            if str(path).endswith(pto):
                ab_path = dirname + "/" + path
                paths.append(ab_path)
                await message.client.send_photo(
                    message.chat.id, ab_path, caption=get_caption(post)[:1023])
                await message.client.send_photo(
                    Config.LOG_CHANNEL_ID,
                    ab_path,
                    caption=get_caption(post)[:1023])

    if post.typename == "GraphVideo":
        # upload a video
        for path in natsorted(os.listdir(dirname)):
            if str(path).endswith(vdo):
                ab_path = dirname + "/" + path
                paths.append(ab_path)
                thumb = await get_thumb(ab_path)
                duration = 0
                metadata = extractMetadata(createParser(ab_path))
                if metadata and metadata.has("duration"):
                    duration = metadata.get("duration").seconds

                await message.client.send_video(
                    chat_id=message.chat.id,
                    video=ab_path,
                    duration=duration,
                    thumb=thumb,
                    caption=get_caption(post)[:1023],
                )
                await message.client.send_video(
                    chat_id=Config.LOG_CHANNEL_ID,
                    video=ab_path,
                    duration=duration,
                    thumb=thumb,
                    caption=get_caption(post)[:1023],
                )
                await remove_thumb(thumb)
    for del_p in paths:
        if os.path.lexists(del_p):
            os.remove(del_p)
Example #16
0
async def primary_task(client: Client, msg: Message) -> None:
    _pid = randint(100, 999)
    link = msg.reply_to_message.text
    LOGGER.debug(f"WEB_SCRS:{_pid} --> new request >> processing settings")
    random_message = await msg.edit(text="<b><i>processing...</b></i>")
    printer = await settings_parser(link, msg.reply_markup.inline_keyboard,
                                    _pid)
    asyncio.create_task(printer.allocate_folder(msg.chat.id, msg.message_id))
    # logging the request into a specific group or channel
    try:
        log = int(os.environ["LOG_GROUP"])
        LOGGER.debug(
            f"WEB_SCRS:{printer.PID} --> LOG GROUP FOUND >> sending log")
        await client.send_message(
            log, f'#WebSS:\n\n@{msg.chat.username} got {printer.__str__()}')
    except Exception as e:
        LOGGER.debug(f"WEB_SCRS:{printer.PID} --> LOGGING FAILED >> {e}")
    await random_message.edit(text="<b><i>rendering.</b></i>")
    try:
        await asyncio.wait_for(screenshot_driver(printer), 30)
        out = printer.filename
    except asyncio.exceptions.TimeoutError:
        await random_message.edit("<b>request timeout</b>")
        LOGGER.debug(f"WEB_SCRS:{printer.PID} --> request failed >> timeout")
        return
    except Exception as e:
        await random_message.edit(f"<b>{e}</b>")
        LOGGER.debug(f"WEB_SCRS:{printer.PID} --> request failed >> {e}")
        return
    await random_message.edit(text="<b><i>rendering..</b></i>")
    if printer.split and printer.fullpage:
        LOGGER.debug(
            f"WEB_SCRS:{printer.PID} --> split setting detected -> spliting images"
        )
        await random_message.edit(text="<b><i>spliting images...</b></i>")
        location_of_image = await split_func(printer.location,
                                             printer.filename, printer.type)
        LOGGER.debug(f"WEB_SCRS:{printer.PID} --> image splited successfully")
        # spliting finished
        if len(location_of_image) > 10:
            LOGGER.debug(
                f"WEB_SCRS:{printer.PID} --> found split pieces more than 10 >> zipping file"
            )
            await random_message.edit(
                text="<b>detected images more than 10\n\n<i>Zipping...</i></b>"
            )
            await asyncio.sleep(0.1)
            # zipping if length is too high
            out = await zipper(printer.location, location_of_image)
            LOGGER.debug(
                f"WEB_SCRS:{printer.PID} --> zipping completed >> sending file"
            )
            #  finished zipping and sending the zipped file as document
        else:
            LOGGER.debug(
                f"WEB_SCRS:{printer.PID} --> sending split pieces as media group"
            )
            await random_message.edit(text="<b><i>uploading...</b></i>")
            location_to_send = []
            for count, image in enumerate(location_of_image, start=1):
                location_to_send.append(
                    InputMediaPhoto(media=image, caption=str(count)))
            await asyncio.gather(
                client.send_chat_action(msg.chat.id, "upload_photo"),
                client.send_media_group(
                    media=location_to_send,
                    chat_id=msg.chat.id,
                    disable_notification=True,
                ),
            )
            shutil.rmtree(printer.location)
            LOGGER.debug(
                f"WEB_SCRS:{printer.PID} --> mediagroup send successfully >> request statisfied"
            )
            return
    if not printer.fullpage and not printer.type == "pdf":
        LOGGER.debug(
            f"WEB_SCRS:{printer.PID} --> split setting not found >> sending directly"
        )
        await asyncio.gather(
            random_message.edit(text="<b><i>uploading...</b></i>"),
            client.send_chat_action(msg.chat.id, "upload_photo"),
            client.send_photo(photo=out, chat_id=msg.chat.id),
        )
        LOGGER.info(
            f"WEB_SCRS:{printer.PID} --> photo send successfully >> request statisfied"
        )
    if printer.type == "pdf" or printer.fullpage:
        await asyncio.gather(
            client.send_chat_action(msg.chat.id, "upload_document"),
            client.send_document(document=out, chat_id=msg.chat.id),
        )
        LOGGER.debug(
            f"WEB_SCRS:{printer.PID} --> document send successfully >> request statisfied"
        )
    await random_message.delete()
    shutil.rmtree(printer.location)
Example #17
0
async def poto_x(message: Message):
    chat_id = message.chat.id
    reply = message.reply_to_message
    reply_id = reply.message_id if reply else None
    await message.edit("`Fetching photos ...`")
    if reply:
        input_ = reply.from_user.id
    elif message.filtered_input_str:
        input_ = message.filtered_input_str.strip()
        if len(input_.split()) != 1:
            await message.err("provide a valid ID or username", del_in=5)
            return
    else:
        input_ = chat_id
    type_, peer_id, f_id = await chat_type_(message, input_)
    if peer_id == 0:
        await message.err(type_, del_in=7)
        return
    if type_ in ("group", "supergroup", "channel") and message.client.is_bot:
        photo_ = await userge.bot.download_media(f_id)
        await userge.bot.send_photo(chat_id,
                                    photo_,
                                    reply_to_message_id=reply_id)
        os.remove(photo_)
        await message.delete()
        return
    flags_ = message.flags
    if "-p" in flags_:
        pos_ = flags_.get("-p", 0)
        if not str(pos_).isdigit():
            await message.err('"-p" Flag only takes integers', del_in=5)
            return
        await send_single(message,
                          peer_id=peer_id,
                          pos=int(pos_),
                          reply_id=reply_id)
    elif "-l" in flags_:
        get_l = flags_.get("-l", 0)
        if not str(get_l).isdigit():
            await message.err('"-l" Flag only takes integers', del_in=5)
            return
        media, media_group = [], []
        async for photo_ in message.client.iter_profile_photos(peer_id,
                                                               limit=min(
                                                                   int(get_l),
                                                                   100)):
            media.append(InputMediaPhoto(photo_.file_id))
            if len(media) == 10:
                media_group.append(media)
                media = []
        if len(media) != 0:
            media_group.append(media)
        if len(media_group) == 0:
            # Happens if bot doesn't know the user
            await message.delete()
            return
        try:
            for poto_ in media_group:
                await userge.send_media_group(chat_id, media=poto_)
                await asyncio.sleep(2)
        except FloodWait as e:
            await asyncio.sleep(e.x + 3)
        except Exception as err:
            await CHANNEL.log(f"**ERROR:** `{str(err)}`")
    else:
        await send_single(message, peer_id=peer_id, pos=1, reply_id=reply_id)
    await message.delete()
Example #18
0
async def upload_worker(update, filename, send_as, generatess, download_directory):
    tmp_directory_for_each_user = os.path.join(
        Config.WORK_DIR, str(update.from_user.id)
    )
    thumb_image_path = os.path.join(Config.WORK_DIR, str(update.from_user.id) + ".jpg")
    download_directory_dirname = os.path.dirname(download_directory)
    download_directory_contents = os.listdir(download_directory_dirname)
    for download_directory_c in download_directory_contents:
        current_file_name = os.path.join(
            download_directory_dirname, download_directory_c
        )
        file_size = os.stat(current_file_name).st_size

        if file_size > Config.TG_MAX_FILE_SIZE:
            await update.message.edit_caption(
                caption=String.RCHD_TG_API_LIMIT.format(humanbytes(file_size))
            )
            return

        # get the correct width, height, and duration
        # for videos greater than 10MB
        # ref: message from @BotSupport
        width = 0
        height = 0
        duration = 0
        if send_as != "file":
            metadata = extractMetadata(createParser(current_file_name))
            if metadata is not None and metadata.has("duration"):
                duration = metadata.get("duration").seconds
        # get the correct width, height, and duration
        # for videos greater than 10MB
        if os.path.exists(thumb_image_path):
            # https://stackoverflow.com/a/21669827/4723940
            Image.open(thumb_image_path).convert("RGB").save(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")
        else:
            thumb_image_path = None
        start_upload = datetime.now()
        c_time = time.time()
        if send_as == "audio":
            await update.message.reply_audio(
                audio=current_file_name,
                caption=filename,
                parse_mode="HTML",
                duration=duration,
                # performer=response_json["uploader"],
                # title=response_json["title"],
                # reply_markup=reply_markup,
                thumb=thumb_image_path,
                progress=progress_for_pyrogram,
                progress_args=(String.UPLOAD_START, update.message, c_time),
            )

        elif send_as == "file":
            await update.message.reply_document(
                document=current_file_name,
                thumb=thumb_image_path,
                caption=filename,
                parse_mode="HTML",
                # reply_markup=reply_markup,
                progress=progress_for_pyrogram,
                progress_args=(String.UPLOAD_START, update.message, c_time),
            )

        elif send_as == "video":
            await update.message.reply_video(
                video=current_file_name,
                caption=filename,
                parse_mode="HTML",
                duration=duration,
                width=width,
                height=height,
                supports_streaming=True,
                # reply_markup=reply_markup,
                thumb=thumb_image_path,
                progress=progress_for_pyrogram,
                progress_args=(String.UPLOAD_START, update.message, c_time),
            )

        else:
            LOGGER.info("Did this happen? :\\")
        end_upload = datetime.now()
        time_taken_for_upload = (end_upload - start_upload).seconds
        min_duration = 300
        media_album_p = []
        if generatess and duration > min_duration:
            images = generate_screenshots(
                current_file_name, tmp_directory_for_each_user, duration, 5
            )
            LOGGER.info(images)
            i = 0
            caption = f"© @AnyDLBot - Uploaded in {time_taken_for_upload} seconds"
            for image in images:
                if os.path.exists(image):
                    if i == 0:
                        media_album_p.append(
                            InputMediaPhoto(
                                media=image, caption=caption, parse_mode="html"
                            )
                        )
                    else:
                        media_album_p.append(InputMediaPhoto(media=image))
                    i += 1
        await update.message.reply_media_group(
            media=media_album_p, disable_notification=True
        )
        #
        return True
async def manual_screenshot_fn(c, m):

    chat_id = m.chat.id
    if c.CURRENT_PROCESSES.get(chat_id, 0) == Config.MAX_PROCESSES_PER_USER:
        await m.reply_text('You have reached the maximum parallel processes! Try again after one of them finishes.', True)
        return
    if not c.CURRENT_PROCESSES.get(chat_id):
        c.CURRENT_PROCESSES[chat_id] = 0
    c.CURRENT_PROCESSES[chat_id] += 1
    
    message = await c.get_messages(
        chat_id,
        m.reply_to_message.message_id
    )
    await m.reply_to_message.delete()
    media_msg = message.reply_to_message
    
    if media_msg.empty:
        await m.reply_text('Why did you delete the file 😠, Now i cannot help you 😒.', True)
        c.CURRENT_PROCESSES[chat_id] -= 1
        return
    
    try:
        raw_user_input = [int(i.strip()) for i in m.text.split(',')]
    except:
        await m.reply_text('Please follow the specified format', True)
        c.CURRENT_PROCESSES[chat_id] -= 1
        return
    
    uid = str(uuid.uuid4())
    output_folder = Config.SCRST_OP_FLDR.joinpath(uid)
    os.makedirs(output_folder, exist_ok=True)
    
    if Config.TRACK_CHANNEL:
        tr_msg = await media_msg.forward(Config.TRACK_CHANNEL)
        await tr_msg.reply_text(f"User id: `{chat_id}`")
    
    if media_msg.media:
        typ = 1
    else:
        typ = 2
    
    snt = await m.reply_text('Processing your request, Please wait! 😴', True)
    
    try:
        async with timeout(Config.TIMEOUT) as cm:
            start_time = time.time()
            
            if typ == 2:
                file_link = media_msg.text
            else:
                file_link = generate_stream_link(media_msg)
            
            duration = await get_duration(file_link)
            if isinstance(duration, str):
                await snt.edit_text("😟 Sorry! I cannot open the file.")
                
                l = await media_msg.forward(Config.LOG_CHANNEL)
                await l.reply_text(f'stream link : {file_link}\n\nRequested manual screenshots\n\n{duration}', True)
                c.CURRENT_PROCESSES[chat_id] -= 1
                return
            
            valid_positions = []
            invalid_positions = []
            for pos in raw_user_input:
                if pos<0 or pos>duration:
                    invalid_positions.append(str(pos))
                else:
                    valid_positions.append(pos)
            
            if not valid_positions:
                await snt.edit_text("😟 Sorry! None of the given positions where valid!")
                c.CURRENT_PROCESSES[chat_id] -= 1
                return
            
            if len(valid_positions) > 10:
                await snt.edit_text(f"😟 Sorry! Only 10 screenshots can be generated. Found {len(valid_positions)} valid positions in your request")
                c.CURRENT_PROCESSES[chat_id] -= 1
                return
            
            if invalid_positions:
                invalid_position_str = ', '.join(invalid_positions)
                txt = f"Found {len(invalid_positions)} invalid positions ({invalid_position_str}).\n\n😀 Generating screenshots after ignoring these!."
            else:
                txt = '😀 Generating screenshots!.'
            
            await snt.edit_text(txt)
            
            screenshots = []
            watermark = await c.db.get_watermark_text(chat_id)
            watermark_color_code = await c.db.get_watermark_color(chat_id)
            watermark_color = Config.COLORS[watermark_color_code]
            as_file = await c.db.is_as_file(chat_id)
            font_size = await c.db.get_font_size(chat_id)
            ffmpeg_errors = ''
            
            width, height = await get_dimentions(file_link)
            fontsize = int((math.sqrt( width**2 + height**2 ) / 1388.0) * Config.FONT_SIZES[font_size])
            
            log.info(f"Generating screenshots at positions {valid_positions} from location: {file_link} for {chat_id}")
            
            for i, sec in enumerate(valid_positions):
                thumbnail_template = output_folder.joinpath(f'{i+1}.png')
                #print(sec)
                ffmpeg_cmd = f"ffmpeg -hide_banner -ss {sec} -i {shlex.quote(file_link)} -vf \"drawtext=fontcolor={watermark_color}:fontsize={fontsize}:x=20:y=H-th-10:text='{shlex.quote(watermark)}', scale=1280:-1\" -y  -vframes 1 '{thumbnail_template}'"
                output = await run_subprocess(ffmpeg_cmd)
                log.debug(output)
                await snt.edit_text(f'😀 `{i+1}` of `{len(valid_positions)}` generated!')
                if thumbnail_template.exists():
                    if as_file:
                        screenshots.append({
                            'document':str(thumbnail_template),
                            'caption':f"ScreenShot at {datetime.timedelta(seconds=sec)}"
                        })
                    else:
                        screenshots.append(
                            InputMediaPhoto(
                                str(thumbnail_template),
                                caption=f"ScreenShot at {datetime.timedelta(seconds=sec)}"
                            )
                        )
                    continue
                ffmpeg_errors += output[0].decode() + '\n' + output[1].decode() + '\n\n'
            
            if not screenshots:
                await snt.edit_text('😟 Sorry! Screenshot generation failed possibly due to some infrastructure failure 😥.')
                
                l = await media_msg.forward(Config.LOG_CHANNEL)
                if ffmpeg_errors:
                    error_file = f"{uid}-errors.txt"
                    with open(error_file, 'w') as f:
                        f.write(ffmpeg_errors)
                    await l.reply_document(error_file, caption=f"stream link : {file_link}\n\nmanual screenshots {raw_user_input}.")
                    os.remove(error_file)
                else:
                    await l.reply_text(f'stream link : {file_link}\n\nmanual screenshots {raw_user_input}.', True)
                c.CURRENT_PROCESSES[chat_id] -= 1
                return
            
            await snt.edit_text(text=f'🤓 You requested {len(valid_positions)} screenshots and {len(screenshots)} screenshots generated, Now starting to upload!')
            
            await media_msg.reply_chat_action("upload_photo")
            
            if as_file:
                aws = [media_msg.reply_document(quote=True, **photo) for photo in screenshots]
                await asyncio.gather(*aws)
            else:
                await media_msg.reply_media_group(screenshots, True)
            
            await snt.edit_text(f'Successfully completed process in {datetime.timedelta(seconds=int(time.time()-start_time))}\n\nIf You find me helpful, please rate me [here](tg://resolve?domain=botsarchive&post=1206).')
            c.CURRENT_PROCESSES[chat_id] -= 1
    except (asyncio.TimeoutError, asyncio.CancelledError):
        await snt.edit_text('😟 Sorry! Video trimming failed due to timeout. Your process was taking too long to complete, hence cancelled')
        c.CURRENT_PROCESSES[chat_id] -= 1
    except Exception as e:
        log.error(e, exc_info=True)
        await snt.edit_text('😟 Sorry! Screenshot generation failed possibly due to some infrastructure failure 😥.')
        
        l = await media_msg.forward(Config.LOG_CHANNEL)
        await l.reply_text(f'manual screenshots ({raw_user_input}) where requested and some error occoured\\n{traceback.format_exc()}', True)
        c.CURRENT_PROCESSES[chat_id] -= 1
    async def manual_screenshot_fn(self, c, m):

        chat_id = m.chat.id
        if c.CURRENT_PROCESSES[chat_id] >= Config.MAX_PROCESSES_PER_USER:
            await m.reply_text(
                'You have reached the maximum parallel processes! Try again after one of them finishes.',
                True)
            return

        try:
            async with timeout(Config.TIMEOUT) as cm, ProcessCounter(
                    c.CURRENT_PROCESSES, chat_id):
                uid = str(uuid.uuid4())
                output_folder = Config.SCRST_OP_FLDR.joinpath(uid)
                os.makedirs(output_folder, exist_ok=True)

                message = await c.get_messages(chat_id,
                                               m.reply_to_message.message_id)
                await m.reply_to_message.delete()
                media_msg = message.reply_to_message

                if media_msg.empty:
                    await m.reply_text(
                        'Why did you delete the file 😠, Now i cannot help you 😒.',
                        True)
                    return

                try:
                    raw_user_input = [
                        int(i.strip()) for i in m.text.split(',')
                    ]
                except:
                    await m.reply_text('Please follow the specified format',
                                       True)
                    return

                if Config.TRACK_CHANNEL:
                    tr_msg = await media_msg.forward(Config.TRACK_CHANNEL)
                    await tr_msg.reply_text(f"User id: `{chat_id}`")

                snt = await m.reply_text(
                    'Processing your request, Please wait! 😴', True)

                start_time = time.time()

                if media_msg.media:
                    file_link = self.generate_stream_link(media_msg)
                else:
                    file_link = media_msg.text

                duration = await self.get_duration(file_link)
                if isinstance(duration, str):
                    await snt.edit_text("😟 Sorry! I cannot open the file.")
                    l = await media_msg.forward(Config.LOG_CHANNEL)
                    await l.reply_text(
                        f'stream link : {file_link}\n\nRequested manual screenshots\n\n{duration}',
                        True)
                    return

                valid_positions = []
                invalid_positions = []
                for pos in raw_user_input:
                    if pos < 0 or pos > duration:
                        invalid_positions.append(str(pos))
                    else:
                        valid_positions.append(pos)

                if not valid_positions:
                    await snt.edit_text(
                        "😟 Sorry! None of the given positions where valid!")
                    return

                if len(valid_positions) > 10:
                    await snt.edit_text(
                        f"😟 Sorry! Only 10 screenshots can be generated. Found {len(valid_positions)} valid positions in your request"
                    )
                    return

                if invalid_positions:
                    invalid_position_str = ', '.join(invalid_positions)
                    txt = f"Found {len(invalid_positions)} invalid positions ({invalid_position_str}).\n\n"\
                           "😀 Generating screenshots after ignoring these!."
                else:
                    txt = '😀 Generating screenshots!.'

                await snt.edit_text(txt)

                screenshots = []
                ffmpeg_errors = ''
                as_file = await c.db.is_as_file(chat_id)
                watermark = await c.db.get_watermark_text(chat_id)
                if watermark:
                    watermark_color_code = await c.db.get_watermark_color(
                        chat_id)
                    watermark_color = Config.COLORS[watermark_color_code]
                    watermark_position = await c.db.get_watermark_position(
                        chat_id)
                    font_size = await c.db.get_font_size(chat_id)
                    width, height = await self.get_dimentions(file_link)
                    fontsize = int((math.sqrt(width**2 + height**2) / 1388.0) *
                                   Config.FONT_SIZES[font_size])
                    x_pos, y_pos = self.get_watermark_coordinates(
                        watermark_position, width, height)
                    watermark_options = f'drawtext=fontcolor={watermark_color}:fontsize={fontsize}:x={x_pos}:'\
                                        f'y={y_pos}:text={watermark}, scale=1280:-1'

                log.info(
                    f"Generating screenshots at positions {valid_positions} from location: {file_link} for {chat_id}"
                )

                for i, sec in enumerate(valid_positions):
                    thumbnail_template = output_folder.joinpath(f'{i+1}.png')
                    ffmpeg_cmd = [
                        'ffmpeg', '-headers', f'IAM:{Config.IAM_HEADER}',
                        '-hide_banner', '-ss',
                        str(sec), '-i', file_link, '-vf'
                    ]
                    if watermark:
                        ffmpeg_cmd.append(watermark_options)
                    else:
                        ffmpeg_cmd.append('scale=1280:-1')
                    ffmpeg_cmd += [
                        '-y', '-vframes', '1',
                        str(thumbnail_template)
                    ]

                    log.debug(ffmpeg_cmd)
                    output = await self.run_subprocess(ffmpeg_cmd)
                    log.debug(output)
                    await snt.edit_text(
                        f'😀 `{i+1}` of `{len(valid_positions)}` generated!')
                    if thumbnail_template.exists():
                        if as_file:
                            screenshots.append({
                                'document':
                                str(thumbnail_template),
                                'caption':
                                f"ScreenShot at {datetime.timedelta(seconds=sec)}"
                            })
                        else:
                            screenshots.append(
                                InputMediaPhoto(
                                    str(thumbnail_template),
                                    caption=
                                    f"ScreenShot at {datetime.timedelta(seconds=sec)}"
                                ))
                        continue
                    ffmpeg_errors += output[0].decode(
                    ) + '\n' + output[1].decode() + '\n\n'

                if not screenshots:
                    await snt.edit_text(
                        '😟 Sorry! Screenshot generation failed possibly due to some infrastructure failure 😥.'
                    )
                    l = await media_msg.forward(Config.LOG_CHANNEL)
                    if ffmpeg_errors:
                        error_file = io.BytesIO()
                        error_file.name = f"{uid}-errors.txt"
                        error_file.write(ffmpeg_errors.encode())
                        await l.reply_document(
                            error_file,
                            caption=
                            f"stream link : {file_link}\n\nmanual screenshots {raw_user_input}."
                        )
                    else:
                        await l.reply_text(
                            f'stream link : {file_link}\n\nmanual screenshots {raw_user_input}.',
                            True)
                    return

                await snt.edit_text(
                    text=f'🤓 You requested {len(valid_positions)} screenshots and {len(screenshots)} screenshots generated, '\
                          'Now starting to upload!')

                await media_msg.reply_chat_action("upload_photo")

                if as_file:
                    aws = [
                        media_msg.reply_document(quote=True, **photo)
                        for photo in screenshots
                    ]
                    await asyncio.gather(*aws)
                else:
                    await media_msg.reply_media_group(screenshots, True)

                await snt.edit_text(
                    f'Successfully completed process in {datetime.timedelta(seconds=int(time.time()-start_time))}\n\n'\
                    'If You find me helpful, please join my [channel](https://t.me/Bot_Gram_Developers).')
        except (asyncio.TimeoutError, asyncio.CancelledError):
            await snt.edit_text(
                '😟 Sorry! Video trimming failed due to timeout. Your process was taking too long to complete, hence cancelled'
            )
        except Exception as e:
            log.error(e, exc_info=True)
            await snt.edit_text(
                '😟 Sorry! Screenshot generation failed possibly due to some infrastructure failure 😥.'
            )
            l = await media_msg.forward(Config.LOG_CHANNEL)
            await l.reply_text(
                f'manual screenshots ({raw_user_input}) where requested and some error occoured\\n{traceback.format_exc()}',
                True)
        finally:
            shutil.rmtree(output_folder, ignore_errors=True)