async def darkmode(c, m): cb_data = m.data if cb_data.startswith("d||"): filename = cb_data.split("||")[-1].strip(".png") print(cb_data) light_button = InlineKeyboardMarkup([ [ InlineKeyboardButton("Light Mode ☀️", callback_data=f"l||{filename}") ], ]) darkimage = InputMediaPhoto(media=f"{filename}_dark.png", ) await m.edit_message_media(media=darkimage, reply_markup=light_button) elif cb_data.startswith("l||"): filename = cb_data.split("||")[-1].strip("_dark.png") dark_button = InlineKeyboardMarkup([ [ InlineKeyboardButton("Darkmode 🌜", callback_data=f"d||{filename}") ], ]) darkimage = InputMediaPhoto(media=f"{filename}.png", ) await m.edit_message_media(media=darkimage, reply_markup=dark_button) else: raise ContinuePropagation
async def google_img(message: Message): if (GCS_API_KEY and GCS_IMAGE_E_ID) is None: await message.edit(REQ_ERR, disable_web_page_preview=True) return if os.path.exists(PATH): shutil.rmtree(PATH, ignore_errors=True) fetcher = GIS(GCS_API_KEY, GCS_IMAGE_E_ID) query = message.input_str search = { 'q': query, 'num': 5, 'safe': "off", 'fileType': "jpg", 'imgType': "photo", 'imgSize': "MEDIUM" } await message.edit("`Processing...`") fetcher.search(search_params=search) for image in fetcher.results(): image.download(PATH) if not os.path.exists(PATH): await message.edit("Oops, No Results Found") return ss = [] for img in os.listdir(PATH): imgs = PATH + img ss.append(InputMediaPhoto(str(imgs))) if len(ss) == 5: break await message.reply_chat_action("upload_photo") await message.reply_media_group(ss, True) shutil.rmtree(PATH, ignore_errors=True) await message.delete()
def edit_post(self, app, chat_id, msg_id, kb): app.edit_message_media(chat_id=chat_id, message_id=msg_id, media=InputMediaPhoto(media=self.file_id, file_ref=self.file_ref, caption=self.text), reply_markup=kb)
def edit_message_photo(client: Client, cid: int, mid: int, photo: str, file_ref: str = None, caption: str = "", markup: InlineKeyboardMarkup = None) -> Union[bool, Message, None]: # Edit the message's photo result = None try: media = InputMediaPhoto( media=photo, file_ref=file_ref, caption=caption, parse_mode="html" ) result = client.edit_message_media( chat_id=cid, message_id=mid, media=media, reply_markup=markup ) except FloodWait as e: raise e except ButtonDataInvalid: logger.warning(f"Edit message {mid} photo {photo} in {cid} - invalid markup: {markup}") except (ChannelInvalid, ChannelPrivate, ChatAdminRequired, PeerIdInvalid): return False except Exception as e: logger.warning(f"Edit message photo error: {e}", exc_info=True) return result
async def generate_screen_shot(bot, update): tmp_directory_for_each_user = os.path.join(os.getcwd(), "Screenshots", str(update.from_user.id)) if not os.path.isdir(tmp_directory_for_each_user): os.makedirs(tmp_directory_for_each_user) ss_folder = [f for f in os.listdir(tmp_directory_for_each_user)] for f in ss_folder: try: os.remove(os.path.join(tmp_directory_for_each_user, f)) except IndexError: pass saved_file_path = os.getcwd() + "/" + "downloads" + "/" + str( update.from_user.id) + "/" for file in os.listdir(saved_file_path): dir_content = (os.path.join(saved_file_path, file)) if dir_content is not None: images = await generate_screen_shots(dir_content, tmp_directory_for_each_user, 5, 9) media_album_p = [] if images is not None: i = 0 for image in images: if os.path.exists(image): if i == 0: media_album_p.append( InputMediaPhoto( media=image, caption=Translation.CAPTION_TEXT, parse_mode="html")) else: media_album_p.append(InputMediaPhoto(media=image)) i = i + 1 await bot.send_chat_action(chat_id=update.message.chat.id, action="upload_photo") 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) await trim(bot, update) except IndexError: pass
def img(message): query = extract_args(message) lim = findall(r"lim=\d+", query) try: lim = lim[0] lim = lim.replace("lim=", "") query = query.replace("lim=" + lim[0], "") lim = int(lim) if lim > 10: lim = 10 except IndexError: lim = 5 if len(query) < 1: edit(message, '`Bir arama terimi girmelisiniz.`') return edit(message, '`İşleniyor...`') url = f'https://www.google.com/search?tbm=isch&q={query}&gbv=2&sa=X&biw=1920&bih=1080' driver = get_webdriver() driver.get(url) count = 1 files = [] for i in driver.find_elements_by_xpath( '//div[contains(@class,"isv-r PNCib MSM1fd BUooTd")]'): i.click() try_count = 0 while len(element := driver.find_elements_by_xpath( '//img[contains(@class,"n3VNCb") and contains(@src,"http")]') ) < 1 and try_count < 20: try_count += 1 time.sleep(.1) if len(element) < 1: continue link = element[0].get_attribute('src') filename = f'result_{count}.jpg' try: with open(filename, 'wb') as result: result.write(get(link).content) ftype = guess_type(filename) if not ftype[0] or ftype[0].split('/')[1] not in [ 'png', 'jpg', 'jpeg' ]: os.remove(filename) continue except Exception as e: continue files.append(InputMediaPhoto(filename)) time.sleep(1) driver.find_elements_by_xpath( '//a[contains(@class,"hm60ue")]')[0].click() count += 1 if lim < count: break time.sleep(1)
async def generate_screen_shot(client, update): await client.send_chat_action(chat_id=update.message.chat.id, action="upload_document") tmp_directory_for_each_user = os.path.join(os.getcwd(), "screenshots", str(update.from_user.id)) if not os.path.isdir(tmp_directory_for_each_user): os.makedirs(tmp_directory_for_each_user) saved_file_path = os.path.join(os.getcwd(), "downloads", str(update.message.chat.id)) for file in os.listdir(saved_file_path): dir_content = (os.path.join(saved_file_path, file)) if dir_content is not None: images = await generate_screen_shots(dir_content, tmp_directory_for_each_user, 5, 9) media_album_p = [] if images is not None: i = 0 caption = str(Config.PRE_FILE_TXT) 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 client.send_chat_action(chat_id=update.message.chat.id, action="upload_photo") await client.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) await trim(client, update) except IndexError: pass
async def post_async(client): item_store_channel = (await redis_hgetall("fortnite:store:channel")) item_store_file, item_store_hash = await parse_item_store() item_store_caption = "🛒 Магазин предметов в Фортнайте был обновлен. #магазин" item_store_caption_edited = f"{item_store_caption}\n\n__Магазин предметов после оригинальной публикации " \ "сообщения был обновлен в {} по московскому времени.__" if not item_store_channel or item_store_channel[ 'hash'] != item_store_hash or config.DEVELOPER_MODE: logging.info( "Магазин предметов в Фортнайте был обновлен. Публикуется его изображение в канал, " "указанный в конфигурационном файле.") try: assert item_store_channel['chat_id'] assert item_store_channel['message_id'] assert item_store_channel['time'] if int(time()) - int(item_store_channel['time']) < 3600: logging.info( "Последний пост с магазином предметов был опубликован в канал меньше, " "чем час назад, поэтому сообщение было отредактировано обновленным магазином." ) message = client.edit_message_media( int(item_store_channel['chat_id']), int(item_store_channel['message_id']), media=InputMediaPhoto( item_store_file, caption=item_store_caption_edited.format( convert_to_moscow( datetime.utcnow()).strftime("%H:%M:%S")))) else: raise AssertionError except (AssertionError, TypeError, KeyError): message = client.send_photo(config.CHANNEL_ID, item_store_file, caption=item_store_caption) await Redis.execute("HSET", "fortnite:store:channel", "hash", item_store_hash, "chat_id", message['chat']['id'], "message_id", message['message_id'], "time", int(time())) await Redis.execute("EXPIRE", "fortnite:store:channel", 86400) """
async def new_cat_callback_handler(c: bot, cb: CallbackQuery): await cb.answer() cat_file = await cat().random_cat() await c.edit_message_media(chat_id=cb.message.chat.id, message_id=cb.message.message_id, media=InputMediaPhoto(cat_file), reply_markup=InlineKeyboardMarkup([[ InlineKeyboardButton( text=f"{Emoji.CAT_FACE} New Cat", callback_data="new_cat_callback") ]])) try: os.remove(cat_file) except Exception as e: logging.error(str(e))
async def post_async(client): news_channel = (await redis_hgetall("fortnite:news:channel")) news_file, news_hash = await parse_news() news_caption = "📰 Новости Королевской Битвы и/или Сражения с Бурей были обновлены. #новости" news_caption_edited = f"{news_caption}\n\n__Новости после оригинальной публикации " \ "сообщения были обновлены в {} по московскому времени.__" if not news_channel or news_channel[ 'hash'] != news_hash or config.DEVELOPER_MODE: logging.info( "Новости в Фортнайте были обновлены. Публикуется их изображение в канал, " "указанный в конфигурационном файле.") try: assert news_channel['chat_id'] assert news_channel['message_id'] assert news_channel['time'] if int(time()) - int(news_channel['time']) < 3600: logging.info( "Последний пост с новостями был опубликован в канал меньше, чем час назад, поэтому " "сообщение было отредактировано обновленными новостями.") message = client.edit_message_media( int(news_channel['chat_id']), int(news_channel['message_id']), media=InputMediaPhoto( news_file, caption=news_caption_edited.format( convert_to_moscow( datetime.utcnow()).strftime("%H:%M:%S")))) else: raise AssertionError except (AssertionError, TypeError, KeyError): message = client.send_photo(config.CHANNEL_ID, news_file, caption=news_caption) await Redis.execute("HSET", "fortnite:news:channel", "hash", news_hash, "chat_id", message['chat']['id'], "message_id", message['message_id'], "time", int(time())) await Redis.execute("EXPIRE", "fortnite:news:channel", 604800)
def media_group_worker(cli: Client, msg: Message): chat_id = msg.chat.id media_group_id = msg.media_group_id if media_group_id not in last_media_group_ids: last_media_group_ids.append(media_group_id) print('Catch media_group') for ids in from_to_ids: from_id = ids['from_id'] to_id = ids['to_id'] if from_id == chat_id: photos = [] for message in app.get_history(chat_id, limit=10): if message.media_group_id == msg.media_group_id: caption = message.caption if message.caption else '' photos.append( InputMediaPhoto(message.photo.file_id, message.photo.file_ref, caption)) photos.reverse() app.send_media_group(to_id, photos)
async def cb_(client, callback_query): 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..!') 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' # starting folder creartion with message id if not os.path.isdir('./FILES'): os.mkdir('./FILES') location = f"./FILES/{str(msg.chat.id)}/{str(msg.message_id)}" if not os.path.isdir(location): os.makedirs(location) # logging the request into a specific group or channel try: LOGGING_GROUP = int(os.environ["LOG_GROUP"]) 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: print(f'Logging Avoided\nREASON : {e}') # opening chrome bin try: browser = await launch(headless=True, executablePath=EXEC_PATH) page = await browser.newPage() await page.goto(link, {"waitUtil": 'networkidle0'}) await asyncio.sleep(2) # getting page title text = str(await page.title()) if len(text) > 14: text = text[:14] text = text.replace(' ', '') # implementing the settings await random_message.edit(text='<b><i>Rendering</b></i>') if format == 'jpeg' or format == 'PNG': 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 if page_value: arguments_for_photo['fullPage'] = True await random_message.edit(text='<b><i>Rendering.</b></i>') # naming for the output file if format == 'jpeg': arguments_for_photo[ 'path'] = f'{location}/{text.strip()}-webshotbot.jpeg' arguments_for_photo['type'] = 'jpeg' if format == 'PNG': arguments_for_photo[ 'path'] = f'{location}/{text.strip()}-webshotbot.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 await page.screenshot(arguments_for_photo) await browser.close() # spliting the image if split and page_value: 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(arguments_for_photo['path']) 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'{location}/slice_{str(count)}.jpeg' else: location_to_save_slice = f'{location}/slice_{str(count)}.png' location_of_image.append(location_to_save_slice) working_slice.save(location_to_save_slice) count += 1 # spliting finished if len(location_of_image) > 20: 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 zipped_file = f'{location}/webshot.zip' with ZipFile(zipped_file, 'w') as zipper: for files in location_of_image: zipper.write(files) # 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 ) # sending as media group if files are not too long else: 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=images, 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) # if split is not selected else: 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=arguments_for_photo['path'], chat_id=msg.chat.id, reply_to_message_id=msg.reply_to_message.message_id ) else: await client.send_chat_action(msg.chat.id, "upload_document") await client.send_document( document=arguments_for_photo['path'], chat_id=msg.chat.id, reply_to_message_id=msg.reply_to_message.message_id ) await asyncio.sleep(1) await random_message.delete() shutil.rmtree(location) # configuring pdf settings else: 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} arguments_for_pdf['scale'] = 2 elif '640' in resolution: arguments_for_pdf = {'width': 640, 'height': 480} else: arguments_for_pdf = {'width': 800, 'height': 600} await page.emulateMedia('screen') arguments_for_pdf['path'] = f'{location}/{text}-webshotbot.pdf' if not page_value: arguments_for_pdf['pageRanges'] = '1-2' 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>') await page.pdf(arguments_for_pdf) await random_message.edit(text='<b><i>Uploading...</b></i>') await client.send_chat_action(msg.chat.id, "upload_document") await browser.close() await client.send_document( document=arguments_for_pdf['path'], chat_id=msg.chat.id, reply_to_message_id=msg.reply_to_message.message_id) await asyncio.sleep(1) await random_message.delete() shutil.rmtree(location) except errors.PageError: await msg.edit(text='Not a valid link 😓🤔') return False 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 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 = DOWNLOAD_LOCATION + \ "/" + str(update.from_user.id) + ".jpg" save_ytdl_json_path = 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: await update.message.delete() return False youtube_dl_url, \ custom_file_name, \ youtube_dl_username, \ youtube_dl_password = get_link( update.message.reply_to_message ) if not custom_file_name: custom_file_name = str(response_json.get("title")) + \ "_" + youtube_dl_format + "." + youtube_dl_ext await update.message.edit_caption(caption=Translation.DOWNLOAD_START) 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 = os.path.join(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 = os.path.join(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(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(TG_MAX_FILE_SIZE), "--embed-subs", "-f", minus_f_format, "--hls-prefer-ffmpeg", youtube_dl_url, "-o", download_directory ] if HTTP_PROXY is not None: command_to_exec.append("--proxy") command_to_exec.append(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") command_to_exec.append("--restrict-filenames") LOGGER.info(command_to_exec) start = datetime.now() t_response, e_response = await run_shell_command(command_to_exec) LOGGER.info(e_response) LOGGER.info(t_response) if e_response and Translation.YTDL_ERROR_MESSAGE in e_response: error_message = e_response.replace(Translation.YTDL_ERROR_MESSAGE, "") await update.message.edit_caption(caption=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 = TG_MAX_FILE_SIZE + 1 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 > TG_MAX_FILE_SIZE: await update.message.edit_caption( caption=Translation.RCHD_TG_API_LIMIT.format( time_taken_for_download, humanbytes(file_size))) else: is_w_f = False images = await generate_screen_shots( current_file_name, tmp_directory_for_each_user, is_w_f, "", 300, 9) LOGGER.info(images) await update.message.edit_caption( caption=Translation.UPLOAD_START) # 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(current_file_name)) 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): # 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") if tg_send_type == "vm": height = width else: thumb_image_path = None start_time = time.time() # try to upload file if tg_send_type == "audio": await update.message.reply_audio( audio=current_file_name, caption=description, 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=(Translation.UPLOAD_START, update.message, start_time)) elif tg_send_type == "file": await update.message.reply_document( document=current_file_name, thumb=thumb_image_path, caption=description, parse_mode="HTML", # reply_markup=reply_markup, progress=progress_for_pyrogram, progress_args=(Translation.UPLOAD_START, update.message, start_time)) elif tg_send_type == "vm": await update.message.reply_video_note( video_note=current_file_name, duration=duration, length=width, thumb=thumb_image_path, progress=progress_for_pyrogram, progress_args=(Translation.UPLOAD_START, update.message, start_time)) elif tg_send_type == "video": await update.message.reply_video( video=current_file_name, caption=description, 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=(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 = "© @KS_AnyDLBot" 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 update.message.reply_media_group( media=media_album_p, disable_notification=True) # shutil.rmtree(tmp_directory_for_each_user, ignore_errors=True) os.remove(thumb_image_path) await update.message.delete()
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 = DOWNLOAD_LOCATION + \ "/" + str(update.from_user.id) + ".jpg" save_ytdl_json_path = 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 update.message.delete() 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] if len(custom_file_name) > 64: await update.message.reply_text( Translation.IFLONG_FILE_NAME.format( alimit="64", num=len(custom_file_name) ) ) return 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 update.message.edit_caption( caption=Translation.DOWNLOAD_START ) 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 = 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(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(TG_MAX_FILE_SIZE), "--embed-subs", "-f", minus_f_format, "--hls-prefer-ffmpeg", youtube_dl_url, "-o", download_directory ] if HTTP_PROXY is not None: command_to_exec.append("--proxy") command_to_exec.append(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") command_to_exec.append("--restrict-filenames") 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 update.message.edit_caption( caption=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 = TG_MAX_FILE_SIZE + 1 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 > TG_MAX_FILE_SIZE: await update.message.edit_caption( caption=Translation.RCHD_TG_API_LIMIT.format( time_taken_for_download, humanbytes(file_size) ) ) else: is_w_f = False images = await generate_screen_shots( current_file_name, tmp_directory_for_each_user, is_w_f, "", 300, 9 ) LOGGER.info(images) await update.message.edit_caption( caption=Translation.UPLOAD_START ) # 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(current_file_name)) 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 = 90 # 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 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 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 = "© @AnyDLBot" if is_w_f: caption = "/upgrade to Plan D to remove the watermark\n© @AnyDLBot" 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) 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 screenshot_fn(c, m): _, num_screenshots = m.data.split('+') num_screenshots = int(num_screenshots) media_msg = m.message.reply_to_message #print(media_msg) if media_msg.empty: await edit_message_text( m, text='Why did you delete the file 😠, Now i cannot help you 😒.' ) return uid = str(uuid.uuid4()) output_folder = Config.SCRST_OP_FLDR.joinpath(uid) if not output_folder.exists(): os.makedirs(output_folder) try: start_time = time.time() file_link = media_msg.text await edit_message_text(m, text='😀 Generating screenshots!') duration = await get_duration(file_link) if duration is None: await edit_message_text(m, 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\n{num_screenshots} Could not open the file.', True) return hh, mm, ss = [int(i) for i in duration.split(":")] seconds = hh * 60 * 60 + mm * 60 + ss reduced_sec = seconds - int(seconds * 2 / 100) print(f"Total seconds: {seconds}, Reduced seconds: {reduced_sec}") as_file = await db.is_as_file(m.from_user.id) screenshots = [] for i in range(1, 1 + num_screenshots): sec = int(reduced_sec / num_screenshots) * i thumbnail_template = output_folder.joinpath(f'{i}.png') print(sec) ffmpeg_cmd = f"ffmpeg -ss {sec} -i {shlex.quote(file_link)} -vframes 1 '{thumbnail_template}'" output = await run_subprocess(ffmpeg_cmd) await edit_message_text( m, text=f'`{i}` 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)}") ) if not screenshots: await edit_message_text(m, text="😟 Sorry! I cannot open the file.") l = await media_msg.forward(Config.LOG_CHANNEL) await l.reply_text(f'Could not open the file.', True) return await edit_message_text( m, 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 edit_message_text( m, text= f'Successfully completed process in {datetime.timedelta(seconds=int(time.time()-start_time))}' ) except: traceback.print_exc() await edit_message_text( m, 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)
async def screenshot_fn(c, m): _, num_screenshots = m.data.split('+') num_screenshots = int(num_screenshots) media_msg = m.message.reply_to_message #print(media_msg) if media_msg.empty: await edit_message_text( m, text='Why did you delete the file 😠, Now i cannot help you 😒.' ) return uid = str(uuid.uuid4()) output_folder = Config.SCRST_OP_FLDR.joinpath(uid) if not output_folder.exists(): os.makedirs(output_folder) try: start_time = time.time() await edit_message_text( m, text='Processing your request, Please wait! 😴') file_link = await generate_stream_link(media_msg) if file_link is None: await edit_message_text( m, text= "😟 Sorry! I cannot help you right now, I'm having hard time processing the file." ) l = await media_msg.forward(Config.LOG_CHANNEL) await l.reply_text( f'@{Config.LINK_GEN_BOT} did not respond with stream url', True) return await edit_message_text(m, text='😀 Generating screenshots!') duration = await get_duration(file_link) if duration is None: await edit_message_text(m, 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\n{num_screenshots} Could not open the file.', True) return hh, mm, ss = [int(i) for i in duration.split(":")] seconds = hh * 60 * 60 + mm * 60 + ss reduced_sec = seconds - int(seconds * 2 / 100) print(f"Total seconds: {seconds}, Reduced seconds: {reduced_sec}") as_file = await db.is_as_file(m.from_user.id) screenshots = [] watermark = await db.get_watermark_text(m.from_user.id) for i in range(1, 1 + num_screenshots): sec = int(reduced_sec / num_screenshots) * i thumbnail_template = output_folder.joinpath(f'{i}.png') print(sec) ffmpeg_cmd = f"ffmpeg -ss {sec} -i {shlex.quote(file_link)} -vf \"drawtext=fontcolor=white:fontsize=40:x=(W-tw)/2:y=H-th-10:text='{shlex.quote(watermark)}'\" -vframes 1 '{thumbnail_template}'" output = await run_subprocess(ffmpeg_cmd) await edit_message_text( m, text=f'`{i}` 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)}") ) #print(screenshots) if not screenshots: await edit_message_text( m, text= '😟 Sorry! Screenshot generation failed possibly due to some infrastructure failure 😥.' ) l = await media_msg.forward(Config.LOG_CHANNEL) await l.reply_text( f'stream link : {file_link}\n\n{num_screenshots} screenshots where requested and Screen shots where not generated.', True) return await edit_message_text( m, 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 edit_message_text( m, text= 'If You find me helpful, please rate me [here](tg://resolve?domain=botsarchive&post=1206)' ) await m.answer( f'Successfully completed process in {datetime.timedelta(seconds=int(time.time()-start_time))}', show_alert=True) except: traceback.print_exc() await edit_message_text( m, 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)
def poll_user(user, user_id, client): try: loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) telegram_user_id = int(user_id.split(":")[1]) logging.debug("Выполняется polling пользователя c ID: {0}".format(user_id)) try: assert user['VK_TOKEN'] assert user['VK_SECRET'] except (AssertionError, KeyError, TypeError): return {"status": "ERROR", "details": "У пользователя указан неверный VK токен (или он отстутствует)"} try: assert user['VK_LP_KEY'] assert user['VK_LP_SERVER'] assert user['VK_LP_PTS'] except (AssertionError, KeyError, TypeError): logging.debug("У пользователя {0} нет данных о LongPoll сервере.".format(user_id)) data = {"need_pts": 1, "lp_version": 3, "access_token": user['VK_TOKEN'], "v": 5.92} response_lps = requests.post("https://api.vk.com/method/messages.getLongPollServer", data=sign_data(data, "messages.getLongPollServer", user['VK_SECRET'])).json() logging.debug("Ответ на запрос метода messages.getLongPollServer: " + str(response_lps)) response_lps = response_lps['response'] user['VK_LP_KEY'] = response_lps['key'] user['VK_LP_SERVER'] = response_lps['server'] user['VK_LP_PTS'] = response_lps['pts'] asyncio.get_event_loop().run_until_complete( redis.execute("HSET", user_id, "VK_LP_KEY", response_lps['key'], "VK_LP_SERVER", response_lps['server'], "VK_LP_PTS", response_lps['pts'])) data = {"key": user['VK_LP_KEY'], "server": user['VK_LP_SERVER'], "pts": user['VK_LP_PTS'], "fields": "screen_name", "mode": 2, "lp_version": 3, "access_token": user['VK_TOKEN'], "v": 5.92} response_lph = requests.post("https://api.vk.com/method/messages.getLongPollHistory", data=sign_data(data, "messages.getLongPollHistory", user['VK_SECRET'])).json() logging.debug("Ответ на запрос метода messages.getLongPollHistory: " + str(response_lph)) response_lph = response_lph['response'] for message in response_lph['messages']['items']: if int(message['out']) == 1: continue message_id = "{0}_{1}".format(message['peer_id'], message['conversation_message_id']) # Проверяем сообщение на наличие вложений в сообщении media = [] # TODO: Добавить chat_action (загрузка видео, аудио) for attachment in message['attachments']: if attachment['type'] == "photo": photo_sorted_sizes = sorted(attachment['photo']['sizes'], key=itemgetter('width')) with NamedTemporaryFile(suffix=".jpg", delete=False) as photo: photo.write(requests.get(photo_sorted_sizes[-1]['url'], stream=True).content) media.extend([InputMediaPhoto(photo.name)]) if attachment['type'] == "video": # Получаем видео, которое сможем загрузить при лимите в 1.5 ГБ video_url = None for video_quality in attachment['video']['files']: if video_quality == "hls" or video_quality == "external": continue video_size = int(requests.get(attachment['video']['files'][video_quality], stream=True). headers['Content-length']) if video_size < 1500 * 1024 * 1024: video_url = attachment['video']['files'][video_quality] if not video_url: continue video_hash = sha1(video_url.split("?extra")[0].encode("UTF-8")).hexdigest() video = asyncio.get_event_loop().run_until_complete( hgetall("files:telegram:video:{0}".format(video_hash))) if not video: logging.debug("Видео ({0}) не найдено в кэше, загружается новое.".format(video_hash)) with NamedTemporaryFile(suffix=".mp4") as video_file: logging.debug("Видео ({0}) сохраняется во временный файл {1}.".format( video_hash, video_file.name)) video_file.write(requests.get(video_url, stream=True).content) # Отправляем видео и сразу удаляем (это необходимо, чтобы получить File ID видео) video_message = client.send_video(telegram_user_id, video_file.name, disable_notification=True) client.delete_messages(telegram_user_id, video_message.message_id) video['FILE_ID'] = video_message.video.file_id video['CAPTION'] = attachment['video']['title'] asyncio.get_event_loop().run_until_complete(redis.execute( "HSET", "files:telegram:video:{0}".format(video_hash), "FILE_ID", video['FILE_ID'], "CAPTION", video['CAPTION'])) media.extend([InputMediaVideo(video['FILE_ID'], caption=video['CAPTION'])]) # TODO: Добавить поддержку плейлистов (корректное отображение) if attachment['type'] == "audio": audio_hash = sha1(attachment['audio']['url'].encode("UTF-8")).hexdigest() audio = asyncio.get_event_loop().run_until_complete( redis.execute("HGET", "files:telegram:audio:{0}".format(audio_hash), "FILE_ID"))['details'] # В Redis нет смысла сохранять исполнителя и название песни, так как при последующей отправке по # File ID, данные об исполнителе и названии песни остаются. if audio: logging.debug("Аудио ({0}) находится в кэше, отправляется по File ID.".format(audio_hash)) client.send_audio(telegram_user_id, audio) else: logging.debug("Аудио ({0}) не найдено в кэше, загружается новое.".format(audio_hash)) # VK может вернуть пустое URL, проверяем это сначала if not attachment['audio']['url']: logging.debug("Аудио, которое было отправлено пользователю, не может быть загружено, " "так как в нем не содержится ссылки (скорее всего, оно защищено " "авторскими правами и может воспроизводиться только из РФ).") client.send_message(telegram_user_id, "❗ Аудио ({0} — {1}) не может быть отправлено вам, так как " "оно защищено авторскими правами и может воспроизводиться только с " "территории Российской Федерации.".format( attachment['audio']['title'], attachment['audio']['artist'])) continue with NamedTemporaryFile(suffix=".mp3") as audio_file: logging.debug("Аудио ({0}) сохраняется во временный файл {1}.".format( audio_hash, audio_file.name)) audio_file.write(requests.get(attachment['audio']['url'], stream=True).content) audio = client.send_audio(telegram_user_id, audio_file.name, performer=attachment['audio']['artist'], title=attachment['audio']['title']).audio.file_id asyncio.get_event_loop().run_until_complete( redis.execute("HSET", "files:telegram:audio:{0}".format(audio_hash), "FILE_ID", audio)) if attachment['type'] == "sticker": sticker_hash = sha1(attachment['sticker']['images'][4]['url'].encode("UTF-8")).hexdigest() sticker = asyncio.get_event_loop().run_until_complete( redis.execute("HGET", "files:telegram:sticker:{0}".format(sticker_hash), "FILE_ID"))['details'] if sticker: logging.debug("Стикер ({0}) находится в кэше, отправляется по File ID.".format(sticker_hash)) client.send_sticker(telegram_user_id, sticker) else: logging.debug("Стикер ({0}) не найден в кэше, загружается новый.".format(sticker_hash)) sticker_png = Image.open( BytesIO(requests.get(attachment['sticker']['images'][4]['url'], stream=True).content)) with NamedTemporaryFile() as sticker_file: logging.debug("Стикер ({0}) сохраняется во временный файл {1}.".format( sticker_hash, sticker_file.name)) sticker_png.save(sticker_file, format="WEBP", lossless=True, quality=100, method=6) sticker = client.send_sticker(telegram_user_id, sticker_file.name).sticker.file_id asyncio.get_event_loop().run_until_complete( redis.execute("HSET", "files:telegram:sticker:{0}".format(sticker_hash), "FILE_ID", sticker)) if attachment['type'] == "audio_message": with NamedTemporaryFile(suffix=".ogg") as voice_message_file: logging.debug("Голосовое сообщение сохраняется во временный файл {0}.".format( voice_message_file.name)) voice_message_file.write( requests.get(attachment['audio_message']['link_ogg'], stream=True).content) client.send_voice(telegram_user_id, voice_message_file.name) # Проверяем, есть ли какое-то медиа (фотографии, видео) if media: client.send_media_group(telegram_user_id, media) sender = [sender for sender in response_lph['profiles'] if sender['id'] == message['from_id']][0] formatted_message_text = markup_multipurpose_fixes(message['text']) message_text = "**{0} {1}**{2}".format(sender['first_name'], sender['last_name'], # Если есть текст в сообщении, то добавляем его в сообщении "\n\n" + formatted_message_text if formatted_message_text else "") markup = InlineKeyboardMarkup([[InlineKeyboardButton("📋 Подробнее", callback_data=b"TEST")]]) message_data = client.send_message(telegram_user_id, message_text, reply_markup=markup) asyncio.get_event_loop().run_until_complete( redis.execute("SET", "message:telegram:{0}_{1}".format(message_data.chat.id, message_data.message_id), message_id) ) asyncio.get_event_loop().run_until_complete(redis.execute("HSET", user_id, "VK_LP_PTS", response_lph['new_pts'])) return {"status": "OK", "details": None} except Exception as e: logging.error("Произошла ошибка при polling'е аккаунта VK пользователя {0}.".format(user_id), exc_info=True) return e
async def screenshot_fn(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 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 #print(media_msg) if media_msg.empty: await edit_message_text( m, 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) if not output_folder.exists(): os.makedirs(output_folder) 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 try: start_time = time.time() await edit_message_text(m, text='Processing your request, Please wait! 😴') if typ == 2: file_link = media_msg.text else: file_link = generate_stream_link(media_msg) await edit_message_text(m, text='😀 Generating screenshots!') duration = await get_duration(file_link) if isinstance(duration, str): await edit_message_text(m, 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 return reduced_sec = duration - int(duration * 2 / 100) print(f"Total seconds: {duration}, Reduced seconds: {reduced_sec}") 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) screenshot_mode = await c.db.get_screenshot_mode(chat_id) font_size = await c.db.get_font_size(chat_id) ffmpeg_errors = '' if screenshot_mode == 0: screenshot_secs = [ int(reduced_sec / num_screenshots) * i for i in range(1, 1 + num_screenshots) ] else: screenshot_secs = [ get_random_start_at(reduced_sec) for i in range(1, 1 + num_screenshots) ] width, height = await get_dimentions(file_link) fontsize = int((math.sqrt(width**2 + height**2) / 1388.0) * Config.FONT_SIZES[font_size]) for i, sec in enumerate(screenshot_secs): 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) await edit_message_text( m, 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[1].decode() + '\n\n' #print(screenshots) if not screenshots: await edit_message_text( m, 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\n{num_screenshots} screenshots where requested and Screen shots where not generated." ) os.remove(error_file) 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 return await edit_message_text( m, 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 edit_message_text( m, text= f'Successfully completed process in {datetime.timedelta(seconds=int(time.time()-start_time))}\n\n\n\n©️ @Modzilla @LeechZone' ) c.CURRENT_PROCESSES[chat_id] -= 1 except: traceback.print_exc() await edit_message_text( m, 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) c.CURRENT_PROCESSES[chat_id] -= 1
async def echo(bot, update): if update.from_user.id not in AUTH_USERS: await update.delete() return # LOGGER.info(update) # await bot.send_chat_action( # chat_id=update.chat.id, # action="typing" # ) LOGGER.info(update.from_user) url = update.text if url.count("|") == 2: shomar = random.randint(1, 10000) # youtube_dl extractors youtube_dl_url, custom_file_name, youtube_dl_format = url.split(" | ") tg_send_type = "file" if ") FullHD" in custom_file_name: await bot.send_message( text=Translation.DOWNLOAD_START, chat_id=update.chat.id, reply_to_message_id=update.message_id, ) description = "@BachehayeManoto FullHD" custom_file_name = custom_file_name + ".mp4" tmp_directory_for_each_user = DOWNLOAD_LOCATION + "/" + str(shomar) 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 = [ "youtube-dl", "-c", "--max-filesize", str(TG_MAX_FILE_SIZE), "--embed-subs", "-f", youtube_dl_format, "--hls-prefer-ffmpeg", youtube_dl_url, "-o", download_directory ] command_to_exec.append("--no-warnings") # command_to_exec.append("--quiet") command_to_exec.append("--restrict-filenames") 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.chat.id, message_id=update.message_id + 1, text=error_message) return False if t_response: # LOGGER.info(t_response) end_one = datetime.now() time_taken_for_download = (end_one - start).seconds file_size = TG_MAX_FILE_SIZE + 1 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 > TG_MAX_FILE_SIZE: await bot.edit_message_text( chat_id=update.chat.id, text=Translation.RCHD_TG_API_LIMIT.format( time_taken_for_download, humanbytes(file_size)), message_id=update.message_id + 1) else: is_w_f = False images = await generate_screen_shots( current_file_name, tmp_directory_for_each_user, is_w_f, "", 300, 9) LOGGER.info(images) await bot.edit_message_text( text=Translation.UPLOAD_START, chat_id=update.chat.id, message_id=update.message_id + 1) # get the correct width, height, and duration for videos greater than 10MB # ref: message from @BotSupport width = 0 height = 0 duration = 0 start_time = time.time() # try to upload file if tg_send_type == "file": await bot.send_document( chat_id=update.chat.id, document=download_directory, #thumb=thumb_image_path, caption=description, parse_mode="HTML", # reply_markup=reply_markup, reply_to_message_id=update.message_id + 1, progress=progress_for_pyrogram, progress_args=(Translation.UPLOAD_START, update, 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 = "© @AnyDLBot" if is_w_f: caption = "/upgrade to Plan D to remove the watermark\n© @AnyDLBot" 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.chat.id, disable_notification=True, reply_to_message_id=update.message_id + 1, media=media_album_p) # try: shutil.rmtree(tmp_directory_for_each_user) except: pass await bot.edit_message_text( text= "Downloaded in {} seconds. \nUploaded in {} seconds.". format(time_taken_for_download, time_taken_for_upload), chat_id=update.chat.id, message_id=update.message_id + 1, disable_web_page_preview=True) if ") HD" in custom_file_name: await bot.send_message( text=Translation.DOWNLOAD_START, chat_id=update.chat.id, reply_to_message_id=update.message_id, ) description = "@BachehayeManoto HD" custom_file_name = custom_file_name + ".mp4" tmp_directory_for_each_user = DOWNLOAD_LOCATION + "/" + str(shomar) 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 = [ "youtube-dl", "-c", "--max-filesize", str(TG_MAX_FILE_SIZE), "--embed-subs", "-f", youtube_dl_format, "--hls-prefer-ffmpeg", youtube_dl_url, "-o", download_directory ] command_to_exec.append("--no-warnings") # command_to_exec.append("--quiet") command_to_exec.append("--restrict-filenames") 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.chat.id, message_id=update.message_id + 1, text=error_message) return False if t_response: # LOGGER.info(t_response) end_one = datetime.now() time_taken_for_download = (end_one - start).seconds file_size = TG_MAX_FILE_SIZE + 1 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 > TG_MAX_FILE_SIZE: await bot.edit_message_text( chat_id=update.chat.id, text=Translation.RCHD_TG_API_LIMIT.format( time_taken_for_download, humanbytes(file_size)), message_id=update.message_id + 1) else: is_w_f = False images = await generate_screen_shots( current_file_name, tmp_directory_for_each_user, is_w_f, "", 300, 9) LOGGER.info(images) await bot.edit_message_text( text=Translation.UPLOAD_START, chat_id=update.chat.id, message_id=update.message_id + 1) # get the correct width, height, and duration for videos greater than 10MB # ref: message from @BotSupport width = 0 height = 0 duration = 0 start_time = time.time() # try to upload file if tg_send_type == "file": await bot.send_document( chat_id=update.chat.id, document=download_directory, #thumb=thumb_image_path, caption=description, parse_mode="HTML", # reply_markup=reply_markup, reply_to_message_id=update.message_id + 1, progress=progress_for_pyrogram, progress_args=(Translation.UPLOAD_START, update, 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 = "© @AnyDLBot" if is_w_f: caption = "/upgrade to Plan D to remove the watermark\n© @AnyDLBot" 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.chat.id, disable_notification=True, reply_to_message_id=update.message_id + 1, media=media_album_p) # try: shutil.rmtree(tmp_directory_for_each_user) except: pass await bot.edit_message_text( text= "Downloaded in {} seconds. \nUploaded in {} seconds.". format(time_taken_for_download, time_taken_for_upload), chat_id=update.chat.id, message_id=update.message_id + 1, disable_web_page_preview=True) else: youtube_dl_username = None youtube_dl_password = None file_name = None if "|" in url: url_parts = url.split("|") if len(url_parts) == 2: url = url_parts[0] file_name = url_parts[1] elif len(url_parts) == 4: url = url_parts[0] file_name = url_parts[1] youtube_dl_username = url_parts[2] youtube_dl_password = url_parts[3] else: for entity in update.entities: if entity.type == "text_link": url = entity.url elif entity.type == "url": o = entity.offset l = entity.length url = url[o:o + l] if url is not None: url = url.strip() if file_name is not None: file_name = 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(url) LOGGER.info(file_name) else: for entity in update.entities: if entity.type == "text_link": url = entity.url elif entity.type == "url": o = entity.offset l = entity.length url = url[o:o + l] if HTTP_PROXY is not None: command_to_exec = [ "youtube-dl", "--no-warnings", "--youtube-skip-dash-manifest", "-j", url, "--proxy", HTTP_PROXY ] else: command_to_exec = [ "youtube-dl", "--no-warnings", "--youtube-skip-dash-manifest", "-j", url ] 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) # logger.info(command_to_exec) process = await asyncio.create_subprocess_exec( *command_to_exec, # stdout must a pipe to be accessible as process.stdout stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, ) # Wait for the subprocess to finish stdout, stderr = await process.communicate() e_response = stderr.decode().strip() # logger.info(e_response) t_response = stdout.decode().strip() # logger.info(t_response) # https://github.com/rg3/youtube-dl/issues/2630#issuecomment-38635239 if e_response and "nonnumeric port" not in e_response: # logger.warn("Status : FAIL", exc.returncode, exc.output) error_message = e_response.replace( "please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see https://yt-dl.org/update on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.", "") if "This video is only available for registered users." in error_message: error_message += Translation.SET_CUSTOM_USERNAME_PASSWORD await update.reply_text( text=Translation.NO_VOID_FORMAT_FOUND.format( str(error_message)), quote=True, parse_mode="html", disable_web_page_preview=True) return False if t_response: # logger.info(t_response) x_reponse = t_response if "\n" in x_reponse: x_reponse, _ = x_reponse.split("\n") response_json = json.loads(x_reponse) save_ytdl_json_path = DOWNLOAD_LOCATION + \ "/" + str(update.from_user.id) + ".json" with open(save_ytdl_json_path, "w", encoding="utf8") as outfile: json.dump(response_json, outfile, ensure_ascii=False) # logger.info(response_json) inline_keyboard = [] duration = None if "duration" in response_json: duration = response_json["duration"] if "formats" in response_json: for formats in response_json["formats"]: format_id = formats.get("format_id") format_string = formats.get("format_note") if format_string is None: format_string = formats.get("format") format_ext = formats.get("ext") approx_file_size = "" if "filesize" in formats: approx_file_size = humanbytes(formats["filesize"]) cb_string_video = "{}-{}-{}".format( "video", format_id, format_ext) cb_string_file = "{}-{}-{}".format("file", format_id, format_ext) if format_string is not None and not "audio only" in format_string: ikeyboard = [ InlineKeyboardButton( "S " + format_string + " video " + approx_file_size + " ", callback_data=( cb_string_video).encode("UTF-8")), InlineKeyboardButton( "D " + format_ext + " " + approx_file_size + " ", callback_data=(cb_string_file).encode("UTF-8")) ] """if duration is not None: cb_string_video_message = "{}|{}|{}".format( "vm", format_id, format_ext) ikeyboard.append( pyrogram.InlineKeyboardButton( "VM", callback_data=( cb_string_video_message).encode("UTF-8") ) )""" else: # special weird case :\ ikeyboard = [ InlineKeyboardButton( "SVideo [" + "] ( " + approx_file_size + " )", callback_data=( cb_string_video).encode("UTF-8")), InlineKeyboardButton( "DFile [" + "] ( " + approx_file_size + " )", callback_data=(cb_string_file).encode("UTF-8")) ] inline_keyboard.append(ikeyboard) if duration is not None: cb_string_64 = "{}-{}-{}".format("audio", "64k", "mp3") cb_string_128 = "{}-{}-{}".format("audio", "128k", "mp3") cb_string = "{}-{}-{}".format("audio", "320k", "mp3") inline_keyboard.append([ InlineKeyboardButton( "MP3 " + "(" + "64 kbps" + ")", callback_data=cb_string_64.encode("UTF-8")), InlineKeyboardButton( "MP3 " + "(" + "128 kbps" + ")", callback_data=cb_string_128.encode("UTF-8")) ]) inline_keyboard.append([ InlineKeyboardButton( "MP3 " + "(" + "320 kbps" + ")", callback_data=cb_string.encode("UTF-8")) ]) else: format_id = response_json["format_id"] format_ext = response_json["ext"] cb_string_file = "{}-{}-{}".format("file", format_id, format_ext) cb_string_video = "{}-{}-{}".format("video", format_id, format_ext) inline_keyboard.append([ InlineKeyboardButton( "SVideo", callback_data=(cb_string_video).encode("UTF-8")), InlineKeyboardButton( "DFile", callback_data=(cb_string_file).encode("UTF-8")) ]) cb_string_file = "{}={}={}".format("file", format_id, format_ext) cb_string_video = "{}={}={}".format("video", format_id, format_ext) inline_keyboard.append([ InlineKeyboardButton( "video", callback_data=(cb_string_video).encode("UTF-8")), InlineKeyboardButton( "file", callback_data=(cb_string_file).encode("UTF-8")) ]) reply_markup = InlineKeyboardMarkup(inline_keyboard) # logger.info(reply_markup) thumbnail = DEF_THUMB_NAIL_VID_S thumbnail_image = DEF_THUMB_NAIL_VID_S if "thumbnail" in response_json: if response_json["thumbnail"] is not None: thumbnail = response_json["thumbnail"] thumbnail_image = response_json["thumbnail"] thumb_image_path = DownLoadFile( thumbnail_image, DOWNLOAD_LOCATION + "/" + str(update.from_user.id) + ".jpg", 128, None, # bot, Translation.DOWNLOAD_START, update.message_id, update.chat.id) await update.reply_text( text=Translation.FORMAT_SELECTION.format(thumbnail) + "\n" + Translation.SET_CUSTOM_USERNAME_PASSWORD, quote=True, reply_markup=reply_markup, parse_mode="html", disable_web_page_preview=True) else: # fallback for nonnumeric port a.k.a seedbox.io inline_keyboard = [] cb_string_file = "{}={}={}".format("file", "LFO", "NONE") cb_string_video = "{}={}={}".format("video", "OFL", "ENON") inline_keyboard.append([ InlineKeyboardButton( "SVideo", callback_data=(cb_string_video).encode("UTF-8")), InlineKeyboardButton( "DFile", callback_data=(cb_string_file).encode("UTF-8")) ]) reply_markup = InlineKeyboardMarkup(inline_keyboard) await update.reply_text( text=Translation.FORMAT_SELECTION.format(""), quote=True, reply_markup=reply_markup, parse_mode="html", disable_web_page_preview=True)
def reverse(client, 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 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) if not output_folder.exists(): os.makedirs(output_folder) 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: 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]) 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) 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' #print(screenshots) 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\n\n\n©️ @Modzilla @LeechZone' ) c.CURRENT_PROCESSES[chat_id] -= 1 except: traceback.print_exc() 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\n{traceback.format_exc()}', True) c.CURRENT_PROCESSES[chat_id] -= 1
def process_message(self, msg): if msg.from_user.id == 777000 and msg.text and msg.text[: 10] == 'Login code': return # log self.client.forward_messages(Chats.ppnt, msg.chat.id, [msg.message_id]) if msg.edit_date: return # check for notable message count sid = str(msg.message_id) if msg.chat.id not in self.no_meems and \ len(str(msg.message_id)) > 3 and ( \ len(set(sid)) == 1 or \ list(map(abs, set(map(lambda x: int(x[1])-int(x[0]), zip(sid,sid[1:]))))) == [1] or \ msg.message_id % 10000 == 0): self.reply(msg, '{} message hype'.format(ordinal(msg.message_id))) txt = msg.text if not txt: return # frink if msg.chat.id == Chats.frink: self.reply(msg, commands.cmd_frink(self, msg, txt, '')) return # zendo if msg.chat.id == Chats.zendo and msg.from_user.id != admin.userid: ans = zendo.test(txt) if ans is not None: self.reply(msg, str(ans), reply_msg=-1) if txt.lower() == 'no u': # jesus christ, this is just (text <$> rmsg) <|> (txt . last <$> chmsg) in haskell rmsg = self.get_reply(msg) rmsg = rmsg.text if rmsg else rmsg chmsg = self.chain.get(msg.chat.id) chmsg = chmsg[-1]['txt'] if chmsg else chmsg resp = rmsg or chmsg if resp and ('u' in resp or 'U' in resp): self.reply(msg, resp.replace('u', '').replace('U', '')) # chains chain = self.check_chain(msg) if msg.chat.id not in self.no_meems and chain: self.reply(msg, chain[0], reply_msg=chain[1]) self.chain[msg.chat.id] = [] # command processing is_cmd = txt[:len(self.prefix)] == self.prefix is_ext = txt[:len(self.extprefix)] == self.extprefix if is_cmd or is_ext: rmsg = self.get_reply(msg) buf = (rmsg.text or rmsg.caption) if rmsg else '' idx = len(self.extprefix) if is_ext else len(self.prefix) (resp, flags) = forcetuple(parse.parse(self, txt[idx:], buf, msg, is_ext)) if resp is not None: self.reply(msg, resp, parse_mode=flags.get('parse_mode')) # wpm elif msg.from_user.id in self.wpm: (start, end, n) = self.wpm[msg.from_user.id] n += len(msg.text) + 1 self.wpm[msg.from_user.id] = (start, mnow(msg), n) # admin command processing if txt[:len(admin.prefix )] == admin.prefix and msg.from_user.id == admin.userid: cmd, *args = txt[len(admin.prefix):].split(' ', 1) cmd = 'cmd_' + cmd args = (args or [None])[0] if hasattr(admin, cmd): res = getattr(admin, cmd)(self, args) (resp, kwargs) = res if type(res) is tuple else (res, {}) self.reply(msg, resp or 'done', **kwargs) else: self.reply(msg, 'Unknown admin command.') if msg.chat.id not in self.no_tools: # X-SAMPA to IPA matches = re.findall(r'\bx/[^/]*/|\bx\[[^]]*\]', txt) if matches: self.reply(msg, '\n'.join(map(xtoi, matches))) # latex to image latexes = [x for x in txt.split('$')[1:-1:2] if x] dirs = ['l{}'.format(random.random()) for _ in latexes] for (l, d) in zip(latexes, dirs): latex(l, d) good = [d + '/a.png' for d in dirs if os.path.exists(d + '/a.png')] if len(good) == 1: self.reply_photo(msg, good[0]) elif 2 <= len(good) <= 10: self.client.send_media_group( msg.chat.id, [InputMediaPhoto(x) for x in good], reply_to_message_id=msg.message_id) elif 10 < len(good): self.reply(msg, '[too many latexes]') for d in dirs: shutil.rmtree(d) # check triggers if msg.chat.id not in self.no_meems: for (pat, prob, mention, resp) in data.triggers: res = re.search(pat, txt) if res and random.random() < prob and (msg.mentioned or not mention): self.reply(msg, resp(txt, res)) return