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)
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)
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
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]))
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)
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()
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)
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)
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)
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)
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)
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()
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)