Spaces:
Paused
Paused
Captain Ezio
commited on
Commit
·
dee310b
1
Parent(s):
026b3d9
Adding flood and minor changes
Browse files- Powers/database/flood_db.py +66 -0
- Powers/plugins/bans.py +1 -1
- Powers/plugins/flood.py +247 -0
- Powers/plugins/muting.py +1 -1
- Powers/plugins/search.py +248 -0
- Powers/utils/custom_filters.py +1 -1
- Powers/utils/extras.py +12 -0
- README.md +1 -1
- app.json +1 -1
Powers/database/flood_db.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from threading import RLock
|
| 2 |
+
|
| 3 |
+
from Powers.database import MongoDB
|
| 4 |
+
from Powers.utils.msg_types import Types
|
| 5 |
+
|
| 6 |
+
INSERTION_LOCK = RLock()
|
| 7 |
+
|
| 8 |
+
class Floods(MongoDB):
|
| 9 |
+
"""Class to store flood limit and action of a chat"""
|
| 10 |
+
|
| 11 |
+
db_name = "flood"
|
| 12 |
+
|
| 13 |
+
def __init__(self):
|
| 14 |
+
super().__init__(self.db_name)
|
| 15 |
+
|
| 16 |
+
def save_flood(
|
| 17 |
+
self,
|
| 18 |
+
chat_id: int,
|
| 19 |
+
limit: int,
|
| 20 |
+
within: int,
|
| 21 |
+
action: str,
|
| 22 |
+
):
|
| 23 |
+
with INSERTION_LOCK:
|
| 24 |
+
curr = self.find_one({"chat_id": chat_id, "limit": limit, "within": within, "action": action})
|
| 25 |
+
if curr:
|
| 26 |
+
if not(limit == int(curr['limit']) or within == int(curr['within']) or action == str(curr['action'])):
|
| 27 |
+
return self.update(
|
| 28 |
+
{
|
| 29 |
+
"_id": chat_id,
|
| 30 |
+
"limit": limit,
|
| 31 |
+
"within": within,
|
| 32 |
+
"action": action,
|
| 33 |
+
}
|
| 34 |
+
)
|
| 35 |
+
return self.insert_one(
|
| 36 |
+
{
|
| 37 |
+
"chat_id" : chat_id,
|
| 38 |
+
"limit": limit,
|
| 39 |
+
"within": within,
|
| 40 |
+
"action" : action
|
| 41 |
+
},
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
def is_chat(self, chat_id: int):
|
| 45 |
+
with INSERTION_LOCK:
|
| 46 |
+
curr = self.find_all({"chat_id": chat_id})
|
| 47 |
+
if curr:
|
| 48 |
+
action = [str(curr['limit']), str(curr['within']), str(curr['action'])]
|
| 49 |
+
return action
|
| 50 |
+
return False
|
| 51 |
+
|
| 52 |
+
def get_action(self, chat_id: int, limit: int, within: int, action: str):
|
| 53 |
+
with INSERTION_LOCK:
|
| 54 |
+
curr = self.find_one({"chat_id": chat_id, "limit": limit, "within": within, "action": action})
|
| 55 |
+
if curr:
|
| 56 |
+
return curr
|
| 57 |
+
return "Flood haven't set"
|
| 58 |
+
|
| 59 |
+
def rm_flood(self, chat_id: int, limit: int, within: int, action: str):
|
| 60 |
+
with INSERTION_LOCK:
|
| 61 |
+
curr = self.find_one({"chat_id": chat_id, "limit": limit, "within": within, "action": action})
|
| 62 |
+
if curr:
|
| 63 |
+
self.delete_one(curr)
|
| 64 |
+
return True
|
| 65 |
+
return False
|
| 66 |
+
|
Powers/plugins/bans.py
CHANGED
|
@@ -886,7 +886,7 @@ async def unbanbutton(c: Gojo, q: CallbackQuery):
|
|
| 886 |
user_id = int(splitter[1])
|
| 887 |
user = await q.message.chat.get_member(q.from_user.id)
|
| 888 |
|
| 889 |
-
if not user.can_restrict_members and q.from_user.id != OWNER_ID:
|
| 890 |
await q.answer(
|
| 891 |
"You don't have enough permission to do this!\nStay in your limits!",
|
| 892 |
show_alert=True,
|
|
|
|
| 886 |
user_id = int(splitter[1])
|
| 887 |
user = await q.message.chat.get_member(q.from_user.id)
|
| 888 |
|
| 889 |
+
if not user.privileges.can_restrict_members and q.from_user.id != OWNER_ID:
|
| 890 |
await q.answer(
|
| 891 |
"You don't have enough permission to do this!\nStay in your limits!",
|
| 892 |
show_alert=True,
|
Powers/plugins/flood.py
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import time
|
| 2 |
+
|
| 3 |
+
from pyrogram import filters
|
| 4 |
+
from pyrogram.enums import ChatMemberStatus as CMS
|
| 5 |
+
from pyrogram.enums import ChatType as CT
|
| 6 |
+
from pyrogram.errors import RPCError
|
| 7 |
+
from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
|
| 8 |
+
InlineKeyboardMarkup, Message)
|
| 9 |
+
|
| 10 |
+
from Powers import SUPPORT_STAFF
|
| 11 |
+
from Powers.bot_class import Gojo
|
| 12 |
+
from Powers.database.approve_db import Approve
|
| 13 |
+
from Powers.database.flood_db import Floods
|
| 14 |
+
from Powers.utils.custom_filters import admin_filter, command
|
| 15 |
+
from Powers.utils.kbhelpers import ikb
|
| 16 |
+
|
| 17 |
+
Flood = Floods()
|
| 18 |
+
|
| 19 |
+
approve = Approve()
|
| 20 |
+
|
| 21 |
+
on_key = ["on", "start", "disable"]
|
| 22 |
+
off_key = ["off", "end", "enable", "stop"]
|
| 23 |
+
|
| 24 |
+
close_kb =InlineKeyboardMarkup(
|
| 25 |
+
[
|
| 26 |
+
[
|
| 27 |
+
InlineKeyboardButton(
|
| 28 |
+
"Close ❌",
|
| 29 |
+
callback_data="close"
|
| 30 |
+
)
|
| 31 |
+
]
|
| 32 |
+
]
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
action_kb = InlineKeyboardMarkup(
|
| 36 |
+
[
|
| 37 |
+
[
|
| 38 |
+
InlineKeyboardButton(
|
| 39 |
+
"Mute 🔇",
|
| 40 |
+
callback_data="mute"
|
| 41 |
+
),
|
| 42 |
+
InlineKeyboardButton(
|
| 43 |
+
"Ban 🚷",
|
| 44 |
+
callback_data="ban"
|
| 45 |
+
),
|
| 46 |
+
InlineKeyboardButton(
|
| 47 |
+
"Kick",
|
| 48 |
+
callback_data="kick"
|
| 49 |
+
)
|
| 50 |
+
]
|
| 51 |
+
]
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
within_kb = InlineKeyboardMarkup(
|
| 55 |
+
[
|
| 56 |
+
[
|
| 57 |
+
InlineKeyboardButton(
|
| 58 |
+
"5",
|
| 59 |
+
callback_data="5"
|
| 60 |
+
),
|
| 61 |
+
InlineKeyboardButton(
|
| 62 |
+
"10",
|
| 63 |
+
callback_data="10"
|
| 64 |
+
),
|
| 65 |
+
InlineKeyboardButton(
|
| 66 |
+
"15",
|
| 67 |
+
callback_data="15"
|
| 68 |
+
)
|
| 69 |
+
]
|
| 70 |
+
]
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
+
limit_kb = InlineKeyboardMarkup(
|
| 74 |
+
[
|
| 75 |
+
[
|
| 76 |
+
InlineKeyboardButton(
|
| 77 |
+
"5",
|
| 78 |
+
callback_data="l_5"
|
| 79 |
+
),
|
| 80 |
+
InlineKeyboardButton(
|
| 81 |
+
"10",
|
| 82 |
+
callback_data="l_10"
|
| 83 |
+
),
|
| 84 |
+
InlineKeyboardButton(
|
| 85 |
+
"15",
|
| 86 |
+
callback_data="l_15"
|
| 87 |
+
)
|
| 88 |
+
]
|
| 89 |
+
]
|
| 90 |
+
)
|
| 91 |
+
|
| 92 |
+
@Gojo.on_message(command(['floodaction','actionflood']))
|
| 93 |
+
async def flood_action(c: Gojo, m: Message):
|
| 94 |
+
if m.chat.type == CT.PRIVATE:
|
| 95 |
+
await m.reply_text("Use this command in group")
|
| 96 |
+
return
|
| 97 |
+
c_id = m.chat.id
|
| 98 |
+
is_flood = Flood.is_chat(c_id)
|
| 99 |
+
saction = is_flood[2]
|
| 100 |
+
if is_flood:
|
| 101 |
+
await m.reply_text(
|
| 102 |
+
f"Choose a action given bellow to do when flood happens.\n **CURRENT ACTION** is {saction}",
|
| 103 |
+
reply_markup=action_kb
|
| 104 |
+
)
|
| 105 |
+
return
|
| 106 |
+
await m.reply_text("Switch on the flood protection first.")
|
| 107 |
+
return
|
| 108 |
+
|
| 109 |
+
@Gojo.on_message(command(['setflood', 'flood']) & ~filters.bot & admin_filter)
|
| 110 |
+
async def flood_set(c: Gojo, m: Message):
|
| 111 |
+
if m.chat.type == CT.PRIVATE:
|
| 112 |
+
return await m.reply_text("This command is ment to be used in groups.")
|
| 113 |
+
split = m.text.split(None, 1)
|
| 114 |
+
c_id = m.chat.id
|
| 115 |
+
is_flood = Flood.is_chat(c_id)
|
| 116 |
+
if len(split) == 1:
|
| 117 |
+
c_id = m.chat.id
|
| 118 |
+
if is_flood:
|
| 119 |
+
saction = is_flood[2]
|
| 120 |
+
slimit = is_flood[0]
|
| 121 |
+
swithin = is_flood[1]
|
| 122 |
+
return await m.reply_text(f"Flood is on for this chat\n**Action**:{saction}\n**Messages**:{slimit} within {swithin} sec")
|
| 123 |
+
return await m.reply_text("Flood protection is off of this chat.")
|
| 124 |
+
|
| 125 |
+
if len(split) == 2:
|
| 126 |
+
c_id = m.chat.id
|
| 127 |
+
if split[1].lower() in on_key:
|
| 128 |
+
Flood.save_flood(m.chat.id, 5, 5, 'mute')
|
| 129 |
+
await m.reply_text("Flood protection has been started for this group.")
|
| 130 |
+
return
|
| 131 |
+
if split[1].lower() in off_key:
|
| 132 |
+
Flood.rm_flood(m.chat.id, slimit, swithin, saction)
|
| 133 |
+
await m.reply_text("Flood protection has been stopped for this chat")
|
| 134 |
+
return
|
| 135 |
+
await m.reply_text("**Usage:**\n `/setflood on/off`")
|
| 136 |
+
return
|
| 137 |
+
|
| 138 |
+
@Gojo.on_callback_query()
|
| 139 |
+
async def callbacks(c: Gojo, q: CallbackQuery):
|
| 140 |
+
data = q.data
|
| 141 |
+
if data == "close":
|
| 142 |
+
await q.message.delete()
|
| 143 |
+
q.answer("Closed")
|
| 144 |
+
return
|
| 145 |
+
c_id = q.message.chat.id
|
| 146 |
+
is_flood = Flood.is_chat(c_id)
|
| 147 |
+
saction = is_flood[2]
|
| 148 |
+
slimit = is_flood[0]
|
| 149 |
+
swithin = is_flood[1]
|
| 150 |
+
user = q.from_user.id
|
| 151 |
+
user_status = (await q.message.chat.get_member(q.from_user.id)).status
|
| 152 |
+
if user in SUPPORT_STAFF or user_status in [CMS.OWNER, CMS.ADMINISTRATOR]:
|
| 153 |
+
if data in ["mute", "ban", "kick"]:
|
| 154 |
+
Flood.save_flood(c_id, slimit, swithin, data)
|
| 155 |
+
await q.answer("Updated action", show_alert=True)
|
| 156 |
+
q.edit_message_caption(
|
| 157 |
+
f"Set the limit of message after the flood protection will be activated\n **CURRENT LIMIT** {slimit} messages",
|
| 158 |
+
reply_markup=limit_kb
|
| 159 |
+
)
|
| 160 |
+
return
|
| 161 |
+
if data in ["l_5", "l_10", "l_15"]:
|
| 162 |
+
change = int(data.split("_")[1])
|
| 163 |
+
Flood.save_flood(c_id, change, swithin, saction)
|
| 164 |
+
await q.answer("Updated limit", show_alert=True)
|
| 165 |
+
q.edit_message_caption(
|
| 166 |
+
f"Set the time with the number of message recived treated as flood\n **CUURENT TIME** {swithin}",
|
| 167 |
+
reply_markup=within_kb
|
| 168 |
+
)
|
| 169 |
+
return
|
| 170 |
+
if data in ["5", "10", "15"]:
|
| 171 |
+
change = int(data)
|
| 172 |
+
Flood.save_flood(c_id, slimit, change, saction)
|
| 173 |
+
await q.answer("Updated", show_alert=True)
|
| 174 |
+
q.edit_message_caption(
|
| 175 |
+
"Flood protection setting has been updated",
|
| 176 |
+
reply_markup=close_kb
|
| 177 |
+
)
|
| 178 |
+
return
|
| 179 |
+
else:
|
| 180 |
+
await q.answer(
|
| 181 |
+
"You don't have enough permission to do this!\nStay in your limits!",
|
| 182 |
+
show_alert=True,
|
| 183 |
+
)
|
| 184 |
+
|
| 185 |
+
@Gojo.on_callback_query(filters.regex("^un_"))
|
| 186 |
+
async def reverse_callbacks(c: Gojo, q: CallbackQuery):
|
| 187 |
+
data = q.data.split("_")
|
| 188 |
+
action = data[1]
|
| 189 |
+
user_id = int(data[2])
|
| 190 |
+
if action == "ban":
|
| 191 |
+
user = await q.message.chat.get_member(q.from_user.id)
|
| 192 |
+
if not user.privileges.can_restrict_members and q.from_user.id in SUPPORT_STAFF:
|
| 193 |
+
await q.answer(
|
| 194 |
+
"You don't have enough permission to do this!\nStay in your limits!",
|
| 195 |
+
show_alert=True,
|
| 196 |
+
)
|
| 197 |
+
return
|
| 198 |
+
whoo = await c.get_chat(user_id)
|
| 199 |
+
doneto = whoo.first_name if whoo.first_name else whoo.title
|
| 200 |
+
try:
|
| 201 |
+
await q.message.chat.unban_member(user_id)
|
| 202 |
+
except RPCError as e:
|
| 203 |
+
await q.message.edit_text(f"Error: {e}")
|
| 204 |
+
return
|
| 205 |
+
await q.message.edit_text(f"{q.from_user.mention} unbanned {doneto}!")
|
| 206 |
+
return
|
| 207 |
+
|
| 208 |
+
if action == "mute":
|
| 209 |
+
user = await q.message.chat.get_member(q.from_user.id)
|
| 210 |
+
|
| 211 |
+
if not user.privileges.can_restrict_members and user.id in SUPPORT_STAFF:
|
| 212 |
+
await q.answer(
|
| 213 |
+
"You don't have enough permission to do this!\nStay in your limits!",
|
| 214 |
+
show_alert=True,
|
| 215 |
+
)
|
| 216 |
+
return
|
| 217 |
+
whoo = await c.get_users(user_id)
|
| 218 |
+
try:
|
| 219 |
+
await q.message.chat.unban_member(user_id)
|
| 220 |
+
except RPCError as e:
|
| 221 |
+
await q.message.edit_text(f"Error: {e}")
|
| 222 |
+
return
|
| 223 |
+
await q.message.edit_text(f"{q.from_user.mention} unmuted {whoo.mention}!")
|
| 224 |
+
return
|
| 225 |
+
|
| 226 |
+
@Gojo.on_message(filters.all & ~filters.bot, ~filters.private, 10)
|
| 227 |
+
async def flood_watcher(c: Gojo, m: Message):
|
| 228 |
+
c_id = m.chat.id
|
| 229 |
+
u_id = m.from_user.id
|
| 230 |
+
is_flood = Flood.is_chat(c_id)
|
| 231 |
+
app_users = Approve(m.chat.id).list_approved()
|
| 232 |
+
if u_id in {i[0] for i in app_users}:
|
| 233 |
+
return #return if the user is approved
|
| 234 |
+
if not is_flood or u_id in SUPPORT_STAFF:
|
| 235 |
+
return #return if the user is in support_staff
|
| 236 |
+
user_status = (await m.chat.get_member(m.from_user.id)).status
|
| 237 |
+
if user_status in [CMS.OWNER, CMS.ADMINISTRATOR]:
|
| 238 |
+
return #return if the user is owner or admin
|
| 239 |
+
action = is_flood[2]
|
| 240 |
+
limit = int(is_flood[0])
|
| 241 |
+
within = int(is_flood[1])
|
| 242 |
+
dic = {}
|
| 243 |
+
for i in str(dic.keys()):
|
| 244 |
+
if str(c_id) != i:
|
| 245 |
+
z = {c_id : set()}
|
| 246 |
+
dic.update(z)
|
| 247 |
+
dic[c_id].add(u_id)
|
Powers/plugins/muting.py
CHANGED
|
@@ -597,7 +597,7 @@ async def unmutebutton(c: Gojo, q: CallbackQuery):
|
|
| 597 |
user_id = int(splitter[1])
|
| 598 |
user = await q.message.chat.get_member(q.from_user.id)
|
| 599 |
|
| 600 |
-
if not user.can_restrict_members and user.id != OWNER_ID:
|
| 601 |
await q.answer(
|
| 602 |
"You don't have enough permission to do this!\nStay in your limits!",
|
| 603 |
show_alert=True,
|
|
|
|
| 597 |
user_id = int(splitter[1])
|
| 598 |
user = await q.message.chat.get_member(q.from_user.id)
|
| 599 |
|
| 600 |
+
if not user.privileges.can_restrict_members and user.id != OWNER_ID:
|
| 601 |
await q.answer(
|
| 602 |
"You don't have enough permission to do this!\nStay in your limits!",
|
| 603 |
show_alert=True,
|
Powers/plugins/search.py
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from traceback import format_exc
|
| 2 |
+
|
| 3 |
+
from pyrogram.types import Message
|
| 4 |
+
from search_engine_parser.core.engines.google import Search as GoogleSearch
|
| 5 |
+
from search_engine_parser.core.engines.myanimelist import Search as AnimeSearch
|
| 6 |
+
from search_engine_parser.core.engines.stackoverflow import \
|
| 7 |
+
Search as StackSearch
|
| 8 |
+
from search_engine_parser.core.exceptions import (NoResultsFound,
|
| 9 |
+
NoResultsOrTrafficError)
|
| 10 |
+
|
| 11 |
+
from Powers import LOGGER, SUPPORT_CHANNEL
|
| 12 |
+
from Powers.bot_class import Gojo
|
| 13 |
+
from Powers.utils.custom_filters import command
|
| 14 |
+
from Powers.utils.kbhelpers import ikb
|
| 15 |
+
|
| 16 |
+
#have to add youtube
|
| 17 |
+
|
| 18 |
+
gsearch = GoogleSearch()
|
| 19 |
+
anisearch = AnimeSearch()
|
| 20 |
+
stsearch = StackSearch()
|
| 21 |
+
|
| 22 |
+
@Gojo.on_message(command('google'))
|
| 23 |
+
async def g_search(c: Gojo, m: Message):
|
| 24 |
+
split = m.text.split(None, 1)
|
| 25 |
+
if len(split) == 1:
|
| 26 |
+
return await m.reply_text("No query given\nDo `/help search` to see how to use it")
|
| 27 |
+
to_del = await m.reply_text("Searching google...")
|
| 28 |
+
query = split[1]
|
| 29 |
+
try:
|
| 30 |
+
result = await gsearch.async_search(query)
|
| 31 |
+
keyboard = ikb(
|
| 32 |
+
[
|
| 33 |
+
[
|
| 34 |
+
(
|
| 35 |
+
f"{result[0]['titles']}",
|
| 36 |
+
f"{result[0]['links']}",
|
| 37 |
+
"url",
|
| 38 |
+
),
|
| 39 |
+
],
|
| 40 |
+
[
|
| 41 |
+
(
|
| 42 |
+
f"{result[1]['titles']}",
|
| 43 |
+
f"{result[1]['links']}",
|
| 44 |
+
"url",
|
| 45 |
+
),
|
| 46 |
+
],
|
| 47 |
+
[
|
| 48 |
+
(
|
| 49 |
+
f"{result[2]['titles']}",
|
| 50 |
+
f"{result[2]['links']}",
|
| 51 |
+
"url",
|
| 52 |
+
),
|
| 53 |
+
],
|
| 54 |
+
[
|
| 55 |
+
(
|
| 56 |
+
f"{result[3]['titles']}",
|
| 57 |
+
f"{result[3]['links']}",
|
| 58 |
+
"url",
|
| 59 |
+
),
|
| 60 |
+
],
|
| 61 |
+
[
|
| 62 |
+
(
|
| 63 |
+
f"{result[4]['titles']}",
|
| 64 |
+
f"{result[4]['links']}",
|
| 65 |
+
"url",
|
| 66 |
+
),
|
| 67 |
+
],
|
| 68 |
+
]
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
txt = f"Here are the results of requested query **{query.upper()}**"
|
| 72 |
+
await to_del.delete()
|
| 73 |
+
await m.reply_text(txt, reply_markup=keyboard)
|
| 74 |
+
return
|
| 75 |
+
except NoResultsFound:
|
| 76 |
+
await to_del.delete()
|
| 77 |
+
await m.reply_text("No result found corresponding to your query")
|
| 78 |
+
return
|
| 79 |
+
except NoResultsOrTrafficError:
|
| 80 |
+
await to_del.delete()
|
| 81 |
+
await m.reply_text("No result found due to too many traffic")
|
| 82 |
+
return
|
| 83 |
+
except Exception as e:
|
| 84 |
+
await to_del.delete()
|
| 85 |
+
await m.reply_text(f"Got an error:\nReport it at @{SUPPORT_CHANNEL}")
|
| 86 |
+
LOGGER.error(e)
|
| 87 |
+
LOGGER.error(format_exc())
|
| 88 |
+
return
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
@Gojo.on_message(command('anime'))
|
| 92 |
+
async def anime_search(c: Gojo, m: Message):
|
| 93 |
+
split = m.text.split(None, 1)
|
| 94 |
+
if len(split) == 1:
|
| 95 |
+
return await m.reply_text("No query given\nDo `/help search` to see how to use it")
|
| 96 |
+
to_del = await m.reply_text("Searching myanimelist...")
|
| 97 |
+
query = split[1]
|
| 98 |
+
try:
|
| 99 |
+
result = await anisearch.async_search(query)
|
| 100 |
+
keyboard = ikb(
|
| 101 |
+
[
|
| 102 |
+
[
|
| 103 |
+
(
|
| 104 |
+
f"{result[0]['titles']}",
|
| 105 |
+
f"{result[0]['links']}",
|
| 106 |
+
"url",
|
| 107 |
+
),
|
| 108 |
+
],
|
| 109 |
+
[
|
| 110 |
+
(
|
| 111 |
+
f"{result[1]['titles']}",
|
| 112 |
+
f"{result[1]['links']}",
|
| 113 |
+
"url",
|
| 114 |
+
),
|
| 115 |
+
],
|
| 116 |
+
[
|
| 117 |
+
(
|
| 118 |
+
f"{result[2]['titles']}",
|
| 119 |
+
f"{result[2]['links']}",
|
| 120 |
+
"url",
|
| 121 |
+
),
|
| 122 |
+
],
|
| 123 |
+
[
|
| 124 |
+
(
|
| 125 |
+
f"{result[3]['titles']}",
|
| 126 |
+
f"{result[3]['links']}",
|
| 127 |
+
"url",
|
| 128 |
+
),
|
| 129 |
+
],
|
| 130 |
+
[
|
| 131 |
+
(
|
| 132 |
+
f"{result[4]['titles']}",
|
| 133 |
+
f"{result[4]['links']}",
|
| 134 |
+
"url",
|
| 135 |
+
),
|
| 136 |
+
],
|
| 137 |
+
]
|
| 138 |
+
)
|
| 139 |
+
|
| 140 |
+
txt = f"Here are the results of requested query **{query.upper()}**"
|
| 141 |
+
await to_del.delete()
|
| 142 |
+
await m.reply_text(txt, reply_markup=keyboard)
|
| 143 |
+
return
|
| 144 |
+
except NoResultsFound:
|
| 145 |
+
await to_del.delete()
|
| 146 |
+
await m.reply_text("No result found corresponding to your query")
|
| 147 |
+
return
|
| 148 |
+
except NoResultsOrTrafficError:
|
| 149 |
+
await to_del.delete()
|
| 150 |
+
await m.reply_text("No result found due to too many traffic")
|
| 151 |
+
return
|
| 152 |
+
except Exception as e:
|
| 153 |
+
await to_del.delete()
|
| 154 |
+
await m.reply_text(f"Got an error:\nReport it at @{SUPPORT_CHANNEL}")
|
| 155 |
+
LOGGER.error(e)
|
| 156 |
+
LOGGER.error(format_exc())
|
| 157 |
+
return
|
| 158 |
+
|
| 159 |
+
@Gojo.on_message(command('anime'))
|
| 160 |
+
async def stack_search(c: Gojo, m: Message):
|
| 161 |
+
split = m.text.split(None, 1)
|
| 162 |
+
if len(split) == 1:
|
| 163 |
+
return await m.reply_text("No query given\nDo `/help search` to see how to use it")
|
| 164 |
+
to_del = await m.reply_text("Searching Stackoverflow...")
|
| 165 |
+
query = split[1]
|
| 166 |
+
try:
|
| 167 |
+
result = await stsearch.async_search(query)
|
| 168 |
+
keyboard = ikb(
|
| 169 |
+
[
|
| 170 |
+
[
|
| 171 |
+
(
|
| 172 |
+
f"{result[0]['titles']}",
|
| 173 |
+
f"{result[0]['links']}",
|
| 174 |
+
"url",
|
| 175 |
+
),
|
| 176 |
+
],
|
| 177 |
+
[
|
| 178 |
+
(
|
| 179 |
+
f"{result[1]['titles']}",
|
| 180 |
+
f"{result[1]['links']}",
|
| 181 |
+
"url",
|
| 182 |
+
),
|
| 183 |
+
],
|
| 184 |
+
[
|
| 185 |
+
(
|
| 186 |
+
f"{result[2]['titles']}",
|
| 187 |
+
f"{result[2]['links']}",
|
| 188 |
+
"url",
|
| 189 |
+
),
|
| 190 |
+
],
|
| 191 |
+
[
|
| 192 |
+
(
|
| 193 |
+
f"{result[3]['titles']}",
|
| 194 |
+
f"{result[3]['links']}",
|
| 195 |
+
"url",
|
| 196 |
+
),
|
| 197 |
+
],
|
| 198 |
+
[
|
| 199 |
+
(
|
| 200 |
+
f"{result[4]['titles']}",
|
| 201 |
+
f"{result[4]['links']}",
|
| 202 |
+
"url",
|
| 203 |
+
),
|
| 204 |
+
],
|
| 205 |
+
]
|
| 206 |
+
)
|
| 207 |
+
|
| 208 |
+
txt = f"Here are the results of requested query **{query.upper()}**"
|
| 209 |
+
await to_del.delete()
|
| 210 |
+
await m.reply_text(txt, reply_markup=keyboard)
|
| 211 |
+
return
|
| 212 |
+
except NoResultsFound:
|
| 213 |
+
await to_del.delete()
|
| 214 |
+
await m.reply_text("No result found corresponding to your query")
|
| 215 |
+
return
|
| 216 |
+
except NoResultsOrTrafficError:
|
| 217 |
+
await to_del.delete()
|
| 218 |
+
await m.reply_text("No result found due to too many traffic")
|
| 219 |
+
return
|
| 220 |
+
except Exception as e:
|
| 221 |
+
await to_del.delete()
|
| 222 |
+
await m.reply_text(f"Got an error:\nReport it at @{SUPPORT_CHANNEL}")
|
| 223 |
+
LOGGER.error(e)
|
| 224 |
+
LOGGER.error(format_exc())
|
| 225 |
+
return
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
__PLUGIN__ = "search"
|
| 229 |
+
|
| 230 |
+
|
| 231 |
+
__alt_name__ = [
|
| 232 |
+
"google",
|
| 233 |
+
"anime",
|
| 234 |
+
"stack",
|
| 235 |
+
]
|
| 236 |
+
|
| 237 |
+
__HELP__ = """
|
| 238 |
+
**Search**
|
| 239 |
+
|
| 240 |
+
**Admin only:**
|
| 241 |
+
• /google `<query>` : Search the google for the given query.
|
| 242 |
+
• /anime `<query>` : Search myanimelist for the given query.
|
| 243 |
+
• /stack `<query>` : Search stackoverflow for the given query.
|
| 244 |
+
|
| 245 |
+
|
| 246 |
+
**Example:**
|
| 247 |
+
`/google pyrogram`: return top 5 reuslts.
|
| 248 |
+
"""
|
Powers/utils/custom_filters.py
CHANGED
|
@@ -222,7 +222,7 @@ async def restrict_check_func(_, __, m: Message or CallbackQuery):
|
|
| 222 |
|
| 223 |
user = await m.chat.get_member(m.from_user.id)
|
| 224 |
|
| 225 |
-
if user.can_restrict_members or user.status == CMS.OWNER:
|
| 226 |
status = True
|
| 227 |
else:
|
| 228 |
status = False
|
|
|
|
| 222 |
|
| 223 |
user = await m.chat.get_member(m.from_user.id)
|
| 224 |
|
| 225 |
+
if user.privileges.can_restrict_members or user.status == CMS.OWNER:
|
| 226 |
status = True
|
| 227 |
else:
|
| 228 |
status = False
|
Powers/utils/extras.py
CHANGED
|
@@ -672,4 +672,16 @@ StartPic = [
|
|
| 672 |
"https://te.legra.ph/file/c10f1b32adaf93c1a9fe1.jpg",
|
| 673 |
"https://te.legra.ph/file/68c607517cca7d08e8910.jpg",
|
| 674 |
"https://te.legra.ph/file/c86855e6d5a5668748ce1.jpg",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 675 |
]
|
|
|
|
| 672 |
"https://te.legra.ph/file/c10f1b32adaf93c1a9fe1.jpg",
|
| 673 |
"https://te.legra.ph/file/68c607517cca7d08e8910.jpg",
|
| 674 |
"https://te.legra.ph/file/c86855e6d5a5668748ce1.jpg",
|
| 675 |
+
"https://te.legra.ph/file/e999d233a4a29a7ccc7fa.jpg",
|
| 676 |
+
"https://te.legra.ph/file/2baf1c80ee22ffe1d73fb.jpg",
|
| 677 |
+
"https://te.legra.ph/file/29133374260bf9e7786ee.jpg",
|
| 678 |
+
"https://te.legra.ph/file/0a57ea903409439fadd6a.jpg",
|
| 679 |
+
"https://te.legra.ph/file/326618accb5f9ab6d2e18.jpg",
|
| 680 |
+
"https://te.legra.ph/file/2a899cfc97a46bfd2feae.jpg",
|
| 681 |
+
"https://te.legra.ph/file/f0cd5bcebcd547a507dbf.jpg",
|
| 682 |
+
"https://te.legra.ph/file/8bcb57e91776e3ed63b60.jpg",
|
| 683 |
+
"https://te.legra.ph/file/3c569e93c426aa1941ea6.jpg",
|
| 684 |
+
"https://te.legra.ph/file/1751252a9f0483811e9b9.jpg",
|
| 685 |
+
"https://te.legra.ph/file/380b862e0248225cc1a45.jpg",
|
| 686 |
+
"https://te.legra.ph/file/f314f89640ce4b4118e9e.jpg",
|
| 687 |
]
|
README.md
CHANGED
|
@@ -60,7 +60,7 @@ The Gojo Satoru is a powerful Group Management bot with awesome plugins and feat
|
|
| 60 |
* Fully open-source
|
| 61 |
* Frequently updated
|
| 62 |
|
| 63 |
-
***Can be found on Telegram as __[@
|
| 64 |
|
| 65 |
* Feel free to give ideas for next update. Drop your ideas [here](https://github.com/Gojo-Bots/Gojo_Satoru/discussions/new?category=ideas)
|
| 66 |
|
|
|
|
| 60 |
* Fully open-source
|
| 61 |
* Frequently updated
|
| 62 |
|
| 63 |
+
***Can be found on Telegram as __[@GojoSuperbot](https://telegram.dog/GojoSuperbot)__***
|
| 64 |
|
| 65 |
* Feel free to give ideas for next update. Drop your ideas [here](https://github.com/Gojo-Bots/Gojo_Satoru/discussions/new?category=ideas)
|
| 66 |
|
app.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
| 11 |
"Anime"
|
| 12 |
],
|
| 13 |
"repository": "https://github.com/Gojo-Bots/Gojo_Satoru",
|
| 14 |
-
"success_url": "https://t.me/
|
| 15 |
"env": {
|
| 16 |
"BOT_TOKEN": {
|
| 17 |
"description": "Your telegram bot token, get from @Botfather in telegram.",
|
|
|
|
| 11 |
"Anime"
|
| 12 |
],
|
| 13 |
"repository": "https://github.com/Gojo-Bots/Gojo_Satoru",
|
| 14 |
+
"success_url": "https://t.me/GojoSuperbot",
|
| 15 |
"env": {
|
| 16 |
"BOT_TOKEN": {
|
| 17 |
"description": "Your telegram bot token, get from @Botfather in telegram.",
|