diff --git a/misskaty/helper/__init__.py b/misskaty/helper/__init__.py index eaac85a8..5d82ce2f 100644 --- a/misskaty/helper/__init__.py +++ b/misskaty/helper/__init__.py @@ -9,5 +9,6 @@ from .misc import * from .pyro_progress import * from .stickerset import * from .time_gap import * +from .ssgen_helper import * from .tools import * from .ytdl_helper import * \ No newline at end of file diff --git a/misskaty/helper/ssgen_helper.py b/misskaty/helper/ssgen_helper.py new file mode 100644 index 00000000..68ffe7bd --- /dev/null +++ b/misskaty/helper/ssgen_helper.py @@ -0,0 +1,141 @@ +from misskaty.core.message_utils import * +import uuid +import os +import time +import shlex +import datetime +from pyrogram import enums +import random +import traceback +from pyrogram.types import InputMediaPhoto, InlineKeyboardButton, InlineKeyboardMarkup + +async def run_subprocess(cmd): + process = await asyncio.create_subprocess_shell( + cmd, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE + ) + return await process.communicate() + +def get_random_start_at(seconds, dur=0): + return random.randint(0, seconds-dur) + +async def get_duration(input_file_link): + ffmpeg_dur_cmd = f"ffprobe -v error -show_entries format=duration -of csv=p=0:s=x -select_streams v:0 {shlex.quote(input_file_link)}" + #print(ffmpeg_dur_cmd) + out, err = await run_subprocess(ffmpeg_dur_cmd) + out = out.decode().strip() + if not out: + return err.decode() + duration = round(float(out)) + if duration: + return duration + return 'No duration!' + +def is_url(text): + return text.startswith('http') + +async def get_dimentions(input_file_link): + ffprobe_cmd = f"ffprobe -v error -show_entries stream=width,height -of csv=p=0:s=x -select_streams v:0 {shlex.quote(input_file_link)}" + output = await run_subprocess(ffprobe_cmd) + try: + width, height = [int(i.strip()) for i in output[0].decode().split('x')] + except Exception as e: + print(e) + width, height = 1280, 534 + return width, height + +async def screenshot_flink(c, m): + + chat_id = m.from_user.id + if c.CURRENT_PROCESSES.get(chat_id, 0) == 1: + return await m.answer('You have reached the maximum parallel processes! Try again after one of them finishes.', show_alert=True) + 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 editPesan(m, 'Why did you delete the file 😠, Now i cannot help you πŸ˜’.') + c.CURRENT_PROCESSES[chat_id] -= 1 + return + + uid = str(uuid.uuid4()) + output_folder = "GenSS/".joinpath(uid) + if not output_folder.exists(): + os.makedirs(output_folder) + + try: + start_time = time.time() + + await editPesan(m, 'Give me some time bruh!! 😴') + + await editPesan(m, 'πŸ˜€ Taking Snaps!') + file_link = m.command[1] + duration = await get_duration(file_link) + if isinstance(duration, str): + await editPesan(m, "Oops, What's that? Couldn't Open the file😟.") + c.CURRENT_PROCESSES[chat_id] -= 1 + return + + reduced_sec = duration - int(duration*2 / 100) + print(f"Total seconds: {duration}, Reduced seconds: {reduced_sec}") + screenshots = [] + ffmpeg_errors = '' + + screenshot_secs = [get_random_start_at(reduced_sec) for i in range(1, 1+num_screenshots)] + width, height = await get_dimentions(file_link) + + for i, sec in enumerate(screenshot_secs): + thumbnail_template = output_folder.joinpath(f'{i+1}.png') + #print(sec) + ffmpeg_cmd = f"mediaextract -hide_banner -ss {sec} -i {shlex.quote(file_link)} -vframes 1 '{thumbnail_template}'" + output = await run_subprocess(ffmpeg_cmd) + await editPesan(m, f'πŸ˜€ `{i+1}` of `{num_screenshots}` generated!') + if thumbnail_template.exists(): + 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 editPesan(m, '😟 Sorry! Screenshot generation failed possibly due to some infrastructure failure πŸ˜₯.') + c.CURRENT_PROCESSES[chat_id] -= 1 + return + + await editPesan(m, f'πŸ€“ Its done , Now starting to upload!') + await media_msg.reply_chat_action(enums.ChatAction.UPLOAD_PHOTO) + await media_msg.reply_media_group(screenshots, True) + + await editPesan(m, f'Completed in {datetime.timedelta(seconds=int(time.time()-start_time))}\n\nJoin @moviesonlydiscussion\n\n©️ @prgofficial') + c.CURRENT_PROCESSES[chat_id] -= 1 + + except: + aa = traceback.print_exc() + await editPesan(m, '😟 Sorry! Screenshot generation failed, ERR: {aa} πŸ˜₯.') + c.CURRENT_PROCESSES[chat_id] -= 1 + +def gen_ik_buttons(): + btns = [] + i_keyboard = [] + for i in range(2, 11): + i_keyboard.append( + InlineKeyboardButton( + f"{i}", + f"scht+{i}" + ) + ) + if (i>2) and (i%2) == 1: + btns.append(i_keyboard) + i_keyboard = [] + if i==10: + btns.append(i_keyboard) + return btns \ No newline at end of file diff --git a/misskaty/plugins/genss.py b/misskaty/plugins/genss.py index 0c3080b7..15853b8f 100644 --- a/misskaty/plugins/genss.py +++ b/misskaty/plugins/genss.py @@ -5,6 +5,7 @@ * @projectName MissKatyPyro * Copyright @YasirPedia All rights reserved """ +import datetime import os import time import traceback @@ -14,12 +15,14 @@ from shutil import rmtree from pyrogram import enums, filters from pyrogram.errors import FloodWait +from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup from misskaty import BOT_USERNAME, app -from misskaty.core.message_utils import * -from misskaty.core.decorator.pyro_cooldown import wait from misskaty.core.decorator.errors import capture_err -from misskaty.helper import genss_link, progress_for_pyrogram, take_ss +from misskaty.core.decorator.pyro_cooldown import wait +from misskaty.core.message_utils import * +from misskaty.helper import (gen_ik_buttons, get_duration, is_url, + progress_for_pyrogram, screenshot_flink, take_ss) from misskaty.vars import COMMAND_HANDLER LOGGER = getLogger(__name__) @@ -98,34 +101,21 @@ async def genss(client, m): async def genss_link(client, m): if len(m.command) == 1: return await kirimPesan(m, f"Use /{m.command[0]} link to generate screenshot from URL.") - try: - link = m.text.split(" ")[1] - process = await kirimPesan(m, "`Processing, please wait..`") - tmp_directory_for_each_user = f"./MissKaty_Genss/{str(m.from_user.id)}" - if not os.path.isdir(tmp_directory_for_each_user): - os.makedirs(tmp_directory_for_each_user) - images = await genss_link(process, link, tmp_directory_for_each_user, 5, 8) - await sleep(2) - await editPesan(process, "Mencoba mengupload, hasil generate screenshot..") - await client.send_chat_action(chat_id=m.chat.id, action=enums.ChatAction.UPLOAD_PHOTO) - try: - await m.reply_media_group(images, reply_to_message_id=m.id) - except FloodWait as e: - await sleep(e.value) - await m.reply_media_group(images, reply_to_message_id=m.id) - await kirimPesan( - m, - f"β˜‘οΈ Uploaded [8] screenshoot.\n\nGenerated by @{BOT_USERNAME}." - ) - await process.delete() - try: - rmtree(tmp_directory_for_each_user) - except: - pass - except Exception: - exc = traceback.format_exc() - await kirimPesan(m, f"Gagal generate screenshot.\n\n{exc}") - try: - rmtree(tmp_directory_for_each_user) - except: - pass + if not is_url(m.command[1]): + return await kirimPesan(m, "Please use valid URL.") + snt = await m.reply_text("Give me some time to process your request!! 😴", quote=True) + + duration = await get_duration(m.command[1]) + if isinstance(duration, str): + return await snt.edit_text("😟 Sorry! (β•₯﹏β•₯) I cannot open the file.") + + btns = gen_ik_buttons() + + await snt.edit_text( + text=f"Tell me what to do bro πŸ₯³.\n\nTotal duration: `{datetime.timedelta(seconds=duration)}` (`{duration}s`)", + reply_markup=InlineKeyboardMarkup(btns) + ) + +@app.on_callback_query(filters.create(lambda _, query: query.data.startswith('scht'))) +async def _(c, m): + asyncio.create_task(screenshot_flink()(c, m)) \ No newline at end of file diff --git a/misskaty/plugins/paste.py b/misskaty/plugins/paste.py index 9ad76ed9..fac89f45 100644 --- a/misskaty/plugins/paste.py +++ b/misskaty/plugins/paste.py @@ -13,6 +13,7 @@ from pyrogram import filters from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup from misskaty import app +from misskaty.core.message_utils import * from misskaty.helper import http, rentry, post_to_telegraph from misskaty.vars import COMMAND_HANDLER @@ -67,7 +68,7 @@ pattern = compiles(r"^text/|json$|yaml$|xml$|toml$|x-sh$|x-shellscript$|x-subrip async def telegraph_paste(_, message): reply = message.reply_to_message if not reply and len(message.command) < 2: - return await message.reply_text(f"**Reply To A Message With /{message.command[0]} or with command**") + return await kirimPesan(message, f"**Reply To A Message With /{message.command[0]} or with command**") if message.from_user: if message.from_user.username: @@ -76,10 +77,14 @@ async def telegraph_paste(_, message): uname = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id}) [{message.from_user.id}]" else: uname = message.sender_chat.title - msg = await message.reply_text("`Pasting to Telegraph...`") + msg = await kirimPesan(message, "`Pasting to Telegraph...`") if reply and (reply.photo or reply.animation): file = await reply.download() - url = await post_to_telegraph(True, media=file) + try: + url = await post_to_telegraph(True, media=file) + except Exception as err: + remove(file) + return editPesan(msg, f"Failed to upload. ERR: {err}") button = [ [InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], @@ -87,14 +92,14 @@ async def telegraph_paste(_, message): pasted = f"**Successfully upload your media to Telegraph.\n\nUpload by {uname}**" remove(file) - return await msg.edit(pasted, reply_markup=InlineKeyboardMarkup(button)) + return await editPesan(msg, pasted, reply_markup=InlineKeyboardMarkup(button)) data = "" limit = 1024 * 1024 if reply and reply.document: if reply.document.file_size > limit: - return await msg.edit(f"**You can only paste files smaller than {humanbytes(limit)}.**") + return await editPesan(msg, f"**You can only paste files smaller than {humanbytes(limit)}.**") if not pattern.search(reply.document.mime_type): - return await msg.edit("**Only text files can be pasted.**") + return await editPesan(msg, "**Only text files can be pasted.**") file = await reply.download() title = message.text.split(None, 1)[1] if len(message.command) > 1 else "MissKaty Paste" try: @@ -106,7 +111,7 @@ async def telegraph_paste(_, message): remove(file) except: pass - return await msg.edit("`File Not Supported !`") + return await editPesan(msg, "`File Not Supported !`") elif reply and (reply.text or reply.caption): title = message.text.split(None, 1)[1] if len(message.command) > 1 else "MissKaty Paste" data = reply.text.html or reply.caption.html @@ -117,18 +122,17 @@ async def telegraph_paste(_, message): try: url = await post_to_telegraph(False, title, data) except Exception as e: - await msg.edit(f"ERROR: {e}") - return + return await editPesan(msg, f"ERROR: {e}") if not url: - return await msg.edit("Text Too Short Or File Problems") + return await editPesan(msg, "Text Too Short Or File Problems") button = [ [InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], ] pasted = f"**Successfully pasted your data to Telegraph.\n\nPaste by {uname}**" - await msg.edit(pasted, reply_markup=InlineKeyboardMarkup(button)) + await editPesan(msg, pasted, reply_markup=InlineKeyboardMarkup(button)) # Default Paste to Wastebin using Deta @app.on_message(filters.command(["paste"], COMMAND_HANDLER)) @@ -136,16 +140,16 @@ async def wastepaste(_, message): reply = message.reply_to_message target = str(message.command[0]).split("@", maxsplit=1)[0] if not reply and len(message.command) < 2: - return await message.reply_text(f"**Reply To A Message With /{target} or with command**") + return await kirimPesan(message, f"**Reply To A Message With /{target} or with command**") - msg = await message.reply_text("`Pasting to YasirBin...`") + msg = await kirimPesan(message, "`Pasting to YasirBin...`") data = "" limit = 1024 * 1024 if reply and reply.document: if reply.document.file_size > limit: - return await msg.edit(f"**You can only paste files smaller than {humanbytes(limit)}.**") + return await editPesan(msg, f"**You can only paste files smaller than {humanbytes(limit)}.**") if not pattern.search(reply.document.mime_type): - return await msg.edit("**Only text files can be pasted.**") + return await editPesan(msg, "**Only text files can be pasted.**") file = await reply.download() try: with open(file, "r") as text: @@ -156,7 +160,7 @@ async def wastepaste(_, message): remove(file) except: pass - return await msg.edit("`File Not Supported !`") + return await editPesan(msg, "`File Not Supported !`") elif reply and (reply.text or reply.caption): data = reply.text.html or reply.caption.html elif not reply and len(message.command) >= 2: @@ -182,18 +186,17 @@ async def wastepaste(_, message): response = await http.post('https://yasirbin.deta.dev/api/new', json=json_data) url = f"https://yasirbin.deta.dev/{response.json()['id']}" except Exception as e: - await msg.edit(f"ERROR: {e}") - return + return await editPesan(msg, f"ERROR: {e}") if not url: - return await msg.edit("Text Too Short Or File Problems") + return await editPesan(msg, "Text Too Short Or File Problems") button = [ [InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], ] pasted = f"**Successfully pasted your data to YasirBin.\n\nPaste by {uname}**" - await msg.edit(pasted, reply_markup=InlineKeyboardMarkup(button)) + await editPesan(msg, pasted, reply_markup=InlineKeyboardMarkup(button)) # Nekobin Paste @app.on_message(filters.command(["neko"], COMMAND_HANDLER)) @@ -201,16 +204,16 @@ async def nekopaste(_, message): reply = message.reply_to_message target = str(message.command[0]).split("@", maxsplit=1)[0] if not reply and len(message.command) < 2: - return await message.reply_text(f"**Reply To A Message With /{target} or with command**") + return await kirimPesan(message, f"**Reply To A Message With /{target} or with command**") - msg = await message.reply_text("`Pasting to Nekobin...`") + msg = await kirimPesan(message, "`Pasting to Nekobin...`") data = "" limit = 1024 * 1024 if reply and reply.document: if reply.document.file_size > limit: - return await msg.edit(f"**You can only paste files smaller than {humanbytes(limit)}.**") + return await editPesan(message, f"**You can only paste files smaller than {humanbytes(limit)}.**") if not pattern.search(reply.document.mime_type): - return await msg.edit("**Only text files can be pasted.**") + return await editPesan(message, "**Only text files can be pasted.**") file = await reply.download() try: with open(file, "r") as text: @@ -221,7 +224,7 @@ async def nekopaste(_, message): remove(file) except: pass - return await msg.edit("`File Not Supported !`") + return await editPesan(message, "`File Not Supported !`") elif reply and (reply.text or reply.caption): data = reply.text.html or reply.caption.html elif not reply and len(message.command) >= 2: @@ -239,18 +242,17 @@ async def nekopaste(_, message): x = (await http.post("https://nekobin.com/api/documents", json={"content": data})).json() url = f"https://nekobin.com/{x['result']['key']}" except Exception as e: - await msg.edit(f"ERROR: {e}") - return + return await editPesan(msg, f"ERROR: {e}") if not url: - return await msg.edit("Text Too Short Or File Problems") + return await editPesan(msg, "Text Too Short Or File Problems") button = [ [InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], ] pasted = f"**Successfully pasted your data to Nekobin.\n\nPaste by {uname}**" - await msg.edit(pasted, reply_markup=InlineKeyboardMarkup(button)) + await editPesan(msg, pasted, reply_markup=InlineKeyboardMarkup(button)) # Paste as spacebin @app.on_message(filters.command(["sbin"], COMMAND_HANDLER)) @@ -258,16 +260,16 @@ async def spacebinn(_, message): reply = message.reply_to_message target = str(message.command[0]).split("@", maxsplit=1)[0] if not reply and len(message.command) < 2: - return await message.reply_text(f"**Reply To A Message With /{target} or with command**") + return await kirimPesan(message, f"**Reply To A Message With /{target} or with command**") - msg = await message.reply_text("`Pasting to Spacebin...`") + msg = await kirimPesan(message, "`Pasting to Spacebin...`") data = "" limit = 1024 * 1024 if reply and reply.document: if reply.document.file_size > limit: - return await msg.edit(f"**You can only paste files smaller than {humanbytes(limit)}.**") + return await editPesan(msg, f"**You can only paste files smaller than {humanbytes(limit)}.**") if not pattern.search(reply.document.mime_type): - return await msg.edit("**Only text files can be pasted.**") + return await editPesan(msg, "**Only text files can be pasted.**") file = await reply.download() try: with open(file, "r") as text: @@ -278,7 +280,7 @@ async def spacebinn(_, message): remove(file) except: pass - return await msg.edit("`File Not Supported !`") + return await editPesan(msg, "`File Not Supported !`") elif reply and (reply.text or reply.caption): data = reply.text.html or reply.caption.html elif not reply and len(message.command) >= 2: @@ -298,18 +300,17 @@ async def spacebinn(_, message): response = response.json() url = "https://spaceb.in/"+response['payload']['id'] except Exception as e: - await msg.edit(f"ERROR: {e}") - return + return await editPesan(msg, f"ERROR: {e}") if not url: - return await msg.edit("Text Too Short Or File Problems") + return await editPesan(msg, "Text Too Short Or File Problems") button = [ [InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], ] pasted = f"**Successfully pasted your data to Spacebin.\n\nPaste by {uname}**" - await msg.edit(pasted, reply_markup=InlineKeyboardMarkup(button)) + await editPesan(msg, pasted, reply_markup=InlineKeyboardMarkup(button)) # Rentry paste @app.on_message(filters.command(["rentry"], COMMAND_HANDLER)) @@ -317,16 +318,16 @@ async def rentrypaste(_, message): reply = message.reply_to_message target = str(message.command[0]).split("@", maxsplit=1)[0] if not reply and len(message.command) < 2: - return await message.reply_text(f"**Reply To A Message With /{target} or with command**") + return await kirimPesan(message, f"**Reply To A Message With /{target} or with command**") - msg = await message.reply_text("`Pasting to Rentry...`") + msg = await kirimPesan(message, "`Pasting to Rentry...`") data = "" limit = 1024 * 1024 if reply and reply.document: if reply.document.file_size > limit: - return await msg.edit(f"**You can only paste files smaller than {humanbytes(limit)}.**") + return await editPesan(msg, f"**You can only paste files smaller than {humanbytes(limit)}.**") if not pattern.search(reply.document.mime_type): - return await msg.edit("**Only text files can be pasted.**") + return await editPesan(msg, "**Only text files can be pasted.**") file = await reply.download() try: with open(file, "r") as text: @@ -337,7 +338,7 @@ async def rentrypaste(_, message): remove(file) except: pass - return await msg.edit("`File Not Supported !`") + return await editPesan(msg, "`File Not Supported !`") elif reply and (reply.text or reply.caption): data = reply.text.markdown or reply.caption.markdown elif not reply and len(message.command) >= 2: @@ -354,18 +355,17 @@ async def rentrypaste(_, message): try: url = await rentry(data) except Exception as e: - await msg.edit(f"`{e}`") - return + return await msg.edit(f"`{e}`") if not url: - return await msg.edit("Text Too Short Or File Problems") + return await editPesan(msg, "Text Too Short Or File Problems") button = [ [InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], ] pasted = f"**Successfully pasted your data to Rentry.\n\nPaste by {uname}**" - await msg.edit(pasted, reply_markup=InlineKeyboardMarkup(button)) + await editPesan(msg, pasted, reply_markup=InlineKeyboardMarkup(button)) # Tempaste pastebin @@ -374,16 +374,16 @@ async def tempaste(_, message): reply = message.reply_to_message target = str(message.command[0]).split("@", maxsplit=1)[0] if not reply and len(message.command) < 2: - return await message.reply_text(f"**Reply To A Message With /{target} or with command**") + return await editPesan(message, f"**Reply To A Message With /{target} or with command**") - msg = await message.reply_text("`Pasting to TempPaste...`") + msg = await kirimPesan(message, "`Pasting to TempPaste...`") data = "" limit = 1024 * 1024 if reply and reply.document: if reply.document.file_size > limit: - return await msg.edit(f"**You can only paste files smaller than {humanbytes(limit)}.**") + return await editPesan(msg, f"**You can only paste files smaller than {humanbytes(limit)}.**") if not pattern.search(reply.document.mime_type): - return await msg.edit("**Only text files can be pasted.**") + return await editPesan(msg, "**Only text files can be pasted.**") file = await reply.download() try: with open(file, "r") as text: @@ -394,7 +394,7 @@ async def tempaste(_, message): remove(file) except: pass - return await msg.edit("`File Not Supported !`") + return await editPesan(msg, "`File Not Supported !`") elif reply and (reply.text or reply.caption): data = reply.text.html or reply.caption.html elif not reply and len(message.command) >= 2: @@ -417,20 +417,19 @@ async def tempaste(_, message): "paste_content": data, "visibility": "public", "expiry_date_type": "months", - "expiry_date": 12, + "expiry_date": 1, }, ) url = f"https://tempaste.com/{json_loads(req.text)['url']}" except Exception as e: - await msg.edit(f"`{e}`") - return + return await editPesan(msg, f"`{e}`") if not url: - return await msg.edit("Text Too Short Or File Problems") + return await editPesan(msg, "Text Too Short Or File Problems") button = [ [InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], ] pasted = f"**Successfully pasted your data to Tempaste.\n\nPaste by {uname}**" - await msg.edit(pasted, reply_markup=InlineKeyboardMarkup(button)) + await editPesan(msg, pasted, reply_markup=InlineKeyboardMarkup(button))