diff --git a/misskaty/__main__.py b/misskaty/__main__.py
index af5628a4..5853d980 100644
--- a/misskaty/__main__.py
+++ b/misskaty/__main__.py
@@ -27,6 +27,7 @@ from misskaty import (
user,
)
from misskaty.core.message_utils import *
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import bot_sys_stats, paginate_modules
from misskaty.plugins import ALL_MODULES
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, SUDO
@@ -127,6 +128,7 @@ keyboard = InlineKeyboardMarkup(
@app.on_message(filters.command("start", COMMAND_HANDLER))
+@ratelimiter
async def start(_, message):
if not message.from_user: return
if message.chat.type.value != "private":
@@ -180,6 +182,7 @@ async def start(_, message):
@app.on_callback_query(filters.regex("bot_commands"))
+@ratelimiter
async def commands_callbacc(_, CallbackQuery):
text, keyboard = await help_parser(CallbackQuery.from_user.mention)
await app.send_message(
@@ -191,12 +194,14 @@ async def commands_callbacc(_, CallbackQuery):
@app.on_callback_query(filters.regex("stats_callback"))
+@ratelimiter
async def stats_callbacc(_, CallbackQuery):
text = await bot_sys_stats()
await app.answer_callback_query(CallbackQuery.id, text, show_alert=True)
@app.on_message(filters.command("help", COMMAND_HANDLER))
+@ratelimiter
async def help_command(_, message):
if not message.from_user: return
if message.chat.type.value != "private":
@@ -280,6 +285,7 @@ If you want give coffee to my owner you can send /donate command for more info.
@app.on_callback_query(filters.regex(r"help_(.*?)"))
+@ratelimiter
async def help_button(client, query):
home_match = re.match(r"help_home\((.+?)\)", query.data)
mod_match = re.match(r"help_module\((.+?)\)", query.data)
diff --git a/misskaty/core/decorator/ratelimiter.py b/misskaty/core/decorator/ratelimiter.py
new file mode 100644
index 00000000..cd9a411d
--- /dev/null
+++ b/misskaty/core/decorator/ratelimiter.py
@@ -0,0 +1,41 @@
+from cachetools import TTLCache
+from functools import wraps
+from ..ratelimiter_func import RateLimiter
+from typing import Callable, Union
+from pyrogram import Client
+from pyrogram.types import CallbackQuery, Message
+
+ratelimit = RateLimiter()
+# storing spammy user in cache for 1minute before allowing them to use commands again.
+warned_users = TTLCache(maxsize=128, ttl=60)
+warning_message = "Spam detected! ignoring your all requests for few minutes."
+
+def ratelimiter(func: Callable) -> Callable:
+ """
+ Restricts user's from spamming commands or pressing buttons multiple times
+ using leaky bucket algorithm and pyrate_limiter.
+ """
+
+ @wraps(func)
+ async def decorator(client: Client, update: Union[Message, CallbackQuery]):
+ userid = update.from_user.id if update.from_user else update.sender_chat.id
+ is_limited = await ratelimit.acquire(userid)
+
+ if is_limited and userid not in warned_users:
+
+ if isinstance(update, Message):
+ await update.reply_text(warning_message)
+ warned_users[userid] = 1
+ return
+
+ elif isinstance(update, CallbackQuery):
+ await update.answer(warning_message, show_alert=True)
+ warned_users[userid] = 1
+ return
+
+ elif is_limited and userid in warned_users:
+ pass
+ else:
+ return await func(client, update)
+
+ return decorator
\ No newline at end of file
diff --git a/misskaty/core/ratelimiter_func.py b/misskaty/core/ratelimiter_func.py
new file mode 100644
index 00000000..97a26141
--- /dev/null
+++ b/misskaty/core/ratelimiter_func.py
@@ -0,0 +1,45 @@
+from typing import Union
+
+from pyrate_limiter import (BucketFullException, Duration, Limiter,
+ MemoryListBucket, RequestRate)
+
+
+class RateLimiter:
+ """
+ Implement rate limit logic using leaky bucket
+ algorithm, via pyrate_limiter.
+ (https://pypi.org/project/pyrate-limiter/)
+ """
+
+ def __init__(self) -> None:
+
+ # 3 requests per seconds
+ self.second_rate = RequestRate(3, Duration.SECOND)
+
+ # 20 requests per minute.
+ self.minute_rate = RequestRate(20, Duration.MINUTE)
+
+ # 1000 requests per hour
+ self.hourly_rate = RequestRate(1000, Duration.HOUR)
+
+ # 10000 requests per day
+ self.daily_rate = RequestRate(10000, Duration.DAY)
+
+ self.limiter = Limiter(
+ self.minute_rate,
+ self.hourly_rate,
+ self.daily_rate,
+ bucket_class=MemoryListBucket,
+ )
+
+ async def acquire(self, userid: Union[int, str]) -> bool:
+ """
+ Acquire rate limit per userid and return True / False
+ based on userid ratelimit status.
+ """
+
+ try:
+ self.limiter.try_acquire(userid)
+ return False
+ except BucketFullException:
+ return True
\ No newline at end of file
diff --git a/misskaty/plugins/admin.py b/misskaty/plugins/admin.py
index 5dc3b1db..e0aa80f4 100644
--- a/misskaty/plugins/admin.py
+++ b/misskaty/plugins/admin.py
@@ -16,6 +16,7 @@ from misskaty.core.decorator.permissions import (
list_admins,
member_permissions,
)
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.keyboard import ikb
from misskaty.core.message_utils import kirimPesan
from misskaty.helper.functions import (
@@ -74,6 +75,7 @@ async def admin_cache_func(_, cmu):
# Purge CMD
@app.on_message(filters.command("purge", COMMAND_HANDLER) & filters.group)
@adminsOnly("can_delete_messages")
+@ratelimiter
async def purge(_, message):
if not message.from_user:
return
@@ -128,6 +130,7 @@ async def purge(_, message):
# Kick members
@app.on_message(filters.command(["kick", "dkick"], COMMAND_HANDLER) & filters.group)
@adminsOnly("can_restrict_members")
+@ratelimiter
async def kickFunc(client, message):
if not message.from_user:
return
@@ -159,6 +162,7 @@ async def kickFunc(client, message):
# Ban/DBan/TBan User
@app.on_message(filters.command(["ban", "dban", "tban"], COMMAND_HANDLER) & filters.group)
@adminsOnly("can_restrict_members")
+@ratelimiter
async def banFunc(client, message):
if not message.from_user:
return
@@ -211,6 +215,7 @@ async def banFunc(client, message):
# Unban members
@app.on_message(filters.command("unban", COMMAND_HANDLER) & filters.group)
@adminsOnly("can_restrict_members")
+@ratelimiter
async def unban_func(_, message):
if not message.from_user:
return
@@ -236,6 +241,7 @@ async def unban_func(_, message):
# Ban users listed in a message
@app.on_message(filters.user(SUDO) & filters.command("listban", COMMAND_HANDLER) & filters.group)
+@ratelimiter
async def list_ban_(c, message):
if not message.from_user:
return
@@ -287,6 +293,7 @@ async def list_ban_(c, message):
# Unban users listed in a message
@app.on_message(filters.user(SUDO) & filters.command("listunban", COMMAND_HANDLER) & filters.group)
+@ratelimiter
async def list_unban_(c, message):
if not message.from_user:
return
@@ -331,6 +338,7 @@ async def list_unban_(c, message):
# Delete messages
@app.on_message(filters.command("del", COMMAND_HANDLER) & filters.group)
@adminsOnly("can_delete_messages")
+@ratelimiter
async def deleteFunc(_, message):
if not message.from_user:
return
@@ -346,6 +354,7 @@ async def deleteFunc(_, message):
# Promote Members
@app.on_message(filters.command(["promote", "fullpromote"], COMMAND_HANDLER) & filters.group)
@adminsOnly("can_promote_members")
+@ratelimiter
async def promoteFunc(client, message):
if not message.from_user:
return
@@ -392,6 +401,7 @@ async def promoteFunc(client, message):
# Demote Member
@app.on_message(filters.command("demote", COMMAND_HANDLER) & filters.group)
@adminsOnly("can_promote_members")
+@ratelimiter
async def demote(client, message):
if not message.from_user:
return
@@ -420,6 +430,7 @@ async def demote(client, message):
# Pin Messages
@app.on_message(filters.command(["pin", "unpin"], COMMAND_HANDLER) & filters.group)
@adminsOnly("can_pin_messages")
+@ratelimiter
async def pin(_, message):
if not message.from_user:
return
@@ -448,6 +459,7 @@ async def pin(_, message):
# Mute members
@app.on_message(filters.command(["mute", "tmute"], COMMAND_HANDLER) & filters.group)
@adminsOnly("can_restrict_members")
+@ratelimiter
async def mute(client, message):
if not message.from_user:
return
@@ -496,6 +508,7 @@ async def mute(client, message):
# Unmute members
@app.on_message(filters.command("unmute", COMMAND_HANDLER) & filters.group)
@adminsOnly("can_restrict_members")
+@ratelimiter
async def unmute(_, message):
if not message.from_user:
return
@@ -509,6 +522,7 @@ async def unmute(_, message):
@app.on_message(filters.command(["warn", "dwarn"], COMMAND_HANDLER) & filters.group)
@adminsOnly("can_restrict_members")
+@ratelimiter
async def warn_user(client, message):
if not message.from_user:
return
@@ -547,6 +561,7 @@ async def warn_user(client, message):
@app.on_callback_query(filters.regex("unwarn_"))
+@ratelimiter
async def remove_warning(_, cq):
from_user = cq.from_user
chat_id = cq.message.chat.id
@@ -572,6 +587,7 @@ async def remove_warning(_, cq):
@app.on_callback_query(filters.regex("unmute_"))
+@ratelimiter
async def unmute_user(_, cq):
from_user = cq.from_user
chat_id = cq.message.chat.id
@@ -591,6 +607,7 @@ async def unmute_user(_, cq):
@app.on_callback_query(filters.regex("unban_"))
+@ratelimiter
async def unban_user(_, cq):
from_user = cq.from_user
chat_id = cq.message.chat.id
@@ -613,6 +630,7 @@ async def unban_user(_, cq):
# Remove Warn
@app.on_message(filters.command("rmwarn", COMMAND_HANDLER) & filters.group)
@adminsOnly("can_restrict_members")
+@ratelimiter
async def remove_warnings(_, message):
if not message.from_user:
return
@@ -634,6 +652,7 @@ async def remove_warnings(_, message):
# Warns
@app.on_message(filters.command("warns", COMMAND_HANDLER) & filters.group)
@capture_err
+@ratelimiter
async def check_warns(_, message):
if not message.from_user:
return
@@ -652,6 +671,7 @@ async def check_warns(_, message):
# Report User in Group
@app.on_message((filters.command("report", COMMAND_HANDLER) | filters.command(["admins", "admin"], prefixes="@")) & filters.group)
@capture_err
+@ratelimiter
async def report_user(_, message):
if not message.reply_to_message:
return await message.reply_text("Reply to a message to report that user.")
diff --git a/misskaty/plugins/afk.py b/misskaty/plugins/afk.py
index a7db83b7..dafb5fe2 100644
--- a/misskaty/plugins/afk.py
+++ b/misskaty/plugins/afk.py
@@ -17,6 +17,7 @@ from database.afk_db import add_afk, cleanmode_off, cleanmode_on, is_afk, remove
from misskaty import app
from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.permissions import adminsOnly
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import kirimPesan
from misskaty.helper import get_readable_time2
from misskaty.vars import COMMAND_HANDLER
@@ -32,6 +33,7 @@ Just type something in group to remove AFK Status."""
# Handle set AFK Command
@capture_err
@app.on_message(filters.command(["afk"], COMMAND_HANDLER))
+@ratelimiter
async def active_afk(_, message):
if message.sender_chat:
return await kirimPesan(message, "This feature not supported for channel.")
@@ -182,6 +184,7 @@ async def active_afk(_, message):
@app.on_message(filters.command("afkdel", COMMAND_HANDLER) & filters.group)
+@ratelimiter
@adminsOnly("can_change_info")
async def afk_state(_, message):
if not message.from_user:
diff --git a/misskaty/plugins/auto_approve.py b/misskaty/plugins/auto_approve.py
index c01096d8..c3364244 100644
--- a/misskaty/plugins/auto_approve.py
+++ b/misskaty/plugins/auto_approve.py
@@ -10,6 +10,7 @@ from pyrogram.errors import UserAlreadyParticipant, UserIsBlocked
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err
@@ -37,6 +38,7 @@ async def approve_join_chat(c, m):
@app.on_callback_query(filters.regex(r"^approve"))
+@ratelimiter
async def approve_chat(c, q):
i, chat = q.data.split("_")
try:
@@ -49,6 +51,7 @@ async def approve_chat(c, q):
@app.on_callback_query(filters.regex(r"^declined"))
+@ratelimiter
async def decline_chat(c, q):
i, chat = q.data.split("_")
try:
diff --git a/misskaty/plugins/bypass.py b/misskaty/plugins/bypass.py
index 62c07d65..ed03538e 100644
--- a/misskaty/plugins/bypass.py
+++ b/misskaty/plugins/bypass.py
@@ -17,6 +17,7 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app
from misskaty.core.message_utils import *
from misskaty.core.decorator.errors import capture_err
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import http, get_readable_file_size, rentry
from misskaty.vars import COMMAND_HANDLER
@@ -87,6 +88,7 @@ def wetransfer_bypass(url: str) -> str:
@app.on_message(filters.command(["directurl"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def bypass(_, message):
if len(message.command) == 1:
return await kirimPesan(message, f"Gunakan perintah /{message.command[0]} untuk bypass url")
@@ -114,6 +116,8 @@ async def bypass(_, message):
reply_markup=markup,
disable_web_page_preview=True,
)
- else:
+ elif "we.tl" or "wetransfer.com" in message.command[1]:
data = wetransfer_bypass(url)
await editPesan(msg, f"{data}\n\n{mention}")
+ else:
+ await kirimPesan(message, "Unsupported url..")
\ No newline at end of file
diff --git a/misskaty/plugins/chatbot_ai.py b/misskaty/plugins/chatbot_ai.py
index 8d4a5db8..88ef935a 100644
--- a/misskaty/plugins/chatbot_ai.py
+++ b/misskaty/plugins/chatbot_ai.py
@@ -4,10 +4,12 @@ from pyrogram.errors import MessageNotModified
from misskaty import app
from misskaty.helper.http import http
from misskaty.core.message_utils import *
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.vars import COMMAND_HANDLER, OPENAI_API
@app.on_message(filters.command("ask", COMMAND_HANDLER))
+@ratelimiter
async def chatbot(c, m):
if len(m.command) == 1:
return await kirimPesan(m, f"Gunakan perintah /{m.command[0]} [pertanyaan] untuk menanyakan pertanyaan menggunakan AI.")
diff --git a/misskaty/plugins/code_tester.py b/misskaty/plugins/code_tester.py
index 53a845c9..d2eeb967 100644
--- a/misskaty/plugins/code_tester.py
+++ b/misskaty/plugins/code_tester.py
@@ -4,6 +4,7 @@ from pyrogram.errors import MessageTooLong
from misskaty import app
from misskaty.helper.tools import rentry
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "CodeTester"
@@ -72,6 +73,7 @@ async def glot(lang, langcode, code):
@app.on_message(filters.command(["codelist"], COMMAND_HANDLER))
+@ratelimiter
async def list_lang(client, message):
daftarlang = await listcode()
list_ = "".join(f"~> {i['name']}\n" for i in daftarlang)
@@ -80,6 +82,7 @@ async def list_lang(client, message):
@app.on_message(filters.command(["assembly"], "!"))
@app.on_edited_message(filters.command(["assembly"], "!"))
+@ratelimiter
async def assembly(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -97,6 +100,7 @@ async def assembly(client, message):
@app.on_message(filters.command(["ats"], "!"))
@app.on_edited_message(filters.command(["ats"], "!"))
+@ratelimiter
async def ats(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -114,6 +118,7 @@ async def ats(client, message):
@app.on_message(filters.command(["bash"], "!"))
@app.on_edited_message(filters.command(["bash"], "!"))
+@ratelimiter
async def bash(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -131,6 +136,7 @@ async def bash(client, message):
@app.on_message(filters.command(["c"], "!"))
@app.on_edited_message(filters.command(["c"], "!"))
+@ratelimiter
async def c(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -148,6 +154,7 @@ async def c(client, message):
@app.on_message(filters.command(["clojure"], "!"))
@app.on_edited_message(filters.command(["clojure"], "!"))
+@ratelimiter
async def clojure(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -165,6 +172,7 @@ async def clojure(client, message):
@app.on_message(filters.command(["cobol"], "!"))
@app.on_edited_message(filters.command(["cobol"], "!"))
+@ratelimiter
async def cobol(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -182,6 +190,7 @@ async def cobol(client, message):
@app.on_message(filters.command(["coffeescript"], "!"))
@app.on_edited_message(filters.command(["coffeescript"], "!"))
+@ratelimiter
async def coffeescript(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -199,6 +208,7 @@ async def coffeescript(client, message):
@app.on_message(filters.command(["cpp"], "!"))
@app.on_edited_message(filters.command(["cpp"], "!"))
+@ratelimiter
async def cpp(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -216,6 +226,7 @@ async def cpp(client, message):
@app.on_message(filters.command(["crystal"], "!"))
@app.on_edited_message(filters.command(["crystal"], "!"))
+@ratelimiter
async def crystal(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -233,6 +244,7 @@ async def crystal(client, message):
@app.on_message(filters.command(["csharp"], "!"))
@app.on_edited_message(filters.command(["csharp"], "!"))
+@ratelimiter
async def csharp(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -250,6 +262,7 @@ async def csharp(client, message):
@app.on_message(filters.command(["d"], "!"))
@app.on_edited_message(filters.command(["d"], "!"))
+@ratelimiter
async def d(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -267,6 +280,7 @@ async def d(client, message):
@app.on_message(filters.command(["elixir"], "!"))
@app.on_edited_message(filters.command(["elixir"], "!"))
+@ratelimiter
async def elixir(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -301,6 +315,7 @@ async def elm(client, message):
@app.on_message(filters.command(["erlang"], "!"))
@app.on_edited_message(filters.command(["erlang"], "!"))
+@ratelimiter
async def erlang(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -318,6 +333,7 @@ async def erlang(client, message):
@app.on_message(filters.command(["fsharp"], "!"))
@app.on_edited_message(filters.command(["fsharp"], "!"))
+@ratelimiter
async def fsharp(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -335,6 +351,7 @@ async def fsharp(client, message):
@app.on_message(filters.command(["go"], "!"))
@app.on_edited_message(filters.command(["go"], "!"))
+@ratelimiter
async def go(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -352,6 +369,7 @@ async def go(client, message):
@app.on_message(filters.command(["groovy"], "!"))
@app.on_edited_message(filters.command(["groovy"], "!"))
+@ratelimiter
async def groovy(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -369,6 +387,7 @@ async def groovy(client, message):
@app.on_message(filters.command(["haskell"], "!"))
@app.on_edited_message(filters.command(["haskell"], "!"))
+@ratelimiter
async def haskell(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -386,6 +405,7 @@ async def haskell(client, message):
@app.on_message(filters.command(["idris"], "!"))
@app.on_edited_message(filters.command(["idris"], "!"))
+@ratelimiter
async def idris(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -403,6 +423,7 @@ async def idris(client, message):
@app.on_message(filters.command(["java"], "!"))
@app.on_edited_message(filters.command(["java"], "!"))
+@ratelimiter
async def java(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -420,6 +441,7 @@ async def java(client, message):
@app.on_message(filters.command(["javascript"], "!"))
@app.on_edited_message(filters.command(["javascript"], "!"))
+@ratelimiter
async def javascript(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -437,6 +459,7 @@ async def javascript(client, message):
@app.on_message(filters.command(["julia"], "!"))
@app.on_edited_message(filters.command(["julia"], "!"))
+@ratelimiter
async def julia(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -454,6 +477,7 @@ async def julia(client, message):
@app.on_message(filters.command(["kotlin"], "!"))
@app.on_edited_message(filters.command(["kotlin"], "!"))
+@ratelimiter
async def kotlin(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -471,6 +495,7 @@ async def kotlin(client, message):
@app.on_message(filters.command(["lua"], "!"))
@app.on_edited_message(filters.command(["lua"], "!"))
+@ratelimiter
async def lua(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -488,6 +513,7 @@ async def lua(client, message):
@app.on_message(filters.command(["mercury"], "!"))
@app.on_edited_message(filters.command(["mercury"], "!"))
+@ratelimiter
async def mercury(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -505,6 +531,7 @@ async def mercury(client, message):
@app.on_message(filters.command(["nim"], "!"))
@app.on_edited_message(filters.command(["nim"], "!"))
+@ratelimiter
async def nim(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -522,6 +549,7 @@ async def nim(client, message):
@app.on_message(filters.command(["nix"], "!"))
@app.on_edited_message(filters.command(["nix"], "!"))
+@ratelimiter
async def nix(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -539,6 +567,7 @@ async def nix(client, message):
@app.on_message(filters.command(["ocaml"], "!"))
@app.on_edited_message(filters.command(["ocaml"], "!"))
+@ratelimiter
async def ocaml(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -556,6 +585,7 @@ async def ocaml(client, message):
@app.on_message(filters.command(["perl"], "!"))
@app.on_edited_message(filters.command(["perl"], "!"))
+@ratelimiter
async def perl(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -590,6 +620,7 @@ async def php(client, message):
@app.on_message(filters.command(["python"], "!"))
@app.on_edited_message(filters.command(["python"], "!"))
+@ratelimiter
async def python(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -607,6 +638,7 @@ async def python(client, message):
@app.on_message(filters.command(["raku"], "!"))
@app.on_edited_message(filters.command(["raku"], "!"))
+@ratelimiter
async def raku(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -624,6 +656,7 @@ async def raku(client, message):
@app.on_message(filters.command(["ruby"], "!"))
@app.on_edited_message(filters.command(["ruby"], "!"))
+@ratelimiter
async def ruby(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -641,6 +674,7 @@ async def ruby(client, message):
@app.on_message(filters.command(["rust"], "!"))
@app.on_edited_message(filters.command(["rust"], "!"))
+@ratelimiter
async def rust(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -658,6 +692,7 @@ async def rust(client, message):
@app.on_message(filters.command(["scala"], "!"))
@app.on_edited_message(filters.command(["scala"], "!"))
+@ratelimiter
async def scala(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
@@ -692,6 +727,7 @@ async def swift(client, message):
@app.on_message(filters.command(["typescript"], "!"))
@app.on_edited_message(filters.command(["typescript"], "!"))
+@ratelimiter
async def typescript(client, message):
if len(message.command) < 2:
return await message.reply("Please enter the code you want to run.")
diff --git a/misskaty/plugins/copy_forward.py b/misskaty/plugins/copy_forward.py
index 16c5981d..69e5cff8 100644
--- a/misskaty/plugins/copy_forward.py
+++ b/misskaty/plugins/copy_forward.py
@@ -3,11 +3,13 @@ from pyrogram.errors import UserIsBlocked, UserNotParticipant
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import BOT_USERNAME, app
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err
from misskaty.vars import COMMAND_HANDLER
@app.on_message(filters.command(["copy"], COMMAND_HANDLER))
+@ratelimiter
async def copy(client, message):
if len(message.command) == 1:
if not message.reply_to_message:
diff --git a/misskaty/plugins/download_upload.py b/misskaty/plugins/download_upload.py
index 8194884c..f2e839f8 100644
--- a/misskaty/plugins/download_upload.py
+++ b/misskaty/plugins/download_upload.py
@@ -11,6 +11,7 @@ from pySmartDL import SmartDL
from misskaty import app
from misskaty.core.decorator.errors import capture_err
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
from misskaty.helper.pyro_progress import humanbytes, progress_for_pyrogram
from misskaty.vars import COMMAND_HANDLER, SUDO
@@ -30,6 +31,7 @@ __HELP__ = """
@app.on_message(filters.command(["anon"], COMMAND_HANDLER))
+@ratelimiter
async def upload(bot, message):
if not message.reply_to_message:
return await message.reply("Please reply to media file.")
@@ -103,7 +105,7 @@ async def download(client, message):
estimated_total_time = downloader.get_eta(human=True)
try:
- current_message = "trying to download...\n"
+ current_message = "Trying to download...\n"
current_message += f"URL: {url}\n"
current_message += f"File Name: {custom_file_name}\n"
current_message += f"Speed: {speed}\n"
@@ -126,6 +128,7 @@ async def download(client, message):
@app.on_message(filters.command(["tiktokdl"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def tiktokdl(client, message):
if len(message.command) == 1:
return await message.reply(f"Use command /{message.command[0]} [link] to download tiktok video.")
@@ -162,6 +165,7 @@ async def fbdl(client, message):
await message.reply_video(
path,
caption=f"{os.path.basename(path)}\n\nUploaded for {message.from_user.mention} [{message.from_user.id}]",
+ thumb="img/thumb.jpg"
)
await msg.delete()
try:
diff --git a/misskaty/plugins/filter_request.py b/misskaty/plugins/filter_request.py
index efc1693f..aca36014 100644
--- a/misskaty/plugins/filter_request.py
+++ b/misskaty/plugins/filter_request.py
@@ -9,6 +9,7 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app
from .web_scraper import SCRAP_DICT, data_kuso
from .pypi_search import PYPI_DICT
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err
from misskaty.helper.time_gap import check_time_gap
@@ -131,7 +132,8 @@ async def start(_, message):
@app.on_callback_query(filters.regex(r"^donereq"))
-async def _callbackreq(c, q):
+@ratelimiter
+async def callbackreq(c, q):
try:
user = await c.get_chat_member(-1001201566570, q.from_user.id)
if user.status in [
@@ -169,7 +171,8 @@ async def _callbackreq(c, q):
@app.on_callback_query(filters.regex(r"^dahada"))
-async def _callbackreqada(c, q):
+@ratelimiter
+async def callbackreqada(c, q):
try:
user = await c.get_chat_member(-1001201566570, q.from_user.id)
if user.status in [
@@ -225,7 +228,8 @@ async def _callbackreqada(c, q):
@app.on_callback_query(filters.regex(r"^rejectreq"))
-async def _callbackreject(c, q):
+@ratelimiter
+async def callbackreject(c, q):
try:
user = await c.get_chat_member(-1001201566570, q.from_user.id)
if user.status in [
@@ -263,7 +267,8 @@ async def _callbackreject(c, q):
@app.on_callback_query(filters.regex(r"^unavailablereq"))
-async def _callbackunav(c, q):
+@ratelimiter
+async def callbackunav(c, q):
try:
user = await c.get_chat_member(-1001201566570, q.from_user.id)
if user.status in [
@@ -323,7 +328,8 @@ async def _callbackunav(c, q):
@app.on_callback_query(filters.regex(r"^reqcompl$"))
-async def _callbackaft_done(c, q):
+@ratelimiter
+async def callbackaft_done(c, q):
await q.answer(
"Request ini sudah terselesaikan 🥳, silahkan cek di channel atau grup yaa..",
show_alert=True,
@@ -332,7 +338,8 @@ async def _callbackaft_done(c, q):
@app.on_callback_query(filters.regex(r"^reqreject$"))
-async def _callbackaft_rej(c, q):
+@ratelimiter
+async def callbackaft_rej(c, q):
await q.answer(
"Request ini ditolak 💔, silahkan cek rules grup yaa.",
show_alert=True,
@@ -341,7 +348,8 @@ async def _callbackaft_rej(c, q):
@app.on_callback_query(filters.regex(r"^requnav$"))
-async def _callbackaft_unav(c, q):
+@ratelimiter
+async def callbackaft_unav(c, q):
await q.answer(
"Request ini tidak tersedia ☹️, mungkin filmnya belum rilis atau memang tidak tersedia versi digital.",
show_alert=True,
@@ -350,7 +358,8 @@ async def _callbackaft_unav(c, q):
@app.on_callback_query(filters.regex(r"^reqavailable$"))
-async def _callbackaft_dahada(c, q):
+@ratelimiter
+async def callbackaft_dahada(c, q):
await q.answer("Request ini sudah ada, silahkan cari 🔍 di channelnya yaa 😉..", show_alert=True)
diff --git a/misskaty/plugins/filters.py b/misskaty/plugins/filters.py
index b176c675..10e7ac9e 100644
--- a/misskaty/plugins/filters.py
+++ b/misskaty/plugins/filters.py
@@ -28,6 +28,7 @@ from pyrogram import filters
from database.filters_db import delete_filter, get_filter, get_filters_names, save_filter
from misskaty import app
from misskaty.core.decorator.errors import capture_err
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.permissions import adminsOnly
from misskaty.core.keyboard import ikb
from misskaty.core.message_utils import *
@@ -44,14 +45,15 @@ You can use markdown or html to save text too.
@app.on_message(filters.command("addfilter") & ~filters.private)
@adminsOnly("can_change_info")
+@ratelimiter
async def save_filters(_, m):
if len(m.command) == 1 or not m.reply_to_message:
- return await kirimPesan(m, "**Usage:**\nReply to a text or sticker with /filter [FILTER_NAME] to save it.")
+ return await kirimPesan(m, "**Usage:**\nReply to a text or sticker with /addfilter [FILTER_NAME] to save it.")
if not m.reply_to_message.text and not m.reply_to_message.sticker:
return await kirimPesan(m, "__**You can only save text or stickers in filters for now.**__")
name = m.text.split(None, 1)[1].strip()
if not name:
- return await kirimPesan(m, "**Usage:**\n__/filter [FILTER_NAME]__")
+ return await kirimPesan(m, "**Usage:**\n__/addfilter [FILTER_NAME]__")
chat_id = m.chat.id
_type = "text" if m.reply_to_message.text else "sticker"
_filter = {
@@ -64,6 +66,7 @@ async def save_filters(_, m):
@app.on_message(filters.command("filters") & ~filters.private)
@capture_err
+@ratelimiter
async def get_filterss(_, m):
_filters = await get_filters_names(m.chat.id)
if not _filters:
@@ -77,12 +80,13 @@ async def get_filterss(_, m):
@app.on_message(filters.command("stopfilter") & ~filters.private)
@adminsOnly("can_change_info")
+@ratelimiter
async def del_filter(_, m):
if len(m.command) < 2:
- return await kirimPesan(m, "**Usage:**\n__/stop [FILTER_NAME]__")
+ return await kirimPesan(m, "**Usage:**\n__/stopfilter [FILTER_NAME]__")
name = m.text.split(None, 1)[1].strip()
if not name:
- return await kirimPesan(m, "**Usage:**\n__/stop [FILTER_NAME]__")
+ return await kirimPesan(m, "**Usage:**\n__/stopfilter [FILTER_NAME]__")
chat_id = m.chat.id
deleted = await delete_filter(chat_id, name)
if deleted:
@@ -95,7 +99,6 @@ async def del_filter(_, m):
filters.text & ~filters.private & ~filters.via_bot & ~filters.forwarded,
group=2,
)
-@capture_err
async def filters_re(_, message):
text = message.text.lower().strip()
if not text:
diff --git a/misskaty/plugins/genss.py b/misskaty/plugins/genss.py
index 6e27c9d8..b9e20221 100644
--- a/misskaty/plugins/genss.py
+++ b/misskaty/plugins/genss.py
@@ -18,7 +18,7 @@ from pyrogram.types import InlineKeyboardMarkup
from misskaty import BOT_USERNAME, app
from misskaty.core.decorator.errors import capture_err
-from misskaty.core.decorator.pyro_cooldown import wait
+from misskaty.core.decorator.ratelimiter import ratelimiter
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
@@ -32,8 +32,9 @@ __HELP__ = """"
"""
-@app.on_message(filters.command(["genss"], COMMAND_HANDLER) & wait(30))
+@app.on_message(filters.command(["genss"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def genss(client, m):
if not m.from_user:
return
@@ -105,5 +106,6 @@ async def genss(client, m):
@app.on_callback_query(filters.regex(r"^scht"))
+@ratelimiter
async def _(c, m):
asyncio.create_task(screenshot_flink(c, m))
diff --git a/misskaty/plugins/grup_tools.py b/misskaty/plugins/grup_tools.py
index 41033c26..4d243919 100644
--- a/misskaty/plugins/grup_tools.py
+++ b/misskaty/plugins/grup_tools.py
@@ -11,6 +11,7 @@ from pyrogram.types import ChatMemberUpdated, InlineKeyboardButton, InlineKeyboa
from database.users_chats_db import db
from misskaty import BOT_USERNAME, app
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import asyncify, capture_err
from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, SUDO, SUPPORT_CHAT
@@ -320,6 +321,7 @@ async def gen_invite(bot, message):
@app.on_message(filters.command(["adminlist"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def adminlist(_, message):
if message.chat.type == enums.ChatType.PRIVATE:
return await message.reply("Perintah ini hanya untuk grup")
@@ -336,6 +338,7 @@ async def adminlist(_, message):
@app.on_message(filters.command(["kickme"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def kickme(_, message):
reason = None
if len(message.text.split()) >= 2:
diff --git a/misskaty/plugins/imdb_search.py b/misskaty/plugins/imdb_search.py
index 5ba9220d..8614eab0 100644
--- a/misskaty/plugins/imdb_search.py
+++ b/misskaty/plugins/imdb_search.py
@@ -20,8 +20,8 @@ from database.imdb_db import *
from misskaty import BOT_USERNAME, app
from misskaty.core.message_utils import *
from misskaty.core.decorator.errors import capture_err
-from misskaty.helper.http import http
-from misskaty.helper.tools import get_random_string, search_jw, GENRES_EMOJI
+from misskaty.core.decorator.ratelimiter import ratelimiter
+from misskaty.helper import http, get_random_string, search_jw, GENRES_EMOJI
from misskaty.vars import COMMAND_HANDLER
LOGGER = logging.getLogger(__name__)
@@ -32,6 +32,7 @@ headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWe
# IMDB Choose Language
@app.on_message(filters.command(["imdb"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def imdb_choose(_, m):
if len(m.command) == 1:
return await kirimPesan(m, f"ℹ️ Please add query after CMD!\nEx: /{m.command[0]} Jurassic World")
@@ -62,6 +63,7 @@ async def imdb_choose(_, m):
@app.on_callback_query(filters.regex("^imdbset"))
+@ratelimiter
async def imdbsetlang(client, query):
i, uid = query.data.split("#")
if query.from_user.id != int(uid):
@@ -79,6 +81,7 @@ async def imdbsetlang(client, query):
@app.on_callback_query(filters.regex("^setimdb"))
+@ratelimiter
async def imdbsetlang(client, query):
i, lang, uid = query.data.split("#")
if query.from_user.id != int(uid):
@@ -195,6 +198,7 @@ async def imdb_search_en(kueri, message):
@app.on_callback_query(filters.regex("^imdbcari"))
+@ratelimiter
async def imdbcari(client, query):
BTN = []
i, lang, msg, uid = query.data.split("#")
@@ -279,6 +283,7 @@ async def imdbcari(client, query):
@app.on_callback_query(filters.regex("^imdbres_id"))
+@ratelimiter
async def imdb_id_callback(_, query):
i, userid, movie = query.data.split("#")
if query.from_user.id != int(userid):
@@ -399,6 +404,7 @@ async def imdb_id_callback(_, query):
@app.on_callback_query(filters.regex("^imdbres_en"))
+@ratelimiter
async def imdb_en_callback(bot, query):
i, userid, movie = query.data.split("#")
if query.from_user.id != int(userid):
diff --git a/misskaty/plugins/inkick_user.py b/misskaty/plugins/inkick_user.py
index 237ac2d7..ed49ee0b 100644
--- a/misskaty/plugins/inkick_user.py
+++ b/misskaty/plugins/inkick_user.py
@@ -10,17 +10,19 @@ from pyrogram.errors.exceptions.bad_request_400 import (
from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden
from misskaty import app
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import editPesan, kirimPesan
from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "Inkick"
__HELP__ = """"
/instatus - View member status in group.
-/dkick - Remove deleted account from group.
+/ban_ghosts - Remove deleted account from group.
"""
@app.on_message(filters.incoming & ~filters.private & filters.command(["inkick"], COMMAND_HANDLER))
+@ratelimiter
async def inkick(_, message):
if message.sender_chat:
return await message.reply("This feature not available for channel.")
@@ -60,6 +62,7 @@ async def inkick(_, message):
# Kick User Without Username
@app.on_message(filters.incoming & ~filters.private & filters.command(["uname"], COMMAND_HANDLER))
+@ratelimiter
async def uname(_, message):
if message.sender_chat:
return await message.reply("This feature not available for channel.")
@@ -95,7 +98,8 @@ async def uname(_, message):
@app.on_message(filters.incoming & ~filters.private & filters.command(["ban_ghosts"], COMMAND_HANDLER))
-async def dkick(client, message):
+@ratelimiter
+async def rm_delacc(client, message):
if message.sender_chat:
return await message.reply("This feature not available for channel.")
user = await app.get_chat_member(message.chat.id, message.from_user.id)
@@ -127,6 +131,7 @@ async def dkick(client, message):
@app.on_message(filters.incoming & ~filters.private & filters.command(["instatus"], COMMAND_HANDLER))
+@ratelimiter
async def instatus(client, message):
if message.sender_chat:
return await kirimPesan(message, "Not supported channel.")
diff --git a/misskaty/plugins/inline_search.py b/misskaty/plugins/inline_search.py
index c2f79b18..c33b5334 100644
--- a/misskaty/plugins/inline_search.py
+++ b/misskaty/plugins/inline_search.py
@@ -21,6 +21,7 @@ from pyrogram.types import (
)
from misskaty import BOT_USERNAME, app, user
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import post_to_telegraph, http, GENRES_EMOJI, search_jw
from misskaty.plugins.misc_tools import get_content
from utils import demoji
@@ -98,7 +99,7 @@ async def inline_menu(_, inline_query: InlineQuery):
kueri = inline_query.query.split(None, 1)[1].strip()
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/61.0.3163.100 Safari/537.36"}
jsonapi = await http.get(
- "https://github.com/yasirarism/telegram-bot-api-spec/raw/main/api.json",
+ "https://github.com/PaulSonOfLars/telegram-bot-api-spec/raw/main/api.json",
headers=headers,
follow_redirects=True,
)
@@ -500,6 +501,7 @@ async def inline_menu(_, inline_query: InlineQuery):
@app.on_callback_query(filters.regex(r"prvtmsg\((.+)\)"))
+@ratelimiter
async def prvt_msg(_, c_q):
msg_id = str(c_q.matches[0].group(1))
@@ -516,6 +518,7 @@ async def prvt_msg(_, c_q):
@app.on_callback_query(filters.regex(r"destroy\((.+)\)"))
+@ratelimiter
async def destroy_msg(_, c_q):
msg_id = str(c_q.matches[0].group(1))
@@ -534,6 +537,7 @@ async def destroy_msg(_, c_q):
@app.on_callback_query(filters.regex("^imdbinl#"))
+@ratelimiter
async def imdb_inl(_, query):
i, user, movie = query.data.split("#")
if user == f"{query.from_user.id}":
diff --git a/misskaty/plugins/json.py b/misskaty/plugins/json.py
index 519d663a..f626d4a8 100644
--- a/misskaty/plugins/json.py
+++ b/misskaty/plugins/json.py
@@ -12,11 +12,13 @@ from pyrogram import filters
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.vars import COMMAND_HANDLER
# View Structure Telegram Message As JSON
@app.on_message(filters.command(["json"], COMMAND_HANDLER))
+@ratelimiter
async def jsonify(_, message):
the_real_message = None
reply_to_id = None
diff --git a/misskaty/plugins/karma.py b/misskaty/plugins/karma.py
index 8ec92683..939405fb 100644
--- a/misskaty/plugins/karma.py
+++ b/misskaty/plugins/karma.py
@@ -13,6 +13,7 @@ from database.karma_db import (
from misskaty import app
from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.permissions import adminsOnly
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.functions import alpha_to_int, int_to_alpha
__MODULE__ = "Karma"
@@ -116,6 +117,7 @@ async def downvote(_, message):
@app.on_message(filters.command("karma") & filters.group)
@capture_err
+@ratelimiter
async def command_karma(_, message):
chat_id = message.chat.id
if not message.reply_to_message:
@@ -162,6 +164,7 @@ async def command_karma(_, message):
@app.on_message(filters.command("karma_toggle") & ~filters.private)
@adminsOnly
+@ratelimiter
async def captcha_state(_, message):
usage = "**Usage:**\n/karma_toggle [ENABLE|DISABLE]"
if len(message.command) != 2:
diff --git a/misskaty/plugins/mediainfo.py b/misskaty/plugins/mediainfo.py
index 7afb6c98..330d8425 100644
--- a/misskaty/plugins/mediainfo.py
+++ b/misskaty/plugins/mediainfo.py
@@ -15,36 +15,37 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app
from misskaty.core.message_utils import *
-from misskaty.core.decorator.pyro_cooldown import wait
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import http, progress_for_pyrogram, runcmd, post_to_telegraph
from misskaty.vars import COMMAND_HANDLER
from utils import get_file_id
-@app.on_message(filters.command(["mediainfo"], COMMAND_HANDLER) & wait(30))
+@app.on_message(filters.command(["mediainfo"], COMMAND_HANDLER))
+@ratelimiter
async def mediainfo(client, message):
if not message.from_user:
return
if message.reply_to_message and message.reply_to_message.media:
- process = await kirimPesan(message, "`Sedang memproses, lama waktu tergantung ukuran file kamu...`", quote=True)
+ process = await kirimPesan(message, "`Processing, total time is based size of your files...`", quote=True)
file_info = get_file_id(message.reply_to_message)
if file_info is None:
- return await editPesan(process, "Balas ke format media yang valid")
+ return await editPesan(process, "Please reply to valid media.")
c_time = time.time()
file_path = await message.reply_to_message.download(
progress=progress_for_pyrogram,
- progress_args=("trying to download, sabar yakk..", process, c_time),
+ progress_args=("Trying to download..", process, c_time),
)
output_ = await runcmd(f'mediainfo "{file_path}"')
out = output_[0] if len(output_) != 0 else None
body_text = f"""
- MissKatyBot MediaInfo
- JSON
- {file_info}.type
+MissKatyBot MediaInfo
+JSON
+{file_info}.type
- DETAILS
- {out or 'Not Supported'}
+DETAILS
+{out or 'Not Supported'}
"""
text_ = file_info.message_type
try:
diff --git a/misskaty/plugins/memify.py b/misskaty/plugins/memify.py
index 21534698..becad598 100644
--- a/misskaty/plugins/memify.py
+++ b/misskaty/plugins/memify.py
@@ -5,6 +5,7 @@ from PIL import Image, ImageDraw, ImageFont
from pyrogram import filters
from misskaty import app
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err
from misskaty.vars import COMMAND_HANDLER
@@ -134,6 +135,7 @@ async def draw_meme_text(image_path, text):
@app.on_message(filters.command(["mmf"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def memify(client, message):
if message.reply_to_message and (message.reply_to_message.sticker or message.reply_to_message.photo):
try:
diff --git a/misskaty/plugins/misc_tools.py b/misskaty/plugins/misc_tools.py
index e91c46fa..69ef4126 100644
--- a/misskaty/plugins/misc_tools.py
+++ b/misskaty/plugins/misc_tools.py
@@ -25,6 +25,7 @@ from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMa
from misskaty import BOT_USERNAME, app
from misskaty.core.decorator.errors import capture_err
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import hapusPesan, kirimPesan
from misskaty.helper.http import http
from misskaty.helper.tools import rentry
@@ -54,6 +55,7 @@ def remove_html_tags(text):
@app.on_message(filters.command("readqr", COMMAND_HANDLER))
+@ratelimiter
async def readqr(c, m):
if not m.reply and not m.reply.media and not m.reply.photo:
return await m.reply("Please reply photo that contain valid QR Code.")
@@ -68,6 +70,7 @@ async def readqr(c, m):
@app.on_message(filters.command("createqr", COMMAND_HANDLER))
+@ratelimiter
async def makeqr(c, m):
if m.reply_to_message and m.reply_to_message.text:
teks = m.reply_to_message.text
@@ -103,6 +106,7 @@ async def stackoverflow(client, message):
@app.on_message(filters.command(["google"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def gsearch(client, message):
if len(message.command) == 1:
return await message.reply("Give a query to search in Google!")
@@ -150,6 +154,7 @@ async def gsearch(client, message):
@app.on_message(filters.command(["tr", "trans", "translate"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def translate(client, message):
if message.reply_to_message and (message.reply_to_message.text or message.reply_to_message.caption):
target_lang = "id" if len(message.command) == 1 else message.text.split()[1]
@@ -175,6 +180,7 @@ async def translate(client, message):
@app.on_message(filters.command(["tts"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def tts(_, message):
if message.reply_to_message and (message.reply_to_message.text or message.reply_to_message.caption):
if len(message.text.split()) == 1:
@@ -207,6 +213,7 @@ async def tts(_, message):
@app.on_message(filters.command(["tosticker"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def tostick(client, message):
try:
if not message.reply_to_message or not message.reply_to_message.photo:
@@ -223,6 +230,7 @@ async def tostick(client, message):
@app.on_message(filters.command(["toimage"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def topho(client, message):
try:
if not message.reply_to_message or not message.reply_to_message.sticker:
@@ -241,6 +249,7 @@ async def topho(client, message):
@app.on_message(filters.command(["id"], COMMAND_HANDLER))
+@ratelimiter
async def showid(client, message):
chat_type = message.chat.type
if chat_type == "private":
@@ -274,6 +283,7 @@ async def showid(client, message):
@app.on_message(filters.command(["info"], COMMAND_HANDLER))
+@ratelimiter
async def who_is(client, message):
# https://github.com/SpEcHiDe/PyroGramBot/blob/master/pyrobot/plugins/admemes/whois.py#L19
if message.sender_chat:
@@ -295,11 +305,11 @@ async def who_is(client, message):
message_out_str += f"➲Last Name: {last_name}\n"
message_out_str += f"➲Telegram ID: {from_user.id}\n"
username = from_user.username or "None"
- dc_id = from_user.dc_id or "[User Doesnt Have A Valid DP]"
+ dc_id = from_user.dc_id or "[User Doesn't Have Profile Pic]"
message_out_str += f"➲Data Centre: {dc_id}\n"
message_out_str += f"➲User Name: @{username}\n"
- message_out_str += f"➲User 𝖫𝗂𝗇𝗄: Click Here\n"
- if message.chat.type in (("supergroup", "channel")):
+ message_out_str += f"➲User Link: Click Here\n"
+ if message.chat.type.value in (("supergroup", "channel")):
try:
chat_member_p = await message.chat.get_member(from_user.id)
joined_date = datetime.fromtimestamp(chat_member_p.joined_date or time.time()).strftime("%Y.%m.%d %H:%M:%S")
@@ -331,6 +341,7 @@ async def who_is(client, message):
@app.on_callback_query(filters.regex("^close"))
+@ratelimiter
async def close_callback(bot: Client, query: CallbackQuery):
i, userid = query.data.split("#")
if query.from_user.id != int(userid):
@@ -359,6 +370,7 @@ async def mdlapi(title):
@app.on_message(filters.command(["mdl"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def mdlsearch(client, message):
if " " in message.text:
r, title = message.text.split(None, 1)
@@ -385,6 +397,7 @@ async def mdlsearch(client, message):
@app.on_callback_query(filters.regex("^mdls"))
+@ratelimiter
async def mdl_callback(bot: Client, query: CallbackQuery):
i, user, msg_id, slug = query.data.split("#")
if user == f"{query.from_user.id}":
diff --git a/misskaty/plugins/nightmode.py b/misskaty/plugins/nightmode.py
index 00ac2e15..f34f803e 100644
--- a/misskaty/plugins/nightmode.py
+++ b/misskaty/plugins/nightmode.py
@@ -13,6 +13,7 @@ from pyrogram.types import (
)
from misskaty import BOT_USERNAME, app
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.vars import LOG_CHANNEL, NIGHTMODE
@@ -190,6 +191,7 @@ async def job_open_ymoviez():
@app.on_callback_query(filters.regex(r"^nightmd$"))
+@ratelimiter
async def callbackanightmd(c: Client, q: CallbackQuery):
await q.answer(
f"🔖 Hai, Aku {BOT_USERNAME} dibuat menggunakan Framework Pyrogram v{__version__} dan Python 3.10.\n\nMau buat bot seperti ini? Yuuk belajar di @botindonesia\nOwner: @YasirArisM",
diff --git a/misskaty/plugins/notes.py b/misskaty/plugins/notes.py
index 9b87aeed..b825d531 100644
--- a/misskaty/plugins/notes.py
+++ b/misskaty/plugins/notes.py
@@ -28,6 +28,7 @@ from pyrogram import filters
from database.notes_db import delete_note, get_note, get_note_names, save_note
from misskaty import app
from misskaty.core.decorator.errors import capture_err
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.permissions import adminsOnly
from misskaty.core.keyboard import ikb
from misskaty.helper.functions import extract_text_and_keyb
@@ -45,6 +46,7 @@ __HELP__ = """/notes To Get All The Notes In The Chat.
@app.on_message(filters.command("addnote") & ~filters.private)
@adminsOnly("can_change_info")
+@ratelimiter
async def save_notee(_, message):
if len(message.command) < 2 or not message.reply_to_message:
await message.reply(
@@ -70,6 +72,7 @@ async def save_notee(_, message):
@app.on_message(filters.command("notes") & ~filters.private)
@capture_err
+@ratelimiter
async def get_notes(_, message):
message.text.split()[0][0]
chat_id = message.chat.id
@@ -87,6 +90,7 @@ async def get_notes(_, message):
@app.on_message(filters.regex(r"^#.+") & filters.text & ~filters.private)
@capture_err
+@ratelimiter
async def get_one_note(_, message):
name = message.text.replace("#", "", 1)
if not name:
@@ -111,6 +115,7 @@ async def get_one_note(_, message):
@app.on_message(filters.command("delnote") & ~filters.private)
@adminsOnly("can_change_info")
+@ratelimiter
async def del_note(_, message):
if len(message.command) == 1:
return await message.reply("**Usage**\n__/delnote [NOTE_NAME]__")
diff --git a/misskaty/plugins/ocr.py b/misskaty/plugins/ocr.py
index 87336620..05ead49b 100644
--- a/misskaty/plugins/ocr.py
+++ b/misskaty/plugins/ocr.py
@@ -8,10 +8,11 @@
import os
from pyrogram import filters
-from telegraph import upload_file
+from telegraph.aio import Telegraph
from misskaty import app
from misskaty.core.message_utils import *
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err
from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER
@@ -22,6 +23,7 @@ __HELP__ = "/ocr [reply to photo] - Read Text From Image"
@app.on_message(filters.command(["ocr"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def ocr(_, m):
reply = m.reply_to_message
if not reply or not reply.photo and not reply.sticker:
@@ -31,8 +33,8 @@ async def ocr(_, m):
file_path = await reply.download()
if reply.sticker:
file_path = await reply.download(f"ocr_{m.from_user.id}.jpg")
- response = upload_file(file_path)
- url = f"https://telegra.ph{response[0]}"
+ response = await Telegraph().upload_file(file_path)
+ url = f"https://telegra.ph{response[0]['src']}"
req = (
await http.get(
f"https://script.google.com/macros/s/AKfycbwURISN0wjazeJTMHTPAtxkrZTWTpsWIef5kxqVGoXqnrzdLdIQIfLO7jsR5OQ5GO16/exec?url={url}",
diff --git a/misskaty/plugins/paste.py b/misskaty/plugins/paste.py
index 0b9019b2..a25b69c6 100644
--- a/misskaty/plugins/paste.py
+++ b/misskaty/plugins/paste.py
@@ -1,7 +1,6 @@
"""
- * @author yasir
- * @date 2022-12-01 09:12:27
- * @lastModified 2022-12-01 09:32:31
+ * @author Yasir Aris M
+ * @created 2022-12-01 09:12:27
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
@@ -13,6 +12,7 @@ from pyrogram import filters
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import *
from misskaty.helper import http, rentry, post_to_telegraph
from misskaty.vars import COMMAND_HANDLER
@@ -67,6 +67,7 @@ pattern = compiles(r"^text/|json$|yaml$|xml$|toml$|x-sh$|x-shellscript$|x-subrip
@app.on_message(filters.command(["tgraph"], COMMAND_HANDLER))
+@ratelimiter
async def telegraph_paste(_, message):
reply = message.reply_to_message
if not reply and len(message.command) < 2:
@@ -139,6 +140,7 @@ async def telegraph_paste(_, message):
# Default Paste to Wastebin using Deta
@app.on_message(filters.command(["paste"], COMMAND_HANDLER))
+@ratelimiter
async def wastepaste(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
@@ -203,6 +205,7 @@ async def wastepaste(_, message):
# Nekobin Paste
@app.on_message(filters.command(["neko"], COMMAND_HANDLER))
+@ratelimiter
async def nekopaste(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
@@ -260,6 +263,7 @@ async def nekopaste(_, message):
# Paste as spacebin
@app.on_message(filters.command(["sbin"], COMMAND_HANDLER))
+@ratelimiter
async def spacebinn(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
@@ -319,6 +323,7 @@ async def spacebinn(_, message):
# Rentry paste
@app.on_message(filters.command(["rentry"], COMMAND_HANDLER))
+@ratelimiter
async def rentrypaste(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
@@ -375,6 +380,7 @@ async def rentrypaste(_, message):
# Tempaste pastebin
@app.on_message(filters.command(["temp_paste"], COMMAND_HANDLER))
+@ratelimiter
async def tempaste(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
diff --git a/misskaty/plugins/ping.py b/misskaty/plugins/ping.py
index 08acd06b..550463e4 100644
--- a/misskaty/plugins/ping.py
+++ b/misskaty/plugins/ping.py
@@ -13,11 +13,13 @@ from subprocess import run as srun
from pyrogram import filters
from misskaty import app, botStartTime
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.human_read import get_readable_time
from misskaty.vars import COMMAND_HANDLER
@app.on_message(filters.command(["ping"], COMMAND_HANDLER))
+@ratelimiter
async def ping(_, message):
currentTime = get_readable_time(time.time() - botStartTime)
start_t = time.time()
@@ -31,6 +33,7 @@ async def ping(_, message):
@app.on_message(filters.command(["ping_dc"], COMMAND_HANDLER))
+@ratelimiter
async def ping_handler(_, message):
m = await message.reply("Pinging datacenters...")
async with Lock():
diff --git a/misskaty/plugins/pypi_search.py b/misskaty/plugins/pypi_search.py
index 6a692776..42e9bdff 100644
--- a/misskaty/plugins/pypi_search.py
+++ b/misskaty/plugins/pypi_search.py
@@ -9,6 +9,7 @@ from pykeyboard import InlineButton, InlineKeyboard
from pyrogram import filters
from misskaty import app
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import *
from misskaty.helper.http import http
from misskaty.plugins.web_scraper import split_arr, headers
@@ -40,6 +41,7 @@ async def getDataPypi(msg, kueri, CurrentPage, user):
@app.on_message(filters.command(["pypi"], COMMAND_HANDLER))
+@ratelimiter
async def pypi_s(client, message):
kueri = " ".join(message.command[1:])
if not kueri:
@@ -58,6 +60,7 @@ async def pypi_s(client, message):
@app.on_callback_query(filters.create(lambda _, __, query: "page_pypi#" in query.data))
+@ratelimiter
async def pypipage_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -82,6 +85,7 @@ async def pypipage_callback(client, callback_query):
@app.on_callback_query(filters.create(lambda _, __, query: "pypidata#" in query.data))
+@ratelimiter
async def pypi_getdata(_, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
diff --git a/misskaty/plugins/quotly.py b/misskaty/plugins/quotly.py
index 5cca75e4..f7e82d55 100644
--- a/misskaty/plugins/quotly.py
+++ b/misskaty/plugins/quotly.py
@@ -5,6 +5,7 @@ from pyrogram.types import Message
from misskaty import app
from misskaty.helper.http import http
+from misskaty.core.decorator.ratelimiter import ratelimiter
__MODULE__ = "Fun"
__HELP__ = """
@@ -197,6 +198,7 @@ def isArgInt(txt) -> list:
@app.on_message(filters.command(["q"]) & filters.reply)
+@ratelimiter
async def msg_quotly_cmd(c: Client, m: Message):
if len(m.text.split()) > 1:
check_arg = isArgInt(m.command[1])
diff --git a/misskaty/plugins/sangmata.py b/misskaty/plugins/sangmata.py
index 06863ec5..172a0419 100644
--- a/misskaty/plugins/sangmata.py
+++ b/misskaty/plugins/sangmata.py
@@ -3,6 +3,7 @@ from pyrogram import filters
from database.sangmata_db import *
from misskaty import app
from misskaty.core.decorator.permissions import adminsOnly
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import kirimPesan
from misskaty.vars import COMMAND_HANDLER
@@ -42,6 +43,7 @@ async def cek_mataa(_, m):
@app.on_message(filters.group & filters.command("sangmata_set", COMMAND_HANDLER) & ~filters.bot & ~filters.via_bot)
@adminsOnly("can_change_info")
+@ratelimiter
async def set_mataa(_, m):
if len(m.command) == 1:
return await kirimPesan(m, f"Use /{m.command[0]} on, to enable sangmata. If you want disable, you can use off parameter.")
diff --git a/misskaty/plugins/sed.py b/misskaty/plugins/sed.py
index 1b1cd01b..5ccd86c9 100644
--- a/misskaty/plugins/sed.py
+++ b/misskaty/plugins/sed.py
@@ -8,9 +8,11 @@ from pyrogram import filters
from pyrogram.errors import MessageEmpty
from misskaty import app
+from misskaty.core.decorator.ratelimiter import ratelimiter
@app.on_message(filters.regex(r"^s/(.+)?/(.+)?(/.+)?") & filters.reply)
+@ratelimiter
async def sed(c, m):
exp = regex.split(r"(?{stickerid}".format(stickerid=m.reply_to_message.sticker.file_id))
@app.on_message(filters.command("unkang", COMMAND_HANDLER) & filters.reply)
+@ratelimiter
async def getstickerid(c, m):
if m.reply_to_message.sticker:
pp = await m.reply_text("Trying to remove from pack..")
@@ -87,6 +91,7 @@ async def getstickerid(c, m):
@app.on_message(filters.command(["curi", "kang"], COMMAND_HANDLER))
+@ratelimiter
async def kang_sticker(c, m):
if not m.from_user:
return await m.reply_text("You are anon admin, kang stickers in my pm.")
diff --git a/misskaty/plugins/sub_extractor.py b/misskaty/plugins/sub_extractor.py
index 50b1849c..41056c47 100644
--- a/misskaty/plugins/sub_extractor.py
+++ b/misskaty/plugins/sub_extractor.py
@@ -1,6 +1,6 @@
"""
* @author yasir
- * @date 2022-12-01 09:12:27
+ * @created 2022-12-01 09:12:27
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
@@ -17,6 +17,7 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app
from misskaty.core.message_utils import *
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err
from misskaty.helper.pyro_progress import progress_for_pyrogram
from misskaty.helper.tools import get_random_string
@@ -61,6 +62,7 @@ def get_subname(lang, url, format):
@app.on_message(filters.command(["ceksub", "extractmedia"], COMMAND_HANDLER))
+@ratelimiter
async def ceksub(_, m):
cmd = m.text.split(" ", 1)
if len(cmd) == 1:
@@ -107,6 +109,7 @@ async def ceksub(_, m):
@app.on_message(filters.command(["converttosrt"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def convertsrt(c, m):
reply = m.reply_to_message
if not reply and reply.document and (reply.document.file_name.endswith(".vtt") or reply.document.file_name.endswith(".ass")):
@@ -133,6 +136,7 @@ async def convertsrt(c, m):
@app.on_callback_query(filters.regex(r"^streamextract#"))
+@ratelimiter
async def stream_extract(bot, update):
cb_data = update.data
usr = update.message.reply_to_message
diff --git a/misskaty/plugins/ubot_plugin.py b/misskaty/plugins/ubot_plugin.py
index b42dd6f5..51741532 100644
--- a/misskaty/plugins/ubot_plugin.py
+++ b/misskaty/plugins/ubot_plugin.py
@@ -1,7 +1,6 @@
"""
* @author yasir
* @date 2022-12-01 09:12:27
- * @lastModified 2022-12-01 09:32:31
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
diff --git a/misskaty/plugins/urban_dict.py b/misskaty/plugins/urban_dict.py
index 49199134..f93ee020 100644
--- a/misskaty/plugins/urban_dict.py
+++ b/misskaty/plugins/urban_dict.py
@@ -2,6 +2,7 @@ import asyncio
from pykeyboard import InlineKeyboard
from pyrogram import filters
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
from misskaty import app
from misskaty.vars import COMMAND_HANDLER
@@ -32,6 +33,7 @@ async def getData(chat_id, message_id, GetWord, CurrentPage):
@app.on_message(filters.command(["ud"], COMMAND_HANDLER))
+@ratelimiter
async def urbanDictionary(client, message):
if not message.from_user:
return
@@ -51,6 +53,7 @@ async def urbanDictionary(client, message):
@app.on_callback_query(filters.create(lambda _, __, query: "pagination_urban#" in query.data))
+@ratelimiter
async def ud_callback(client, callback_query):
message_id = callback_query.message.id
chat_id = callback_query.message.chat.id
diff --git a/misskaty/plugins/web_scraper.py b/misskaty/plugins/web_scraper.py
index 57169baa..3f4228b1 100644
--- a/misskaty/plugins/web_scraper.py
+++ b/misskaty/plugins/web_scraper.py
@@ -1,7 +1,6 @@
"""
* @author yasir
- * @date 2022-12-01 09:12:27
- * @lastModified 2023-01-11 12:23:31
+ * @created 2022-12-01 09:12:27
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
@@ -10,6 +9,7 @@ import logging
from bs4 import BeautifulSoup
from pykeyboard import InlineKeyboard, InlineButton
from pyrogram import filters
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
from misskaty.helper.kuso_utils import Kusonime
from misskaty import app
@@ -336,6 +336,7 @@ async def getDataGomov(msg, kueri, CurrentPage, user):
# Terbit21 CMD
@app.on_message(filters.command(["terbit21"], COMMAND_HANDLER))
+@ratelimiter
async def terbit21_s(client, message):
kueri = " ".join(message.command[1:])
if not kueri:
@@ -353,6 +354,7 @@ async def terbit21_s(client, message):
# LK21 CMD
@app.on_message(filters.command(["lk21"], COMMAND_HANDLER))
+@ratelimiter
async def lk21_s(client, message):
message.chat.id
kueri = " ".join(message.command[1:])
@@ -371,6 +373,7 @@ async def lk21_s(client, message):
# Pahe CMD
@app.on_message(filters.command(["pahe"], COMMAND_HANDLER))
+@ratelimiter
async def pahe_s(client, message):
message.chat.id
kueri = " ".join(message.command[1:])
@@ -389,6 +392,7 @@ async def pahe_s(client, message):
# Gomov CMD
@app.on_message(filters.command(["gomov"], COMMAND_HANDLER))
+@ratelimiter
async def gomov_s(client, message):
kueri = " ".join(message.command[1:])
if not kueri:
@@ -408,6 +412,7 @@ async def gomov_s(client, message):
# MelongMovie CMD
@app.on_message(filters.command(["melongmovie"], COMMAND_HANDLER))
+@ratelimiter
async def melong_s(client, message):
kueri = " ".join(message.command[1:])
if not kueri:
@@ -427,6 +432,7 @@ async def melong_s(client, message):
# Savefilm21 CMD
@app.on_message(filters.command(["savefilm21"], COMMAND_HANDLER))
+@ratelimiter
async def savefilm_s(client, message):
kueri = " ".join(message.command[1:])
if not kueri:
@@ -446,6 +452,7 @@ async def savefilm_s(client, message):
# Kusonime CMD
@app.on_message(filters.command(["kusonime"], COMMAND_HANDLER))
+@ratelimiter
async def kusonime_s(client, message):
kueri = " ".join(message.command[1:])
if not kueri:
@@ -467,6 +474,7 @@ async def kusonime_s(client, message):
# Lendrive CMD
@app.on_message(filters.command(["lendrive"], COMMAND_HANDLER))
+@ratelimiter
async def lendrive_s(client, message):
kueri = " ".join(message.command[1:])
if not kueri:
@@ -486,6 +494,7 @@ async def lendrive_s(client, message):
# Movieku CMD
@app.on_message(filters.command(["movieku"], COMMAND_HANDLER))
+@ratelimiter
async def movieku_s(client, message):
kueri = " ".join(message.command[1:])
if not kueri:
@@ -503,6 +512,7 @@ async def movieku_s(client, message):
# Savefillm21 Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_savefilm#" in query.data))
+@ratelimiter
async def savefilmpage_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -528,6 +538,7 @@ async def savefilmpage_callback(client, callback_query):
# Kuso Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_kuso#" in query.data))
+@ratelimiter
async def kusopage_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -555,6 +566,7 @@ async def kusopage_callback(client, callback_query):
# Lendrive Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_lendrive#" in query.data))
+@ratelimiter
async def moviekupage_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -580,6 +592,7 @@ async def moviekupage_callback(client, callback_query):
# Movieku Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_movieku#" in query.data))
+@ratelimiter
async def moviekupage_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -603,6 +616,7 @@ async def moviekupage_callback(client, callback_query):
# Terbit21 Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_terbit21#" in query.data))
+@ratelimiter
async def terbit21page_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -626,6 +640,7 @@ async def terbit21page_callback(client, callback_query):
# Page Callback Melong
@app.on_callback_query(filters.create(lambda _, __, query: "page_melong#" in query.data))
+@ratelimiter
async def melongpage_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -651,6 +666,7 @@ async def melongpage_callback(client, callback_query):
# Lk21 Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_lk21#" in query.data))
+@ratelimiter
async def lk21page_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -674,6 +690,7 @@ async def lk21page_callback(client, callback_query):
# Pahe Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_pahe#" in query.data))
+@ratelimiter
async def pahepage_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -697,6 +714,7 @@ async def pahepage_callback(client, callback_query):
# Gomov Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_gomov#" in query.data))
+@ratelimiter
async def gomovpage_callback(client, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -723,6 +741,7 @@ async def gomovpage_callback(client, callback_query):
### Scrape DDL Link From Web ###
# Kusonime DDL
@app.on_callback_query(filters.create(lambda _, __, query: "kusoextract#" in query.data))
+@ratelimiter
async def kusonime_scrap(_, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -755,6 +774,7 @@ async def kusonime_scrap(_, callback_query):
# Savefilm21 DDL
@app.on_callback_query(filters.create(lambda _, __, query: "sf21extract#" in query.data))
+@ratelimiter
async def savefilm21_scrap(_, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -781,6 +801,7 @@ async def savefilm21_scrap(_, callback_query):
# Scrape Link Download Movieku.CC
@app.on_message(filters.command(["movieku_scrap"], COMMAND_HANDLER))
+@ratelimiter
async def muviku_scrap(_, message):
try:
link = message.text.split(" ", maxsplit=1)[1]
@@ -806,6 +827,7 @@ async def muviku_scrap(_, message):
# Scrape DDL Link Melongmovie
@app.on_callback_query(filters.create(lambda _, __, query: "melongextract#" in query.data))
+@ratelimiter
async def melong_scrap(_, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -835,6 +857,7 @@ async def melong_scrap(_, callback_query):
# Scrape DDL Link Gomov
@app.on_callback_query(filters.create(lambda _, __, query: "gomovextract#" in query.data))
+@ratelimiter
async def gomov_dl(_, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
@@ -864,6 +887,7 @@ async def gomov_dl(_, callback_query):
@app.on_callback_query(filters.create(lambda _, __, query: "lendriveextract#" in query.data))
+@ratelimiter
async def lendrive_dl(_, callback_query):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
return await callback_query.answer("Not yours..", True)
diff --git a/misskaty/plugins/webss.py b/misskaty/plugins/webss.py
index c1b05b0e..1a4cbe15 100644
--- a/misskaty/plugins/webss.py
+++ b/misskaty/plugins/webss.py
@@ -1,14 +1,12 @@
-import base64
import os
from asyncio import gather
-from io import BytesIO
-from PIL import Image
from pyrogram import filters
from misskaty import app
from misskaty.core.message_utils import *
from misskaty.core.decorator.errors import capture_err
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER
@@ -20,18 +18,16 @@ __HELP__ = """
@app.on_message(filters.command(["webss"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def take_ss(_, m):
if len(m.command) == 1:
return await kirimPesan(m, "Give A Url To Fetch Screenshot.")
url = m.command[1] if m.command[1].startswith("http") else f"https://{m.command[1]}"
- filename = f"webSS_{m.from_user.id}.jpg"
+ filename = f"webSS_{m.from_user.id}.png"
msg = await m.reply("Capturing screenshot...")
try:
- photo = (await http.get(f"https://yasirapi.eu.org/webss?url={url}")).json()
- img = Image.open(BytesIO(base64.decodebytes(bytes(photo["result"], "utf-8"))))
- img.save(filename)
- await editPesan(msg, "Uploading...")
- await gather(*[m.reply_document(filename), m.reply_photo(filename)])
+ url = f"https://webss.yasirapi.eu.org/api?url={url}&width=1280&height=720"
+ await gather(*[m.reply_document(url, file_name=filename), m.reply_photo(url, file_name=filename)])
await hapusPesan(m)
os.remove(filename)
except Exception as e:
diff --git a/misskaty/plugins/ytdl_download_new.py b/misskaty/plugins/ytdl_download_new.py
index 27718afb..5845684b 100644
--- a/misskaty/plugins/ytdl_download_new.py
+++ b/misskaty/plugins/ytdl_download_new.py
@@ -9,7 +9,7 @@ from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMa
from misskaty import app
from misskaty.core.message_utils import *
from misskaty.core.decorator.errors import capture_err
-from misskaty.core.decorator.pyro_cooldown import wait
+from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL
@@ -22,8 +22,9 @@ def rand_key():
return str(uuid4())[:8]
-@app.on_message(filters.command(["ytsearch"], COMMAND_HANDLER) & ~filters.channel & wait(30))
+@app.on_message(filters.command(["ytsearch"], COMMAND_HANDLER) & ~filters.channel)
@capture_err
+@ratelimiter
async def ytsearch(_, message):
if message.sender_chat:
return await kirimPesan(message, "This feature not supported for channel.")
@@ -60,6 +61,7 @@ async def ytsearch(_, message):
@app.on_message(filters.command(["ytdown"], COMMAND_HANDLER))
@capture_err
+@ratelimiter
async def ytdownv2(_, message):
if not message.from_user:
return
@@ -77,6 +79,7 @@ async def ytdownv2(_, message):
@app.on_callback_query(filters.regex(r"^yt_listall"))
+@ratelimiter
async def ytdl_listall_callback(_, cq: CallbackQuery):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
return await cq.answer("Not your task", True)
@@ -87,6 +90,7 @@ async def ytdl_listall_callback(_, cq: CallbackQuery):
@app.on_callback_query(filters.regex(r"^yt_extract_info"))
+@ratelimiter
async def ytdl_extractinfo_callback(_, cq: CallbackQuery):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
return await cq.answer("Not your task", True)
@@ -112,6 +116,7 @@ async def ytdl_extractinfo_callback(_, cq: CallbackQuery):
@app.on_callback_query(filters.regex(r"^yt_(gen|dl)"))
+@ratelimiter
async def ytdl_gendl_callback(_, cq: CallbackQuery):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
return await cq.answer("Not your task", True)
@@ -155,6 +160,7 @@ async def ytdl_gendl_callback(_, cq: CallbackQuery):
@app.on_callback_query(filters.regex(r"^ytdl_scroll"))
+@ratelimiter
async def ytdl_scroll_callback(_, cq: CallbackQuery):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
return await cq.answer("Not your task", True)