diff --git a/misskaty/__init__.py b/misskaty/__init__.py index bc5c914d..625fa85f 100644 --- a/misskaty/__init__.py +++ b/misskaty/__init__.py @@ -42,7 +42,7 @@ MOD_NOLOAD = ["subscene_dl"] HELPABLE = {} cleanmode = {} botStartTime = time.time() -misskaty_version = "v2.13" +misskaty_version = "v2.14" uvloop.install() faulthandler_enable() @@ -54,7 +54,7 @@ app = Client( api_id=API_ID, api_hash=API_HASH, bot_token=BOT_TOKEN, - mongodb=dict(connection=AsyncClient(DATABASE_URI), remove_peers=False), + mongodb=dict(connection=AsyncClient(DATABASE_URI), remove_peers=True), sleep_threshold=180, app_version="MissKatyPyro Stable", workers=50, @@ -69,6 +69,7 @@ user = Client( session_string=USER_SESSION, mongodb=dict(connection=AsyncClient(DATABASE_URI), remove_peers=False), sleep_threshold=180, + app_version="MissKaty Ubot", ) jobstores = { diff --git a/misskaty/helper/tools.py b/misskaty/helper/tools.py index 70323f3b..12532f85 100644 --- a/misskaty/helper/tools.py +++ b/misskaty/helper/tools.py @@ -4,6 +4,8 @@ import random import re import string import time +import cv2 +import numpy as np from http.cookies import SimpleCookie from re import match as re_match from typing import Union @@ -167,4 +169,44 @@ def isValidURL(str): # If the string is empty # return false - return False if str is None else bool((re.search(p, str))) \ No newline at end of file + return False if str is None else bool((re.search(p, str))) + + +async def gen_trans_image(msg, path): + # Download image + dl = await msg.download() + + # load image + img = cv2.imread(dl) + + # convert to graky + gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + + # threshold input image as mask + mask = cv2.threshold(gray, 250, 255, cv2.THRESH_BINARY)[1] + + # negate mask + mask = 255 - mask + + # apply morphology to remove isolated extraneous noise + # use borderconstant of black since foreground touches the edges + kernel = np.ones((3,3), np.uint8) + mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel) + mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel) + + # anti-alias the mask -- blur then stretch + # blur alpha channel + mask = cv2.GaussianBlur(mask, (0,0), sigmaX=2, sigmaY=2, borderType = cv2.BORDER_DEFAULT) + + # linear stretch so that 127.5 goes to 0, but 255 stays 255 + mask = (2*(mask.astype(np.float32))-255.0).clip(0,255).astype(np.uint8) + + # put mask into alpha channel + result = img.copy() + result = cv2.cvtColor(result, cv2.COLOR_BGR2BGRA) + result[:, :, 3] = mask + + # save resulting masked image + cv2.imwrite(path, result) + os.remove(dl) + return path \ No newline at end of file diff --git a/misskaty/plugins/chatbot_ai.py b/misskaty/plugins/chatbot_ai.py index be5643a6..0cc93d0a 100644 --- a/misskaty/plugins/chatbot_ai.py +++ b/misskaty/plugins/chatbot_ai.py @@ -13,7 +13,7 @@ from pyrogram.types import Message from misskaty import app from misskaty.core import pyro_cooldown -from misskaty.helper import check_time_gap, fetch, post_to_telegraph, use_chat_lang +from misskaty.helper import check_time_gap, fetch, post_to_telegraph, use_chat_lang, from misskaty.vars import GOOGLEAI_KEY, COMMAND_HANDLER, OPENAI_KEY, SUDO @@ -38,14 +38,16 @@ async def gemini_chatbot(_, ctx: Message, strings): try: data = { "query": ctx.text.split(maxsplit=1)[1], + "key": GOOGLEAI_KEY } + # Fetch from API beacuse my VPS is not supported response = await fetch.post( "https://yasirapi.eu.org/gemini", data=data ) if not response.json().get("candidates"): await ctx.reply_msg("⚠️ Sorry, the prompt you sent maybe contains a forbidden word that is not permitted by AI.") else: - await ctx.reply_msg(html.escape(response.json()["candidates"][0]["content"]["parts"][0]["text"])) + await ctx.reply_msg(html.escape(f'{response.json()["candidates"][0]["content"]["parts"][0]["text"]}\n\nPowered by: Gemini Flash 1.5')) await msg.delete() except Exception as e: await ctx.reply_msg(str(e)) diff --git a/misskaty/plugins/misc_tools.py b/misskaty/plugins/misc_tools.py index d38a2e62..06669f04 100644 --- a/misskaty/plugins/misc_tools.py +++ b/misskaty/plugins/misc_tools.py @@ -39,7 +39,7 @@ from pyrogram.types import ( from misskaty import BOT_USERNAME, app from misskaty.core.decorator.errors import capture_err from misskaty.helper.http import fetch -from misskaty.helper.tools import rentry +from misskaty.helper.tools import rentry, gen_trans_image from misskaty.vars import COMMAND_HANDLER from utils import extract_user, get_file_id @@ -48,6 +48,7 @@ LOGGER = getLogger("MissKaty") __MODULE__ = "Misc" __HELP__ = """ /carbon [text or reply to text or caption] - Make beautiful snippet code on carbon from text. +/removebg [Reply to image] - Remove background from image. /calc - Simple math calculator using inline buttons. /kbbi [keyword] - Search definition on KBBI (For Indonesian People) /sof [query] - Search your problem in StackOverflow. @@ -171,6 +172,18 @@ async def calc_cb(self, query): except Exception as error: LOGGER.error(error) + +@app.on_cmd("removebg") +async def removebg(_, ctx: Client): + if not ctx.reply_to_message: + return await ctx.reply_msg("Please reply image.") + if not ctx.reply_to_message.photo: + return await ctx.reply_msg("Only support photo for remove background.") + await gen_trans_image(ctx.reply_to_message, f"transp_bckgrnd-{ctx.from_user.id}.png") + await ctx.reply_photo(f"transp_bckgrnd-{ctx.from_user.id}.png") + os.remove(f"transp_bckgrnd-{ctx.from_user.id}.png") + + @app.on_cmd("kbbi") async def kbbi_search(_, ctx: Client): if len(ctx.command) == 1: diff --git a/requirements.txt b/requirements.txt index d88ce1b6..3267ecb3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,7 @@ requests beautifulsoup4 aiohttp chevron +cv-3 gTTS regex apscheduler==3.10.4