Spaces:
Sleeping
Sleeping
iamgojoof6eyes
commited on
Commit
·
ca4eb6d
1
Parent(s):
1b4a9e6
Second commit....Looks good
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- Powers/__main__.py +4 -0
- Powers/bot_class.py +116 -0
- Powers/core/decorators/errors.py +0 -0
- Powers/core/filters.py +0 -0
- Powers/core/types/__init__.py +0 -0
- Powers/database/__init__.py +75 -0
- Powers/database/antispam_db.py +73 -0
- Powers/database/approve_db.py +106 -0
- Powers/database/blacklist_db.py +148 -0
- Powers/database/chats_db.py +141 -0
- Powers/database/disable_db.py +147 -0
- Powers/database/filters_db.py +103 -0
- Powers/database/greetings_db.py +146 -0
- Powers/database/group_blacklist.py +46 -0
- Powers/database/lang_db.py +93 -0
- Powers/database/notes_db.py +141 -0
- Powers/database/pins_db.py +113 -0
- Powers/database/reporting_db.py +78 -0
- Powers/database/rules_db.py +102 -0
- Powers/database/users_db.py +101 -0
- Powers/database/warns_db.py +177 -0
- Powers/modules/__init__.py +0 -0
- Powers/plugins/__init__.py +14 -0
- Powers/plugins/admin.py +769 -0
- Powers/plugins/antispam.py +181 -0
- Powers/plugins/approve.py +234 -0
- Powers/plugins/bans.py +901 -0
- Powers/plugins/blacklist.py +218 -0
- Powers/plugins/botstaff.py +54 -0
- Powers/plugins/chat_blacklist.py +86 -0
- Powers/plugins/dev.py +360 -0
- Powers/plugins/disable.py +156 -0
- Powers/plugins/filters.py +301 -0
- Powers/plugins/formatting.py +84 -0
- Powers/plugins/fun.py +195 -0
- Powers/plugins/greetings.py +479 -0
- Powers/plugins/initial.py +114 -0
- Powers/plugins/langs.py +119 -0
- Powers/plugins/locks.py +322 -0
- Powers/plugins/muting.py +609 -0
- Powers/plugins/notes.py +426 -0
- Powers/plugins/pin.py +245 -0
- Powers/plugins/purge.py +121 -0
- Powers/plugins/report.py +202 -0
- Powers/plugins/rules.py +153 -0
- Powers/plugins/start.py +213 -0
- Powers/plugins/stats.py +68 -0
- Powers/plugins/utils.py +393 -0
- Powers/plugins/warns.py +370 -0
- Powers/plugins/watchers.py +229 -0
Powers/__main__.py
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from Powers.bot_class import Gojo
|
2 |
+
|
3 |
+
if __name__ == "__main__":
|
4 |
+
Gojo().run()
|
Powers/bot_class.py
ADDED
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from platform import python_version
|
2 |
+
from threading import RLock
|
3 |
+
from time import gmtime, strftime, time
|
4 |
+
|
5 |
+
from pyrogram import Client, __version__
|
6 |
+
from pyrogram.raw.all import layer
|
7 |
+
|
8 |
+
from Powers import (
|
9 |
+
API_HASH,
|
10 |
+
APP_ID,
|
11 |
+
BOT_TOKEN,
|
12 |
+
LOG_DATETIME,
|
13 |
+
LOGFILE,
|
14 |
+
LOGGER,
|
15 |
+
MESSAGE_DUMP,
|
16 |
+
NO_LOAD,
|
17 |
+
UPTIME,
|
18 |
+
WORKERS,
|
19 |
+
load_cmds,
|
20 |
+
)
|
21 |
+
from Powers.database import MongoDB
|
22 |
+
from Powers.plugins import all_plugins
|
23 |
+
from Powers.tr_engine import lang_dict
|
24 |
+
from Powers.vars import Config
|
25 |
+
|
26 |
+
INITIAL_LOCK = RLock()
|
27 |
+
|
28 |
+
# Check if MESSAGE_DUMP is correct
|
29 |
+
if MESSAGE_DUMP == -100 or not str(MESSAGE_DUMP).startswith("-100"):
|
30 |
+
raise Exception(
|
31 |
+
"Please enter a vaild Supergroup ID, A Supergroup ID starts with -100",
|
32 |
+
)
|
33 |
+
|
34 |
+
|
35 |
+
class Gojo(Client):
|
36 |
+
"""Starts the Pyrogram Client on the Bot Token when we do 'python3 -m Powers'"""
|
37 |
+
|
38 |
+
def __init__(self):
|
39 |
+
name = self.__class__.__name__.lower()
|
40 |
+
|
41 |
+
super().__init__(
|
42 |
+
"Gojo_Satarou",
|
43 |
+
bot_token=BOT_TOKEN,
|
44 |
+
plugins=dict(root=f"{name}.plugins", exclude=NO_LOAD),
|
45 |
+
api_id=APP_ID,
|
46 |
+
api_hash=API_HASH,
|
47 |
+
workers=WORKERS,
|
48 |
+
)
|
49 |
+
|
50 |
+
async def start(self):
|
51 |
+
"""Start the bot."""
|
52 |
+
await super().start()
|
53 |
+
|
54 |
+
meh = await self.get_me() # Get bot info from pyrogram client
|
55 |
+
LOGGER.info("Starting bot...")
|
56 |
+
Config.BOT_ID = meh.id
|
57 |
+
Config.BOT_NAME = meh.first_name
|
58 |
+
Config.BOT_USERNAME = meh.username
|
59 |
+
|
60 |
+
startmsg = await self.send_message(MESSAGE_DUMP, "<i>Starting Bot...</i>")
|
61 |
+
|
62 |
+
# Load Languages
|
63 |
+
lang_status = len(lang_dict) >= 1
|
64 |
+
LOGGER.info(f"Loading Languages: {lang_status}\n")
|
65 |
+
|
66 |
+
# Show in Log that bot has started
|
67 |
+
LOGGER.info(
|
68 |
+
f"Pyrogram v{__version__} (Layer - {layer}) started on {meh.username}",
|
69 |
+
)
|
70 |
+
LOGGER.info(f"Python Version: {python_version()}\n")
|
71 |
+
|
72 |
+
# Get cmds and keys
|
73 |
+
cmd_list = await load_cmds(await all_plugins())
|
74 |
+
|
75 |
+
LOGGER.info(f"Plugins Loaded: {cmd_list}")
|
76 |
+
|
77 |
+
# Send a message to MESSAGE_DUMP telling that the
|
78 |
+
# bot has started and has loaded all plugins!
|
79 |
+
await startmsg.edit_text(
|
80 |
+
(
|
81 |
+
f"<b><i>@{meh.username} started on Pyrogram v{__version__} (Layer - {layer})</i></b>\n"
|
82 |
+
f"\n<b>Python:</b> <u>{python_version()}</u>\n"
|
83 |
+
"\n<b>Loaded Plugins:</b>\n"
|
84 |
+
f"<i>{cmd_list}</i>\n"
|
85 |
+
),
|
86 |
+
)
|
87 |
+
|
88 |
+
LOGGER.info("Bot Started Successfully!\n")
|
89 |
+
|
90 |
+
async def stop(self):
|
91 |
+
"""Stop the bot and send a message to MESSAGE_DUMP telling that the bot has stopped."""
|
92 |
+
runtime = strftime("%Hh %Mm %Ss", gmtime(time() - UPTIME))
|
93 |
+
LOGGER.info("Uploading logs before stopping...!\n")
|
94 |
+
# Send Logs to MESSAGE_DUMP and LOG_CHANNEL
|
95 |
+
await self.send_document(
|
96 |
+
MESSAGE_DUMP,
|
97 |
+
document=LOGFILE,
|
98 |
+
caption=(
|
99 |
+
"Bot Stopped!\n\n" f"Uptime: {runtime}\n" f"<code>{LOG_DATETIME}</code>"
|
100 |
+
),
|
101 |
+
)
|
102 |
+
if MESSAGE_DUMP:
|
103 |
+
# LOG_CHANNEL is not necessary
|
104 |
+
await self.send_document(
|
105 |
+
MESSAGE_DUMP,
|
106 |
+
document=LOGFILE,
|
107 |
+
caption=f"Uptime: {runtime}",
|
108 |
+
)
|
109 |
+
await super().stop()
|
110 |
+
MongoDB.close()
|
111 |
+
LOGGER.info(
|
112 |
+
f"""Bot Stopped.
|
113 |
+
Logs have been uploaded to the MESSAGE_DUMP Group!
|
114 |
+
Runtime: {runtime}s\n
|
115 |
+
""",
|
116 |
+
)
|
Powers/core/decorators/errors.py
DELETED
File without changes
|
Powers/core/filters.py
DELETED
File without changes
|
Powers/core/types/__init__.py
DELETED
File without changes
|
Powers/database/__init__.py
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from sys import exit as exiter
|
2 |
+
|
3 |
+
from pymongo import MongoClient
|
4 |
+
from pymongo.errors import PyMongoError
|
5 |
+
|
6 |
+
from Powers import DB_NAME, DB_URI, LOGGER
|
7 |
+
|
8 |
+
try:
|
9 |
+
Powers_db_client = MongoClient(DB_URI)
|
10 |
+
except PyMongoError as f:
|
11 |
+
LOGGER.error(f"Error in Mongodb: {f}")
|
12 |
+
exiter(1)
|
13 |
+
Powers_main_db = Powers_db_client[DB_NAME]
|
14 |
+
|
15 |
+
|
16 |
+
class MongoDB:
|
17 |
+
"""Class for interacting with Bot database."""
|
18 |
+
|
19 |
+
def __init__(self, collection) -> None:
|
20 |
+
self.collection = Powers_main_db[collection]
|
21 |
+
|
22 |
+
# Insert one entry into collection
|
23 |
+
def insert_one(self, document):
|
24 |
+
result = self.collection.insert_one(document)
|
25 |
+
return repr(result.inserted_id)
|
26 |
+
|
27 |
+
# Find one entry from collection
|
28 |
+
def find_one(self, query):
|
29 |
+
result = self.collection.find_one(query)
|
30 |
+
if result:
|
31 |
+
return result
|
32 |
+
return False
|
33 |
+
|
34 |
+
# Find entries from collection
|
35 |
+
def find_all(self, query=None):
|
36 |
+
if query is None:
|
37 |
+
query = {}
|
38 |
+
return list(self.collection.find(query))
|
39 |
+
|
40 |
+
# Count entries from collection
|
41 |
+
def count(self, query=None):
|
42 |
+
if query is None:
|
43 |
+
query = {}
|
44 |
+
return self.collection.count_documents(query)
|
45 |
+
|
46 |
+
# Delete entry/entries from collection
|
47 |
+
def delete_one(self, query):
|
48 |
+
self.collection.delete_many(query)
|
49 |
+
return self.collection.count_documents({})
|
50 |
+
|
51 |
+
# Replace one entry in collection
|
52 |
+
def replace(self, query, new_data):
|
53 |
+
old = self.collection.find_one(query)
|
54 |
+
_id = old["_id"]
|
55 |
+
self.collection.replace_one({"_id": _id}, new_data)
|
56 |
+
new = self.collection.find_one({"_id": _id})
|
57 |
+
return old, new
|
58 |
+
|
59 |
+
# Update one entry from collection
|
60 |
+
def update(self, query, update):
|
61 |
+
result = self.collection.update_one(query, {"$set": update})
|
62 |
+
new_document = self.collection.find_one(query)
|
63 |
+
return result.modified_count, new_document
|
64 |
+
|
65 |
+
@staticmethod
|
66 |
+
def close():
|
67 |
+
return Powers_db_client.close()
|
68 |
+
|
69 |
+
|
70 |
+
def __connect_first():
|
71 |
+
_ = MongoDB("test")
|
72 |
+
LOGGER.info("Initialized Database!\n")
|
73 |
+
|
74 |
+
|
75 |
+
__connect_first()
|
Powers/database/antispam_db.py
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from datetime import datetime
|
2 |
+
from threading import RLock
|
3 |
+
|
4 |
+
from Powers.database import MongoDB
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
ANTISPAM_BANNED = set()
|
8 |
+
|
9 |
+
|
10 |
+
class GBan(MongoDB):
|
11 |
+
"""Class for managing Gbans in bot."""
|
12 |
+
|
13 |
+
db_name = "gbans"
|
14 |
+
|
15 |
+
def __init__(self) -> None:
|
16 |
+
super().__init__(self.db_name)
|
17 |
+
|
18 |
+
def check_gban(self, user_id: int):
|
19 |
+
with INSERTION_LOCK:
|
20 |
+
return bool(self.find_one({"_id": user_id}))
|
21 |
+
|
22 |
+
def add_gban(self, user_id: int, reason: str, by_user: int):
|
23 |
+
global ANTISPAM_BANNED
|
24 |
+
with INSERTION_LOCK:
|
25 |
+
# Check if user is already gbanned or not
|
26 |
+
if self.find_one({"_id": user_id}):
|
27 |
+
return self.update_gban_reason(user_id, reason)
|
28 |
+
|
29 |
+
# If not already gbanned, then add to gban
|
30 |
+
time_rn = datetime.now()
|
31 |
+
return self.insert_one(
|
32 |
+
{
|
33 |
+
"_id": user_id,
|
34 |
+
"reason": reason,
|
35 |
+
"by": by_user,
|
36 |
+
"time": time_rn,
|
37 |
+
},
|
38 |
+
)
|
39 |
+
|
40 |
+
def remove_gban(self, user_id: int):
|
41 |
+
global ANTISPAM_BANNED
|
42 |
+
with INSERTION_LOCK:
|
43 |
+
# Check if user is already gbanned or not
|
44 |
+
if self.find_one({"_id": user_id}):
|
45 |
+
return self.delete_one({"_id": user_id})
|
46 |
+
|
47 |
+
return "User not gbanned!"
|
48 |
+
|
49 |
+
def get_gban(self, user_id: int):
|
50 |
+
if self.check_gban(user_id):
|
51 |
+
curr = self.find_one({"_id": user_id})
|
52 |
+
if curr:
|
53 |
+
return True, curr["reason"]
|
54 |
+
return False, ""
|
55 |
+
|
56 |
+
def update_gban_reason(self, user_id: int, reason: str):
|
57 |
+
with INSERTION_LOCK:
|
58 |
+
return self.update(
|
59 |
+
{"_id": user_id},
|
60 |
+
{"reason": reason},
|
61 |
+
)
|
62 |
+
|
63 |
+
def count_gbans(self):
|
64 |
+
with INSERTION_LOCK:
|
65 |
+
return self.count()
|
66 |
+
|
67 |
+
def load_from_db(self):
|
68 |
+
with INSERTION_LOCK:
|
69 |
+
return self.find_all()
|
70 |
+
|
71 |
+
def list_gbans(self):
|
72 |
+
with INSERTION_LOCK:
|
73 |
+
return self.find_all()
|
Powers/database/approve_db.py
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
|
3 |
+
from Powers import LOGGER
|
4 |
+
from Powers.database import MongoDB
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
|
8 |
+
|
9 |
+
class Approve(MongoDB):
|
10 |
+
"""Class for managing Approves in Chats in Bot."""
|
11 |
+
|
12 |
+
# Database name to connect to to preform operations
|
13 |
+
db_name = "approve"
|
14 |
+
|
15 |
+
def __init__(self, chat_id: int) -> None:
|
16 |
+
super().__init__(self.db_name)
|
17 |
+
self.chat_id = chat_id
|
18 |
+
self.chat_info = self.__ensure_in_db()
|
19 |
+
|
20 |
+
def check_approve(self, user_id: int):
|
21 |
+
with INSERTION_LOCK:
|
22 |
+
return bool(user_id in self.chat_info["users"])
|
23 |
+
|
24 |
+
def add_approve(self, user_id: int, user_name: str):
|
25 |
+
with INSERTION_LOCK:
|
26 |
+
self.chat_info["users"].append((user_id, user_name))
|
27 |
+
if not self.check_approve(user_id):
|
28 |
+
return self.update(
|
29 |
+
{"_id": self.chat_id},
|
30 |
+
{"users": self.chat_info["users"]},
|
31 |
+
)
|
32 |
+
return True
|
33 |
+
|
34 |
+
def remove_approve(self, user_id: int):
|
35 |
+
with INSERTION_LOCK:
|
36 |
+
if self.check_approve(user_id):
|
37 |
+
user_full = next(
|
38 |
+
user for user in self.chat_info["users"] if user[0] == user_id
|
39 |
+
)
|
40 |
+
self.chat_info["users"].pop(user_full)
|
41 |
+
return self.update(
|
42 |
+
{"_id": self.chat_id},
|
43 |
+
{"users": self.chat_info["users"]},
|
44 |
+
)
|
45 |
+
return True
|
46 |
+
|
47 |
+
def unapprove_all(self):
|
48 |
+
with INSERTION_LOCK:
|
49 |
+
return self.delete_one(
|
50 |
+
{"_id": self.chat_id},
|
51 |
+
)
|
52 |
+
|
53 |
+
def list_approved(self):
|
54 |
+
with INSERTION_LOCK:
|
55 |
+
return self.chat_info["users"]
|
56 |
+
|
57 |
+
def count_approved(self):
|
58 |
+
with INSERTION_LOCK:
|
59 |
+
return len(self.chat_info["users"])
|
60 |
+
|
61 |
+
def load_from_db(self):
|
62 |
+
return self.find_all()
|
63 |
+
|
64 |
+
def __ensure_in_db(self):
|
65 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
66 |
+
if not chat_data:
|
67 |
+
new_data = {"_id": self.chat_id, "users": []}
|
68 |
+
self.insert_one(new_data)
|
69 |
+
LOGGER.info(f"Initialized Approve Document for chat {self.chat_id}")
|
70 |
+
return new_data
|
71 |
+
return chat_data
|
72 |
+
|
73 |
+
# Migrate if chat id changes!
|
74 |
+
def migrate_chat(self, new_chat_id: int):
|
75 |
+
old_chat_db = self.find_one({"_id": self.chat_id})
|
76 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
77 |
+
self.insert_one(new_data)
|
78 |
+
self.delete_one({"_id": self.chat_id})
|
79 |
+
|
80 |
+
@staticmethod
|
81 |
+
def count_all_approved():
|
82 |
+
with INSERTION_LOCK:
|
83 |
+
collection = MongoDB(Approve.db_name)
|
84 |
+
all_data = collection.find_all()
|
85 |
+
return sum(len(i["users"]) for i in all_data if len(i["users"]) >= 1)
|
86 |
+
|
87 |
+
@staticmethod
|
88 |
+
def count_approved_chats():
|
89 |
+
with INSERTION_LOCK:
|
90 |
+
collection = MongoDB(Approve.db_name)
|
91 |
+
all_data = collection.find_all()
|
92 |
+
return sum(len(i["users"]) >= 1 for i in all_data)
|
93 |
+
|
94 |
+
@staticmethod
|
95 |
+
def repair_db(collection):
|
96 |
+
all_data = collection.find_all()
|
97 |
+
keys = {"users": []}
|
98 |
+
for data in all_data:
|
99 |
+
for key, val in keys.items():
|
100 |
+
try:
|
101 |
+
_ = data[key]
|
102 |
+
except KeyError:
|
103 |
+
LOGGER.warning(
|
104 |
+
f"Repairing Approve Database - setting '{key}:{val}' for {data['_id']}",
|
105 |
+
)
|
106 |
+
collection.update({"_id": data["_id"]}, {key: val})
|
Powers/database/blacklist_db.py
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
from time import time
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.database import MongoDB
|
6 |
+
|
7 |
+
INSERTION_LOCK = RLock()
|
8 |
+
|
9 |
+
|
10 |
+
class Blacklist(MongoDB):
|
11 |
+
"""Class to manage database for blacklists for chats."""
|
12 |
+
|
13 |
+
# Database name to connect to to preform operations
|
14 |
+
db_name = "blacklists"
|
15 |
+
|
16 |
+
def __init__(self, chat_id: int) -> None:
|
17 |
+
super().__init__(self.db_name)
|
18 |
+
self.chat_id = chat_id
|
19 |
+
self.chat_info = self.__ensure_in_db()
|
20 |
+
|
21 |
+
def check_word_blacklist_status(self, word: str):
|
22 |
+
with INSERTION_LOCK:
|
23 |
+
bl_words = self.chat_info["triggers"]
|
24 |
+
return bool(word in bl_words)
|
25 |
+
|
26 |
+
def add_blacklist(self, trigger: str):
|
27 |
+
with INSERTION_LOCK:
|
28 |
+
if not self.check_word_blacklist_status(trigger):
|
29 |
+
return self.update(
|
30 |
+
{"_id": self.chat_id},
|
31 |
+
{
|
32 |
+
"_id": self.chat_id,
|
33 |
+
"triggers": self.chat_info["triggers"] + [trigger],
|
34 |
+
},
|
35 |
+
)
|
36 |
+
|
37 |
+
def remove_blacklist(self, trigger: str):
|
38 |
+
with INSERTION_LOCK:
|
39 |
+
if self.check_word_blacklist_status(trigger):
|
40 |
+
self.chat_info["triggers"].remove(trigger)
|
41 |
+
return self.update(
|
42 |
+
{"_id": self.chat_id},
|
43 |
+
{
|
44 |
+
"_id": self.chat_id,
|
45 |
+
"triggers": self.chat_info["triggers"],
|
46 |
+
},
|
47 |
+
)
|
48 |
+
|
49 |
+
def get_blacklists(self):
|
50 |
+
with INSERTION_LOCK:
|
51 |
+
return self.chat_info["triggers"]
|
52 |
+
|
53 |
+
@staticmethod
|
54 |
+
def count_blacklists_all():
|
55 |
+
with INSERTION_LOCK:
|
56 |
+
collection = MongoDB(Blacklist.db_name)
|
57 |
+
curr = collection.find_all()
|
58 |
+
return sum(len(chat["triggers"]) for chat in curr)
|
59 |
+
|
60 |
+
@staticmethod
|
61 |
+
def count_blackists_chats():
|
62 |
+
with INSERTION_LOCK:
|
63 |
+
collection = MongoDB(Blacklist.db_name)
|
64 |
+
curr = collection.find_all()
|
65 |
+
return sum(1 for chat in curr if chat["triggers"])
|
66 |
+
|
67 |
+
def set_action(self, action: str):
|
68 |
+
with INSERTION_LOCK:
|
69 |
+
return self.update(
|
70 |
+
{"_id": self.chat_id},
|
71 |
+
{"_id": self.chat_id, "action": action},
|
72 |
+
)
|
73 |
+
|
74 |
+
def get_action(self):
|
75 |
+
with INSERTION_LOCK:
|
76 |
+
return self.chat_info["action"]
|
77 |
+
|
78 |
+
def set_reason(self, reason: str):
|
79 |
+
with INSERTION_LOCK:
|
80 |
+
return self.update(
|
81 |
+
{"_id": self.chat_id},
|
82 |
+
{"_id": self.chat_id, "reason": reason},
|
83 |
+
)
|
84 |
+
|
85 |
+
def get_reason(self):
|
86 |
+
with INSERTION_LOCK:
|
87 |
+
return self.chat_info["reason"]
|
88 |
+
|
89 |
+
@staticmethod
|
90 |
+
def count_action_bl_all(action: str):
|
91 |
+
with INSERTION_LOCK:
|
92 |
+
collection = MongoDB(Blacklist.db_name)
|
93 |
+
all_data = collection.find_all({"action": action})
|
94 |
+
return sum(len(i["triggers"]) >= 1 for i in all_data)
|
95 |
+
|
96 |
+
def rm_all_blacklist(self):
|
97 |
+
with INSERTION_LOCK:
|
98 |
+
return self.update(
|
99 |
+
{"_id": self.chat_id},
|
100 |
+
{"triggers": []},
|
101 |
+
)
|
102 |
+
|
103 |
+
def __ensure_in_db(self):
|
104 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
105 |
+
if not chat_data:
|
106 |
+
new_data = new_data = {
|
107 |
+
"_id": self.chat_id,
|
108 |
+
"triggers": [],
|
109 |
+
"action": "none",
|
110 |
+
"reason": "Automated blacklisted word: {{}}",
|
111 |
+
}
|
112 |
+
self.insert_one(new_data)
|
113 |
+
LOGGER.info(f"Initialized Blacklist Document for chat {self.chat_id}")
|
114 |
+
return new_data
|
115 |
+
return chat_data
|
116 |
+
|
117 |
+
# Migrate if chat id changes!
|
118 |
+
def migrate_chat(self, new_chat_id: int):
|
119 |
+
old_chat_db = self.find_one({"_id": self.chat_id})
|
120 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
121 |
+
self.insert_one(new_data)
|
122 |
+
self.delete_one({"_id": self.chat_id})
|
123 |
+
|
124 |
+
@staticmethod
|
125 |
+
def repair_db(collection):
|
126 |
+
all_data = collection.find_all()
|
127 |
+
keys = {
|
128 |
+
"triggers": [],
|
129 |
+
"action": "none",
|
130 |
+
"reason": "Automated blacklisted word: {{}}",
|
131 |
+
}
|
132 |
+
for data in all_data:
|
133 |
+
for key, val in keys.items():
|
134 |
+
try:
|
135 |
+
_ = data[key]
|
136 |
+
except KeyError:
|
137 |
+
LOGGER.warning(
|
138 |
+
f"Repairing Blacklist Database - setting '{key}:{val}' for {data['_id']}",
|
139 |
+
)
|
140 |
+
collection.update({"_id": data["_id"]}, {key: val})
|
141 |
+
|
142 |
+
|
143 |
+
def __pre_req_blacklists():
|
144 |
+
start = time()
|
145 |
+
LOGGER.info("Starting Blacklists Database Repair...")
|
146 |
+
collection = MongoDB(Blacklist.db_name)
|
147 |
+
Blacklist.repair_db(collection)
|
148 |
+
LOGGER.info(f"Done in {round((time() - start), 3)}s!")
|
Powers/database/chats_db.py
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
from time import time
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.database import MongoDB
|
6 |
+
|
7 |
+
INSERTION_LOCK = RLock()
|
8 |
+
|
9 |
+
|
10 |
+
class Chats(MongoDB):
|
11 |
+
"""Class to manage users for bot."""
|
12 |
+
|
13 |
+
# Database name to connect to to preform operations
|
14 |
+
db_name = "chats"
|
15 |
+
|
16 |
+
def __init__(self, chat_id: int) -> None:
|
17 |
+
super().__init__(self.db_name)
|
18 |
+
self.chat_id = chat_id
|
19 |
+
self.chat_info = self.__ensure_in_db()
|
20 |
+
|
21 |
+
def user_is_in_chat(self, user_id: int):
|
22 |
+
return bool(user_id in set(self.chat_info["users"]))
|
23 |
+
|
24 |
+
def update_chat(self, chat_name: str, user_id: int):
|
25 |
+
with INSERTION_LOCK:
|
26 |
+
|
27 |
+
if chat_name == self.chat_info["chat_name"] and self.user_is_in_chat(
|
28 |
+
user_id,
|
29 |
+
):
|
30 |
+
return True
|
31 |
+
|
32 |
+
if chat_name != self.chat_info["chat_name"] and self.user_is_in_chat(
|
33 |
+
user_id,
|
34 |
+
):
|
35 |
+
return self.update(
|
36 |
+
{"_id": self.chat_id},
|
37 |
+
{"chat_name": chat_name},
|
38 |
+
)
|
39 |
+
|
40 |
+
if chat_name == self.chat_info["chat_name"] and not self.user_is_in_chat(
|
41 |
+
user_id,
|
42 |
+
):
|
43 |
+
self.chat_info["users"].append(user_id)
|
44 |
+
return self.update(
|
45 |
+
{"_id": self.chat_id},
|
46 |
+
{"users": self.chat_info["users"]},
|
47 |
+
)
|
48 |
+
|
49 |
+
users_old = self.chat_info["users"]
|
50 |
+
users_old.append(user_id)
|
51 |
+
users = list(set(users_old))
|
52 |
+
return self.update(
|
53 |
+
{"_id": self.chat_id},
|
54 |
+
{
|
55 |
+
"_id": self.chat_id,
|
56 |
+
"chat_name": chat_name,
|
57 |
+
"users": users,
|
58 |
+
},
|
59 |
+
)
|
60 |
+
|
61 |
+
def count_chat_users(self):
|
62 |
+
with INSERTION_LOCK:
|
63 |
+
return len(self.chat_info["users"]) or 0
|
64 |
+
|
65 |
+
def chat_members(self):
|
66 |
+
with INSERTION_LOCK:
|
67 |
+
return self.chat_info["users"]
|
68 |
+
|
69 |
+
@staticmethod
|
70 |
+
def remove_chat(chat_id: int):
|
71 |
+
with INSERTION_LOCK:
|
72 |
+
collection = MongoDB(Chats.db_name)
|
73 |
+
collection.delete_one({"_id": chat_id})
|
74 |
+
|
75 |
+
@staticmethod
|
76 |
+
def count_chats():
|
77 |
+
with INSERTION_LOCK:
|
78 |
+
collection = MongoDB(Chats.db_name)
|
79 |
+
return collection.count() or 0
|
80 |
+
|
81 |
+
@staticmethod
|
82 |
+
def list_chats_by_id():
|
83 |
+
with INSERTION_LOCK:
|
84 |
+
collection = MongoDB(Chats.db_name)
|
85 |
+
chats = collection.find_all()
|
86 |
+
chat_list = {i["_id"] for i in chats}
|
87 |
+
return list(chat_list)
|
88 |
+
|
89 |
+
@staticmethod
|
90 |
+
def list_chats_full():
|
91 |
+
with INSERTION_LOCK:
|
92 |
+
collection = MongoDB(Chats.db_name)
|
93 |
+
return collection.find_all()
|
94 |
+
|
95 |
+
@staticmethod
|
96 |
+
def get_chat_info(chat_id: int):
|
97 |
+
with INSERTION_LOCK:
|
98 |
+
collection = MongoDB(Chats.db_name)
|
99 |
+
return collection.find_one({"_id": chat_id})
|
100 |
+
|
101 |
+
def load_from_db(self):
|
102 |
+
with INSERTION_LOCK:
|
103 |
+
return self.find_all()
|
104 |
+
|
105 |
+
def __ensure_in_db(self):
|
106 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
107 |
+
if not chat_data:
|
108 |
+
new_data = {"_id": self.chat_id, "chat_name": "", "users": []}
|
109 |
+
self.insert_one(new_data)
|
110 |
+
LOGGER.info(f"Initialized Chats Document for chat {self.chat_id}")
|
111 |
+
return new_data
|
112 |
+
return chat_data
|
113 |
+
|
114 |
+
# Migrate if chat id changes!
|
115 |
+
def migrate_chat(self, new_chat_id: int):
|
116 |
+
old_chat_db = self.find_one({"_id": self.chat_id})
|
117 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
118 |
+
self.insert_one(new_data)
|
119 |
+
self.delete_one({"_id": self.chat_id})
|
120 |
+
|
121 |
+
@staticmethod
|
122 |
+
def repair_db(collection):
|
123 |
+
all_data = collection.find_all()
|
124 |
+
keys = {"chat_name": "", "users": []}
|
125 |
+
for data in all_data:
|
126 |
+
for key, val in keys.items():
|
127 |
+
try:
|
128 |
+
_ = data[key]
|
129 |
+
except KeyError:
|
130 |
+
LOGGER.warning(
|
131 |
+
f"Repairing Chats Database - setting '{key}:{val}' for {data['_id']}",
|
132 |
+
)
|
133 |
+
collection.update({"_id": data["_id"]}, {key: val})
|
134 |
+
|
135 |
+
|
136 |
+
def __pre_req_chats():
|
137 |
+
start = time()
|
138 |
+
LOGGER.info("Starting Chats Database Repair...")
|
139 |
+
collection = MongoDB(Chats.db_name)
|
140 |
+
Chats.repair_db(collection)
|
141 |
+
LOGGER.info(f"Done in {round((time() - start), 3)}s!")
|
Powers/database/disable_db.py
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
|
3 |
+
from Powers import LOGGER
|
4 |
+
from Powers.database import MongoDB
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
DISABLED_CMDS = {}
|
8 |
+
|
9 |
+
|
10 |
+
class Disabling(MongoDB):
|
11 |
+
"""Class to manage database for Disabling for chats."""
|
12 |
+
|
13 |
+
# Database name to connect to to preform operations
|
14 |
+
db_name = "disabled"
|
15 |
+
|
16 |
+
def __init__(self, chat_id: int) -> None:
|
17 |
+
super().__init__(self.db_name)
|
18 |
+
self.chat_id = chat_id
|
19 |
+
self.chat_info = self.__ensure_in_db()
|
20 |
+
|
21 |
+
def check_cmd_status(self, cmd: str):
|
22 |
+
with INSERTION_LOCK:
|
23 |
+
# cmds = self.chat_info["commands"]
|
24 |
+
cmds = DISABLED_CMDS[self.chat_id]["commands"]
|
25 |
+
# return bool(cmd in cmds)
|
26 |
+
return bool(cmd in cmds)
|
27 |
+
|
28 |
+
def add_disable(self, cmd: str):
|
29 |
+
with INSERTION_LOCK:
|
30 |
+
if not self.check_cmd_status(cmd):
|
31 |
+
# DISABLED_CMDS[self.chat_id]["commands"].append(cmd)
|
32 |
+
return self.update(
|
33 |
+
{"_id": self.chat_id},
|
34 |
+
{
|
35 |
+
"_id": self.chat_id,
|
36 |
+
"commands": self.chat_info["commands"] + [cmd],
|
37 |
+
},
|
38 |
+
)
|
39 |
+
|
40 |
+
def remove_disabled(self, comm: str):
|
41 |
+
with INSERTION_LOCK:
|
42 |
+
if self.check_cmd_status(comm):
|
43 |
+
self.chat_info["commands"].remove(comm)
|
44 |
+
DISABLED_CMDS[self.chat_id]["commands"].remove(comm)
|
45 |
+
return self.update(
|
46 |
+
{"_id": self.chat_id},
|
47 |
+
{
|
48 |
+
"_id": self.chat_id,
|
49 |
+
"commands": self.chat_info["commands"],
|
50 |
+
},
|
51 |
+
)
|
52 |
+
|
53 |
+
def get_disabled(self):
|
54 |
+
with INSERTION_LOCK:
|
55 |
+
global DISABLED_CMDS
|
56 |
+
try:
|
57 |
+
cmds = DISABLED_CMDS[self.chat_id]["commands"]
|
58 |
+
except KeyError:
|
59 |
+
cmds = self.chat_info["commands"]
|
60 |
+
DISABLED_CMDS[self.chat_id]["commands"] = cmds
|
61 |
+
return cmds
|
62 |
+
|
63 |
+
@staticmethod
|
64 |
+
def count_disabled_all():
|
65 |
+
with INSERTION_LOCK:
|
66 |
+
collection = MongoDB(Disabling.db_name)
|
67 |
+
curr = collection.find_all()
|
68 |
+
return sum(len(chat["commands"]) for chat in curr)
|
69 |
+
|
70 |
+
@staticmethod
|
71 |
+
def count_disabling_chats():
|
72 |
+
with INSERTION_LOCK:
|
73 |
+
collection = MongoDB(Disabling.db_name)
|
74 |
+
curr = collection.find_all()
|
75 |
+
return sum(1 for chat in curr if chat["commands"])
|
76 |
+
|
77 |
+
def set_action(self, action: str):
|
78 |
+
with INSERTION_LOCK:
|
79 |
+
global DISABLED_CMDS
|
80 |
+
DISABLED_CMDS[self.chat_id]["action"] = action
|
81 |
+
return self.update(
|
82 |
+
{"_id": self.chat_id},
|
83 |
+
{"_id": self.chat_id, "action": action},
|
84 |
+
)
|
85 |
+
|
86 |
+
def get_action(self):
|
87 |
+
with INSERTION_LOCK:
|
88 |
+
global DISABLED_CMDS
|
89 |
+
try:
|
90 |
+
action = DISABLED_CMDS[self.chat_id]["action"]
|
91 |
+
except KeyError:
|
92 |
+
action = self.chat_info["action"]
|
93 |
+
DISABLED_CMDS[self.chat_id]["action"] = action
|
94 |
+
return action
|
95 |
+
|
96 |
+
@staticmethod
|
97 |
+
def count_action_dis_all(action: str):
|
98 |
+
with INSERTION_LOCK:
|
99 |
+
collection = MongoDB(Disabling.db_name)
|
100 |
+
all_data = collection.find_all({"action": action})
|
101 |
+
return sum(len(i["commands"]) >= 1 for i in all_data)
|
102 |
+
|
103 |
+
def rm_all_disabled(self):
|
104 |
+
with INSERTION_LOCK:
|
105 |
+
DISABLED_CMDS[self.chat_id]["commands"] = []
|
106 |
+
return self.update(
|
107 |
+
{"_id": self.chat_id},
|
108 |
+
{"commands": []},
|
109 |
+
)
|
110 |
+
|
111 |
+
def __ensure_in_db(self):
|
112 |
+
try:
|
113 |
+
chat_data = DISABLED_CMDS[self.chat_id]
|
114 |
+
except KeyError:
|
115 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
116 |
+
if not chat_data:
|
117 |
+
new_data = new_data = {
|
118 |
+
"_id": self.chat_id,
|
119 |
+
"commands": [],
|
120 |
+
"action": "none",
|
121 |
+
}
|
122 |
+
self.insert_one(new_data)
|
123 |
+
LOGGER.info(f"Initialized Disabling Document for chat {self.chat_id}")
|
124 |
+
return new_data
|
125 |
+
return chat_data
|
126 |
+
|
127 |
+
# Migrate if chat id changes!
|
128 |
+
def migrate_chat(self, new_chat_id: int):
|
129 |
+
global DISABLED_CMDS # global only when we are modifying the value
|
130 |
+
old_chat_db = self.find_one({"_id": self.chat_id})
|
131 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
132 |
+
DISABLED_CMDS[new_chat_id] = DISABLED_CMDS[self.chat_id]
|
133 |
+
del DISABLED_CMDS[self.chat_id]
|
134 |
+
self.insert_one(new_data)
|
135 |
+
self.delete_one({"_id": self.chat_id})
|
136 |
+
|
137 |
+
|
138 |
+
def __load_disable_cache():
|
139 |
+
global DISABLED_CMDS
|
140 |
+
collection = MongoDB(Disabling.db_name)
|
141 |
+
all_data = collection.find_all()
|
142 |
+
DISABLED_CMDS = {
|
143 |
+
i["_id"]: {"action": i["action"], "commands": i["commands"]} for i in all_data
|
144 |
+
}
|
145 |
+
|
146 |
+
|
147 |
+
__load_disable_cache()
|
Powers/database/filters_db.py
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
|
9 |
+
class Filters(MongoDB):
|
10 |
+
db_name = "chat_filters"
|
11 |
+
|
12 |
+
def __init__(self) -> None:
|
13 |
+
super().__init__(self.db_name)
|
14 |
+
|
15 |
+
def save_filter(
|
16 |
+
self,
|
17 |
+
chat_id: int,
|
18 |
+
keyword: str,
|
19 |
+
filter_reply: str,
|
20 |
+
msgtype: int = Types.TEXT,
|
21 |
+
fileid="",
|
22 |
+
):
|
23 |
+
with INSERTION_LOCK:
|
24 |
+
# Database update
|
25 |
+
curr = self.find_one({"chat_id": chat_id, "keyword": keyword})
|
26 |
+
if curr:
|
27 |
+
return False
|
28 |
+
return self.insert_one(
|
29 |
+
{
|
30 |
+
"chat_id": chat_id,
|
31 |
+
"keyword": keyword,
|
32 |
+
"filter_reply": filter_reply,
|
33 |
+
"msgtype": msgtype,
|
34 |
+
"fileid": fileid,
|
35 |
+
},
|
36 |
+
)
|
37 |
+
|
38 |
+
def get_filter(self, chat_id: int, keyword: str):
|
39 |
+
with INSERTION_LOCK:
|
40 |
+
curr = self.find_one({"chat_id": chat_id, "keyword": keyword})
|
41 |
+
if curr:
|
42 |
+
return curr
|
43 |
+
return "Filter does not exist!"
|
44 |
+
|
45 |
+
def get_all_filters(self, chat_id: int):
|
46 |
+
with INSERTION_LOCK:
|
47 |
+
curr = self.find_all({"chat_id": chat_id})
|
48 |
+
if curr:
|
49 |
+
filter_list = {i["keyword"] for i in curr}
|
50 |
+
return list(filter_list)
|
51 |
+
return []
|
52 |
+
|
53 |
+
def rm_filter(self, chat_id: int, keyword: str):
|
54 |
+
with INSERTION_LOCK:
|
55 |
+
curr = self.find_one({"chat_id": chat_id, "keyword": keyword})
|
56 |
+
if curr:
|
57 |
+
self.delete_one(curr)
|
58 |
+
return True
|
59 |
+
return False
|
60 |
+
|
61 |
+
def rm_all_filters(self, chat_id: int):
|
62 |
+
with INSERTION_LOCK:
|
63 |
+
return self.delete_one({"chat_id": chat_id})
|
64 |
+
|
65 |
+
def count_filters_all(self):
|
66 |
+
with INSERTION_LOCK:
|
67 |
+
return self.count()
|
68 |
+
|
69 |
+
def count_filter_aliases(self):
|
70 |
+
with INSERTION_LOCK:
|
71 |
+
curr = self.find_all()
|
72 |
+
if curr:
|
73 |
+
return len(
|
74 |
+
[z for z in (i["keyword"].split("|") for i in curr) if len(z) >= 2],
|
75 |
+
)
|
76 |
+
return 0
|
77 |
+
|
78 |
+
def count_filters_chats(self):
|
79 |
+
with INSERTION_LOCK:
|
80 |
+
filters = self.find_all()
|
81 |
+
chats_ids = {i["chat_id"] for i in filters}
|
82 |
+
return len(chats_ids)
|
83 |
+
|
84 |
+
def count_all_filters(self):
|
85 |
+
with INSERTION_LOCK:
|
86 |
+
return self.count()
|
87 |
+
|
88 |
+
def count_filter_type(self, ntype):
|
89 |
+
with INSERTION_LOCK:
|
90 |
+
return self.count({"msgtype": ntype})
|
91 |
+
|
92 |
+
def load_from_db(self):
|
93 |
+
with INSERTION_LOCK:
|
94 |
+
return self.find_all()
|
95 |
+
|
96 |
+
# Migrate if chat id changes!
|
97 |
+
def migrate_chat(self, old_chat_id: int, new_chat_id: int):
|
98 |
+
with INSERTION_LOCK:
|
99 |
+
old_chat_db = self.find_one({"_id": old_chat_id})
|
100 |
+
if old_chat_db:
|
101 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
102 |
+
self.delete_one({"_id": old_chat_id})
|
103 |
+
self.insert_one(new_data)
|
Powers/database/greetings_db.py
ADDED
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
|
3 |
+
from Powers import LOGGER
|
4 |
+
from Powers.database import MongoDB
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
|
8 |
+
|
9 |
+
class Greetings(MongoDB):
|
10 |
+
"""Class for managing antichannelpins in chats."""
|
11 |
+
|
12 |
+
# Database name to connect to to preform operations
|
13 |
+
db_name = "welcome_chats"
|
14 |
+
|
15 |
+
def __init__(self, chat_id: int) -> None:
|
16 |
+
super().__init__(self.db_name)
|
17 |
+
self.chat_id = chat_id
|
18 |
+
self.chat_info = self.__ensure_in_db()
|
19 |
+
|
20 |
+
# Get settings from database
|
21 |
+
def get_welcome_status(self):
|
22 |
+
with INSERTION_LOCK:
|
23 |
+
return self.chat_info["welcome"]
|
24 |
+
|
25 |
+
def get_goodbye_status(self):
|
26 |
+
with INSERTION_LOCK:
|
27 |
+
return self.chat_info["goodbye"]
|
28 |
+
|
29 |
+
def get_current_cleanservice_settings(self):
|
30 |
+
with INSERTION_LOCK:
|
31 |
+
return self.chat_info["cleanservice"]
|
32 |
+
|
33 |
+
def get_current_cleanwelcome_settings(self):
|
34 |
+
with INSERTION_LOCK:
|
35 |
+
return self.chat_info["cleanwelcome"]
|
36 |
+
|
37 |
+
def get_current_cleangoodbye_settings(self):
|
38 |
+
with INSERTION_LOCK:
|
39 |
+
return self.chat_info["cleangoodbye"]
|
40 |
+
|
41 |
+
def get_welcome_text(self):
|
42 |
+
with INSERTION_LOCK:
|
43 |
+
return self.chat_info["welcome_text"]
|
44 |
+
|
45 |
+
def get_goodbye_text(self):
|
46 |
+
with INSERTION_LOCK:
|
47 |
+
return self.chat_info["goodbye_text"]
|
48 |
+
|
49 |
+
def get_current_cleanwelcome_id(self):
|
50 |
+
with INSERTION_LOCK:
|
51 |
+
return self.chat_info["cleanwelcome_id"]
|
52 |
+
|
53 |
+
def get_current_cleangoodbye_id(self):
|
54 |
+
with INSERTION_LOCK:
|
55 |
+
return self.chat_info["cleangoodbye_id"]
|
56 |
+
|
57 |
+
# Set settings in database
|
58 |
+
def set_current_welcome_settings(self, status: bool):
|
59 |
+
with INSERTION_LOCK:
|
60 |
+
return self.update({"_id": self.chat_id}, {"welcome": status})
|
61 |
+
|
62 |
+
def set_current_goodbye_settings(self, status: bool):
|
63 |
+
with INSERTION_LOCK:
|
64 |
+
return self.update({"_id": self.chat_id}, {"goodbye": status})
|
65 |
+
|
66 |
+
def set_welcome_text(self, welcome_text: str):
|
67 |
+
with INSERTION_LOCK:
|
68 |
+
return self.update(
|
69 |
+
{"_id": self.chat_id},
|
70 |
+
{"welcome_text": welcome_text},
|
71 |
+
)
|
72 |
+
|
73 |
+
def set_goodbye_text(self, goodbye_text: str):
|
74 |
+
with INSERTION_LOCK:
|
75 |
+
return self.update(
|
76 |
+
{"_id": self.chat_id},
|
77 |
+
{"goodbye_text": goodbye_text},
|
78 |
+
)
|
79 |
+
|
80 |
+
def set_current_cleanservice_settings(self, status: bool):
|
81 |
+
with INSERTION_LOCK:
|
82 |
+
return self.update(
|
83 |
+
{"_id": self.chat_id},
|
84 |
+
{"cleanservice": status},
|
85 |
+
)
|
86 |
+
|
87 |
+
def set_current_cleanwelcome_settings(self, status: bool):
|
88 |
+
with INSERTION_LOCK:
|
89 |
+
return self.update(
|
90 |
+
{"_id": self.chat_id},
|
91 |
+
{"cleanwelcome": status},
|
92 |
+
)
|
93 |
+
|
94 |
+
def set_current_cleangoodbye_settings(self, status: bool):
|
95 |
+
with INSERTION_LOCK:
|
96 |
+
return self.update(
|
97 |
+
{"_id": self.chat_id},
|
98 |
+
{"cleangoodbye": status},
|
99 |
+
)
|
100 |
+
|
101 |
+
def set_cleanwlcm_id(self, status: int):
|
102 |
+
with INSERTION_LOCK:
|
103 |
+
return self.update(
|
104 |
+
{"_id": self.chat_id},
|
105 |
+
{"cleanwelcome_id": status},
|
106 |
+
)
|
107 |
+
|
108 |
+
def set_cleangoodbye_id(self, status: int):
|
109 |
+
with INSERTION_LOCK:
|
110 |
+
return self.update(
|
111 |
+
{"_id": self.chat_id},
|
112 |
+
{"cleangoodbye_id": status},
|
113 |
+
)
|
114 |
+
|
115 |
+
def __ensure_in_db(self):
|
116 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
117 |
+
if not chat_data:
|
118 |
+
new_data = {
|
119 |
+
"_id": self.chat_id,
|
120 |
+
"cleanwelcome": False,
|
121 |
+
"cleanwelcome_id": None,
|
122 |
+
"cleangoodbye_id": None,
|
123 |
+
"cleangoodbye": False,
|
124 |
+
"cleanservice": False,
|
125 |
+
"goodbye_text": "Sad to see you leaving {first}.\nTake Care!",
|
126 |
+
"welcome_text": "Hey {first}, welcome to {chatname}!",
|
127 |
+
"welcome": True,
|
128 |
+
"goodbye": True,
|
129 |
+
}
|
130 |
+
self.insert_one(new_data)
|
131 |
+
LOGGER.info(f"Initialized Greetings Document for chat {self.chat_id}")
|
132 |
+
return new_data
|
133 |
+
return chat_data
|
134 |
+
|
135 |
+
# Migrate if chat id changes!
|
136 |
+
def migrate_chat(self, new_chat_id: int):
|
137 |
+
old_chat_db = self.find_one({"_id": self.chat_id})
|
138 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
139 |
+
self.insert_one(new_data)
|
140 |
+
self.delete_one({"_id": self.chat_id})
|
141 |
+
|
142 |
+
@staticmethod
|
143 |
+
def count_chats(query: str):
|
144 |
+
with INSERTION_LOCK:
|
145 |
+
collection = MongoDB(Greetings.db_name)
|
146 |
+
return collection.count({query: True})
|
Powers/database/group_blacklist.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
|
3 |
+
from Powers.database import MongoDB
|
4 |
+
from Powers.database.chats_db import Chats
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
BLACKLIST_CHATS = []
|
8 |
+
|
9 |
+
|
10 |
+
class GroupBlacklist(MongoDB):
|
11 |
+
"""Class to blacklist chats where bot will exit."""
|
12 |
+
|
13 |
+
db_name = "group_blacklists"
|
14 |
+
|
15 |
+
def __init__(self) -> None:
|
16 |
+
super().__init__(self.db_name)
|
17 |
+
|
18 |
+
def add_chat(self, chat_id: int):
|
19 |
+
with INSERTION_LOCK:
|
20 |
+
global BLACKLIST_CHATS
|
21 |
+
try:
|
22 |
+
Chats.remove_chat(chat_id) # Delete chat from database
|
23 |
+
except KeyError:
|
24 |
+
pass
|
25 |
+
BLACKLIST_CHATS.append(chat_id)
|
26 |
+
BLACKLIST_CHATS.sort()
|
27 |
+
return self.insert_one({"_id": chat_id, "blacklist": True})
|
28 |
+
|
29 |
+
def remove_chat(self, chat_id: int):
|
30 |
+
with INSERTION_LOCK:
|
31 |
+
global BLACKLIST_CHATS
|
32 |
+
BLACKLIST_CHATS.remove(chat_id)
|
33 |
+
BLACKLIST_CHATS.sort()
|
34 |
+
return self.delete_one({"_id": chat_id})
|
35 |
+
|
36 |
+
def list_all_chats(self):
|
37 |
+
with INSERTION_LOCK:
|
38 |
+
try:
|
39 |
+
BLACKLIST_CHATS.sort()
|
40 |
+
return BLACKLIST_CHATS
|
41 |
+
except Exception:
|
42 |
+
all_chats = self.find_all()
|
43 |
+
return [chat["_id"] for chat in all_chats]
|
44 |
+
|
45 |
+
def get_from_db(self):
|
46 |
+
return self.find_all()
|
Powers/database/lang_db.py
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
from time import time
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.database import MongoDB
|
6 |
+
|
7 |
+
INSERTION_LOCK = RLock()
|
8 |
+
|
9 |
+
# Locall cache languages for users!!
|
10 |
+
LANG_CACHE = {}
|
11 |
+
|
12 |
+
|
13 |
+
class Langs(MongoDB):
|
14 |
+
"""Class for language options in bot."""
|
15 |
+
|
16 |
+
db_name = "langs"
|
17 |
+
|
18 |
+
def __init__(self, chat_id: int) -> None:
|
19 |
+
super().__init__(self.db_name)
|
20 |
+
self.chat_id = chat_id
|
21 |
+
self.chat_info = self.__ensure_in_db()
|
22 |
+
|
23 |
+
def get_chat_type(self):
|
24 |
+
return "supergroup" if str(self.chat_id).startswith("-100") else "user"
|
25 |
+
|
26 |
+
def set_lang(self, lang: str):
|
27 |
+
with INSERTION_LOCK:
|
28 |
+
global LANG_CACHE
|
29 |
+
LANG_CACHE[self.chat_id] = lang
|
30 |
+
self.chat_info["lang"] = lang
|
31 |
+
return self.update(
|
32 |
+
{"_id": self.chat_id},
|
33 |
+
{"lang": self.chat_info["lang"]},
|
34 |
+
)
|
35 |
+
|
36 |
+
def get_lang(self):
|
37 |
+
with INSERTION_LOCK:
|
38 |
+
return self.chat_info["lang"]
|
39 |
+
|
40 |
+
@staticmethod
|
41 |
+
def load_from_db():
|
42 |
+
with INSERTION_LOCK:
|
43 |
+
collection = MongoDB(Langs.db_name)
|
44 |
+
return collection.find_all()
|
45 |
+
|
46 |
+
def __ensure_in_db(self):
|
47 |
+
try:
|
48 |
+
chat_data = {"_id": self.chat_id, "lang": LANG_CACHE[self.chat_id]}
|
49 |
+
except KeyError:
|
50 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
51 |
+
if not chat_data:
|
52 |
+
chat_type = self.get_chat_type()
|
53 |
+
new_data = {"_id": self.chat_id, "lang": "en", "chat_type": chat_type}
|
54 |
+
self.insert_one(new_data)
|
55 |
+
LOGGER.info(f"Initialized Language Document for chat {self.chat_id}")
|
56 |
+
return new_data
|
57 |
+
return chat_data
|
58 |
+
|
59 |
+
# Migrate if chat id changes!
|
60 |
+
def migrate_chat(self, new_chat_id: int):
|
61 |
+
old_chat_db = self.find_one({"_id": self.chat_id})
|
62 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
63 |
+
self.insert_one(new_data)
|
64 |
+
self.delete_one({"_id": self.chat_id})
|
65 |
+
|
66 |
+
@staticmethod
|
67 |
+
def repair_db(collection):
|
68 |
+
all_data = collection.find_all()
|
69 |
+
keys = {"lang": "en", "chat_type": ""}
|
70 |
+
for data in all_data:
|
71 |
+
for key, val in keys.items():
|
72 |
+
try:
|
73 |
+
_ = data[key]
|
74 |
+
except KeyError:
|
75 |
+
LOGGER.warning(
|
76 |
+
f"Repairing Langs Database - setting '{key}:{val}' for {data['_id']}",
|
77 |
+
)
|
78 |
+
collection.update({"_id": data["_id"]}, {key: val})
|
79 |
+
|
80 |
+
|
81 |
+
def __pre_req_all_langs():
|
82 |
+
start = time()
|
83 |
+
LOGGER.info("Starting Langs Database Repair...")
|
84 |
+
collection = MongoDB(Langs.db_name)
|
85 |
+
Langs.repair_db(collection)
|
86 |
+
LOGGER.info(f"Done in {round((time() - start), 3)}s!")
|
87 |
+
|
88 |
+
|
89 |
+
def __load_lang_cache():
|
90 |
+
global LANG_CACHE
|
91 |
+
collection = MongoDB(Langs.db_name)
|
92 |
+
all_data = collection.find_all()
|
93 |
+
LANG_CACHE = {i["_id"]: i["lang"] for i in all_data}
|
Powers/database/notes_db.py
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from hashlib import md5
|
2 |
+
from threading import RLock
|
3 |
+
from time import time
|
4 |
+
|
5 |
+
from Powers.database import MongoDB
|
6 |
+
from Powers.utils.msg_types import Types
|
7 |
+
|
8 |
+
INSERTION_LOCK = RLock()
|
9 |
+
|
10 |
+
|
11 |
+
class Notes(MongoDB):
|
12 |
+
db_name = "notes"
|
13 |
+
|
14 |
+
def __init__(self) -> None:
|
15 |
+
super().__init__(self.db_name)
|
16 |
+
|
17 |
+
def save_note(
|
18 |
+
self,
|
19 |
+
chat_id: int,
|
20 |
+
note_name: str,
|
21 |
+
note_value: str,
|
22 |
+
msgtype: int = Types.TEXT,
|
23 |
+
fileid="",
|
24 |
+
):
|
25 |
+
with INSERTION_LOCK:
|
26 |
+
curr = self.find_one(
|
27 |
+
{"chat_id": chat_id, "note_name": note_name},
|
28 |
+
)
|
29 |
+
if curr:
|
30 |
+
return False
|
31 |
+
hash_gen = md5(
|
32 |
+
(note_name + note_value + str(chat_id) + str(int(time()))).encode(),
|
33 |
+
).hexdigest()
|
34 |
+
return self.insert_one(
|
35 |
+
{
|
36 |
+
"chat_id": chat_id,
|
37 |
+
"note_name": note_name,
|
38 |
+
"note_value": note_value,
|
39 |
+
"hash": hash_gen,
|
40 |
+
"msgtype": msgtype,
|
41 |
+
"fileid": fileid,
|
42 |
+
},
|
43 |
+
)
|
44 |
+
|
45 |
+
def get_note(self, chat_id: int, note_name: str):
|
46 |
+
with INSERTION_LOCK:
|
47 |
+
curr = self.find_one(
|
48 |
+
{"chat_id": chat_id, "note_name": note_name},
|
49 |
+
)
|
50 |
+
if curr:
|
51 |
+
return curr
|
52 |
+
return "Note does not exist!"
|
53 |
+
|
54 |
+
def get_note_by_hash(self, note_hash: str):
|
55 |
+
return self.find_one({"hash": note_hash})
|
56 |
+
|
57 |
+
def get_all_notes(self, chat_id: int):
|
58 |
+
with INSERTION_LOCK:
|
59 |
+
curr = self.find_all({"chat_id": chat_id})
|
60 |
+
note_list = [(note["note_name"], note["hash"]) for note in curr]
|
61 |
+
note_list.sort()
|
62 |
+
return note_list
|
63 |
+
|
64 |
+
def rm_note(self, chat_id: int, note_name: str):
|
65 |
+
with INSERTION_LOCK:
|
66 |
+
curr = self.find_one(
|
67 |
+
{"chat_id": chat_id, "note_name": note_name},
|
68 |
+
)
|
69 |
+
if curr:
|
70 |
+
self.delete_one(curr)
|
71 |
+
return True
|
72 |
+
return False
|
73 |
+
|
74 |
+
def rm_all_notes(self, chat_id: int):
|
75 |
+
with INSERTION_LOCK:
|
76 |
+
return self.delete_one({"chat_id": chat_id})
|
77 |
+
|
78 |
+
def count_notes(self, chat_id: int):
|
79 |
+
with INSERTION_LOCK:
|
80 |
+
curr = self.find_all({"chat_id": chat_id})
|
81 |
+
if curr:
|
82 |
+
return len(curr)
|
83 |
+
return 0
|
84 |
+
|
85 |
+
def count_notes_chats(self):
|
86 |
+
with INSERTION_LOCK:
|
87 |
+
notes = self.find_all()
|
88 |
+
chats_ids = [chat["chat_id"] for chat in notes]
|
89 |
+
return len(set(chats_ids))
|
90 |
+
|
91 |
+
def count_all_notes(self):
|
92 |
+
with INSERTION_LOCK:
|
93 |
+
return self.count()
|
94 |
+
|
95 |
+
def count_notes_type(self, ntype):
|
96 |
+
with INSERTION_LOCK:
|
97 |
+
return self.count({"msgtype": ntype})
|
98 |
+
|
99 |
+
# Migrate if chat id changes!
|
100 |
+
def migrate_chat(self, old_chat_id: int, new_chat_id: int):
|
101 |
+
with INSERTION_LOCK:
|
102 |
+
old_chat_db = self.find_one({"_id": old_chat_id})
|
103 |
+
if old_chat_db:
|
104 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
105 |
+
self.delete_one({"_id": old_chat_id})
|
106 |
+
self.insert_one(new_data)
|
107 |
+
|
108 |
+
|
109 |
+
class NotesSettings(MongoDB):
|
110 |
+
db_name = "notes_settings"
|
111 |
+
|
112 |
+
def __init__(self) -> None:
|
113 |
+
super().__init__(self.db_name)
|
114 |
+
|
115 |
+
def set_privatenotes(self, chat_id: int, status: bool = False):
|
116 |
+
curr = self.find_one({"_id": chat_id})
|
117 |
+
if curr:
|
118 |
+
return self.update({"_id": chat_id}, {"privatenotes": status})
|
119 |
+
return self.insert_one({"_id": chat_id, "privatenotes": status})
|
120 |
+
|
121 |
+
def get_privatenotes(self, chat_id: int):
|
122 |
+
curr = self.find_one({"_id": chat_id})
|
123 |
+
if curr:
|
124 |
+
return curr["privatenotes"]
|
125 |
+
self.update({"_id": chat_id}, {"privatenotes": False})
|
126 |
+
return False
|
127 |
+
|
128 |
+
def list_chats(self):
|
129 |
+
return self.find_all({"privatenotes": True})
|
130 |
+
|
131 |
+
def count_chats(self):
|
132 |
+
return len(self.find_all({"privatenotes": True}))
|
133 |
+
|
134 |
+
# Migrate if chat id changes!
|
135 |
+
def migrate_chat(self, old_chat_id: int, new_chat_id: int):
|
136 |
+
with INSERTION_LOCK:
|
137 |
+
old_chat_db = self.find_one({"_id": old_chat_id})
|
138 |
+
if old_chat_db:
|
139 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
140 |
+
self.delete_one({"_id": old_chat_id})
|
141 |
+
self.insert_one(new_data)
|
Powers/database/pins_db.py
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
|
3 |
+
from Powers import LOGGER
|
4 |
+
from Powers.database import MongoDB
|
5 |
+
|
6 |
+
INSERTION_LOCK = RLock()
|
7 |
+
|
8 |
+
|
9 |
+
class Pins(MongoDB):
|
10 |
+
"""Class for managing antichannelpins in chats."""
|
11 |
+
|
12 |
+
# Database name to connect to to preform operations
|
13 |
+
db_name = "antichannelpin"
|
14 |
+
|
15 |
+
def __init__(self, chat_id: int) -> None:
|
16 |
+
super().__init__(self.db_name)
|
17 |
+
self.chat_id = chat_id
|
18 |
+
self.chat_info = self.__ensure_in_db()
|
19 |
+
|
20 |
+
def get_settings(self):
|
21 |
+
with INSERTION_LOCK:
|
22 |
+
return self.chat_info
|
23 |
+
|
24 |
+
def antichannelpin_on(self):
|
25 |
+
with INSERTION_LOCK:
|
26 |
+
return self.set_on("antichannelpin")
|
27 |
+
|
28 |
+
def cleanlinked_on(self):
|
29 |
+
with INSERTION_LOCK:
|
30 |
+
return self.set_on("cleanlinked")
|
31 |
+
|
32 |
+
def antichannelpin_off(self):
|
33 |
+
with INSERTION_LOCK:
|
34 |
+
return self.set_off("antichannelpin")
|
35 |
+
|
36 |
+
def cleanlinked_off(self):
|
37 |
+
with INSERTION_LOCK:
|
38 |
+
return self.set_off("cleanlinked")
|
39 |
+
|
40 |
+
def set_on(self, atype: str):
|
41 |
+
with INSERTION_LOCK:
|
42 |
+
otype = "cleanlinked" if atype == "antichannelpin" else "antichannelpin"
|
43 |
+
return self.update(
|
44 |
+
{"_id": self.chat_id},
|
45 |
+
{atype: True, otype: False},
|
46 |
+
)
|
47 |
+
|
48 |
+
def set_off(self, atype: str):
|
49 |
+
with INSERTION_LOCK:
|
50 |
+
otype = "cleanlinked" if atype == "antichannelpin" else "antichannelpin"
|
51 |
+
return self.update(
|
52 |
+
{"_id": self.chat_id},
|
53 |
+
{atype: False, otype: False},
|
54 |
+
)
|
55 |
+
|
56 |
+
def __ensure_in_db(self):
|
57 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
58 |
+
if not chat_data:
|
59 |
+
new_data = {
|
60 |
+
"_id": self.chat_id,
|
61 |
+
"antichannelpin": False,
|
62 |
+
"cleanlinked": False,
|
63 |
+
}
|
64 |
+
self.insert_one(new_data)
|
65 |
+
LOGGER.info(f"Initialized Pins Document for chat {self.chat_id}")
|
66 |
+
return new_data
|
67 |
+
return chat_data
|
68 |
+
|
69 |
+
# Migrate if chat id changes!
|
70 |
+
def migrate_chat(self, new_chat_id: int):
|
71 |
+
old_chat_db = self.find_one({"_id": self.chat_id})
|
72 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
73 |
+
self.insert_one(new_data)
|
74 |
+
self.delete_one({"_id": self.chat_id})
|
75 |
+
|
76 |
+
# ----- Static Methods -----
|
77 |
+
@staticmethod
|
78 |
+
def count_chats(atype: str):
|
79 |
+
with INSERTION_LOCK:
|
80 |
+
collection = MongoDB(Pins.db_name)
|
81 |
+
return collection.count({atype: True})
|
82 |
+
|
83 |
+
@staticmethod
|
84 |
+
def list_chats(query: str):
|
85 |
+
with INSERTION_LOCK:
|
86 |
+
collection = MongoDB(Pins.db_name)
|
87 |
+
return collection.find_all({query: True})
|
88 |
+
|
89 |
+
@staticmethod
|
90 |
+
def load_from_db():
|
91 |
+
with INSERTION_LOCK:
|
92 |
+
collection = MongoDB(Pins.db_name)
|
93 |
+
return collection.find_all()
|
94 |
+
|
95 |
+
@staticmethod
|
96 |
+
def repair_db(collection):
|
97 |
+
all_data = collection.find_all()
|
98 |
+
keys = {"antichannelpin": False, "cleanlinked": False}
|
99 |
+
for data in all_data:
|
100 |
+
for key, val in keys.items():
|
101 |
+
try:
|
102 |
+
_ = data[key]
|
103 |
+
except KeyError:
|
104 |
+
LOGGER.warning(
|
105 |
+
f"Repairing Pins Database - setting '{key}:{val}' for {data['_id']}",
|
106 |
+
)
|
107 |
+
collection.update({"_id": data["_id"]}, {key: val})
|
108 |
+
|
109 |
+
|
110 |
+
def __pre_req_pins_chats():
|
111 |
+
LOGGER.info("Starting Pins Database Repair...")
|
112 |
+
collection = MongoDB(Pins.db_name)
|
113 |
+
Pins.repair_db(collection)
|
Powers/database/reporting_db.py
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
from time import time
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.database import MongoDB
|
6 |
+
|
7 |
+
INSERTION_LOCK = RLock()
|
8 |
+
|
9 |
+
|
10 |
+
class Reporting(MongoDB):
|
11 |
+
"""Class for managing report settings of users and groups."""
|
12 |
+
|
13 |
+
db_name = "reporting"
|
14 |
+
|
15 |
+
def __init__(self, chat_id: int) -> None:
|
16 |
+
super().__init__(self.db_name)
|
17 |
+
self.chat_id = chat_id
|
18 |
+
self.chat_info = self.__ensure_in_db()
|
19 |
+
|
20 |
+
def get_chat_type(self):
|
21 |
+
return "supergroup" if str(self.chat_id).startswith("-100") else "user"
|
22 |
+
|
23 |
+
def set_settings(self, status: bool = True):
|
24 |
+
with INSERTION_LOCK:
|
25 |
+
self.chat_info["status"] = status
|
26 |
+
return self.update(
|
27 |
+
{"_id": self.chat_id},
|
28 |
+
{"status": self.chat_info["status"]},
|
29 |
+
)
|
30 |
+
|
31 |
+
def get_settings(self):
|
32 |
+
with INSERTION_LOCK:
|
33 |
+
return self.chat_info["status"]
|
34 |
+
|
35 |
+
@staticmethod
|
36 |
+
def load_from_db():
|
37 |
+
with INSERTION_LOCK:
|
38 |
+
collection = MongoDB(Reporting.db_name)
|
39 |
+
return collection.find_all() or []
|
40 |
+
|
41 |
+
def __ensure_in_db(self):
|
42 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
43 |
+
if not chat_data:
|
44 |
+
chat_type = self.get_chat_type()
|
45 |
+
new_data = {"_id": self.chat_id, "status": True, "chat_type": chat_type}
|
46 |
+
self.insert_one(new_data)
|
47 |
+
LOGGER.info(f"Initialized Language Document for chat {self.chat_id}")
|
48 |
+
return new_data
|
49 |
+
return chat_data
|
50 |
+
|
51 |
+
# Migrate if chat id changes!
|
52 |
+
def migrate_chat(self, new_chat_id: int):
|
53 |
+
old_chat_db = self.find_one({"_id": self.chat_id})
|
54 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
55 |
+
self.insert_one(new_data)
|
56 |
+
self.delete_one({"_id": self.chat_id})
|
57 |
+
|
58 |
+
@staticmethod
|
59 |
+
def repair_db(collection):
|
60 |
+
all_data = collection.find_all()
|
61 |
+
keys = {"status": True, "chat_type": ""}
|
62 |
+
for data in all_data:
|
63 |
+
for key, val in keys.items():
|
64 |
+
try:
|
65 |
+
_ = data[key]
|
66 |
+
except KeyError:
|
67 |
+
LOGGER.warning(
|
68 |
+
f"Repairing Reporting Database - setting '{key}:{val}' for {data['_id']}",
|
69 |
+
)
|
70 |
+
collection.update({"_id": data["_id"]}, {key: val})
|
71 |
+
|
72 |
+
|
73 |
+
def __pre_req_all_reporting_settings():
|
74 |
+
start = time()
|
75 |
+
LOGGER.info("Starting Reports Database Repair...")
|
76 |
+
collection = MongoDB(Reporting.db_name)
|
77 |
+
Reporting.repair_db(collection)
|
78 |
+
LOGGER.info(f"Done in {round((time() - start), 3)}s!")
|
Powers/database/rules_db.py
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
from time import time
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.database import MongoDB
|
6 |
+
|
7 |
+
INSERTION_LOCK = RLock()
|
8 |
+
|
9 |
+
|
10 |
+
class Rules(MongoDB):
|
11 |
+
"""Class for rules for chats in bot."""
|
12 |
+
|
13 |
+
db_name = "rules"
|
14 |
+
|
15 |
+
def __init__(self, chat_id: int) -> None:
|
16 |
+
super().__init__(self.db_name)
|
17 |
+
self.chat_id = chat_id
|
18 |
+
self.chat_info = self.__ensure_in_db()
|
19 |
+
|
20 |
+
def get_rules(self):
|
21 |
+
with INSERTION_LOCK:
|
22 |
+
return self.chat_info["rules"]
|
23 |
+
|
24 |
+
def set_rules(self, rules: str):
|
25 |
+
with INSERTION_LOCK:
|
26 |
+
self.chat_info["rules"] = rules
|
27 |
+
self.update({"_id": self.chat_id}, {"rules": rules})
|
28 |
+
|
29 |
+
def get_privrules(self):
|
30 |
+
with INSERTION_LOCK:
|
31 |
+
return self.chat_info["privrules"]
|
32 |
+
|
33 |
+
def set_privrules(self, privrules: bool):
|
34 |
+
with INSERTION_LOCK:
|
35 |
+
self.chat_info["privrules"] = privrules
|
36 |
+
self.update({"_id": self.chat_id}, {"privrules": privrules})
|
37 |
+
|
38 |
+
def clear_rules(self):
|
39 |
+
with INSERTION_LOCK:
|
40 |
+
return self.delete_one({"_id": self.chat_id})
|
41 |
+
|
42 |
+
@staticmethod
|
43 |
+
def count_chats_with_rules():
|
44 |
+
with INSERTION_LOCK:
|
45 |
+
collection = MongoDB(Rules.db_name)
|
46 |
+
return collection.count({"rules": {"$regex": ".*"}})
|
47 |
+
|
48 |
+
@staticmethod
|
49 |
+
def count_privrules_chats():
|
50 |
+
with INSERTION_LOCK:
|
51 |
+
collection = MongoDB(Rules.db_name)
|
52 |
+
return collection.count({"privrules": True})
|
53 |
+
|
54 |
+
@staticmethod
|
55 |
+
def count_grouprules_chats():
|
56 |
+
with INSERTION_LOCK:
|
57 |
+
collection = MongoDB(Rules.db_name)
|
58 |
+
return collection.count({"privrules": False})
|
59 |
+
|
60 |
+
@staticmethod
|
61 |
+
def load_from_db():
|
62 |
+
with INSERTION_LOCK:
|
63 |
+
collection = MongoDB(Rules.db_name)
|
64 |
+
return collection.find_all()
|
65 |
+
|
66 |
+
def __ensure_in_db(self):
|
67 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
68 |
+
if not chat_data:
|
69 |
+
new_data = {"_id": self.chat_id, "privrules": False, "rules": ""}
|
70 |
+
self.insert_one(new_data)
|
71 |
+
LOGGER.info(f"Initialized Language Document for chat {self.chat_id}")
|
72 |
+
return new_data
|
73 |
+
return chat_data
|
74 |
+
|
75 |
+
# Migrate if chat id changes!
|
76 |
+
def migrate_chat(self, new_chat_id: int):
|
77 |
+
old_chat_db = self.find_one({"_id": self.chat_id})
|
78 |
+
new_data = old_chat_db.update({"_id": new_chat_id})
|
79 |
+
self.insert_one(new_data)
|
80 |
+
self.delete_one({"_id": self.chat_id})
|
81 |
+
|
82 |
+
@staticmethod
|
83 |
+
def repair_db(collection):
|
84 |
+
all_data = collection.find_all()
|
85 |
+
keys = {"privrules": False, "rules": ""}
|
86 |
+
for data in all_data:
|
87 |
+
for key, val in keys.items():
|
88 |
+
try:
|
89 |
+
_ = data[key]
|
90 |
+
except KeyError:
|
91 |
+
LOGGER.warning(
|
92 |
+
f"Repairing Rules Database - setting '{key}:{val}' for {data['_id']}",
|
93 |
+
)
|
94 |
+
collection.update({"_id": data["_id"]}, {key: val})
|
95 |
+
|
96 |
+
|
97 |
+
def __pre_req_all_rules():
|
98 |
+
start = time()
|
99 |
+
LOGGER.info("Starting Rules Database Repair...")
|
100 |
+
collection = MongoDB(Rules.db_name)
|
101 |
+
Rules.repair_db(collection)
|
102 |
+
LOGGER.info(f"Done in {round((time() - start), 3)}s!")
|
Powers/database/users_db.py
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
from time import time
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.database import MongoDB
|
6 |
+
|
7 |
+
INSERTION_LOCK = RLock()
|
8 |
+
|
9 |
+
|
10 |
+
class Users(MongoDB):
|
11 |
+
"""Class to manage users for bot."""
|
12 |
+
|
13 |
+
db_name = "users"
|
14 |
+
|
15 |
+
def __init__(self, user_id: int) -> None:
|
16 |
+
super().__init__(self.db_name)
|
17 |
+
self.user_id = user_id
|
18 |
+
self.user_info = self.__ensure_in_db()
|
19 |
+
|
20 |
+
def update_user(self, name: str, username: str = None):
|
21 |
+
with INSERTION_LOCK:
|
22 |
+
if name != self.user_info["name"] or username != self.user_info["username"]:
|
23 |
+
return self.update(
|
24 |
+
{"_id": self.user_id},
|
25 |
+
{"username": username, "name": name},
|
26 |
+
)
|
27 |
+
return True
|
28 |
+
|
29 |
+
def delete_user(self):
|
30 |
+
with INSERTION_LOCK:
|
31 |
+
return self.delete_one({"_id": self.user_id})
|
32 |
+
|
33 |
+
@staticmethod
|
34 |
+
def count_users():
|
35 |
+
with INSERTION_LOCK:
|
36 |
+
collection = MongoDB(Users.db_name)
|
37 |
+
return collection.count()
|
38 |
+
|
39 |
+
def get_my_info(self):
|
40 |
+
with INSERTION_LOCK:
|
41 |
+
return self.user_info
|
42 |
+
|
43 |
+
@staticmethod
|
44 |
+
def list_users():
|
45 |
+
with INSERTION_LOCK:
|
46 |
+
collection = MongoDB(Users.db_name)
|
47 |
+
return collection.find_all()
|
48 |
+
|
49 |
+
@staticmethod
|
50 |
+
def get_user_info(user_id: int or str):
|
51 |
+
with INSERTION_LOCK:
|
52 |
+
collection = MongoDB(Users.db_name)
|
53 |
+
if isinstance(user_id, int):
|
54 |
+
curr = collection.find_one({"_id": user_id})
|
55 |
+
elif isinstance(user_id, str):
|
56 |
+
# user_id[1:] because we don't want the '@' in the username search!
|
57 |
+
curr = collection.find_one({"username": user_id[1:]})
|
58 |
+
else:
|
59 |
+
curr = None
|
60 |
+
|
61 |
+
if curr:
|
62 |
+
return curr
|
63 |
+
|
64 |
+
return {}
|
65 |
+
|
66 |
+
def __ensure_in_db(self):
|
67 |
+
chat_data = self.find_one({"_id": self.user_id})
|
68 |
+
if not chat_data:
|
69 |
+
new_data = {"_id": self.user_id, "username": "", "name": "unknown_till_now"}
|
70 |
+
self.insert_one(new_data)
|
71 |
+
LOGGER.info(f"Initialized User Document for {self.user_id}")
|
72 |
+
return new_data
|
73 |
+
return chat_data
|
74 |
+
|
75 |
+
@staticmethod
|
76 |
+
def load_from_db():
|
77 |
+
with INSERTION_LOCK:
|
78 |
+
collection = MongoDB(Users.db_name)
|
79 |
+
return collection.find_all()
|
80 |
+
|
81 |
+
@staticmethod
|
82 |
+
def repair_db(collection):
|
83 |
+
all_data = collection.find_all()
|
84 |
+
keys = {"username": "", "name": "unknown_till_now"}
|
85 |
+
for data in all_data:
|
86 |
+
for key, val in keys.items():
|
87 |
+
try:
|
88 |
+
_ = data[key]
|
89 |
+
except KeyError:
|
90 |
+
LOGGER.warning(
|
91 |
+
f"Repairing Users Database - setting '{key}:{val}' for {data['_id']}",
|
92 |
+
)
|
93 |
+
collection.update({"_id": data["_id"]}, {key: val})
|
94 |
+
|
95 |
+
|
96 |
+
def __pre_req_users():
|
97 |
+
start = time()
|
98 |
+
LOGGER.info("Starting Users Database Repair...")
|
99 |
+
collection = MongoDB(Users.db_name)
|
100 |
+
Users.repair_db(collection)
|
101 |
+
LOGGER.info(f"Done in {round((time() - start), 3)}s!")
|
Powers/database/warns_db.py
ADDED
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from threading import RLock
|
2 |
+
from time import time
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.database import MongoDB
|
6 |
+
|
7 |
+
INSERTION_LOCK = RLock()
|
8 |
+
|
9 |
+
|
10 |
+
class Warns(MongoDB):
|
11 |
+
db_name = "chat_warns"
|
12 |
+
|
13 |
+
def __init__(self, chat_id: int) -> None:
|
14 |
+
super().__init__(self.db_name)
|
15 |
+
self.chat_id = chat_id
|
16 |
+
|
17 |
+
def warn_user(self, user_id: int, warn_reason=None):
|
18 |
+
with INSERTION_LOCK:
|
19 |
+
self.user_info = self.__ensure_in_db(user_id)
|
20 |
+
self.user_info["warns"].append(warn_reason)
|
21 |
+
self.user_info["num_warns"] = len(self.user_info["warns"])
|
22 |
+
self.update(
|
23 |
+
{"chat_id": self.chat_id, "user_id": user_id},
|
24 |
+
{
|
25 |
+
"warns": self.user_info["warns"],
|
26 |
+
"num_warns": self.user_info["num_warns"],
|
27 |
+
},
|
28 |
+
)
|
29 |
+
return self.user_info["warns"], self.user_info["num_warns"]
|
30 |
+
|
31 |
+
def remove_warn(self, user_id: int):
|
32 |
+
with INSERTION_LOCK:
|
33 |
+
self.user_info = self.__ensure_in_db(user_id)
|
34 |
+
self.user_info["warns"].pop()
|
35 |
+
self.user_info["num_warns"] = len(self.user_info["warns"])
|
36 |
+
self.update(
|
37 |
+
{"chat_id": self.chat_id, "user_id": user_id},
|
38 |
+
{
|
39 |
+
"warns": self.user_info["warns"],
|
40 |
+
"num_warns": self.user_info["num_warns"],
|
41 |
+
},
|
42 |
+
)
|
43 |
+
return self.user_info["warns"], self.user_info["num_warns"]
|
44 |
+
|
45 |
+
def reset_warns(self, user_id: int):
|
46 |
+
with INSERTION_LOCK:
|
47 |
+
self.user_info = self.__ensure_in_db(user_id)
|
48 |
+
return self.delete_one({"chat_id": self.chat_id, "user_id": user_id})
|
49 |
+
|
50 |
+
def get_warns(self, user_id: int):
|
51 |
+
with INSERTION_LOCK:
|
52 |
+
self.user_info = self.__ensure_in_db(user_id)
|
53 |
+
return self.user_info["warns"], len(self.user_info["warns"])
|
54 |
+
|
55 |
+
@staticmethod
|
56 |
+
def count_all_chats_using_warns():
|
57 |
+
with INSERTION_LOCK:
|
58 |
+
collection = MongoDB(Warns.db_name)
|
59 |
+
curr = collection.find_all()
|
60 |
+
return len({i["chat_id"] for i in curr})
|
61 |
+
|
62 |
+
@staticmethod
|
63 |
+
def count_warned_users():
|
64 |
+
with INSERTION_LOCK:
|
65 |
+
collection = MongoDB(Warns.db_name)
|
66 |
+
curr = collection.find_all()
|
67 |
+
return len({i["user_id"] for i in curr if i["num_warns"] >= 1})
|
68 |
+
|
69 |
+
@staticmethod
|
70 |
+
def count_warns_total():
|
71 |
+
with INSERTION_LOCK:
|
72 |
+
collection = MongoDB(Warns.db_name)
|
73 |
+
curr = collection.find_all()
|
74 |
+
return sum(i["num_warns"] for i in curr if i["num_warns"] >= 1)
|
75 |
+
|
76 |
+
@staticmethod
|
77 |
+
def repair_db(collection):
|
78 |
+
all_data = collection.find_all()
|
79 |
+
keys = {
|
80 |
+
"warns": [],
|
81 |
+
"num_warns": 0,
|
82 |
+
}
|
83 |
+
for data in all_data:
|
84 |
+
for key, val in keys.items():
|
85 |
+
try:
|
86 |
+
_ = data[key]
|
87 |
+
except KeyError:
|
88 |
+
LOGGER.warning(
|
89 |
+
f"Repairing Approve Database - setting '{key}:{val}' for {data['user_id']} in {data['chat_id']}",
|
90 |
+
)
|
91 |
+
collection.update(
|
92 |
+
{"chat_id": data["chat_id"], "user_id": data["user_id"]},
|
93 |
+
{key: val},
|
94 |
+
)
|
95 |
+
|
96 |
+
def __ensure_in_db(self, user_id: int):
|
97 |
+
chat_data = self.find_one({"chat_id": self.chat_id, "user_id": user_id})
|
98 |
+
if not chat_data:
|
99 |
+
new_data = {
|
100 |
+
"chat_id": self.chat_id,
|
101 |
+
"user_id": user_id,
|
102 |
+
"warns": [],
|
103 |
+
"num_warns": 0,
|
104 |
+
}
|
105 |
+
self.insert_one(new_data)
|
106 |
+
LOGGER.info(f"Initialized Warn Document for {user_id} in {self.chat_id}")
|
107 |
+
return new_data
|
108 |
+
return chat_data
|
109 |
+
|
110 |
+
|
111 |
+
class WarnSettings(MongoDB):
|
112 |
+
db_name = "chat_warn_settings"
|
113 |
+
|
114 |
+
def __init__(self, chat_id: int) -> None:
|
115 |
+
super().__init__(self.db_name)
|
116 |
+
self.chat_id = chat_id
|
117 |
+
self.chat_info = self.__ensure_in_db()
|
118 |
+
|
119 |
+
def __ensure_in_db(self):
|
120 |
+
chat_data = self.find_one({"_id": self.chat_id})
|
121 |
+
if not chat_data:
|
122 |
+
new_data = {"_id": self.chat_id, "warn_mode": "none", "warn_limit": 3}
|
123 |
+
self.insert_one(new_data)
|
124 |
+
LOGGER.info(f"Initialized Warn Settings Document for {self.chat_id}")
|
125 |
+
return new_data
|
126 |
+
return chat_data
|
127 |
+
|
128 |
+
def get_warnings_settings(self):
|
129 |
+
with INSERTION_LOCK:
|
130 |
+
return self.chat_info
|
131 |
+
|
132 |
+
def set_warnmode(self, warn_mode: str = "none"):
|
133 |
+
with INSERTION_LOCK:
|
134 |
+
self.update({"_id": self.chat_id}, {"warn_mode": warn_mode})
|
135 |
+
return warn_mode
|
136 |
+
|
137 |
+
def get_warnmode(self):
|
138 |
+
with INSERTION_LOCK:
|
139 |
+
return self.chat_info["warn_mode"]
|
140 |
+
|
141 |
+
def set_warnlimit(self, warn_limit: int = 3):
|
142 |
+
with INSERTION_LOCK:
|
143 |
+
self.update({"_id": self.chat_id}, {"warn_limit": warn_limit})
|
144 |
+
return warn_limit
|
145 |
+
|
146 |
+
def get_warnlimit(self):
|
147 |
+
with INSERTION_LOCK:
|
148 |
+
return self.chat_info["warn_limit"]
|
149 |
+
|
150 |
+
@staticmethod
|
151 |
+
def count_action_chats(mode: str):
|
152 |
+
collection = MongoDB(WarnSettings.db_name)
|
153 |
+
return collection.count({"warn_mode": mode})
|
154 |
+
|
155 |
+
@staticmethod
|
156 |
+
def repair_db(collection):
|
157 |
+
all_data = collection.find_all()
|
158 |
+
keys = {"warn_mode": "none", "warn_limit": 3}
|
159 |
+
for data in all_data:
|
160 |
+
for key, val in keys.items():
|
161 |
+
try:
|
162 |
+
_ = data[key]
|
163 |
+
except KeyError:
|
164 |
+
LOGGER.warning(
|
165 |
+
f"Repairing Approve Database - setting '{key}:{val}' for {data['_id']}",
|
166 |
+
)
|
167 |
+
collection.update({"_id": data["_id"]}, {key: val})
|
168 |
+
|
169 |
+
|
170 |
+
def __pre_req_warns():
|
171 |
+
start = time()
|
172 |
+
LOGGER.info("Starting Warns Database Repair...")
|
173 |
+
collection_warns = MongoDB(Warns.db_name)
|
174 |
+
collection_warn_settings = MongoDB(WarnSettings.db_name)
|
175 |
+
Warns.repair_db(collection_warns)
|
176 |
+
WarnSettings.repair_db(collection_warn_settings)
|
177 |
+
LOGGER.info(f"Done in {round((time() - start), 3)}s!")
|
Powers/modules/__init__.py
DELETED
File without changes
|
Powers/plugins/__init__.py
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
async def all_plugins():
|
2 |
+
# This generates a list of plugins in this folder for the * in __main__ to
|
3 |
+
# work.
|
4 |
+
|
5 |
+
from glob import glob
|
6 |
+
from os.path import basename, dirname, isfile
|
7 |
+
|
8 |
+
mod_paths = glob(dirname(__file__) + "/*.py")
|
9 |
+
all_plugs = [
|
10 |
+
basename(f)[:-3]
|
11 |
+
for f in mod_paths
|
12 |
+
if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py")
|
13 |
+
]
|
14 |
+
return sorted(all_plugs)
|
Powers/plugins/admin.py
ADDED
@@ -0,0 +1,769 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from asyncio import sleep
|
2 |
+
from html import escape
|
3 |
+
from os import remove
|
4 |
+
from traceback import format_exc
|
5 |
+
|
6 |
+
from pyrogram import filters
|
7 |
+
from pyrogram.errors import (
|
8 |
+
ChatAdminInviteRequired,
|
9 |
+
ChatAdminRequired,
|
10 |
+
FloodWait,
|
11 |
+
RightForbidden,
|
12 |
+
RPCError,
|
13 |
+
UserAdminInvalid,
|
14 |
+
)
|
15 |
+
from pyrogram.types import Message
|
16 |
+
|
17 |
+
from Powers import DEV_USERS, LOGGER, OWNER_ID, SUPPORT_GROUP, SUPPORT_STAFF
|
18 |
+
from Powers.bot_class import Gojo
|
19 |
+
from Powers.database.approve_db import Approve
|
20 |
+
from Powers.database.reporting_db import Reporting
|
21 |
+
from Powers.tr_engine import tlang
|
22 |
+
from Powers.utils.caching import ADMIN_CACHE, TEMP_ADMIN_CACHE_BLOCK, admin_cache_reload
|
23 |
+
from Powers.utils.custom_filters import (
|
24 |
+
DEV_LEVEL,
|
25 |
+
admin_filter,
|
26 |
+
command,
|
27 |
+
owner_filter,
|
28 |
+
promote_filter,
|
29 |
+
)
|
30 |
+
from Powers.utils.extract_user import extract_user
|
31 |
+
from Powers.utils.parser import mention_html
|
32 |
+
from Powers.vars import Config
|
33 |
+
|
34 |
+
|
35 |
+
@Gojo.on_message(command("adminlist"))
|
36 |
+
async def adminlist_show(_, m: Message):
|
37 |
+
global ADMIN_CACHE
|
38 |
+
if m.chat.type != "supergroup":
|
39 |
+
return await m.reply_text(
|
40 |
+
"This command is made to be used in groups only!",
|
41 |
+
)
|
42 |
+
try:
|
43 |
+
try:
|
44 |
+
admin_list = ADMIN_CACHE[m.chat.id]
|
45 |
+
note = tlang(m, "admin.adminlist.note_cached")
|
46 |
+
except KeyError:
|
47 |
+
admin_list = await admin_cache_reload(m, "adminlist")
|
48 |
+
note = tlang(m, "admin.adminlist.note_updated")
|
49 |
+
|
50 |
+
adminstr = (tlang(m, "admin.adminlist.adminstr")).format(
|
51 |
+
chat_title=m.chat.title,
|
52 |
+
) + "\n\n"
|
53 |
+
|
54 |
+
bot_admins = [i for i in admin_list if (i[1].lower()).endswith("bot")]
|
55 |
+
user_admins = [i for i in admin_list if not (i[1].lower()).endswith("bot")]
|
56 |
+
|
57 |
+
# format is like: (user_id, username/name,anonyamous or not)
|
58 |
+
mention_users = [
|
59 |
+
(
|
60 |
+
admin[1]
|
61 |
+
if admin[1].startswith("@")
|
62 |
+
else (await mention_html(admin[1], admin[0]))
|
63 |
+
)
|
64 |
+
for admin in user_admins
|
65 |
+
if not admin[2] # if non-anonyamous admin
|
66 |
+
]
|
67 |
+
mention_users.sort(key=lambda x: x[1])
|
68 |
+
|
69 |
+
mention_bots = [
|
70 |
+
(
|
71 |
+
admin[1]
|
72 |
+
if admin[1].startswith("@")
|
73 |
+
else (await mention_html(admin[1], admin[0]))
|
74 |
+
)
|
75 |
+
for admin in bot_admins
|
76 |
+
]
|
77 |
+
mention_bots.sort(key=lambda x: x[1])
|
78 |
+
|
79 |
+
adminstr += "<b>User Admins:</b>\n"
|
80 |
+
adminstr += "\n".join(f"- {i}" for i in mention_users)
|
81 |
+
adminstr += "\n\n<b>Bots:</b>\n"
|
82 |
+
adminstr += "\n".join(f"- {i}" for i in mention_bots)
|
83 |
+
|
84 |
+
await m.reply_text(adminstr + "\n\n" + note)
|
85 |
+
LOGGER.info(f"Adminlist cmd use in {m.chat.id} by {m.from_user.id}")
|
86 |
+
|
87 |
+
except Exception as ef:
|
88 |
+
if str(ef) == str(m.chat.id):
|
89 |
+
await m.reply_text(tlang(m, "admin.adminlist.use_admin_cache"))
|
90 |
+
else:
|
91 |
+
ef = str(ef) + f"{admin_list}\n"
|
92 |
+
await m.reply_text(
|
93 |
+
(tlang(m, "general.some_error")).format(
|
94 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
95 |
+
ef=ef,
|
96 |
+
),
|
97 |
+
)
|
98 |
+
LOGGER.error(ef)
|
99 |
+
LOGGER.error(format_exc())
|
100 |
+
|
101 |
+
return
|
102 |
+
|
103 |
+
|
104 |
+
@Gojo.on_message(command("zombies") & owner_filter)
|
105 |
+
async def zombie_clean(c: Gojo, m: Message):
|
106 |
+
|
107 |
+
zombie = 0
|
108 |
+
|
109 |
+
wait = await m.reply_text("Searching ... and banning ...")
|
110 |
+
async for member in c.iter_chat_members(m.chat.id):
|
111 |
+
if member.user.is_deleted:
|
112 |
+
zombie += 1
|
113 |
+
try:
|
114 |
+
await c.kick_chat_member(m.chat.id, member.user.id)
|
115 |
+
except UserAdminInvalid:
|
116 |
+
zombie -= 1
|
117 |
+
except FloodWait as e:
|
118 |
+
await sleep(e.x)
|
119 |
+
if zombie == 0:
|
120 |
+
return await wait.edit_text("Group is clean!")
|
121 |
+
return await wait.edit_text(
|
122 |
+
f"<b>{zombie}</b> Zombies found and has been banned!",
|
123 |
+
)
|
124 |
+
|
125 |
+
|
126 |
+
@Gojo.on_message(command("admincache"))
|
127 |
+
async def reload_admins(_, m: Message):
|
128 |
+
global TEMP_ADMIN_CACHE_BLOCK
|
129 |
+
|
130 |
+
if m.chat.type != "supergroup":
|
131 |
+
return await m.reply_text(
|
132 |
+
"This command is made to be used in groups only!",
|
133 |
+
)
|
134 |
+
|
135 |
+
if (
|
136 |
+
(m.chat.id in set(TEMP_ADMIN_CACHE_BLOCK.keys()))
|
137 |
+
and (m.from_user.id not in SUPPORT_STAFF)
|
138 |
+
and TEMP_ADMIN_CACHE_BLOCK[m.chat.id] == "manualblock"
|
139 |
+
):
|
140 |
+
await m.reply_text("Can only reload admin cache once per 10 mins!")
|
141 |
+
return
|
142 |
+
|
143 |
+
try:
|
144 |
+
await admin_cache_reload(m, "admincache")
|
145 |
+
TEMP_ADMIN_CACHE_BLOCK[m.chat.id] = "manualblock"
|
146 |
+
await m.reply_text(tlang(m, "admin.adminlist.reloaded_admins"))
|
147 |
+
LOGGER.info(f"Admincache cmd use in {m.chat.id} by {m.from_user.id}")
|
148 |
+
except RPCError as ef:
|
149 |
+
await m.reply_text(
|
150 |
+
(tlang(m, "general.some_error")).format(
|
151 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
152 |
+
ef=ef,
|
153 |
+
),
|
154 |
+
)
|
155 |
+
LOGGER.error(ef)
|
156 |
+
LOGGER.error(format_exc())
|
157 |
+
return
|
158 |
+
|
159 |
+
|
160 |
+
@Gojo.on_message(filters.regex(r"^(?i)@admin(s)?") & filters.group)
|
161 |
+
async def tag_admins(_, m: Message):
|
162 |
+
db = Reporting(m.chat.id)
|
163 |
+
if not db.get_settings():
|
164 |
+
return
|
165 |
+
|
166 |
+
try:
|
167 |
+
admin_list = ADMIN_CACHE[m.chat.id]
|
168 |
+
except KeyError:
|
169 |
+
admin_list = await admin_cache_reload(m, "adminlist")
|
170 |
+
|
171 |
+
user_admins = [i for i in admin_list if not (i[1].lower()).endswith("bot")]
|
172 |
+
mention_users = [(await mention_html("\u2063", admin[0])) for admin in user_admins]
|
173 |
+
mention_users.sort(key=lambda x: x[1])
|
174 |
+
mention_str = "".join(mention_users)
|
175 |
+
await m.reply_text(
|
176 |
+
(
|
177 |
+
f"{(await mention_html(m.from_user.first_name, m.from_user.id))}"
|
178 |
+
f" reported the message to admins!{mention_str}"
|
179 |
+
),
|
180 |
+
)
|
181 |
+
|
182 |
+
|
183 |
+
@Gojo.on_message(command("fullpromote") & promote_filter)
|
184 |
+
async def fullpromote_usr(c: Gojo, m: Message):
|
185 |
+
global ADMIN_CACHE
|
186 |
+
|
187 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
188 |
+
await m.reply_text(tlang(m, "admin.promote.no_target"))
|
189 |
+
return
|
190 |
+
|
191 |
+
try:
|
192 |
+
user_id, user_first_name, user_name = await extract_user(c, m)
|
193 |
+
except Exception:
|
194 |
+
return
|
195 |
+
|
196 |
+
bot = await c.get_chat_member(m.chat.id, Config.BOT_ID)
|
197 |
+
|
198 |
+
if user_id == Config.BOT_ID:
|
199 |
+
await m.reply_text("Huh, how can I even promote myself?")
|
200 |
+
return
|
201 |
+
|
202 |
+
if not bot.can_promote_members:
|
203 |
+
return await m.reply_text(
|
204 |
+
"I don't have enough permissions!",
|
205 |
+
) # This should be here
|
206 |
+
|
207 |
+
user = await c.get_chat_member(m.chat.id, m.from_user.id)
|
208 |
+
if m.from_user.id not in [DEV_USERS, OWNER_ID] and user.status != "creator":
|
209 |
+
return await m.reply_text("This command can only be used by chat owner.")
|
210 |
+
# If user is alreay admin
|
211 |
+
try:
|
212 |
+
admin_list = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
213 |
+
except KeyError:
|
214 |
+
admin_list = {
|
215 |
+
i[0] for i in (await admin_cache_reload(m, "promote_cache_update"))
|
216 |
+
}
|
217 |
+
|
218 |
+
if user_id in admin_list:
|
219 |
+
await m.reply_text(
|
220 |
+
"This user is already an admin, how am I supposed to re-promote them?",
|
221 |
+
)
|
222 |
+
return
|
223 |
+
|
224 |
+
try:
|
225 |
+
await m.chat.promote_member(
|
226 |
+
user_id=user_id,
|
227 |
+
can_change_info=bot.can_change_info,
|
228 |
+
can_invite_users=bot.can_invite_users,
|
229 |
+
can_delete_messages=bot.can_delete_messages,
|
230 |
+
can_restrict_members=bot.can_restrict_members,
|
231 |
+
can_pin_messages=bot.can_pin_messages,
|
232 |
+
can_promote_members=bot.can_promote_members,
|
233 |
+
can_manage_chat=bot.can_manage_chat,
|
234 |
+
can_manage_voice_chats=bot.can_manage_voice_chats,
|
235 |
+
)
|
236 |
+
|
237 |
+
title = ""
|
238 |
+
if len(m.text.split()) == 3 and not m.reply_to_message:
|
239 |
+
title = m.text.split()[2]
|
240 |
+
elif len(m.text.split()) == 2 and m.reply_to_message:
|
241 |
+
title = m.text.split()[1]
|
242 |
+
if title and len(title) > 16:
|
243 |
+
title = title[0:16] # trim title to 16 characters
|
244 |
+
|
245 |
+
try:
|
246 |
+
await c.set_administrator_title(m.chat.id, user_id, title)
|
247 |
+
except RPCError as e:
|
248 |
+
LOGGER.error(e)
|
249 |
+
|
250 |
+
LOGGER.info(
|
251 |
+
f"{m.from_user.id} fullpromoted {user_id} in {m.chat.id} with title '{title}'",
|
252 |
+
)
|
253 |
+
|
254 |
+
await m.reply_text(
|
255 |
+
(tlang(m, "admin.promote.promoted_user")).format(
|
256 |
+
promoter=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
257 |
+
promoted=(await mention_html(user_first_name, user_id)),
|
258 |
+
chat_title=f"{escape(m.chat.title)} title set to {title}"
|
259 |
+
if title
|
260 |
+
else f"{escape(m.chat.title)} title set to Admin",
|
261 |
+
),
|
262 |
+
)
|
263 |
+
|
264 |
+
# If user is approved, disapprove them as they willbe promoted and get even more rights
|
265 |
+
if Approve(m.chat.id).check_approve(user_id):
|
266 |
+
Approve(m.chat.id).remove_approve(user_id)
|
267 |
+
|
268 |
+
# ----- Add admin to temp cache -----
|
269 |
+
try:
|
270 |
+
inp1 = user_name or user_first_name
|
271 |
+
admins_group = ADMIN_CACHE[m.chat.id]
|
272 |
+
admins_group.append((user_id, inp1))
|
273 |
+
ADMIN_CACHE[m.chat.id] = admins_group
|
274 |
+
except KeyError:
|
275 |
+
await admin_cache_reload(m, "promote_key_error")
|
276 |
+
|
277 |
+
except ChatAdminRequired:
|
278 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
279 |
+
except RightForbidden:
|
280 |
+
await m.reply_text(tlang(m, "admin.promote.bot_no_right"))
|
281 |
+
except UserAdminInvalid:
|
282 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
283 |
+
except RPCError as e:
|
284 |
+
await m.reply_text(
|
285 |
+
(tlang(m, "general.some_error")).format(
|
286 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
287 |
+
ef=e,
|
288 |
+
),
|
289 |
+
)
|
290 |
+
LOGGER.error(e)
|
291 |
+
LOGGER.error(format_exc())
|
292 |
+
return
|
293 |
+
|
294 |
+
|
295 |
+
@Gojo.on_message(command("promote") & promote_filter)
|
296 |
+
async def promote_usr(c: Gojo, m: Message):
|
297 |
+
|
298 |
+
global ADMIN_CACHE
|
299 |
+
|
300 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
301 |
+
await m.reply_text(tlang(m, "admin.promote.no_target"))
|
302 |
+
return
|
303 |
+
|
304 |
+
try:
|
305 |
+
user_id, user_first_name, user_name = await extract_user(c, m)
|
306 |
+
except Exception:
|
307 |
+
return
|
308 |
+
|
309 |
+
bot = await c.get_chat_member(m.chat.id, Config.BOT_ID)
|
310 |
+
|
311 |
+
if user_id == Config.BOT_ID:
|
312 |
+
await m.reply_text("Huh, how can I even promote myself?")
|
313 |
+
return
|
314 |
+
|
315 |
+
if not bot.can_promote_members:
|
316 |
+
return await m.reply_text(
|
317 |
+
"I don't have enough permissions",
|
318 |
+
) # This should be here
|
319 |
+
# If user is alreay admin
|
320 |
+
try:
|
321 |
+
admin_list = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
322 |
+
except KeyError:
|
323 |
+
admin_list = {
|
324 |
+
i[0] for i in (await admin_cache_reload(m, "promote_cache_update"))
|
325 |
+
}
|
326 |
+
|
327 |
+
if user_id in admin_list:
|
328 |
+
await m.reply_text(
|
329 |
+
"This user is already an admin, how am I supposed to re-promote them?",
|
330 |
+
)
|
331 |
+
return
|
332 |
+
|
333 |
+
try:
|
334 |
+
await m.chat.promote_member(
|
335 |
+
user_id=user_id,
|
336 |
+
can_change_info=bot.can_change_info,
|
337 |
+
can_invite_users=bot.can_invite_users,
|
338 |
+
can_delete_messages=bot.can_delete_messages,
|
339 |
+
can_restrict_members=bot.can_restrict_members,
|
340 |
+
can_pin_messages=bot.can_pin_messages,
|
341 |
+
# can_promote_members=bot.can_promote_members,
|
342 |
+
can_manage_chat=bot.can_manage_chat,
|
343 |
+
can_manage_voice_chats=bot.can_manage_voice_chats,
|
344 |
+
)
|
345 |
+
|
346 |
+
title = "Itadori" # Deafult title
|
347 |
+
if len(m.text.split()) == 3 and not m.reply_to_message:
|
348 |
+
title = m.text.split()[2]
|
349 |
+
elif len(m.text.split()) == 2 and m.reply_to_message:
|
350 |
+
title = m.text.split()[1]
|
351 |
+
if title and len(title) > 16:
|
352 |
+
title = title[0:16] # trim title to 16 characters
|
353 |
+
|
354 |
+
try:
|
355 |
+
await c.set_administrator_title(m.chat.id, user_id, title)
|
356 |
+
except RPCError as e:
|
357 |
+
LOGGER.error(e)
|
358 |
+
|
359 |
+
LOGGER.info(
|
360 |
+
f"{m.from_user.id} promoted {user_id} in {m.chat.id} with title '{title}'",
|
361 |
+
)
|
362 |
+
|
363 |
+
await m.reply_text(
|
364 |
+
(tlang(m, "admin.promote.promoted_user")).format(
|
365 |
+
promoter=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
366 |
+
promoted=(await mention_html(user_first_name, user_id)),
|
367 |
+
chat_title=f"{escape(m.chat.title)} title set to {title}"
|
368 |
+
if title
|
369 |
+
else f"{escape(m.chat.title)} title set to Admin",
|
370 |
+
),
|
371 |
+
)
|
372 |
+
|
373 |
+
# If user is approved, disapprove them as they willbe promoted and get even more rights
|
374 |
+
if Approve(m.chat.id).check_approve(user_id):
|
375 |
+
Approve(m.chat.id).remove_approve(user_id)
|
376 |
+
|
377 |
+
# ----- Add admin to temp cache -----
|
378 |
+
try:
|
379 |
+
inp1 = user_name or user_first_name
|
380 |
+
admins_group = ADMIN_CACHE[m.chat.id]
|
381 |
+
admins_group.append((user_id, inp1))
|
382 |
+
ADMIN_CACHE[m.chat.id] = admins_group
|
383 |
+
except KeyError:
|
384 |
+
await admin_cache_reload(m, "promote_key_error")
|
385 |
+
|
386 |
+
except ChatAdminRequired:
|
387 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
388 |
+
except RightForbidden:
|
389 |
+
await m.reply_text(tlang(m, "admin.promote.bot_no_right"))
|
390 |
+
except UserAdminInvalid:
|
391 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
392 |
+
except RPCError as e:
|
393 |
+
await m.reply_text(
|
394 |
+
(tlang(m, "general.some_error")).format(
|
395 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
396 |
+
ef=e,
|
397 |
+
),
|
398 |
+
)
|
399 |
+
LOGGER.error(e)
|
400 |
+
LOGGER.error(format_exc())
|
401 |
+
return
|
402 |
+
|
403 |
+
|
404 |
+
|
405 |
+
@Gojo.on_message(command("spromote") & promote_filter)
|
406 |
+
async def superpromote_usr(c: Gojo, m: Message):
|
407 |
+
|
408 |
+
global ADMIN_CACHE
|
409 |
+
|
410 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
411 |
+
await m.reply_text(tlang(m, "admin.promote.no_target"))
|
412 |
+
return
|
413 |
+
|
414 |
+
try:
|
415 |
+
user_id, user_first_name, user_name = await extract_user(c, m)
|
416 |
+
except Exception:
|
417 |
+
return
|
418 |
+
|
419 |
+
bot = await c.get_chat_member(m.chat.id, Config.BOT_ID)
|
420 |
+
|
421 |
+
if user_id == Config.BOT_ID:
|
422 |
+
await m.reply_text("Huh, how can I even promote myself?")
|
423 |
+
return
|
424 |
+
|
425 |
+
if not bot.can_promote_members:
|
426 |
+
return await m.reply_text(
|
427 |
+
"I don't have enough permissions",
|
428 |
+
) # This should be here
|
429 |
+
# If user is alreay admin
|
430 |
+
try:
|
431 |
+
admin_list = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
432 |
+
except KeyError:
|
433 |
+
admin_list = {
|
434 |
+
i[0] for i in (await admin_cache_reload(m, "promote_cache_update"))
|
435 |
+
}
|
436 |
+
|
437 |
+
if user_id in admin_list:
|
438 |
+
await m.reply_text(
|
439 |
+
"This user is already an admin, how am I supposed to re-promote them?",
|
440 |
+
)
|
441 |
+
return
|
442 |
+
|
443 |
+
try:
|
444 |
+
await m.chat.promote_member(
|
445 |
+
user_id=user_id,
|
446 |
+
can_change_info=bot.can_change_info,
|
447 |
+
can_invite_users=bot.can_invite_users,
|
448 |
+
can_delete_messages=bot.can_delete_messages,
|
449 |
+
can_restrict_members=bot.can_restrict_members,
|
450 |
+
can_pin_messages=bot.can_pin_messages,
|
451 |
+
can_promote_members=bot.can_promote_members,
|
452 |
+
can_manage_chat=bot.can_manage_chat,
|
453 |
+
can_manage_voice_chats=bot.can_manage_voice_chats,
|
454 |
+
)
|
455 |
+
|
456 |
+
title = "Gojo" # Deafult title
|
457 |
+
if len(m.text.split()) == 3 and not m.reply_to_message:
|
458 |
+
title = m.text.split()[2]
|
459 |
+
elif len(m.text.split()) == 2 and m.reply_to_message:
|
460 |
+
title = m.text.split()[1]
|
461 |
+
if title and len(title) > 16:
|
462 |
+
title = title[0:16] # trim title to 16 characters
|
463 |
+
|
464 |
+
try:
|
465 |
+
await c.set_administrator_title(m.chat.id, user_id, title)
|
466 |
+
except RPCError as e:
|
467 |
+
LOGGER.error(e)
|
468 |
+
|
469 |
+
LOGGER.info(
|
470 |
+
f"{m.from_user.id} super promoted {user_id} in {m.chat.id} with title '{title}'",
|
471 |
+
)
|
472 |
+
|
473 |
+
await m.reply_text(
|
474 |
+
(tlang(m, "admin.promote.promoted_user")).format(
|
475 |
+
promoter=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
476 |
+
promoted=(await mention_html(user_first_name, user_id)),
|
477 |
+
chat_title=f"{escape(m.chat.title)} title set to {title}"
|
478 |
+
if title
|
479 |
+
else f"{escape(m.chat.title)} title set to Admin",
|
480 |
+
),
|
481 |
+
)
|
482 |
+
|
483 |
+
# If user is approved, disapprove them as they willbe promoted and get even more rights
|
484 |
+
if Approve(m.chat.id).check_approve(user_id):
|
485 |
+
Approve(m.chat.id).remove_approve(user_id)
|
486 |
+
|
487 |
+
# ----- Add admin to temp cache -----
|
488 |
+
try:
|
489 |
+
inp1 = user_name or user_first_name
|
490 |
+
admins_group = ADMIN_CACHE[m.chat.id]
|
491 |
+
admins_group.append((user_id, inp1))
|
492 |
+
ADMIN_CACHE[m.chat.id] = admins_group
|
493 |
+
except KeyError:
|
494 |
+
await admin_cache_reload(m, "promote_key_error")
|
495 |
+
|
496 |
+
except ChatAdminRequired:
|
497 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
498 |
+
except RightForbidden:
|
499 |
+
await m.reply_text(tlang(m, "admin.promote.bot_no_right"))
|
500 |
+
except UserAdminInvalid:
|
501 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
502 |
+
except RPCError as e:
|
503 |
+
await m.reply_text(
|
504 |
+
(tlang(m, "general.some_error")).format(
|
505 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
506 |
+
ef=e,
|
507 |
+
),
|
508 |
+
)
|
509 |
+
LOGGER.error(e)
|
510 |
+
LOGGER.error(format_exc())
|
511 |
+
return
|
512 |
+
|
513 |
+
|
514 |
+
@Gojo.on_message(command("demote") & promote_filter)
|
515 |
+
async def demote_usr(c: Gojo, m: Message):
|
516 |
+
|
517 |
+
global ADMIN_CACHE
|
518 |
+
|
519 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
520 |
+
await m.reply_text(tlang(m, "admin.demote.no_target"))
|
521 |
+
return
|
522 |
+
|
523 |
+
try:
|
524 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
525 |
+
except Exception:
|
526 |
+
return
|
527 |
+
|
528 |
+
if user_id == Config.BOT_ID:
|
529 |
+
await m.reply_text("Get an admin to demote me!")
|
530 |
+
return
|
531 |
+
|
532 |
+
# If user not alreay admin
|
533 |
+
try:
|
534 |
+
admin_list = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
535 |
+
except KeyError:
|
536 |
+
admin_list = {
|
537 |
+
i[0] for i in (await admin_cache_reload(m, "demote_cache_update"))
|
538 |
+
}
|
539 |
+
|
540 |
+
if user_id not in admin_list:
|
541 |
+
await m.reply_text(
|
542 |
+
"This user is not an admin, how am I supposed to re-demote them?",
|
543 |
+
)
|
544 |
+
return
|
545 |
+
|
546 |
+
try:
|
547 |
+
await m.chat.promote_member(
|
548 |
+
user_id=user_id,
|
549 |
+
can_change_info=False,
|
550 |
+
can_invite_users=False,
|
551 |
+
can_delete_messages=False,
|
552 |
+
can_restrict_members=False,
|
553 |
+
can_pin_messages=False,
|
554 |
+
can_promote_members=False,
|
555 |
+
can_manage_chat=False,
|
556 |
+
can_manage_voice_chats=False,
|
557 |
+
)
|
558 |
+
LOGGER.info(f"{m.from_user.id} demoted {user_id} in {m.chat.id}")
|
559 |
+
|
560 |
+
# ----- Remove admin from cache -----
|
561 |
+
try:
|
562 |
+
admin_list = ADMIN_CACHE[m.chat.id]
|
563 |
+
user = next(user for user in admin_list if user[0] == user_id)
|
564 |
+
admin_list.remove(user)
|
565 |
+
ADMIN_CACHE[m.chat.id] = admin_list
|
566 |
+
except (KeyError, StopIteration):
|
567 |
+
await admin_cache_reload(m, "demote_key_stopiter_error")
|
568 |
+
|
569 |
+
await m.reply_text(
|
570 |
+
(tlang(m, "admin.demote.demoted_user")).format(
|
571 |
+
demoter=(
|
572 |
+
await mention_html(
|
573 |
+
m.from_user.first_name,
|
574 |
+
m.from_user.id,
|
575 |
+
)
|
576 |
+
),
|
577 |
+
demoted=(await mention_html(user_first_name, user_id)),
|
578 |
+
chat_title=m.chat.title,
|
579 |
+
),
|
580 |
+
)
|
581 |
+
|
582 |
+
except ChatAdminRequired:
|
583 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
584 |
+
except RightForbidden:
|
585 |
+
await m.reply_text(tlang(m, "admin.demote.bot_no_right"))
|
586 |
+
except UserAdminInvalid:
|
587 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
588 |
+
except RPCError as ef:
|
589 |
+
await m.reply_text(
|
590 |
+
(tlang(m, "general.some_error")).format(
|
591 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
592 |
+
ef=ef,
|
593 |
+
),
|
594 |
+
)
|
595 |
+
LOGGER.error(ef)
|
596 |
+
LOGGER.error(format_exc())
|
597 |
+
|
598 |
+
return
|
599 |
+
|
600 |
+
|
601 |
+
|
602 |
+
|
603 |
+
@Gojo.on_message(command("invitelink"))
|
604 |
+
async def get_invitelink(c: Gojo, m: Message):
|
605 |
+
# Bypass the bot devs, sudos and owner
|
606 |
+
if m.from_user.id not in DEV_LEVEL:
|
607 |
+
user = await m.chat.get_member(m.from_user.id)
|
608 |
+
|
609 |
+
if not user.can_invite_users and user.status != "creator":
|
610 |
+
await m.reply_text(tlang(m, "admin.no_user_invite_perm"))
|
611 |
+
return False
|
612 |
+
|
613 |
+
try:
|
614 |
+
link = await c.export_chat_invite_link(m.chat.id)
|
615 |
+
await m.reply_text(
|
616 |
+
(tlang(m, "admin.invitelink")).format(
|
617 |
+
chat_name=m.chat.id,
|
618 |
+
link=link,
|
619 |
+
),
|
620 |
+
disable_web_page_preview=True,
|
621 |
+
)
|
622 |
+
LOGGER.info(f"{m.from_user.id} exported invite link in {m.chat.id}")
|
623 |
+
except ChatAdminRequired:
|
624 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
625 |
+
except ChatAdminInviteRequired:
|
626 |
+
await m.reply_text(tlang(m, "admin.no_invite_perm"))
|
627 |
+
except RightForbidden:
|
628 |
+
await m.reply_text(tlang(m, "admin.no_user_invite_perm"))
|
629 |
+
except RPCError as ef:
|
630 |
+
await m.reply_text(
|
631 |
+
(tlang(m, "general.some_error")).format(
|
632 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
633 |
+
ef=ef,
|
634 |
+
),
|
635 |
+
)
|
636 |
+
LOGGER.error(ef)
|
637 |
+
LOGGER.error(format_exc())
|
638 |
+
|
639 |
+
return
|
640 |
+
|
641 |
+
|
642 |
+
@Gojo.on_message(command("setgtitle") & admin_filter)
|
643 |
+
async def setgtitle(_, m: Message):
|
644 |
+
user = await m.chat.get_member(m.from_user.id)
|
645 |
+
|
646 |
+
if not user.can_change_info and user.status != "creator":
|
647 |
+
await m.reply_text(
|
648 |
+
"You don't have enough permission to use this command!",
|
649 |
+
)
|
650 |
+
return False
|
651 |
+
|
652 |
+
if len(m.command) < 1:
|
653 |
+
return await m.reply_text("Please read /help for using it!")
|
654 |
+
|
655 |
+
gtit = m.text.split(None, 1)[1]
|
656 |
+
try:
|
657 |
+
await m.chat.set_title(gtit)
|
658 |
+
except Exception as e:
|
659 |
+
return await m.reply_text(f"Error: {e}")
|
660 |
+
return await m.reply_text(
|
661 |
+
f"Successfully Changed Group Title From {m.chat.title} To {gtit}",
|
662 |
+
)
|
663 |
+
|
664 |
+
|
665 |
+
@Gojo.on_message(command("setgdes") & admin_filter)
|
666 |
+
async def setgdes(_, m: Message):
|
667 |
+
|
668 |
+
user = await m.chat.get_member(m.from_user.id)
|
669 |
+
if not user.can_change_info and user.status != "creator":
|
670 |
+
await m.reply_text(
|
671 |
+
"You don't have enough permission to use this command!",
|
672 |
+
)
|
673 |
+
return False
|
674 |
+
|
675 |
+
if len(m.command) < 1:
|
676 |
+
return await m.reply_text("Please read /help for using it!")
|
677 |
+
|
678 |
+
desp = m.text.split(None, 1)[1]
|
679 |
+
try:
|
680 |
+
await m.chat.set_description(desp)
|
681 |
+
except Exception as e:
|
682 |
+
return await m.reply_text(f"Error: {e}")
|
683 |
+
return await m.reply_text(
|
684 |
+
f"Successfully Changed Group description From {m.chat.description} To {desp}",
|
685 |
+
)
|
686 |
+
|
687 |
+
|
688 |
+
@Gojo.on_message(command("title") & admin_filter)
|
689 |
+
async def set_user_title(c: Gojo, m: Message):
|
690 |
+
|
691 |
+
user = await m.chat.get_member(m.from_user.id)
|
692 |
+
if not user.can_promote_members and user.status != "creator":
|
693 |
+
await m.reply_text(
|
694 |
+
"You don't have enough permission to use this command!",
|
695 |
+
)
|
696 |
+
return False
|
697 |
+
|
698 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
699 |
+
return await m.reply_text("To whom??")
|
700 |
+
|
701 |
+
if m.reply_to_message:
|
702 |
+
if len(m.text.split()) >= 2:
|
703 |
+
reason = m.text.split(None, 1)[1]
|
704 |
+
else:
|
705 |
+
if len(m.text.split()) >= 3:
|
706 |
+
reason = m.text.split(None, 2)[2]
|
707 |
+
try:
|
708 |
+
user_id, _, _ = await extract_user(c, m)
|
709 |
+
except Exception:
|
710 |
+
return
|
711 |
+
|
712 |
+
if not user_id:
|
713 |
+
return await m.reply_text("Cannot find user!")
|
714 |
+
|
715 |
+
if user_id == Config.BOT_ID:
|
716 |
+
return await m.reply_text("Huh, why ?")
|
717 |
+
|
718 |
+
if not reason:
|
719 |
+
return await m.reply_text("Read /help please!")
|
720 |
+
|
721 |
+
from_user = await c.get_users(user_id)
|
722 |
+
title = reason
|
723 |
+
try:
|
724 |
+
await c.set_administrator_title(m.chat.id, from_user.id, title)
|
725 |
+
except Exception as e:
|
726 |
+
return await m.reply_text(f"Error: {e}")
|
727 |
+
return await m.reply_text(
|
728 |
+
f"Successfully Changed {from_user.mention}'s Admin Title To {title}",
|
729 |
+
)
|
730 |
+
|
731 |
+
|
732 |
+
@Gojo.on_message(command("setgpic") & admin_filter)
|
733 |
+
async def setgpic(c: Gojo, m: Message):
|
734 |
+
user = await m.chat.get_member(m.from_user.id)
|
735 |
+
if not user.can_change_info and user.status != "creator":
|
736 |
+
await m.reply_text(
|
737 |
+
"You don't have enough permission to use this command!",
|
738 |
+
)
|
739 |
+
return False
|
740 |
+
if not m.reply_to_message:
|
741 |
+
return await m.reply_text("Reply to a photo to set it as chat photo")
|
742 |
+
if not m.reply_to_message.photo and not m.reply_to_message.document:
|
743 |
+
return await m.reply_text("Reply to a photo to set it as chat photo")
|
744 |
+
photo = await m.reply_to_message.download()
|
745 |
+
try:
|
746 |
+
await m.chat.set_photo(photo)
|
747 |
+
except Exception as e:
|
748 |
+
remove(photo)
|
749 |
+
return await m.reply_text(f"Error: {e}")
|
750 |
+
await m.reply_text("Successfully Changed Group Photo!")
|
751 |
+
remove(photo)
|
752 |
+
|
753 |
+
|
754 |
+
__PLUGIN__ = "admin"
|
755 |
+
|
756 |
+
__alt_name__ = [
|
757 |
+
"admins",
|
758 |
+
"promote",
|
759 |
+
"spromote",
|
760 |
+
"demote",
|
761 |
+
"adminlist",
|
762 |
+
"setgpic",
|
763 |
+
"title",
|
764 |
+
"setgtitle",
|
765 |
+
"fullpromote",
|
766 |
+
"invitelink",
|
767 |
+
"setgdes",
|
768 |
+
"zombies",
|
769 |
+
]
|
Powers/plugins/antispam.py
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from datetime import datetime
|
2 |
+
from io import BytesIO
|
3 |
+
from traceback import format_exc
|
4 |
+
|
5 |
+
from pyrogram.errors import MessageTooLong, PeerIdInvalid, UserIsBlocked
|
6 |
+
from pyrogram.types import Message
|
7 |
+
|
8 |
+
from Powers import LOGGER, MESSAGE_DUMP, SUPPORT_GROUP, SUPPORT_STAFF
|
9 |
+
from Powers.bot_class import Gojo
|
10 |
+
from Powers.database.antispam_db import GBan
|
11 |
+
from Powers.database.users_db import Users
|
12 |
+
from Powers.tr_engine import tlang
|
13 |
+
from Powers.utils.clean_file import remove_markdown_and_html
|
14 |
+
from Powers.utils.custom_filters import command
|
15 |
+
from Powers.utils.extract_user import extract_user
|
16 |
+
from Powers.utils.parser import mention_html
|
17 |
+
from Powers.vars import Config
|
18 |
+
|
19 |
+
# Initialize
|
20 |
+
db = GBan()
|
21 |
+
|
22 |
+
|
23 |
+
@Gojo.on_message(command(["gban", "globalban"], sudo_cmd=True))
|
24 |
+
async def gban(c: Gojo, m: Message):
|
25 |
+
if len(m.text.split()) == 1:
|
26 |
+
await m.reply_text(tlang(m, "antispam.gban.how_to"))
|
27 |
+
return
|
28 |
+
|
29 |
+
if len(m.text.split()) == 2 and not m.reply_to_message:
|
30 |
+
await m.reply_text(tlang(m, "antispam.gban.enter_reason"))
|
31 |
+
return
|
32 |
+
|
33 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
34 |
+
|
35 |
+
if m.reply_to_message:
|
36 |
+
gban_reason = m.text.split(None, 1)[1]
|
37 |
+
else:
|
38 |
+
gban_reason = m.text.split(None, 2)[2]
|
39 |
+
|
40 |
+
if user_id in SUPPORT_STAFF:
|
41 |
+
await m.reply_text(tlang(m, "antispam.part_of_support"))
|
42 |
+
return
|
43 |
+
|
44 |
+
if user_id == Config.BOT_ID:
|
45 |
+
await m.reply_text(tlang(m, "antispam.gban.not_self"))
|
46 |
+
return
|
47 |
+
|
48 |
+
if db.check_gban(user_id):
|
49 |
+
db.update_gban_reason(user_id, gban_reason)
|
50 |
+
await m.reply_text(
|
51 |
+
(tlang(m, "antispam.gban.updated_reason")).format(
|
52 |
+
gban_reason=gban_reason,
|
53 |
+
),
|
54 |
+
)
|
55 |
+
return
|
56 |
+
|
57 |
+
db.add_gban(user_id, gban_reason, m.from_user.id)
|
58 |
+
await m.reply_text(
|
59 |
+
(tlang(m, "antispam.gban.added_to_watch")).format(
|
60 |
+
first_name=user_first_name,
|
61 |
+
),
|
62 |
+
)
|
63 |
+
LOGGER.info(f"{m.from_user.id} gbanned {user_id} from {m.chat.id}")
|
64 |
+
log_msg = (tlang(m, "antispam.gban.log_msg")).format(
|
65 |
+
chat_id=m.chat.id,
|
66 |
+
ban_admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
67 |
+
gbanned_user=(await mention_html(user_first_name, user_id)),
|
68 |
+
gban_user_id=user_id,
|
69 |
+
time=(datetime.utcnow().strftime("%H:%M - %d-%m-%Y")),
|
70 |
+
)
|
71 |
+
await c.send_message(MESSAGE_DUMP, log_msg)
|
72 |
+
try:
|
73 |
+
# Send message to user telling that he's gbanned
|
74 |
+
await c.send_message(
|
75 |
+
user_id,
|
76 |
+
(tlang(m, "antispam.gban.user_added_to_watch")).format(
|
77 |
+
gban_reason=gban_reason,
|
78 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
79 |
+
),
|
80 |
+
)
|
81 |
+
except UserIsBlocked:
|
82 |
+
LOGGER.error("Could not send PM Message, user blocked bot")
|
83 |
+
except PeerIdInvalid:
|
84 |
+
LOGGER.error(
|
85 |
+
"Haven't seen this user anywhere, mind forwarding one of their messages to me?",
|
86 |
+
)
|
87 |
+
except Exception as ef: # TO DO: Improve Error Detection
|
88 |
+
LOGGER.error(ef)
|
89 |
+
LOGGER.error(format_exc())
|
90 |
+
return
|
91 |
+
|
92 |
+
|
93 |
+
@Gojo.on_message(
|
94 |
+
command(["ungban", "unglobalban", "globalunban"], sudo_cmd=True),
|
95 |
+
)
|
96 |
+
async def ungban(c: Gojo, m: Message):
|
97 |
+
if len(m.text.split()) == 1:
|
98 |
+
await m.reply_text(tlang(m, "antispam.pass_user_id"))
|
99 |
+
return
|
100 |
+
|
101 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
102 |
+
|
103 |
+
if user_id in SUPPORT_STAFF:
|
104 |
+
await m.reply_text(tlang(m, "antispam.part_of_support"))
|
105 |
+
return
|
106 |
+
|
107 |
+
if user_id == Config.BOT_ID:
|
108 |
+
await m.reply_text(tlang(m, "antispam.ungban.not_self"))
|
109 |
+
return
|
110 |
+
|
111 |
+
if db.check_gban(user_id):
|
112 |
+
db.remove_gban(user_id)
|
113 |
+
await m.reply_text(
|
114 |
+
(tlang(m, "antispam.ungban.removed_from_list")).format(
|
115 |
+
first_name=user_first_name,
|
116 |
+
),
|
117 |
+
)
|
118 |
+
LOGGER.info(f"{m.from_user.id} ungbanned {user_id} from {m.chat.id}")
|
119 |
+
log_msg = (tlang(m, "amtispam.ungban.log_msg")).format(
|
120 |
+
chat_id=m.chat.id,
|
121 |
+
ungban_admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
122 |
+
ungbaned_user=(await mention_html(user_first_name, user_id)),
|
123 |
+
ungbanned_user_id=user_id,
|
124 |
+
time=(datetime.utcnow().strftime("%H:%M - %d-%m-%Y")),
|
125 |
+
)
|
126 |
+
await c.send_message(MESSAGE_DUMP, log_msg)
|
127 |
+
try:
|
128 |
+
# Send message to user telling that he's ungbanned
|
129 |
+
await c.send_message(
|
130 |
+
user_id,
|
131 |
+
(tlang(m, "antispam.ungban.user_removed_from_list")),
|
132 |
+
)
|
133 |
+
except Exception as ef: # TODO: Improve Error Detection
|
134 |
+
LOGGER.error(ef)
|
135 |
+
LOGGER.error(format_exc())
|
136 |
+
return
|
137 |
+
|
138 |
+
await m.reply_text(tlang(m, "antispam.ungban.non_gbanned"))
|
139 |
+
return
|
140 |
+
|
141 |
+
|
142 |
+
@Gojo.on_message(
|
143 |
+
command(["numgbans", "countgbans", "gbancount", "gbanscount"], sudo_cmd=True),
|
144 |
+
)
|
145 |
+
async def gban_count(_, m: Message):
|
146 |
+
await m.reply_text(
|
147 |
+
(tlang(m, "antispam.num_gbans")).format(count=(db.count_gbans())),
|
148 |
+
)
|
149 |
+
LOGGER.info(f"{m.from_user.id} counting gbans in {m.chat.id}")
|
150 |
+
return
|
151 |
+
|
152 |
+
|
153 |
+
@Gojo.on_message(
|
154 |
+
command(["gbanlist", "globalbanlist"], sudo_cmd=True),
|
155 |
+
)
|
156 |
+
async def gban_list(_, m: Message):
|
157 |
+
banned_users = db.load_from_db()
|
158 |
+
|
159 |
+
if not banned_users:
|
160 |
+
await m.reply_text(tlang(m, "antispam.none_gbanned"))
|
161 |
+
return
|
162 |
+
|
163 |
+
banfile = tlang(m, "antispam.here_gbanned_start")
|
164 |
+
for user in banned_users:
|
165 |
+
banfile += f"[x] <b>{Users.get_user_info(user['_id'])['name']}</b> - <code>{user['_id']}</code>\n"
|
166 |
+
if user["reason"]:
|
167 |
+
banfile += f"<b>Reason:</b> {user['reason']}\n"
|
168 |
+
|
169 |
+
try:
|
170 |
+
await m.reply_text(banfile)
|
171 |
+
except MessageTooLong:
|
172 |
+
with BytesIO(str.encode(await remove_markdown_and_html(banfile))) as f:
|
173 |
+
f.name = "gbanlist.txt"
|
174 |
+
await m.reply_document(
|
175 |
+
document=f,
|
176 |
+
caption=tlang(m, "antispam.here_gbanned_start"),
|
177 |
+
)
|
178 |
+
|
179 |
+
LOGGER.info(f"{m.from_user.id} exported gbanlist in {m.chat.id}")
|
180 |
+
|
181 |
+
return
|
Powers/plugins/approve.py
ADDED
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.errors import PeerIdInvalid, RPCError, UserNotParticipant
|
3 |
+
from pyrogram.types import CallbackQuery, ChatPermissions, Message
|
4 |
+
|
5 |
+
from Powers import LOGGER, SUPPORT_GROUP
|
6 |
+
from Powers.bot_class import Gojo
|
7 |
+
from Powers.database.approve_db import Approve
|
8 |
+
from Powers.utils.custom_filters import admin_filter, command, owner_filter
|
9 |
+
from Powers.utils.extract_user import extract_user
|
10 |
+
from Powers.utils.kbhelpers import ikb
|
11 |
+
from Powers.utils.parser import mention_html
|
12 |
+
|
13 |
+
|
14 |
+
@Gojo.on_message(command("approve") & admin_filter)
|
15 |
+
async def approve_user(c: Gojo, m: Message):
|
16 |
+
db = Approve(m.chat.id)
|
17 |
+
|
18 |
+
chat_title = m.chat.title
|
19 |
+
|
20 |
+
try:
|
21 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
22 |
+
except Exception:
|
23 |
+
return
|
24 |
+
|
25 |
+
if not user_id:
|
26 |
+
await m.reply_text(
|
27 |
+
"I don't know who you're talking about, you're going to need to specify a user!",
|
28 |
+
)
|
29 |
+
return
|
30 |
+
try:
|
31 |
+
member = await m.chat.get_member(user_id)
|
32 |
+
except UserNotParticipant:
|
33 |
+
await m.reply_text("This user is not in this chat!")
|
34 |
+
return
|
35 |
+
|
36 |
+
except RPCError as ef:
|
37 |
+
await m.reply_text(
|
38 |
+
f"<b>Error</b>: <code>{ef}</code>\nReport it to @{SUPPORT_GROUP}",
|
39 |
+
)
|
40 |
+
return
|
41 |
+
if member.status in ("administrator", "creator"):
|
42 |
+
await m.reply_text(
|
43 |
+
"User is already admin - blacklists and locks already don't apply to them.",
|
44 |
+
)
|
45 |
+
return
|
46 |
+
already_approved = db.check_approve(user_id)
|
47 |
+
if already_approved:
|
48 |
+
await m.reply_text(
|
49 |
+
f"{(await mention_html(user_first_name, user_id))} is already approved in {chat_title}",
|
50 |
+
)
|
51 |
+
return
|
52 |
+
db.add_approve(user_id, user_first_name)
|
53 |
+
LOGGER.info(f"{user_id} approved by {m.from_user.id} in {m.chat.id}")
|
54 |
+
|
55 |
+
# Allow all permissions
|
56 |
+
try:
|
57 |
+
await m.chat.unban_member(user_id=user_id)
|
58 |
+
except RPCError as g:
|
59 |
+
await m.reply_text(f"Error: {g}")
|
60 |
+
return
|
61 |
+
await m.reply_text(
|
62 |
+
(
|
63 |
+
f"{(await mention_html(user_first_name, user_id))} has been approved in {chat_title}!\n"
|
64 |
+
"They will now be ignored by blacklists, locks and antiflood!"
|
65 |
+
),
|
66 |
+
)
|
67 |
+
return
|
68 |
+
|
69 |
+
|
70 |
+
@Gojo.on_message(
|
71 |
+
command(["disapprove", "unapprove"]) & admin_filter,
|
72 |
+
)
|
73 |
+
async def disapprove_user(c: Gojo, m: Message):
|
74 |
+
db = Approve(m.chat.id)
|
75 |
+
|
76 |
+
chat_title = m.chat.title
|
77 |
+
try:
|
78 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
79 |
+
except Exception:
|
80 |
+
return
|
81 |
+
already_approved = db.check_approve(user_id)
|
82 |
+
if not user_id:
|
83 |
+
await m.reply_text(
|
84 |
+
"I don't know who you're talking about, you're going to need to specify a user!",
|
85 |
+
)
|
86 |
+
return
|
87 |
+
try:
|
88 |
+
member = await m.chat.get_member(user_id)
|
89 |
+
except UserNotParticipant:
|
90 |
+
if already_approved: # If user is approved and not in chat, unapprove them.
|
91 |
+
db.remove_approve(user_id)
|
92 |
+
LOGGER.info(f"{user_id} disapproved in {m.chat.id} as UserNotParticipant")
|
93 |
+
await m.reply_text("This user is not in this chat, unapproved them.")
|
94 |
+
return
|
95 |
+
except RPCError as ef:
|
96 |
+
await m.reply_text(
|
97 |
+
f"<b>Error</b>: <code>{ef}</code>\nReport it to @{SUPPORT_GROUP}",
|
98 |
+
)
|
99 |
+
return
|
100 |
+
|
101 |
+
if member.status in ("administrator", "creator"):
|
102 |
+
await m.reply_text("This user is an admin, they can't be disapproved.")
|
103 |
+
return
|
104 |
+
|
105 |
+
if not already_approved:
|
106 |
+
await m.reply_text(
|
107 |
+
f"{(await mention_html(user_first_name, user_id))} isn't approved yet!",
|
108 |
+
)
|
109 |
+
return
|
110 |
+
|
111 |
+
db.remove_approve(user_id)
|
112 |
+
LOGGER.info(f"{user_id} disapproved by {m.from_user.id} in {m.chat.id}")
|
113 |
+
|
114 |
+
# Set permission same as of current user by fetching them from chat!
|
115 |
+
await m.chat.restrict_member(
|
116 |
+
user_id=user_id,
|
117 |
+
permissions=m.chat.permissions,
|
118 |
+
)
|
119 |
+
|
120 |
+
await m.reply_text(
|
121 |
+
f"{(await mention_html(user_first_name, user_id))} is no longer approved in {chat_title}.",
|
122 |
+
)
|
123 |
+
return
|
124 |
+
|
125 |
+
|
126 |
+
@Gojo.on_message(command("approved") & admin_filter)
|
127 |
+
async def check_approved(_, m: Message):
|
128 |
+
db = Approve(m.chat.id)
|
129 |
+
|
130 |
+
chat = m.chat
|
131 |
+
chat_title = chat.title
|
132 |
+
msg = "The following users are approved:\n"
|
133 |
+
approved_people = db.list_approved()
|
134 |
+
|
135 |
+
if not approved_people:
|
136 |
+
await m.reply_text(f"No users are approved in {chat_title}.")
|
137 |
+
return
|
138 |
+
|
139 |
+
for user_id, user_name in approved_people.items():
|
140 |
+
try:
|
141 |
+
await chat.get_member(user_id) # Check if user is in chat or not
|
142 |
+
except UserNotParticipant:
|
143 |
+
db.remove_approve(user_id)
|
144 |
+
continue
|
145 |
+
except PeerIdInvalid:
|
146 |
+
pass
|
147 |
+
msg += f"- `{user_id}`: {user_name}\n"
|
148 |
+
await m.reply_text(msg)
|
149 |
+
LOGGER.info(f"{m.from_user.id} checking approved users in {m.chat.id}")
|
150 |
+
return
|
151 |
+
|
152 |
+
|
153 |
+
@Gojo.on_message(command("approval") & filters.group)
|
154 |
+
async def check_approval(c: Gojo, m: Message):
|
155 |
+
db = Approve(m.chat.id)
|
156 |
+
|
157 |
+
try:
|
158 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
159 |
+
except Exception:
|
160 |
+
return
|
161 |
+
check_approve = db.check_approve(user_id)
|
162 |
+
LOGGER.info(f"{m.from_user.id} checking approval of {user_id} in {m.chat.id}")
|
163 |
+
|
164 |
+
if not user_id:
|
165 |
+
await m.reply_text(
|
166 |
+
"I don't know who you're talking about, you're going to need to specify a user!",
|
167 |
+
)
|
168 |
+
return
|
169 |
+
if check_approve:
|
170 |
+
await m.reply_text(
|
171 |
+
f"{(await mention_html(user_first_name, user_id))} is an approved user. Locks, antiflood, and blacklists won't apply to them.",
|
172 |
+
)
|
173 |
+
else:
|
174 |
+
await m.reply_text(
|
175 |
+
f"{(await mention_html(user_first_name, user_id))} is not an approved user. They are affected by normal commands.",
|
176 |
+
)
|
177 |
+
return
|
178 |
+
|
179 |
+
|
180 |
+
@Gojo.on_message(
|
181 |
+
command("unapproveall") & filters.group & owner_filter,
|
182 |
+
)
|
183 |
+
async def unapproveall_users(_, m: Message):
|
184 |
+
db = Approve(m.chat.id)
|
185 |
+
|
186 |
+
all_approved = db.list_approved()
|
187 |
+
if not all_approved:
|
188 |
+
await m.reply_text("No one is approved in this chat.")
|
189 |
+
return
|
190 |
+
|
191 |
+
await m.reply_text(
|
192 |
+
"Are you sure you want to remove everyone who is approved in this chat?",
|
193 |
+
reply_markup=ikb(
|
194 |
+
[[("⚠️ Confirm", "unapprove_all"), ("❌ Cancel", "close_admin")]],
|
195 |
+
),
|
196 |
+
)
|
197 |
+
return
|
198 |
+
|
199 |
+
|
200 |
+
@Gojo.on_callback_query(filters.regex("^unapprove_all$"))
|
201 |
+
async def unapproveall_callback(_, q: CallbackQuery):
|
202 |
+
user_id = q.from_user.id
|
203 |
+
db = Approve(q.message.chat.id)
|
204 |
+
approved_people = db.list_approved()
|
205 |
+
user_status = (await q.message.chat.get_member(user_id)).status
|
206 |
+
if user_status not in {"creator", "administrator"}:
|
207 |
+
await q.answer(
|
208 |
+
"You're not even an admin, don't try this explosive shit!",
|
209 |
+
show_alert=True,
|
210 |
+
)
|
211 |
+
return
|
212 |
+
if user_status != "creator":
|
213 |
+
await q.answer(
|
214 |
+
"You're just an admin, not owner\nStay in your limits!",
|
215 |
+
show_alert=True,
|
216 |
+
)
|
217 |
+
return
|
218 |
+
db.unapprove_all()
|
219 |
+
for i in approved_people:
|
220 |
+
await q.message.chat.restrict_member(
|
221 |
+
user_id=i[0],
|
222 |
+
permissions=q.message.chat.permissions,
|
223 |
+
)
|
224 |
+
await q.message.delete()
|
225 |
+
LOGGER.info(f"{user_id} disapproved all users in {q.message.chat.id}")
|
226 |
+
await q.answer("Disapproved all users!", show_alert=True)
|
227 |
+
return
|
228 |
+
|
229 |
+
|
230 |
+
__PLUGIN__ = "approve"
|
231 |
+
|
232 |
+
_DISABLE_CMDS_ = ["approval"]
|
233 |
+
|
234 |
+
__alt_name__ = ["approved"]
|
Powers/plugins/bans.py
ADDED
@@ -0,0 +1,901 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from traceback import format_exc
|
2 |
+
import random
|
3 |
+
|
4 |
+
from pyrogram.errors import (
|
5 |
+
ChatAdminRequired,
|
6 |
+
PeerIdInvalid,
|
7 |
+
RightForbidden,
|
8 |
+
RPCError,
|
9 |
+
UserAdminInvalid,
|
10 |
+
)
|
11 |
+
from pyrogram.filters import regex
|
12 |
+
from pyrogram.types import (
|
13 |
+
CallbackQuery,
|
14 |
+
InlineKeyboardButton,
|
15 |
+
InlineKeyboardMarkup,
|
16 |
+
Message,
|
17 |
+
)
|
18 |
+
|
19 |
+
from Powers import LOGGER, OWNER_ID, SUPPORT_GROUP, SUPPORT_STAFF
|
20 |
+
from Powers.bot_class import Gojo
|
21 |
+
from Powers.utils.fun_strings import BAN_GIFS, KICK_GIFS
|
22 |
+
from Powers.tr_engine import tlang
|
23 |
+
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
24 |
+
from Powers.utils.custom_filters import command, restrict_filter
|
25 |
+
from Powers.utils.extract_user import extract_user
|
26 |
+
from Powers.utils.parser import mention_html
|
27 |
+
from Powers.utils.string import extract_time
|
28 |
+
from Powers.vars import Config
|
29 |
+
|
30 |
+
|
31 |
+
BAN_MEDIA = random.choice(BAN_GIFS)
|
32 |
+
KICK_MEDIA = random.choice(KICK_GIFS)
|
33 |
+
|
34 |
+
@Gojo.on_message(command("tban") & restrict_filter)
|
35 |
+
async def tban_usr(c: Gojo, m: Message):
|
36 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
37 |
+
await m.reply_text(tlang(m, "Provide me an user id or username or atleast reply to user"))
|
38 |
+
await m.stop_propagation()
|
39 |
+
|
40 |
+
try:
|
41 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
42 |
+
except Exception:
|
43 |
+
return
|
44 |
+
|
45 |
+
if not user_id:
|
46 |
+
await m.reply_text("Cannot find user to ban")
|
47 |
+
return
|
48 |
+
if user_id == Config.BOT_ID:
|
49 |
+
await m.reply_text("WTF?? Why would I ban myself?")
|
50 |
+
await m.stop_propagation()
|
51 |
+
|
52 |
+
if user_id in SUPPORT_STAFF:
|
53 |
+
await m.reply_text(tlang(m, "If I will ban this user....then who will going to manage me?"))
|
54 |
+
LOGGER.info(
|
55 |
+
f"{m.from_user.id} trying to ban {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
56 |
+
)
|
57 |
+
await m.stop_propagation()
|
58 |
+
|
59 |
+
r_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id
|
60 |
+
|
61 |
+
if m.reply_to_message and len(m.text.split()) >= 2:
|
62 |
+
reason = m.text.split(None, 2)[1]
|
63 |
+
elif not m.reply_to_message and len(m.text.split()) >= 3:
|
64 |
+
reason = m.text.split(None, 2)[2]
|
65 |
+
else:
|
66 |
+
await m.reply_text("Read /help !!")
|
67 |
+
return
|
68 |
+
|
69 |
+
if not reason:
|
70 |
+
await m.reply_text("You haven't specified a time to ban this user for!")
|
71 |
+
return
|
72 |
+
|
73 |
+
split_reason = reason.split(None, 1)
|
74 |
+
time_val = split_reason[0].lower()
|
75 |
+
reason = split_reason[1] if len(split_reason) > 1 else ""
|
76 |
+
|
77 |
+
bantime = await extract_time(m, time_val)
|
78 |
+
|
79 |
+
if not bantime:
|
80 |
+
return
|
81 |
+
|
82 |
+
try:
|
83 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
84 |
+
except KeyError:
|
85 |
+
admins_group = await admin_cache_reload(m, "ban")
|
86 |
+
|
87 |
+
if user_id in admins_group:
|
88 |
+
await m.reply_text(tlang(m, "I am not going to ban an admin"))
|
89 |
+
await m.stop_propagation()
|
90 |
+
|
91 |
+
try:
|
92 |
+
LOGGER.info(f"{m.from_user.id} tbanned {user_id} in {m.chat.id}")
|
93 |
+
await m.chat.ban_member(user_id, until_date=int(bantime))
|
94 |
+
txt = (tlang(m, "Successfully banned the user")).format(
|
95 |
+
admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
96 |
+
banned=(await mention_html(user_first_name, user_id)),
|
97 |
+
chat_title=m.chat.title,
|
98 |
+
)
|
99 |
+
txt += f"\n<b>Reason</b>: {reason}" if reason else ""
|
100 |
+
keyboard = InlineKeyboardMarkup(
|
101 |
+
[
|
102 |
+
[
|
103 |
+
InlineKeyboardButton(
|
104 |
+
"Unban",
|
105 |
+
callback_data=f"unban_={user_id}",
|
106 |
+
),
|
107 |
+
],
|
108 |
+
],
|
109 |
+
)
|
110 |
+
await m.reply_animation(reply_to_message_id = r_id, animation = BAN_MEDIA, caption = txt, reply_markup=keyboard, parse_mode="html")
|
111 |
+
# await m.reply_text(txt, reply_markup=keyboard, reply_to_message_id=r_id)
|
112 |
+
except ChatAdminRequired:
|
113 |
+
await m.reply_text(tlang(m, "You are not an admin here so stay in your limit bud...."))
|
114 |
+
except PeerIdInvalid:
|
115 |
+
await m.reply_text(
|
116 |
+
"I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?",
|
117 |
+
)
|
118 |
+
except UserAdminInvalid:
|
119 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
120 |
+
except RightForbidden:
|
121 |
+
await m.reply_text(tlang(m, tlang(m, "I don't have rights to ban members.....")))
|
122 |
+
except RPCError as ef:
|
123 |
+
await m.reply_text(
|
124 |
+
(tlang(m, "It's a general error contact support staff to know more...")).format(
|
125 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
126 |
+
ef=ef,
|
127 |
+
),
|
128 |
+
)
|
129 |
+
LOGGER.error(ef)
|
130 |
+
LOGGER.error(format_exc())
|
131 |
+
return
|
132 |
+
|
133 |
+
|
134 |
+
@Gojo.on_message(command("stban") & restrict_filter)
|
135 |
+
async def stban_usr(c: Gojo, m: Message):
|
136 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
137 |
+
await m.reply_text(tlang(m, "Provide me an user id or username or atleast reply to user"))
|
138 |
+
await m.stop_propagation()
|
139 |
+
|
140 |
+
try:
|
141 |
+
user_id, _, _ = await extract_user(c, m)
|
142 |
+
except Exception:
|
143 |
+
return
|
144 |
+
|
145 |
+
if not user_id:
|
146 |
+
await m.reply_text("Cannot find user to ban")
|
147 |
+
return
|
148 |
+
if user_id == Config.BOT_ID:
|
149 |
+
await m.reply_text("What the heck? Why would I ban myself?")
|
150 |
+
await m.stop_propagation()
|
151 |
+
|
152 |
+
if user_id in SUPPORT_STAFF:
|
153 |
+
await m.reply_text(tlang(m, "I am not going to ban one of my support staff"))
|
154 |
+
LOGGER.info(
|
155 |
+
f"{m.from_user.id} trying to ban {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
156 |
+
)
|
157 |
+
await m.stop_propagation()
|
158 |
+
|
159 |
+
if m.reply_to_message and len(m.text.split()) >= 2:
|
160 |
+
reason = m.text.split(None, 2)[1]
|
161 |
+
elif not m.reply_to_message and len(m.text.split()) >= 3:
|
162 |
+
reason = m.text.split(None, 2)[2]
|
163 |
+
else:
|
164 |
+
await m.reply_text("Read /help !!")
|
165 |
+
return
|
166 |
+
|
167 |
+
if not reason:
|
168 |
+
await m.reply_text("You haven't specified a time to ban this user for!")
|
169 |
+
return
|
170 |
+
|
171 |
+
split_reason = reason.split(None, 1)
|
172 |
+
time_val = split_reason[0].lower()
|
173 |
+
reason = split_reason[1] if len(split_reason) > 1 else ""
|
174 |
+
|
175 |
+
bantime = await extract_time(m, time_val)
|
176 |
+
|
177 |
+
if not bantime:
|
178 |
+
return
|
179 |
+
|
180 |
+
try:
|
181 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
182 |
+
except KeyError:
|
183 |
+
admins_group = await admin_cache_reload(m, "ban")
|
184 |
+
|
185 |
+
if user_id in admins_group:
|
186 |
+
await m.reply_text(tlang(m, "I am not going to ban an admin..."))
|
187 |
+
await m.stop_propagation()
|
188 |
+
|
189 |
+
try:
|
190 |
+
LOGGER.info(f"{m.from_user.id} stbanned {user_id} in {m.chat.id}")
|
191 |
+
await m.chat.ban_member(user_id, until_date=int(bantime))
|
192 |
+
await m.delete()
|
193 |
+
if m.reply_to_message:
|
194 |
+
await m.reply_to_message.delete()
|
195 |
+
return
|
196 |
+
return
|
197 |
+
except ChatAdminRequired:
|
198 |
+
await m.reply_text(tlang(m, "Stay in your limits....."))
|
199 |
+
except PeerIdInvalid:
|
200 |
+
await m.reply_text(
|
201 |
+
"I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?",
|
202 |
+
)
|
203 |
+
except UserAdminInvalid:
|
204 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
205 |
+
except RightForbidden:
|
206 |
+
await m.reply_text(tlang(m, tlang(m, "I don't have power to ban....")))
|
207 |
+
except RPCError as ef:
|
208 |
+
await m.reply_text(
|
209 |
+
(tlang(m, "general.some_error")).format(
|
210 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
211 |
+
ef=ef,
|
212 |
+
),
|
213 |
+
)
|
214 |
+
LOGGER.error(ef)
|
215 |
+
LOGGER.error(format_exc())
|
216 |
+
return
|
217 |
+
|
218 |
+
|
219 |
+
@Gojo.on_message(command("dtban") & restrict_filter)
|
220 |
+
async def dtban_usr(c: Gojo, m: Message):
|
221 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
222 |
+
await m.reply_text(tlang(m, "admin.ban.no_target"))
|
223 |
+
await m.stop_propagation()
|
224 |
+
|
225 |
+
if not m.reply_to_message:
|
226 |
+
await m.reply_text(
|
227 |
+
"Reply to a message with this command to temp ban and delete the message.",
|
228 |
+
)
|
229 |
+
await m.stop_propagation()
|
230 |
+
|
231 |
+
user_id = m.reply_to_message.from_user.id
|
232 |
+
user_first_name = m.reply_to_message.from_user.first_name
|
233 |
+
|
234 |
+
if not user_id:
|
235 |
+
await m.reply_text("Cannot find user to ban")
|
236 |
+
return
|
237 |
+
if user_id == Config.BOT_ID:
|
238 |
+
await m.reply_text("Huh, why would I ban myself?")
|
239 |
+
await m.stop_propagation()
|
240 |
+
|
241 |
+
if user_id in SUPPORT_STAFF:
|
242 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
243 |
+
LOGGER.info(
|
244 |
+
f"{m.from_user.id} trying to ban {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
245 |
+
)
|
246 |
+
await m.stop_propagation()
|
247 |
+
|
248 |
+
if m.reply_to_message and len(m.text.split()) >= 2:
|
249 |
+
reason = m.text.split(None, 2)[1]
|
250 |
+
elif not m.reply_to_message and len(m.text.split()) >= 3:
|
251 |
+
reason = m.text.split(None, 2)[2]
|
252 |
+
else:
|
253 |
+
await m.reply_text("Read /help !!")
|
254 |
+
return
|
255 |
+
|
256 |
+
if not reason:
|
257 |
+
await m.reply_text("You haven't specified a time to ban this user for!")
|
258 |
+
return
|
259 |
+
|
260 |
+
split_reason = reason.split(None, 1)
|
261 |
+
time_val = split_reason[0].lower()
|
262 |
+
reason = split_reason[1] if len(split_reason) > 1 else ""
|
263 |
+
|
264 |
+
bantime = await extract_time(m, time_val)
|
265 |
+
|
266 |
+
if not bantime:
|
267 |
+
return
|
268 |
+
|
269 |
+
try:
|
270 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
271 |
+
except KeyError:
|
272 |
+
admins_group = await admin_cache_reload(m, "ban")
|
273 |
+
|
274 |
+
if user_id in admins_group:
|
275 |
+
await m.reply_text(tlang(m, "admin.ban.admin_cannot_ban"))
|
276 |
+
await m.stop_propagation()
|
277 |
+
|
278 |
+
try:
|
279 |
+
LOGGER.info(f"{m.from_user.id} dtbanned {user_id} in {m.chat.id}")
|
280 |
+
await m.chat.ban_member(user_id, until_date=int(bantime))
|
281 |
+
await m.reply_to_message.delete()
|
282 |
+
txt = (tlang(m, "admin.ban.banned_user")).format(
|
283 |
+
admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
284 |
+
banned=(await mention_html(user_first_name, user_id)),
|
285 |
+
chat_title=m.chat.title,
|
286 |
+
)
|
287 |
+
txt += f"\n<b>Reason</b>: {reason}" if reason else ""
|
288 |
+
keyboard = InlineKeyboardMarkup(
|
289 |
+
[
|
290 |
+
[
|
291 |
+
InlineKeyboardButton(
|
292 |
+
"Unban",
|
293 |
+
callback_data=f"unban_={user_id}",
|
294 |
+
),
|
295 |
+
],
|
296 |
+
],
|
297 |
+
)
|
298 |
+
await c.send_animation(chat_id = m.chat.id, animation = BAN_MEDIA, caption = txt, reply_markup=keyboard, parse_mode="html")
|
299 |
+
# await c.send_message(m.chat.id, txt, reply_markup=keyboard)
|
300 |
+
except ChatAdminRequired:
|
301 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
302 |
+
except PeerIdInvalid:
|
303 |
+
await m.reply_text(
|
304 |
+
"I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?",
|
305 |
+
)
|
306 |
+
except UserAdminInvalid:
|
307 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
308 |
+
except RightForbidden:
|
309 |
+
await m.reply_text(tlang(m, tlang(m, "admin.ban.bot_no_right")))
|
310 |
+
except RPCError as ef:
|
311 |
+
await m.reply_text(
|
312 |
+
(tlang(m, "general.some_error")).format(
|
313 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
314 |
+
ef=ef,
|
315 |
+
),
|
316 |
+
)
|
317 |
+
LOGGER.error(ef)
|
318 |
+
LOGGER.error(format_exc())
|
319 |
+
return
|
320 |
+
|
321 |
+
|
322 |
+
@Gojo.on_message(command("kick") & restrict_filter)
|
323 |
+
async def kick_usr(c: Gojo, m: Message):
|
324 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
325 |
+
await m.reply_text(tlang(m, "admin.kick.no_target"))
|
326 |
+
return
|
327 |
+
|
328 |
+
reason = None
|
329 |
+
|
330 |
+
if m.reply_to_message:
|
331 |
+
r_id = m.reply_to_message.message_id
|
332 |
+
if len(m.text.split()) >= 2:
|
333 |
+
reason = m.text.split(None, 1)[1]
|
334 |
+
else:
|
335 |
+
r_id = m.message_id
|
336 |
+
if len(m.text.split()) >= 3:
|
337 |
+
reason = m.text.split(None, 2)[2]
|
338 |
+
try:
|
339 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
340 |
+
except Exception:
|
341 |
+
return
|
342 |
+
|
343 |
+
if not user_id:
|
344 |
+
await m.reply_text("Cannot find user to kick")
|
345 |
+
return
|
346 |
+
|
347 |
+
if user_id == Config.BOT_ID:
|
348 |
+
await m.reply_text("Huh, why would I kick myself?")
|
349 |
+
await m.stop_propagation()
|
350 |
+
|
351 |
+
if user_id in SUPPORT_STAFF:
|
352 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
353 |
+
LOGGER.info(
|
354 |
+
f"{m.from_user.id} trying to kick {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
355 |
+
)
|
356 |
+
await m.stop_propagation()
|
357 |
+
|
358 |
+
try:
|
359 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
360 |
+
except KeyError:
|
361 |
+
admins_group = await admin_cache_reload(m, "kick")
|
362 |
+
|
363 |
+
if user_id in admins_group:
|
364 |
+
await m.reply_text(tlang(m, "admin.kick.admin_cannot_kick"))
|
365 |
+
await m.stop_propagation()
|
366 |
+
|
367 |
+
try:
|
368 |
+
LOGGER.info(f"{m.from_user.id} kicked {user_id} in {m.chat.id}")
|
369 |
+
await m.chat.ban_member(user_id)
|
370 |
+
txt = (tlang(m, "admin.kick.kicked_user")).format(
|
371 |
+
admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
372 |
+
kicked=(await mention_html(user_first_name, user_id)),
|
373 |
+
chat_title=m.chat.title,
|
374 |
+
)
|
375 |
+
txt += f"\n<b>Reason</b>: {reason}" if reason else ""
|
376 |
+
# await m.reply_text(txt, reply_to_message_id=r_id)
|
377 |
+
await m.reply_animation(reply_to_message_id = r_id, animation = KICK_MEDIA, caption = txt, parse_mode="html")
|
378 |
+
await m.chat.unban_member(user_id)
|
379 |
+
except ChatAdminRequired:
|
380 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
381 |
+
except PeerIdInvalid:
|
382 |
+
await m.reply_text(
|
383 |
+
"I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?",
|
384 |
+
)
|
385 |
+
except UserAdminInvalid:
|
386 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
387 |
+
except RightForbidden:
|
388 |
+
await m.reply_text(tlang(m, "admin.kick.bot_no_right"))
|
389 |
+
except RPCError as ef:
|
390 |
+
await m.reply_text(
|
391 |
+
(tlang(m, "general.some_error")).format(
|
392 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
393 |
+
ef=ef,
|
394 |
+
),
|
395 |
+
)
|
396 |
+
LOGGER.error(ef)
|
397 |
+
LOGGER.error(format_exc())
|
398 |
+
|
399 |
+
return
|
400 |
+
|
401 |
+
|
402 |
+
@Gojo.on_message(command("skick") & restrict_filter)
|
403 |
+
async def skick_usr(c: Gojo, m: Message):
|
404 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
405 |
+
await m.reply_text(tlang(m, "admin.kick.no_target"))
|
406 |
+
return
|
407 |
+
|
408 |
+
try:
|
409 |
+
user_id, _, _ = await extract_user(c, m)
|
410 |
+
except Exception:
|
411 |
+
return
|
412 |
+
|
413 |
+
if not user_id:
|
414 |
+
await m.reply_text("Cannot find user to kick")
|
415 |
+
return
|
416 |
+
|
417 |
+
if user_id == Config.BOT_ID:
|
418 |
+
await m.reply_text("Huh, why would I kick myself?")
|
419 |
+
await m.stop_propagation()
|
420 |
+
|
421 |
+
if user_id in SUPPORT_STAFF:
|
422 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
423 |
+
LOGGER.info(
|
424 |
+
f"{m.from_user.id} trying to skick {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
425 |
+
)
|
426 |
+
await m.stop_propagation()
|
427 |
+
|
428 |
+
try:
|
429 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
430 |
+
except KeyError:
|
431 |
+
admins_group = await admin_cache_reload(m, "kick")
|
432 |
+
|
433 |
+
if user_id in admins_group:
|
434 |
+
await m.reply_text(tlang(m, "admin.kick.admin_cannot_kick"))
|
435 |
+
await m.stop_propagation()
|
436 |
+
|
437 |
+
try:
|
438 |
+
LOGGER.info(f"{m.from_user.id} skicked {user_id} in {m.chat.id}")
|
439 |
+
await m.chat.ban_member(user_id)
|
440 |
+
await m.delete()
|
441 |
+
if m.reply_to_message:
|
442 |
+
await m.reply_to_message.delete()
|
443 |
+
await m.chat.unban_member(user_id)
|
444 |
+
except ChatAdminRequired:
|
445 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
446 |
+
except PeerIdInvalid:
|
447 |
+
await m.reply_text(
|
448 |
+
"I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?",
|
449 |
+
)
|
450 |
+
except UserAdminInvalid:
|
451 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
452 |
+
except RightForbidden:
|
453 |
+
await m.reply_text(tlang(m, "admin.kick.bot_no_right"))
|
454 |
+
except RPCError as ef:
|
455 |
+
await m.reply_text(
|
456 |
+
(tlang(m, "general.some_error")).format(
|
457 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
458 |
+
ef=ef,
|
459 |
+
),
|
460 |
+
)
|
461 |
+
LOGGER.error(ef)
|
462 |
+
LOGGER.error(format_exc())
|
463 |
+
|
464 |
+
return
|
465 |
+
|
466 |
+
|
467 |
+
@Gojo.on_message(command("dkick") & restrict_filter)
|
468 |
+
async def dkick_usr(c: Gojo, m: Message):
|
469 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
470 |
+
await m.reply_text(tlang(m, "admin.kick.no_target"))
|
471 |
+
return
|
472 |
+
if not m.reply_to_message:
|
473 |
+
return await m.reply_text("Reply to a message to delete it and kick the user!")
|
474 |
+
|
475 |
+
reason = None
|
476 |
+
|
477 |
+
user_id = m.reply_to_message.from_user.id
|
478 |
+
user_first_name = m.reply_to_message.from_user.first_name
|
479 |
+
|
480 |
+
if not user_id:
|
481 |
+
await m.reply_text("Cannot find user to kick")
|
482 |
+
return
|
483 |
+
|
484 |
+
if user_id == Config.BOT_ID:
|
485 |
+
await m.reply_text("Huh, why would I kick myself?")
|
486 |
+
await m.stop_propagation()
|
487 |
+
|
488 |
+
if user_id in SUPPORT_STAFF:
|
489 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
490 |
+
LOGGER.info(
|
491 |
+
f"{m.from_user.id} trying to dkick {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
492 |
+
)
|
493 |
+
await m.stop_propagation()
|
494 |
+
|
495 |
+
try:
|
496 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
497 |
+
except KeyError:
|
498 |
+
admins_group = await admin_cache_reload(m, "kick")
|
499 |
+
|
500 |
+
if user_id in admins_group:
|
501 |
+
await m.reply_text(tlang(m, "admin.kick.admin_cannot_kick"))
|
502 |
+
await m.stop_propagation()
|
503 |
+
|
504 |
+
try:
|
505 |
+
LOGGER.info(f"{m.from_user.id} dkicked {user_id} in {m.chat.id}")
|
506 |
+
await m.reply_to_message.delete()
|
507 |
+
await m.chat.ban_member(user_id)
|
508 |
+
txt = (tlang(m, "admin.kick.kicked_user")).format(
|
509 |
+
admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
510 |
+
kicked=(await mention_html(user_first_name, user_id)),
|
511 |
+
chat_title=m.chat.title,
|
512 |
+
)
|
513 |
+
txt += f"\n<b>Reason</b>: {reason}" if reason else ""
|
514 |
+
await c.send_message(m.chat.id, txt)
|
515 |
+
await c.send_animation(chat_id = m.chat.id, animation = KICK_MEDIA, caption = txt, parse_mode="html")
|
516 |
+
await m.chat.unban_member(user_id)
|
517 |
+
except ChatAdminRequired:
|
518 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
519 |
+
except PeerIdInvalid:
|
520 |
+
await m.reply_text(
|
521 |
+
"I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?",
|
522 |
+
)
|
523 |
+
except UserAdminInvalid:
|
524 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
525 |
+
except RightForbidden:
|
526 |
+
await m.reply_text(tlang(m, "admin.kick.bot_no_right"))
|
527 |
+
except RPCError as ef:
|
528 |
+
await m.reply_text(
|
529 |
+
(tlang(m, "general.some_error")).format(
|
530 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
531 |
+
ef=ef,
|
532 |
+
),
|
533 |
+
)
|
534 |
+
LOGGER.error(ef)
|
535 |
+
LOGGER.error(format_exc())
|
536 |
+
|
537 |
+
return
|
538 |
+
|
539 |
+
|
540 |
+
@Gojo.on_message(command("unban") & restrict_filter)
|
541 |
+
async def unban_usr(c: Gojo, m: Message):
|
542 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
543 |
+
await m.reply_text(tlang(m, "admin.unban.no_target"))
|
544 |
+
await m.stop_propagation()
|
545 |
+
|
546 |
+
if m.reply_to_message and not m.reply_to_message.from_user:
|
547 |
+
user_id, user_first_name = (
|
548 |
+
m.reply_to_message.sender_chat.id,
|
549 |
+
m.reply_to_message.sender_chat.title,
|
550 |
+
)
|
551 |
+
else:
|
552 |
+
try:
|
553 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
554 |
+
except Exception:
|
555 |
+
return
|
556 |
+
|
557 |
+
if m.reply_to_message and len(m.text.split()) >= 2:
|
558 |
+
reason = m.text.split(None, 2)[1]
|
559 |
+
elif not m.reply_to_message and len(m.text.split()) >= 3:
|
560 |
+
reason = m.text.split(None, 2)[2]
|
561 |
+
else:
|
562 |
+
reason = None
|
563 |
+
|
564 |
+
try:
|
565 |
+
await m.chat.unban_member(user_id)
|
566 |
+
txt = (tlang(m, "admin.unban.unbanned_user")).format(
|
567 |
+
admin=m.from_user.mention,
|
568 |
+
unbanned=(await mention_html(user_first_name, user_id)),
|
569 |
+
chat_title=m.chat.title,
|
570 |
+
)
|
571 |
+
txt += f"\n<b>Reason</b>: {reason}" if reason else ""
|
572 |
+
await m.reply_text(txt)
|
573 |
+
except ChatAdminRequired:
|
574 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
575 |
+
except RightForbidden:
|
576 |
+
await m.reply_text(tlang(m, tlang(m, "admin.unban.bot_no_right")))
|
577 |
+
except RPCError as ef:
|
578 |
+
await m.reply_text(
|
579 |
+
(tlang(m, "general.some_error")).format(
|
580 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
581 |
+
ef=ef,
|
582 |
+
),
|
583 |
+
)
|
584 |
+
LOGGER.error(ef)
|
585 |
+
LOGGER.error(format_exc())
|
586 |
+
|
587 |
+
return
|
588 |
+
|
589 |
+
|
590 |
+
@Gojo.on_message(command("sban") & restrict_filter)
|
591 |
+
async def sban_usr(c: Gojo, m: Message):
|
592 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
593 |
+
await m.reply_text(tlang(m, "admin.ban.no_target"))
|
594 |
+
await m.stop_propagation()
|
595 |
+
|
596 |
+
if m.reply_to_message and not m.reply_to_message.from_user:
|
597 |
+
user_id = m.reply_to_message.sender_chat.id
|
598 |
+
else:
|
599 |
+
try:
|
600 |
+
user_id, _, _ = await extract_user(c, m)
|
601 |
+
except Exception:
|
602 |
+
return
|
603 |
+
|
604 |
+
if not user_id:
|
605 |
+
await m.reply_text("Cannot find user to ban")
|
606 |
+
return
|
607 |
+
if user_id == m.chat.id:
|
608 |
+
await m.reply_text("That's an admin!")
|
609 |
+
await m.stop_propagation()
|
610 |
+
if user_id == Config.BOT_ID:
|
611 |
+
await m.reply_text("Huh, why would I ban myself?")
|
612 |
+
await m.stop_propagation()
|
613 |
+
|
614 |
+
if user_id in SUPPORT_STAFF:
|
615 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
616 |
+
LOGGER.info(
|
617 |
+
f"{m.from_user.id} trying to sban {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
618 |
+
)
|
619 |
+
await m.stop_propagation()
|
620 |
+
|
621 |
+
try:
|
622 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
623 |
+
except KeyError:
|
624 |
+
admins_group = await admin_cache_reload(m, "ban")
|
625 |
+
|
626 |
+
if user_id in admins_group:
|
627 |
+
await m.reply_text(tlang(m, "admin.ban.admin_cannot_ban"))
|
628 |
+
await m.stop_propagation()
|
629 |
+
|
630 |
+
try:
|
631 |
+
LOGGER.info(f"{m.from_user.id} sbanned {user_id} in {m.chat.id}")
|
632 |
+
await m.chat.ban_member(user_id)
|
633 |
+
await m.delete()
|
634 |
+
if m.reply_to_message:
|
635 |
+
await m.reply_to_message.delete()
|
636 |
+
except ChatAdminRequired:
|
637 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
638 |
+
except PeerIdInvalid:
|
639 |
+
await m.reply_text(
|
640 |
+
"I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?",
|
641 |
+
)
|
642 |
+
except UserAdminInvalid:
|
643 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
644 |
+
except RightForbidden:
|
645 |
+
await m.reply_text(tlang(m, tlang(m, "admin.ban.bot_no_right")))
|
646 |
+
except RPCError as ef:
|
647 |
+
await m.reply_text(
|
648 |
+
(tlang(m, "general.some_error")).format(
|
649 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
650 |
+
ef=ef,
|
651 |
+
),
|
652 |
+
)
|
653 |
+
LOGGER.error(ef)
|
654 |
+
LOGGER.error(format_exc())
|
655 |
+
return
|
656 |
+
|
657 |
+
|
658 |
+
@Gojo.on_message(command("dban") & restrict_filter)
|
659 |
+
async def dban_usr(c: Gojo, m: Message):
|
660 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
661 |
+
await m.reply_text(tlang(m, "admin.ban.no_target"))
|
662 |
+
await m.stop_propagation()
|
663 |
+
|
664 |
+
if not m.reply_to_message:
|
665 |
+
return await m.reply_text("Reply to a message to delete it and ban the user!")
|
666 |
+
|
667 |
+
if m.reply_to_message and not m.reply_to_message.from_user:
|
668 |
+
user_id, user_first_name = (
|
669 |
+
m.reply_to_message.sender_chat.id,
|
670 |
+
m.reply_to_message.sender_chat.title,
|
671 |
+
)
|
672 |
+
else:
|
673 |
+
user_id, user_first_name = (
|
674 |
+
m.reply_to_message.from_user.id,
|
675 |
+
m.reply_to_message.from_user.first_name,
|
676 |
+
)
|
677 |
+
|
678 |
+
if not user_id:
|
679 |
+
await m.reply_text("Cannot find user to ban")
|
680 |
+
return
|
681 |
+
if user_id == m.chat.id:
|
682 |
+
await m.reply_text("That's an admin!")
|
683 |
+
await m.stop_propagation()
|
684 |
+
if user_id == Config.BOT_ID:
|
685 |
+
await m.reply_text("Huh, why would I ban myself?")
|
686 |
+
await m.stop_propagation()
|
687 |
+
|
688 |
+
if user_id in SUPPORT_STAFF:
|
689 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
690 |
+
LOGGER.info(
|
691 |
+
f"{m.from_user.id} trying to dban {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
692 |
+
)
|
693 |
+
await m.stop_propagation()
|
694 |
+
|
695 |
+
try:
|
696 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
697 |
+
except KeyError:
|
698 |
+
admins_group = await admin_cache_reload(m, "ban")
|
699 |
+
|
700 |
+
if user_id in admins_group:
|
701 |
+
await m.reply_text(tlang(m, "admin.ban.admin_cannot_ban"))
|
702 |
+
await m.stop_propagation()
|
703 |
+
|
704 |
+
reason = None
|
705 |
+
if len(m.text.split()) >= 2:
|
706 |
+
reason = m.text.split(None, 1)[1]
|
707 |
+
|
708 |
+
try:
|
709 |
+
LOGGER.info(f"{m.from_user.id} dbanned {user_id} in {m.chat.id}")
|
710 |
+
await m.reply_to_message.delete()
|
711 |
+
await m.chat.ban_member(user_id)
|
712 |
+
txt = (tlang(m, "admin.ban.banned_user")).format(
|
713 |
+
admin=m.from_user.mention,
|
714 |
+
banned=m.reply_to_message.from_user.mention,
|
715 |
+
chat_title=m.chat.title,
|
716 |
+
)
|
717 |
+
txt += f"\n<b>Reason</b>: {reason}" if reason else ""
|
718 |
+
keyboard = InlineKeyboardMarkup(
|
719 |
+
[
|
720 |
+
[
|
721 |
+
InlineKeyboardButton(
|
722 |
+
"Unban",
|
723 |
+
callback_data=f"unban_={user_id}",
|
724 |
+
),
|
725 |
+
],
|
726 |
+
],
|
727 |
+
)
|
728 |
+
await c.send_message(m.chat.id, txt, reply_markup=keyboard)
|
729 |
+
except ChatAdminRequired:
|
730 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
731 |
+
except PeerIdInvalid:
|
732 |
+
await m.reply_text(
|
733 |
+
"I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?",
|
734 |
+
)
|
735 |
+
except UserAdminInvalid:
|
736 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
737 |
+
except RightForbidden:
|
738 |
+
await m.reply_text(tlang(m, tlang(m, "admin.ban.bot_no_right")))
|
739 |
+
except RPCError as ef:
|
740 |
+
await m.reply_text(
|
741 |
+
(tlang(m, "general.some_error")).format(
|
742 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
743 |
+
ef=ef,
|
744 |
+
),
|
745 |
+
)
|
746 |
+
LOGGER.error(ef)
|
747 |
+
LOGGER.error(format_exc())
|
748 |
+
return
|
749 |
+
|
750 |
+
|
751 |
+
@Gojo.on_message(command("ban") & restrict_filter)
|
752 |
+
async def ban_usr(c: Gojo, m: Message):
|
753 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
754 |
+
await m.reply_text(tlang(m, "admin.ban.no_target"))
|
755 |
+
await m.stop_propagation()
|
756 |
+
|
757 |
+
if m.reply_to_message and not m.reply_to_message.from_user:
|
758 |
+
user_id, user_first_name = (
|
759 |
+
m.reply_to_message.sender_chat.id,
|
760 |
+
m.reply_to_message.sender_chat.title,
|
761 |
+
)
|
762 |
+
else:
|
763 |
+
try:
|
764 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
765 |
+
except Exception:
|
766 |
+
return
|
767 |
+
|
768 |
+
if not user_id:
|
769 |
+
await m.reply_text("Cannot find user to ban")
|
770 |
+
await m.stop_propagation()
|
771 |
+
if user_id == m.chat.id:
|
772 |
+
await m.reply_text("That's an admin!")
|
773 |
+
await m.stop_propagation()
|
774 |
+
if user_id == Config.BOT_ID:
|
775 |
+
await m.reply_text("Huh, why would I ban myself?")
|
776 |
+
await m.stop_propagation()
|
777 |
+
|
778 |
+
if user_id in SUPPORT_STAFF:
|
779 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
780 |
+
LOGGER.info(
|
781 |
+
f"{m.from_user.id} trying to ban {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
782 |
+
)
|
783 |
+
await m.stop_propagation()
|
784 |
+
|
785 |
+
try:
|
786 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
787 |
+
except KeyError:
|
788 |
+
admins_group = await admin_cache_reload(m, "ban")
|
789 |
+
|
790 |
+
if user_id in admins_group:
|
791 |
+
await m.reply_text(tlang(m, "admin.ban.admin_cannot_ban"))
|
792 |
+
await m.stop_propagation()
|
793 |
+
|
794 |
+
reason = None
|
795 |
+
if m.reply_to_message:
|
796 |
+
r_id = m.reply_to_message.message_id
|
797 |
+
if len(m.text.split()) >= 2:
|
798 |
+
reason = m.text.split(None, 1)[1]
|
799 |
+
else:
|
800 |
+
r_id = m.message_id
|
801 |
+
if len(m.text.split()) >= 3:
|
802 |
+
reason = m.text.split(None, 2)[2]
|
803 |
+
|
804 |
+
try:
|
805 |
+
LOGGER.info(f"{m.from_user.id} banned {user_id} in {m.chat.id}")
|
806 |
+
await m.chat.ban_member(user_id)
|
807 |
+
txt = (tlang(m, "admin.ban.banned_user")).format(
|
808 |
+
admin=m.from_user.mention,
|
809 |
+
banned=(await mention_html(user_first_name, user_id)),
|
810 |
+
chat_title=m.chat.title,
|
811 |
+
)
|
812 |
+
txt += f"\n<b>Reason</b>: {reason}" if reason else ""
|
813 |
+
keyboard = InlineKeyboardMarkup(
|
814 |
+
[
|
815 |
+
[
|
816 |
+
InlineKeyboardButton(
|
817 |
+
"Unban",
|
818 |
+
callback_data=f"unban_={user_id}",
|
819 |
+
),
|
820 |
+
],
|
821 |
+
],
|
822 |
+
)
|
823 |
+
await m.reply_text(txt, reply_markup=keyboard, reply_to_message_id=r_id)
|
824 |
+
except ChatAdminRequired:
|
825 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
826 |
+
except PeerIdInvalid:
|
827 |
+
await m.reply_text(
|
828 |
+
"I have not seen this user yet...!\nMind forwarding one of their message so I can recognize them?",
|
829 |
+
)
|
830 |
+
except UserAdminInvalid:
|
831 |
+
await m.reply_text(tlang(m, "admin.user_admin_invalid"))
|
832 |
+
except RightForbidden:
|
833 |
+
await m.reply_text(tlang(m, tlang(m, "admin.ban.bot_no_right")))
|
834 |
+
except RPCError as ef:
|
835 |
+
await m.reply_text(
|
836 |
+
(tlang(m, "general.some_error")).format(
|
837 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
838 |
+
ef=ef,
|
839 |
+
),
|
840 |
+
)
|
841 |
+
LOGGER.error(ef)
|
842 |
+
LOGGER.error(format_exc())
|
843 |
+
return
|
844 |
+
|
845 |
+
|
846 |
+
@Gojo.on_callback_query(regex("^unban_"))
|
847 |
+
async def unbanbutton(c: Gojo, q: CallbackQuery):
|
848 |
+
splitter = (str(q.data).replace("unban_", "")).split("=")
|
849 |
+
user_id = int(splitter[1])
|
850 |
+
user = await q.message.chat.get_member(q.from_user.id)
|
851 |
+
|
852 |
+
if not user.can_restrict_members and q.from_user.id != OWNER_ID:
|
853 |
+
await q.answer(
|
854 |
+
"You don't have enough permission to do this!\nStay in your limits!",
|
855 |
+
show_alert=True,
|
856 |
+
)
|
857 |
+
return
|
858 |
+
whoo = await c.get_chat(user_id)
|
859 |
+
doneto = whoo.first_name if whoo.first_name else whoo.title
|
860 |
+
try:
|
861 |
+
await q.message.chat.unban_member(user_id)
|
862 |
+
except RPCError as e:
|
863 |
+
await q.message.edit_text(f"Error: {e}")
|
864 |
+
return
|
865 |
+
await q.message.edit_text(f"{q.from_user.mention} unbanned {doneto}!")
|
866 |
+
return
|
867 |
+
|
868 |
+
|
869 |
+
@Gojo.on_message(command("kickme"))
|
870 |
+
async def kickme(_, m: Message):
|
871 |
+
reason = None
|
872 |
+
if len(m.text.split()) >= 2:
|
873 |
+
reason = m.text.split(None, 1)[1]
|
874 |
+
try:
|
875 |
+
LOGGER.info(f"{m.from_user.id} kickme used by {m.from_user.id} in {m.chat.id}")
|
876 |
+
await m.chat.ban_member(m.from_user.id)
|
877 |
+
txt = "Why not let me help you!"
|
878 |
+
txt += f"\n<b>Reason</b>: {reason}" if reason else ""
|
879 |
+
await m.reply_text(txt)
|
880 |
+
await m.chat.unban_member(m.from_user.id)
|
881 |
+
except RPCError as ef:
|
882 |
+
await m.reply_text(
|
883 |
+
(tlang(m, "general.some_error")).format(
|
884 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
885 |
+
ef=ef,
|
886 |
+
),
|
887 |
+
)
|
888 |
+
return
|
889 |
+
|
890 |
+
|
891 |
+
__PLUGIN__ = "bans"
|
892 |
+
|
893 |
+
_DISABLE_CMDS_ = ["kickme"]
|
894 |
+
|
895 |
+
__alt_name__ = [
|
896 |
+
"ban",
|
897 |
+
"unban",
|
898 |
+
"kickme",
|
899 |
+
"kick",
|
900 |
+
"tban",
|
901 |
+
]
|
Powers/plugins/blacklist.py
ADDED
@@ -0,0 +1,218 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from html import escape
|
2 |
+
|
3 |
+
from pyrogram import filters
|
4 |
+
from pyrogram.types import CallbackQuery, Message
|
5 |
+
|
6 |
+
from Powers import LOGGER
|
7 |
+
from Powers.bot_class import Gojo
|
8 |
+
from Powers.database.blacklist_db import Blacklist
|
9 |
+
from Powers.tr_engine import tlang
|
10 |
+
from Powers.utils.custom_filters import command, owner_filter, restrict_filter
|
11 |
+
from Powers.utils.kbhelpers import ikb
|
12 |
+
|
13 |
+
|
14 |
+
@Gojo.on_message(command("blacklist") & filters.group)
|
15 |
+
async def view_blacklist(_, m: Message):
|
16 |
+
db = Blacklist(m.chat.id)
|
17 |
+
|
18 |
+
LOGGER.info(f"{m.from_user.id} checking blacklists in {m.chat.id}")
|
19 |
+
|
20 |
+
chat_title = m.chat.title
|
21 |
+
blacklists_chat = (tlang(m, "blacklist.curr_blacklist_initial")).format(
|
22 |
+
chat_title=chat_title,
|
23 |
+
)
|
24 |
+
all_blacklisted = db.get_blacklists()
|
25 |
+
|
26 |
+
if not all_blacklisted:
|
27 |
+
await m.reply_text(
|
28 |
+
(tlang(m, "blacklist.no_blacklist")).format(
|
29 |
+
chat_title=chat_title,
|
30 |
+
),
|
31 |
+
)
|
32 |
+
return
|
33 |
+
|
34 |
+
blacklists_chat += "\n".join(
|
35 |
+
f" • <code>{escape(i)}</code>" for i in all_blacklisted
|
36 |
+
)
|
37 |
+
|
38 |
+
await m.reply_text(blacklists_chat)
|
39 |
+
return
|
40 |
+
|
41 |
+
|
42 |
+
@Gojo.on_message(command("addblacklist") & restrict_filter)
|
43 |
+
async def add_blacklist(_, m: Message):
|
44 |
+
db = Blacklist(m.chat.id)
|
45 |
+
|
46 |
+
if len(m.text.split()) < 2:
|
47 |
+
await m.reply_text(tlang(m, "general.check_help"))
|
48 |
+
return
|
49 |
+
|
50 |
+
bl_words = ((m.text.split(None, 1)[1]).lower()).split()
|
51 |
+
all_blacklisted = db.get_blacklists()
|
52 |
+
already_added_words, rep_text = [], ""
|
53 |
+
|
54 |
+
for bl_word in bl_words:
|
55 |
+
if bl_word in all_blacklisted:
|
56 |
+
already_added_words.append(bl_word)
|
57 |
+
continue
|
58 |
+
db.add_blacklist(bl_word)
|
59 |
+
|
60 |
+
if already_added_words:
|
61 |
+
rep_text = (
|
62 |
+
", ".join([f"<code>{i}</code>" for i in bl_words])
|
63 |
+
+ " already added in blacklist, skipped them!"
|
64 |
+
)
|
65 |
+
LOGGER.info(f"{m.from_user.id} added new blacklists ({bl_words}) in {m.chat.id}")
|
66 |
+
await m.reply_text(
|
67 |
+
(tlang(m, "blacklist.added_blacklist")).format(
|
68 |
+
trigger=", ".join(f"<code>{i}</code>" for i in bl_words),
|
69 |
+
)
|
70 |
+
+ (f"\n{rep_text}" if rep_text else ""),
|
71 |
+
)
|
72 |
+
|
73 |
+
await m.stop_propagation()
|
74 |
+
|
75 |
+
|
76 |
+
@Gojo.on_message(
|
77 |
+
command(["blwarning", "blreason", "blacklistreason"]) & restrict_filter,
|
78 |
+
)
|
79 |
+
async def blacklistreason(_, m: Message):
|
80 |
+
db = Blacklist(m.chat.id)
|
81 |
+
|
82 |
+
if len(m.text.split()) == 1:
|
83 |
+
curr = db.get_reason()
|
84 |
+
await m.reply_text(
|
85 |
+
f"The current reason for blacklists warn is:\n<code>{curr}</code>",
|
86 |
+
)
|
87 |
+
else:
|
88 |
+
reason = m.text.split(None, 1)[1]
|
89 |
+
db.set_reason(reason)
|
90 |
+
await m.reply_text(
|
91 |
+
f"Updated reason for blacklists warn is:\n<code>{reason}</code>",
|
92 |
+
)
|
93 |
+
return
|
94 |
+
|
95 |
+
|
96 |
+
@Gojo.on_message(
|
97 |
+
command(["rmblacklist", "unblacklist"]) & restrict_filter,
|
98 |
+
)
|
99 |
+
async def rm_blacklist(_, m: Message):
|
100 |
+
db = Blacklist(m.chat.id)
|
101 |
+
|
102 |
+
if len(m.text.split()) < 2:
|
103 |
+
await m.reply_text(tlang(m, "general.check_help"))
|
104 |
+
return
|
105 |
+
|
106 |
+
chat_bl = db.get_blacklists()
|
107 |
+
non_found_words, rep_text = [], ""
|
108 |
+
bl_words = ((m.text.split(None, 1)[1]).lower()).split()
|
109 |
+
|
110 |
+
for bl_word in bl_words:
|
111 |
+
if bl_word not in chat_bl:
|
112 |
+
non_found_words.append(bl_word)
|
113 |
+
continue
|
114 |
+
db.remove_blacklist(bl_word)
|
115 |
+
|
116 |
+
if non_found_words == bl_words:
|
117 |
+
return await m.reply_text("Blacklists not found!")
|
118 |
+
|
119 |
+
if non_found_words:
|
120 |
+
rep_text = (
|
121 |
+
"Could not find " + ", ".join(f"<code>{i}</code>" for i in non_found_words)
|
122 |
+
) + " in blcklisted words, skipped them."
|
123 |
+
|
124 |
+
LOGGER.info(f"{m.from_user.id} removed blacklists ({bl_words}) in {m.chat.id}")
|
125 |
+
await m.reply_text(
|
126 |
+
(tlang(m, "blacklist.rm_blacklist")).format(
|
127 |
+
bl_words=", ".join(f"<code>{i}</code>" for i in bl_words),
|
128 |
+
)
|
129 |
+
+ (f"\n{rep_text}" if rep_text else ""),
|
130 |
+
)
|
131 |
+
|
132 |
+
await m.stop_propagation()
|
133 |
+
|
134 |
+
|
135 |
+
@Gojo.on_message(
|
136 |
+
command(["blaction", "blacklistaction", "blacklistmode"]) & restrict_filter,
|
137 |
+
)
|
138 |
+
async def set_bl_action(_, m: Message):
|
139 |
+
db = Blacklist(m.chat.id)
|
140 |
+
|
141 |
+
if len(m.text.split()) == 2:
|
142 |
+
action = m.text.split(None, 1)[1]
|
143 |
+
valid_actions = ("ban", "kick", "mute", "warn", "none")
|
144 |
+
if action not in valid_actions:
|
145 |
+
await m.reply_text(
|
146 |
+
(
|
147 |
+
"Choose a valid blacklist action from "
|
148 |
+
+ ", ".join(f"<code>{i}</code>" for i in valid_actions)
|
149 |
+
),
|
150 |
+
)
|
151 |
+
|
152 |
+
return
|
153 |
+
db.set_action(action)
|
154 |
+
LOGGER.info(
|
155 |
+
f"{m.from_user.id} set blacklist action to '{action}' in {m.chat.id}",
|
156 |
+
)
|
157 |
+
await m.reply_text(
|
158 |
+
(tlang(m, "blacklist.action_set")).format(action=action),
|
159 |
+
)
|
160 |
+
elif len(m.text.split()) == 1:
|
161 |
+
action = db.get_action()
|
162 |
+
LOGGER.info(f"{m.from_user.id} checking blacklist action in {m.chat.id}")
|
163 |
+
await m.reply_text(
|
164 |
+
(tlang(m, "blacklist.action_get")).format(action=action),
|
165 |
+
)
|
166 |
+
else:
|
167 |
+
await m.reply_text(tlang(m, "general.check_help"))
|
168 |
+
|
169 |
+
return
|
170 |
+
|
171 |
+
|
172 |
+
@Gojo.on_message(
|
173 |
+
command("rmallblacklist") & owner_filter,
|
174 |
+
)
|
175 |
+
async def rm_allblacklist(_, m: Message):
|
176 |
+
db = Blacklist(m.chat.id)
|
177 |
+
|
178 |
+
all_bls = db.get_blacklists()
|
179 |
+
if not all_bls:
|
180 |
+
await m.reply_text("No notes are blacklists in this chat")
|
181 |
+
return
|
182 |
+
|
183 |
+
await m.reply_text(
|
184 |
+
"Are you sure you want to clear all blacklists?",
|
185 |
+
reply_markup=ikb(
|
186 |
+
[[("⚠️ Confirm", "rm_allblacklist"), ("❌ Cancel", "close_admin")]],
|
187 |
+
),
|
188 |
+
)
|
189 |
+
return
|
190 |
+
|
191 |
+
|
192 |
+
@Gojo.on_callback_query(filters.regex("^rm_allblacklist$"))
|
193 |
+
async def rm_allbl_callback(_, q: CallbackQuery):
|
194 |
+
user_id = q.from_user.id
|
195 |
+
db = Blacklist(q.message.chat.id)
|
196 |
+
user_status = (await q.message.chat.get_member(user_id)).status
|
197 |
+
if user_status not in {"creator", "administrator"}:
|
198 |
+
await q.answer(
|
199 |
+
"You're not even an admin, don't try this explosive shit!",
|
200 |
+
show_alert=True,
|
201 |
+
)
|
202 |
+
return
|
203 |
+
if user_status != "creator":
|
204 |
+
await q.answer(
|
205 |
+
"You're just an admin, not owner\nStay in your limits!",
|
206 |
+
show_alert=True,
|
207 |
+
)
|
208 |
+
return
|
209 |
+
db.rm_all_blacklist()
|
210 |
+
await q.message.delete()
|
211 |
+
LOGGER.info(f"{user_id} removed all blacklists in {q.message.chat.id}")
|
212 |
+
await q.answer("Cleared all Blacklists!", show_alert=True)
|
213 |
+
return
|
214 |
+
|
215 |
+
|
216 |
+
__PLUGIN__ = "blacklist"
|
217 |
+
|
218 |
+
__alt_name__ = ["blacklists", "blaction"]
|
Powers/plugins/botstaff.py
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram.errors import RPCError
|
2 |
+
from pyrogram.types import Message
|
3 |
+
|
4 |
+
from Powers import DEV_USERS, LOGGER, OWNER_ID, SUDO_USERS, WHITELIST_USERS
|
5 |
+
from Powers.bot_class import Gojo
|
6 |
+
from Powers.utils.custom_filters import command
|
7 |
+
from Powers.utils.parser import mention_html
|
8 |
+
|
9 |
+
|
10 |
+
@Gojo.on_message(command("botstaff", dev_cmd=True))
|
11 |
+
async def botstaff(c: Gojo, m: Message):
|
12 |
+
try:
|
13 |
+
owner = await c.get_users(OWNER_ID)
|
14 |
+
reply = f"<b>🌟 Owner:</b> {(await mention_html(owner.first_name, OWNER_ID))} (<code>{OWNER_ID}</code>)\n"
|
15 |
+
except RPCError:
|
16 |
+
pass
|
17 |
+
true_dev = list(set(DEV_USERS) - {OWNER_ID})
|
18 |
+
reply += "\n<b>Developers ⚡️:</b>\n"
|
19 |
+
if true_dev == []:
|
20 |
+
reply += "No Dev Users\n"
|
21 |
+
else:
|
22 |
+
for each_user in true_dev:
|
23 |
+
user_id = int(each_user)
|
24 |
+
try:
|
25 |
+
user = await c.get_users(user_id)
|
26 |
+
reply += f"• {(await mention_html(user.first_name, user_id))} (<code>{user_id}</code>)\n"
|
27 |
+
except RPCError:
|
28 |
+
pass
|
29 |
+
true_sudo = list(set(SUDO_USERS) - set(DEV_USERS))
|
30 |
+
reply += "\n<b>Sudo Users 🐉:</b>\n"
|
31 |
+
if true_sudo == []:
|
32 |
+
reply += "No Sudo Users\n"
|
33 |
+
else:
|
34 |
+
for each_user in true_sudo:
|
35 |
+
user_id = int(each_user)
|
36 |
+
try:
|
37 |
+
user = await c.get_users(user_id)
|
38 |
+
reply += f"• {(await mention_html(user.first_name, user_id))} (<code>{user_id}</code>)\n"
|
39 |
+
except RPCError:
|
40 |
+
pass
|
41 |
+
reply += "\n<b>Whitelisted Users 🐺:</b>\n"
|
42 |
+
if WHITELIST_USERS == []:
|
43 |
+
reply += "No additional whitelisted users\n"
|
44 |
+
else:
|
45 |
+
for each_user in WHITELIST_USERS:
|
46 |
+
user_id = int(each_user)
|
47 |
+
try:
|
48 |
+
user = await c.get_users(user_id)
|
49 |
+
reply += f"• {(await mention_html(user.first_name, user_id))} (<code>{user_id}</code>)\n"
|
50 |
+
except RPCError:
|
51 |
+
pass
|
52 |
+
await m.reply_text(reply)
|
53 |
+
LOGGER.info(f"{m.from_user.id} fetched botstaff in {m.chat.id}")
|
54 |
+
return
|
Powers/plugins/chat_blacklist.py
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from traceback import format_exc
|
2 |
+
|
3 |
+
from pyrogram.errors import PeerIdInvalid, RPCError
|
4 |
+
from pyrogram.types import Message
|
5 |
+
|
6 |
+
from Powers import LOGGER
|
7 |
+
from Powers.bot_class import Gojo
|
8 |
+
from Powers.database.group_blacklist import GroupBlacklist
|
9 |
+
from Powers.utils.custom_filters import command
|
10 |
+
|
11 |
+
# initialise database
|
12 |
+
db = GroupBlacklist()
|
13 |
+
|
14 |
+
|
15 |
+
@Gojo.on_message(command("blchat", dev_cmd=True))
|
16 |
+
async def blacklist_chat(c: Gojo, m: Message):
|
17 |
+
if len(m.text.split()) >= 2:
|
18 |
+
chat_ids = m.text.split()[1:]
|
19 |
+
replymsg = await m.reply_text(f"Adding {len(chat_ids)} chats to blacklist")
|
20 |
+
LOGGER.info(f"{m.from_user.id} blacklisted {chat_ids} groups for bot")
|
21 |
+
for chat in chat_ids:
|
22 |
+
try:
|
23 |
+
get_chat = await c.get_chat(chat)
|
24 |
+
chat_id = get_chat.id
|
25 |
+
db.add_chat(chat_id)
|
26 |
+
except PeerIdInvalid:
|
27 |
+
await replymsg.edit_text(
|
28 |
+
"Haven't seen this group in this session, maybe try again later?",
|
29 |
+
)
|
30 |
+
except RPCError as ef:
|
31 |
+
LOGGER.error(ef)
|
32 |
+
LOGGER.error(format_exc())
|
33 |
+
await replymsg.edit_text(
|
34 |
+
f"Added the following chats to Blacklist.\n<code>{', '.join(chat_ids)}</code>.",
|
35 |
+
)
|
36 |
+
return
|
37 |
+
|
38 |
+
|
39 |
+
@Gojo.on_message(
|
40 |
+
command(["rmblchat", "unblchat"], dev_cmd=True),
|
41 |
+
)
|
42 |
+
async def unblacklist_chat(c: Gojo, m: Message):
|
43 |
+
if len(m.text.split()) >= 2:
|
44 |
+
chat_ids = m.text.split()[1:]
|
45 |
+
replymsg = await m.reply_text(f"Removing {len(chat_ids)} chats from blacklist")
|
46 |
+
LOGGER.info(f"{m.from_user.id} removed blacklisted {chat_ids} groups for bot")
|
47 |
+
bl_chats = db.list_all_chats()
|
48 |
+
for chat in chat_ids:
|
49 |
+
try:
|
50 |
+
get_chat = await c.get_chat(chat)
|
51 |
+
chat_id = get_chat.id
|
52 |
+
if chat_id not in bl_chats:
|
53 |
+
# If chat is not blaklisted, continue loop
|
54 |
+
continue
|
55 |
+
db.remove_chat(chat_id)
|
56 |
+
except PeerIdInvalid:
|
57 |
+
await replymsg.edit_text(
|
58 |
+
"Haven't seen this group in this session, maybe try again later?",
|
59 |
+
)
|
60 |
+
except RPCError as ef:
|
61 |
+
LOGGER.error(ef)
|
62 |
+
LOGGER.error(format_exc())
|
63 |
+
await replymsg.edit_text(
|
64 |
+
f"Removed the following chats to Blacklist.\n<code>{', '.join(chat_ids)}</code>.",
|
65 |
+
)
|
66 |
+
return
|
67 |
+
|
68 |
+
|
69 |
+
@Gojo.on_message(
|
70 |
+
command(["blchatlist", "blchats"], dev_cmd=True),
|
71 |
+
)
|
72 |
+
async def list_blacklist_chats(_, m: Message):
|
73 |
+
bl_chats = db.list_all_chats()
|
74 |
+
LOGGER.info(f"{m.from_user.id} checking group blacklists in {m.chat.id}")
|
75 |
+
if bl_chats:
|
76 |
+
txt = (
|
77 |
+
(
|
78 |
+
"These Chats are Blacklisted:\n"
|
79 |
+
+ "\n".join(f"<code>{i}</code>" for i in bl_chats)
|
80 |
+
),
|
81 |
+
)
|
82 |
+
|
83 |
+
else:
|
84 |
+
txt = "No chats are currently blacklisted!"
|
85 |
+
await m.reply_text(txt)
|
86 |
+
return
|
Powers/plugins/dev.py
ADDED
@@ -0,0 +1,360 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import sys
|
2 |
+
from asyncio import create_subprocess_shell, sleep, subprocess
|
3 |
+
from io import BytesIO, StringIO
|
4 |
+
from time import gmtime, strftime, time
|
5 |
+
from traceback import format_exc
|
6 |
+
|
7 |
+
from pyrogram.errors import (
|
8 |
+
ChannelInvalid,
|
9 |
+
ChannelPrivate,
|
10 |
+
ChatAdminRequired,
|
11 |
+
FloodWait,
|
12 |
+
MessageTooLong,
|
13 |
+
PeerIdInvalid,
|
14 |
+
RPCError,
|
15 |
+
)
|
16 |
+
from pyrogram.types import Message
|
17 |
+
from speedtest import Speedtest
|
18 |
+
|
19 |
+
from Powers import LOGFILE, LOGGER, MESSAGE_DUMP, UPTIME
|
20 |
+
from Powers.bot_class import Gojo
|
21 |
+
from Powers.database.chats_db import Chats
|
22 |
+
from Powers.tr_engine import tlang
|
23 |
+
from Powers.utils.clean_file import remove_markdown_and_html
|
24 |
+
from Powers.utils.custom_filters import command
|
25 |
+
from Powers.utils.http_helper import HTTPx
|
26 |
+
from Powers.utils.kbhelpers import ikb
|
27 |
+
from Powers.utils.parser import mention_markdown
|
28 |
+
from Powers.vars import Config
|
29 |
+
|
30 |
+
|
31 |
+
@Gojo.on_message(command("ping", sudo_cmd=True))
|
32 |
+
async def ping(_, m: Message):
|
33 |
+
LOGGER.info(f"{m.from_user.id} used ping cmd in {m.chat.id}")
|
34 |
+
start = time()
|
35 |
+
replymsg = await m.reply_text((tlang(m, "utils.ping.pinging")), quote=True)
|
36 |
+
delta_ping = time() - start
|
37 |
+
await replymsg.edit_text(f"<b>Pong!</b>\n{delta_ping * 1000:.3f} ms")
|
38 |
+
return
|
39 |
+
|
40 |
+
|
41 |
+
@Gojo.on_message(command("logs", dev_cmd=True))
|
42 |
+
async def send_log(c: Gojo, m: Message):
|
43 |
+
replymsg = await m.reply_text("Sending logs...!")
|
44 |
+
await c.send_message(
|
45 |
+
MESSAGE_DUMP,
|
46 |
+
f"#LOGS\n\n**User:** {(await mention_markdown(m.from_user.first_name, m.from_user.id))}",
|
47 |
+
)
|
48 |
+
# Send logs
|
49 |
+
with open(LOGFILE) as f:
|
50 |
+
raw = (await (f.read()))[1]
|
51 |
+
await m.reply_document(
|
52 |
+
document=LOGFILE,
|
53 |
+
quote=True,
|
54 |
+
)
|
55 |
+
await replymsg.delete()
|
56 |
+
return
|
57 |
+
|
58 |
+
|
59 |
+
@Gojo.on_message(command("ginfo", sudo_cmd=True))
|
60 |
+
async def group_info(c: Gojo, m: Message):
|
61 |
+
if len(m.text.split()) != 2:
|
62 |
+
await m.reply_text(
|
63 |
+
f"It works like this: <code>{Config.PREFIX_HANDLER} chat_id</code>",
|
64 |
+
)
|
65 |
+
return
|
66 |
+
|
67 |
+
chat_id = m.text.split(None, 1)[1]
|
68 |
+
|
69 |
+
replymsg = await m.reply_text("Fetching info about group...!")
|
70 |
+
grp_data = await c.get_chat(chat_id)
|
71 |
+
msg = (
|
72 |
+
f"Information for group: {chat_id}\n\n"
|
73 |
+
f"Group Name: {grp_data['title']}\n"
|
74 |
+
f"Members Count: {grp_data['members_count']}\n"
|
75 |
+
f"Type: {grp_data['type']}\n"
|
76 |
+
f"Group ID: {grp_data['id']}"
|
77 |
+
)
|
78 |
+
await replymsg.edit_text(msg)
|
79 |
+
return
|
80 |
+
|
81 |
+
|
82 |
+
@Gojo.on_message(command("speedtest", dev_cmd=True))
|
83 |
+
async def test_speed(c: Gojo, m: Message):
|
84 |
+
await c.send_message(
|
85 |
+
MESSAGE_DUMP,
|
86 |
+
f"#SPEEDTEST\n\n**User:** {(await mention_markdown(m.from_user.first_name, m.from_user.id))}",
|
87 |
+
)
|
88 |
+
sent = await m.reply_text(tlang(m, "dev.speedtest.start_speedtest"))
|
89 |
+
s = Speedtest()
|
90 |
+
bs = s.get_best_server()
|
91 |
+
dl = round(s.download() / 1024 / 1024, 2)
|
92 |
+
ul = round(s.upload() / 1024 / 1024, 2)
|
93 |
+
await sent.edit_text(
|
94 |
+
(tlang(m, "dev.speedtest.speedtest_txt")).format(
|
95 |
+
host=bs["sponsor"],
|
96 |
+
ping=int(bs["latency"]),
|
97 |
+
download=dl,
|
98 |
+
upload=ul,
|
99 |
+
),
|
100 |
+
)
|
101 |
+
return
|
102 |
+
|
103 |
+
|
104 |
+
@Gojo.on_message(command("neofetch", dev_cmd=True))
|
105 |
+
async def neofetch_stats(_, m: Message):
|
106 |
+
cmd = "neofetch --stdout"
|
107 |
+
|
108 |
+
process = await create_subprocess_shell(
|
109 |
+
cmd,
|
110 |
+
stdout=subprocess.PIPE,
|
111 |
+
stderr=subprocess.PIPE,
|
112 |
+
)
|
113 |
+
stdout, stderr = await process.communicate()
|
114 |
+
e = stderr.decode()
|
115 |
+
if not e:
|
116 |
+
e = "No Error"
|
117 |
+
OUTPUT = stdout.decode()
|
118 |
+
if not OUTPUT:
|
119 |
+
OUTPUT = "No Output"
|
120 |
+
|
121 |
+
try:
|
122 |
+
await m.reply_text(OUTPUT, quote=True)
|
123 |
+
except MessageTooLong:
|
124 |
+
with BytesIO(str.encode(await remove_markdown_and_html(OUTPUT))) as f:
|
125 |
+
f.name = "neofetch.txt"
|
126 |
+
await m.reply_document(document=f, caption="neofetch result")
|
127 |
+
await m.delete()
|
128 |
+
return
|
129 |
+
|
130 |
+
|
131 |
+
@Gojo.on_message(command(["eval", "py"], dev_cmd=True))
|
132 |
+
async def evaluate_code(c: Gojo, m: Message):
|
133 |
+
if len(m.text.split()) == 1:
|
134 |
+
await m.reply_text(tlang(m, "dev.execute_cmd_err"))
|
135 |
+
return
|
136 |
+
sm = await m.reply_text("`Processing...`")
|
137 |
+
cmd = m.text.split(None, maxsplit=1)[1]
|
138 |
+
|
139 |
+
reply_to_id = m.message_id
|
140 |
+
if m.reply_to_message:
|
141 |
+
reply_to_id = m.reply_to_message.message_id
|
142 |
+
|
143 |
+
old_stderr = sys.stderr
|
144 |
+
old_stdout = sys.stdout
|
145 |
+
redirected_output = sys.stdout = StringIO()
|
146 |
+
redirected_error = sys.stderr = StringIO()
|
147 |
+
stdout, stderr, exc = None, None, None
|
148 |
+
|
149 |
+
try:
|
150 |
+
await aexec(cmd, c, m)
|
151 |
+
except Exception as ef:
|
152 |
+
LOGGER.error(ef)
|
153 |
+
exc = format_exc()
|
154 |
+
|
155 |
+
stdout = redirected_output.getvalue()
|
156 |
+
stderr = redirected_error.getvalue()
|
157 |
+
sys.stdout = old_stdout
|
158 |
+
sys.stderr = old_stderr
|
159 |
+
|
160 |
+
evaluation = ""
|
161 |
+
if exc:
|
162 |
+
evaluation = exc
|
163 |
+
elif stderr:
|
164 |
+
evaluation = stderr
|
165 |
+
elif stdout:
|
166 |
+
evaluation = stdout
|
167 |
+
else:
|
168 |
+
evaluation = "Success"
|
169 |
+
|
170 |
+
final_output = f"<b>EVAL</b>: <code>{cmd}</code>\n\n<b>OUTPUT</b>:\n<code>{evaluation.strip()}</code> \n"
|
171 |
+
|
172 |
+
try:
|
173 |
+
await sm.edit(final_output)
|
174 |
+
except MessageTooLong:
|
175 |
+
with BytesIO(str.encode(await remove_markdown_and_html(final_output))) as f:
|
176 |
+
f.name = "py.txt"
|
177 |
+
await m.reply_document(
|
178 |
+
document=f,
|
179 |
+
caption=cmd,
|
180 |
+
disable_notification=True,
|
181 |
+
reply_to_message_id=reply_to_id,
|
182 |
+
)
|
183 |
+
await sm.delete()
|
184 |
+
|
185 |
+
return
|
186 |
+
|
187 |
+
|
188 |
+
async def aexec(code, c, m):
|
189 |
+
exec("async def __aexec(c, m): " + "".join(f"\n {l}" for l in code.split("\n")))
|
190 |
+
return await locals()["__aexec"](c, m)
|
191 |
+
|
192 |
+
|
193 |
+
@Gojo.on_message(command(["exec", "sh"], dev_cmd=True))
|
194 |
+
async def execution(_, m: Message):
|
195 |
+
if len(m.text.split()) == 1:
|
196 |
+
await m.reply_text(tlang(m, "dev.execute_cmd_err"))
|
197 |
+
return
|
198 |
+
sm = await m.reply_text("`Processing...`")
|
199 |
+
cmd = m.text.split(maxsplit=1)[1]
|
200 |
+
reply_to_id = m.message_id
|
201 |
+
if m.reply_to_message:
|
202 |
+
reply_to_id = m.reply_to_message.message_id
|
203 |
+
|
204 |
+
process = await create_subprocess_shell(
|
205 |
+
cmd,
|
206 |
+
stdout=subprocess.PIPE,
|
207 |
+
stderr=subprocess.PIPE,
|
208 |
+
)
|
209 |
+
stdout, stderr = await process.communicate()
|
210 |
+
e = stderr.decode()
|
211 |
+
if not e:
|
212 |
+
e = "No Error"
|
213 |
+
o = stdout.decode()
|
214 |
+
if not o:
|
215 |
+
o = "No Output"
|
216 |
+
|
217 |
+
OUTPUT = ""
|
218 |
+
OUTPUT += f"<b>QUERY:</b>\n<u>Command:</u>\n<code>{cmd}</code> \n"
|
219 |
+
OUTPUT += f"<u>PID</u>: <code>{process.pid}</code>\n\n"
|
220 |
+
OUTPUT += f"<b>stderr</b>: \n<code>{e}</code>\n\n"
|
221 |
+
OUTPUT += f"<b>stdout</b>: \n<code>{o}</code>"
|
222 |
+
|
223 |
+
try:
|
224 |
+
await sm.edit_text(OUTPUT)
|
225 |
+
except MessageTooLong:
|
226 |
+
with BytesIO(str.encode(await remove_markdown_and_html(OUTPUT))) as f:
|
227 |
+
f.name = "sh.txt"
|
228 |
+
await m.reply_document(
|
229 |
+
document=f,
|
230 |
+
caption=cmd,
|
231 |
+
disable_notification=True,
|
232 |
+
reply_to_message_id=reply_to_id,
|
233 |
+
)
|
234 |
+
await sm.delete()
|
235 |
+
return
|
236 |
+
|
237 |
+
|
238 |
+
@Gojo.on_message(command("ip", dev_cmd=True))
|
239 |
+
async def public_ip(c: Gojo, m: Message):
|
240 |
+
ip = await HTTPx.get("https://api.ipify.org")
|
241 |
+
await c.send_message(
|
242 |
+
MESSAGE_DUMP,
|
243 |
+
f"#IP\n\n**User:** {(await mention_markdown(m.from_user.first_name, m.from_user.id))}",
|
244 |
+
)
|
245 |
+
await m.reply_text(
|
246 |
+
(tlang(m, "dev.bot_ip")).format(ip=f"<code>{ip.text}</code>"),
|
247 |
+
quote=True,
|
248 |
+
)
|
249 |
+
return
|
250 |
+
|
251 |
+
|
252 |
+
@Gojo.on_message(command("chatlist", dev_cmd=True))
|
253 |
+
async def chats(c: Gojo, m: Message):
|
254 |
+
exmsg = await m.reply_text(tlang(m, "dev.chatlist.exporting"))
|
255 |
+
await c.send_message(
|
256 |
+
MESSAGE_DUMP,
|
257 |
+
f"#CHATLIST\n\n**User:** {(await mention_markdown(m.from_user.first_name, m.from_user.id))}",
|
258 |
+
)
|
259 |
+
all_chats = (Chats.list_chats_full()) or {}
|
260 |
+
chatfile = tlang(m, "dev.chatlist.header")
|
261 |
+
P = 1
|
262 |
+
for chat in all_chats:
|
263 |
+
try:
|
264 |
+
chat_info = await c.get_chat(chat["_id"])
|
265 |
+
chat_members = chat_info.members_count
|
266 |
+
try:
|
267 |
+
invitelink = chat_info.invite_link
|
268 |
+
except KeyError:
|
269 |
+
invitelink = "No Link!"
|
270 |
+
chatfile += f"{P}. {chat['chat_name']} | {chat['_id']} | {chat_members} | {invitelink}\n"
|
271 |
+
P += 1
|
272 |
+
except ChatAdminRequired:
|
273 |
+
pass
|
274 |
+
except (ChannelPrivate, ChannelInvalid):
|
275 |
+
Chats.remove_chat(chat["_id"])
|
276 |
+
except PeerIdInvalid:
|
277 |
+
LOGGER.warning(f"Peer not found {chat['_id']}")
|
278 |
+
except FloodWait as ef:
|
279 |
+
LOGGER.error("FloodWait required, Sleeping for 60s")
|
280 |
+
LOGGER.error(ef)
|
281 |
+
sleep(60)
|
282 |
+
except RPCError as ef:
|
283 |
+
LOGGER.error(ef)
|
284 |
+
await m.reply_text(f"**Error:**\n{ef}")
|
285 |
+
|
286 |
+
with BytesIO(str.encode(await remove_markdown_and_html(chatfile))) as f:
|
287 |
+
f.name = "chatlist.txt"
|
288 |
+
await m.reply_document(
|
289 |
+
document=f,
|
290 |
+
caption=(tlang(m, "dev.chatlist.chats_in_db")),
|
291 |
+
)
|
292 |
+
await exmsg.delete()
|
293 |
+
return
|
294 |
+
|
295 |
+
|
296 |
+
@Gojo.on_message(command("uptime", dev_cmd=True))
|
297 |
+
async def uptime(_, m: Message):
|
298 |
+
up = strftime("%Hh %Mm %Ss", gmtime(time() - UPTIME))
|
299 |
+
await m.reply_text((tlang(m, "dev.uptime")).format(uptime=up), quote=True)
|
300 |
+
return
|
301 |
+
|
302 |
+
|
303 |
+
@Gojo.on_message(command("leavechat", dev_cmd=True))
|
304 |
+
async def leave_chat(c: Gojo, m: Message):
|
305 |
+
if len(m.text.split()) != 2:
|
306 |
+
await m.reply_text("Supply a chat id which I should leave!", quoet=True)
|
307 |
+
return
|
308 |
+
|
309 |
+
chat_id = m.text.split(None, 1)[1]
|
310 |
+
|
311 |
+
replymsg = await m.reply_text(f"Trying to leave chat {chat_id}...", quote=True)
|
312 |
+
try:
|
313 |
+
await c.leave_chat(chat_id)
|
314 |
+
await replymsg.edit_text(f"Left <code>{chat_id}</code>.")
|
315 |
+
except PeerIdInvalid:
|
316 |
+
await replymsg.edit_text("Haven't seen this group in this session!")
|
317 |
+
except RPCError as ef:
|
318 |
+
LOGGER.error(ef)
|
319 |
+
await replymsg.edit_text(f"Failed to leave chat!\nError: <code>{ef}</code>.")
|
320 |
+
return
|
321 |
+
|
322 |
+
|
323 |
+
@Gojo.on_message(command("chatbroadcast", dev_cmd=True))
|
324 |
+
async def chat_broadcast(c: Gojo, m: Message):
|
325 |
+
if m.reply_to_message:
|
326 |
+
msg = m.reply_to_message.text.markdown
|
327 |
+
else:
|
328 |
+
await m.reply_text("Reply to a message to broadcast it")
|
329 |
+
return
|
330 |
+
|
331 |
+
exmsg = await m.reply_text("Started broadcasting!")
|
332 |
+
all_chats = (Chats.list_chats_by_id()) or {}
|
333 |
+
err_str, done_broadcast = "", 0
|
334 |
+
|
335 |
+
for chat in all_chats:
|
336 |
+
try:
|
337 |
+
await c.send_message(chat, msg, disable_web_page_preview=True)
|
338 |
+
done_broadcast += 1
|
339 |
+
await sleep(0.1)
|
340 |
+
except RPCError as ef:
|
341 |
+
LOGGER.error(ef)
|
342 |
+
err_str += str(ef)
|
343 |
+
continue
|
344 |
+
|
345 |
+
await exmsg.edit_text(
|
346 |
+
f"Done broadcasting ✅\nSent message to {done_broadcast} chats",
|
347 |
+
)
|
348 |
+
|
349 |
+
if err_str:
|
350 |
+
with BytesIO(str.encode(await remove_markdown_and_html(err_str))) as f:
|
351 |
+
f.name = "error_broadcast.txt"
|
352 |
+
await m.reply_document(
|
353 |
+
document=f,
|
354 |
+
caption="Broadcast Error",
|
355 |
+
)
|
356 |
+
|
357 |
+
return
|
358 |
+
|
359 |
+
|
360 |
+
_DISABLE_CMDS_ = ["ping"]
|
Powers/plugins/disable.py
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from html import escape
|
2 |
+
|
3 |
+
from pyrogram import filters
|
4 |
+
from pyrogram.types import (
|
5 |
+
CallbackQuery,
|
6 |
+
InlineKeyboardButton,
|
7 |
+
InlineKeyboardMarkup,
|
8 |
+
Message,
|
9 |
+
)
|
10 |
+
|
11 |
+
from Powers import HELP_COMMANDS, LOGGER
|
12 |
+
from Powers.bot_class import Gojo
|
13 |
+
from Powers.database.disable_db import Disabling
|
14 |
+
from Powers.utils.custom_filters import (
|
15 |
+
admin_filter,
|
16 |
+
can_change_filter,
|
17 |
+
command,
|
18 |
+
owner_filter,
|
19 |
+
)
|
20 |
+
|
21 |
+
|
22 |
+
@Gojo.on_message(command("disable") & can_change_filter)
|
23 |
+
async def disableit(_, m: Message):
|
24 |
+
if len(m.text.split()) < 2:
|
25 |
+
return await m.reply_text("What to disable?")
|
26 |
+
disable_cmd_keys = sorted(
|
27 |
+
k
|
28 |
+
for j in [HELP_COMMANDS[i]["disablable"] for i in list(HELP_COMMANDS.keys())]
|
29 |
+
for k in j
|
30 |
+
)
|
31 |
+
|
32 |
+
db = Disabling(m.chat.id)
|
33 |
+
disable_list = db.get_disabled()
|
34 |
+
LOGGER.info(f"{m.from_user.id} used disabled cmd in {m.chat.id}")
|
35 |
+
|
36 |
+
if str(m.text.split(None, 1)[1]) in disable_list:
|
37 |
+
return await m.reply_text("It's already disabled!")
|
38 |
+
|
39 |
+
if str((m.text.split(None, 1)[1]).lower()) in disable_cmd_keys:
|
40 |
+
db.add_disable((str(m.text.split(None, 1)[1])).lower())
|
41 |
+
return await m.reply_text(f"Disabled {m.text.split(None, 1)[1]}!")
|
42 |
+
if str(m.text.split(None, 1)[1]) not in disable_cmd_keys:
|
43 |
+
return await m.reply_text("Can't do it sorry !")
|
44 |
+
|
45 |
+
|
46 |
+
@Gojo.on_message(command("disabledel") & can_change_filter)
|
47 |
+
async def set_dsbl_action(_, m: Message):
|
48 |
+
db = Disabling(m.chat.id)
|
49 |
+
|
50 |
+
status = db.get_action()
|
51 |
+
if status == "none":
|
52 |
+
cur = False
|
53 |
+
else:
|
54 |
+
cur = True
|
55 |
+
args = m.text.split(" ", 1)
|
56 |
+
|
57 |
+
LOGGER.info(f"{m.from_user.id} disabledel used in {m.chat.id}")
|
58 |
+
|
59 |
+
if len(args) >= 2:
|
60 |
+
if args[1].lower() == "on":
|
61 |
+
db.set_action("del")
|
62 |
+
await m.reply_text("Oke done!")
|
63 |
+
elif args[1].lower() == "off":
|
64 |
+
db.set_action("none")
|
65 |
+
await m.reply_text("Oke i will not delete!")
|
66 |
+
else:
|
67 |
+
await m.reply_text("what are you trying to do ??")
|
68 |
+
else:
|
69 |
+
await m.reply_text(f"Current settings:- {cur}")
|
70 |
+
return
|
71 |
+
|
72 |
+
|
73 |
+
@Gojo.on_message(command("enable") & can_change_filter)
|
74 |
+
async def enableit(_, m: Message):
|
75 |
+
if len(m.text.split()) < 2:
|
76 |
+
return await m.reply_text("What to enable?")
|
77 |
+
db = Disabling(m.chat.id)
|
78 |
+
disable_list = db.get_disabled()
|
79 |
+
if str(m.text.split(None, 1)[1]) not in disable_list:
|
80 |
+
return await m.reply_text("It's not disabled!")
|
81 |
+
db.remove_disabled((str(m.text.split(None, 1)[1])).lower())
|
82 |
+
LOGGER.info(f"{m.from_user.id} enabled something in {m.chat.id}")
|
83 |
+
return await m.reply_text(f"Enabled {m.text.split(None, 1)[1]}!")
|
84 |
+
|
85 |
+
|
86 |
+
@Gojo.on_message(command("disableable") & can_change_filter)
|
87 |
+
async def disabling(_, m: Message):
|
88 |
+
disable_cmd_keys = sorted(
|
89 |
+
k
|
90 |
+
for j in [HELP_COMMANDS[i]["disablable"] for i in list(HELP_COMMANDS.keys())]
|
91 |
+
for k in j
|
92 |
+
)
|
93 |
+
tes = "List of commnds that can be disabled:\n"
|
94 |
+
tes += "\n".join(f" • <code>{escape(i)}</code>" for i in disable_cmd_keys)
|
95 |
+
LOGGER.info(f"{m.from_user.id} checked disableable {m.chat.id}")
|
96 |
+
return await m.reply_text(tes)
|
97 |
+
|
98 |
+
|
99 |
+
@Gojo.on_message(command("disabled") & admin_filter)
|
100 |
+
async def disabled(_, m: Message):
|
101 |
+
db = Disabling(m.chat.id)
|
102 |
+
disable_list = db.get_disabled()
|
103 |
+
if not disable_list:
|
104 |
+
await m.reply_text("No disabled items!")
|
105 |
+
return
|
106 |
+
tex = "Disabled commands:\n"
|
107 |
+
tex += "\n".join(f" • <code>{escape(i)}</code>" for i in disable_list)
|
108 |
+
LOGGER.info(f"{m.from_user.id} checked disabled {m.chat.id}")
|
109 |
+
return await m.reply_text(tex)
|
110 |
+
|
111 |
+
|
112 |
+
@Gojo.on_message(command("enableall") & owner_filter)
|
113 |
+
async def rm_alldisbl(_, m: Message):
|
114 |
+
db = Disabling(m.chat.id)
|
115 |
+
all_dsbl = db.get_disabled()
|
116 |
+
if not all_dsbl:
|
117 |
+
await m.reply_text("No disabled commands in this chat")
|
118 |
+
return
|
119 |
+
await m.reply_text(
|
120 |
+
"Are you sure you want to enable all?",
|
121 |
+
reply_markup=InlineKeyboardMarkup(
|
122 |
+
[
|
123 |
+
[
|
124 |
+
InlineKeyboardButton(
|
125 |
+
"Confirm",
|
126 |
+
callback_data="enableallcmds",
|
127 |
+
),
|
128 |
+
InlineKeyboardButton("Cancel", callback_data="close_admin"),
|
129 |
+
],
|
130 |
+
],
|
131 |
+
),
|
132 |
+
)
|
133 |
+
return
|
134 |
+
|
135 |
+
|
136 |
+
@Gojo.on_callback_query(filters.regex("^enableallcmds$"))
|
137 |
+
async def enablealll(_, q: CallbackQuery):
|
138 |
+
user_id = q.from_user.id
|
139 |
+
user_status = (await q.message.chat.get_member(user_id)).status
|
140 |
+
if user_status not in {"creator", "administrator"}:
|
141 |
+
await q.answer(
|
142 |
+
"You're not even an admin, don't try this explosive shit!",
|
143 |
+
show_alert=True,
|
144 |
+
)
|
145 |
+
return
|
146 |
+
if user_status != "creator":
|
147 |
+
await q.answer(
|
148 |
+
"You're just an admin, not owner\nStay in your limits!",
|
149 |
+
show_alert=True,
|
150 |
+
)
|
151 |
+
return
|
152 |
+
db = Disabling(q.message.chat.id)
|
153 |
+
db.rm_all_disabled()
|
154 |
+
LOGGER.info(f"{user_id} enabled all in {q.message.chat.id}")
|
155 |
+
await q.message.edit_text("Enabled all!", show_alert=True)
|
156 |
+
return
|
Powers/plugins/filters.py
ADDED
@@ -0,0 +1,301 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from re import escape as re_escape
|
2 |
+
from secrets import choice
|
3 |
+
from traceback import format_exc
|
4 |
+
|
5 |
+
from pyrogram import filters
|
6 |
+
from pyrogram.errors import RPCError
|
7 |
+
from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, Message
|
8 |
+
|
9 |
+
from Powers.bot_class import LOGGER, Gojo
|
10 |
+
from Powers.database.filters_db import Filters
|
11 |
+
from Powers.utils.cmd_senders import send_cmd
|
12 |
+
from Powers.utils.custom_filters import admin_filter, command, owner_filter
|
13 |
+
from Powers.utils.kbhelpers import ikb
|
14 |
+
from Powers.utils.msg_types import Types, get_filter_type
|
15 |
+
from Powers.utils.regex_utils import regex_searcher
|
16 |
+
from Powers.utils.string import (
|
17 |
+
build_keyboard,
|
18 |
+
escape_mentions_using_curly_brackets,
|
19 |
+
parse_button,
|
20 |
+
split_quotes,
|
21 |
+
)
|
22 |
+
|
23 |
+
# Initialise
|
24 |
+
db = Filters()
|
25 |
+
|
26 |
+
|
27 |
+
@Gojo.on_message(command("filters") & filters.group & ~filters.bot)
|
28 |
+
async def view_filters(_, m: Message):
|
29 |
+
LOGGER.info(f"{m.from_user.id} checking filters in {m.chat.id}")
|
30 |
+
|
31 |
+
filters_chat = f"Filters in <b>{m.chat.title}</b>:\n"
|
32 |
+
all_filters = db.get_all_filters(m.chat.id)
|
33 |
+
actual_filters = [j for i in all_filters for j in i.split("|")]
|
34 |
+
|
35 |
+
if not actual_filters:
|
36 |
+
await m.reply_text(f"There are no filters in {m.chat.title}")
|
37 |
+
return
|
38 |
+
|
39 |
+
filters_chat += "\n".join(
|
40 |
+
[
|
41 |
+
f" • {' | '.join([f'<code>{i}</code>' for i in i.split('|')])}"
|
42 |
+
for i in all_filters
|
43 |
+
],
|
44 |
+
)
|
45 |
+
return await m.reply_text(filters_chat, disable_web_page_preview=True)
|
46 |
+
|
47 |
+
|
48 |
+
@Gojo.on_message(command(["filter", "addfilter"]) & admin_filter & ~filters.bot)
|
49 |
+
async def add_filter(_, m: Message):
|
50 |
+
|
51 |
+
args = m.text.split(" ", 1)
|
52 |
+
all_filters = db.get_all_filters(m.chat.id)
|
53 |
+
actual_filters = {j for i in all_filters for j in i.split("|")}
|
54 |
+
|
55 |
+
if (len(all_filters) >= 50) and (len(actual_filters) >= 150):
|
56 |
+
await m.reply_text(
|
57 |
+
"Only 50 filters and 150 aliases are allowed per chat!\nTo add more filters, remove the existing ones.",
|
58 |
+
)
|
59 |
+
return
|
60 |
+
|
61 |
+
if not m.reply_to_message and len(m.text.split()) < 3:
|
62 |
+
return await m.reply_text("Please read help section for how to save a filter!")
|
63 |
+
|
64 |
+
if m.reply_to_message and len(args) < 2:
|
65 |
+
return await m.reply_text("Please read help section for how to save a filter!")
|
66 |
+
|
67 |
+
extracted = await split_quotes(args[1])
|
68 |
+
keyword = extracted[0].lower()
|
69 |
+
|
70 |
+
for k in keyword.split("|"):
|
71 |
+
if k in actual_filters:
|
72 |
+
return await m.reply_text(f"Filter <code>{k}</code> already exists!")
|
73 |
+
|
74 |
+
if not keyword:
|
75 |
+
return await m.reply_text(
|
76 |
+
f"<code>{m.text}</code>\n\nError: You must give a name for this Filter!",
|
77 |
+
)
|
78 |
+
|
79 |
+
if keyword.startswith("<") or keyword.startswith(">"):
|
80 |
+
return await m.reply_text("Cannot save a filter which starts with '<' or '>'")
|
81 |
+
|
82 |
+
eee, msgtype, file_id = await get_filter_type(m)
|
83 |
+
lol = eee if m.reply_to_message else extracted[1]
|
84 |
+
teks = lol if msgtype == Types.TEXT else eee
|
85 |
+
|
86 |
+
if not m.reply_to_message and msgtype == Types.TEXT and len(m.text.split()) < 3:
|
87 |
+
return await m.reply_text(
|
88 |
+
f"<code>{m.text}</code>\n\nError: There is no text in here!",
|
89 |
+
)
|
90 |
+
|
91 |
+
if not teks and not msgtype:
|
92 |
+
return await m.reply_text(
|
93 |
+
'Please provide keyword for this filter reply with!\nEnclose filter in <code>"double quotes"</code>',
|
94 |
+
)
|
95 |
+
|
96 |
+
if not msgtype:
|
97 |
+
return await m.reply_text(
|
98 |
+
"Please provide data for this filter reply with!",
|
99 |
+
)
|
100 |
+
|
101 |
+
add = db.save_filter(m.chat.id, keyword, teks, msgtype, file_id)
|
102 |
+
LOGGER.info(f"{m.from_user.id} added new filter ({keyword}) in {m.chat.id}")
|
103 |
+
if add:
|
104 |
+
await m.reply_text(
|
105 |
+
f"Saved filter for '<code>{', '.join(keyword.split('|'))}</code>' in <b>{m.chat.title}</b>!",
|
106 |
+
)
|
107 |
+
await m.stop_propagation()
|
108 |
+
|
109 |
+
|
110 |
+
@Gojo.on_message(command(["stop", "unfilter"]) & admin_filter & ~filters.bot)
|
111 |
+
async def stop_filter(_, m: Message):
|
112 |
+
args = m.command
|
113 |
+
|
114 |
+
if len(args) < 1:
|
115 |
+
return await m.reply_text("What should I stop replying to?")
|
116 |
+
|
117 |
+
chat_filters = db.get_all_filters(m.chat.id)
|
118 |
+
act_filters = {j for i in chat_filters for j in i.split("|")}
|
119 |
+
|
120 |
+
if not chat_filters:
|
121 |
+
return await m.reply_text("No filters active here!")
|
122 |
+
|
123 |
+
for keyword in act_filters:
|
124 |
+
if keyword == m.text.split(None, 1)[1].lower():
|
125 |
+
db.rm_filter(m.chat.id, m.text.split(None, 1)[1].lower())
|
126 |
+
LOGGER.info(f"{m.from_user.id} removed filter ({keyword}) in {m.chat.id}")
|
127 |
+
await m.reply_text(
|
128 |
+
f"Okay, I'll stop replying to that filter and it's aliases in <b>{m.chat.title}</b>.",
|
129 |
+
)
|
130 |
+
await m.stop_propagation()
|
131 |
+
|
132 |
+
await m.reply_text(
|
133 |
+
"That's not a filter - Click: /filters to get currently active filters.",
|
134 |
+
)
|
135 |
+
await m.stop_propagation()
|
136 |
+
|
137 |
+
|
138 |
+
@Gojo.on_message(
|
139 |
+
command(
|
140 |
+
["rmallfilters", "removeallfilters", "stopall", "stopallfilters"],
|
141 |
+
)
|
142 |
+
& owner_filter,
|
143 |
+
)
|
144 |
+
async def rm_allfilters(_, m: Message):
|
145 |
+
all_bls = db.get_all_filters(m.chat.id)
|
146 |
+
if not all_bls:
|
147 |
+
return await m.reply_text("No filters to stop in this chat.")
|
148 |
+
|
149 |
+
return await m.reply_text(
|
150 |
+
"Are you sure you want to clear all filters?",
|
151 |
+
reply_markup=ikb(
|
152 |
+
[[("⚠️ Confirm", "rm_allfilters"), ("❌ Cancel", "close_admin")]],
|
153 |
+
),
|
154 |
+
)
|
155 |
+
|
156 |
+
|
157 |
+
@Gojo.on_callback_query(filters.regex("^rm_allfilters$"))
|
158 |
+
async def rm_allfilters_callback(_, q: CallbackQuery):
|
159 |
+
user_id = q.from_user.id
|
160 |
+
user_status = (await q.message.chat.get_member(user_id)).status
|
161 |
+
if user_status not in {"creator", "administrator"}:
|
162 |
+
await q.answer(
|
163 |
+
"You're not even an admin, don't try this explosive shit!",
|
164 |
+
show_alert=True,
|
165 |
+
)
|
166 |
+
return
|
167 |
+
if user_status != "creator":
|
168 |
+
await q.answer(
|
169 |
+
"You're just an admin, not owner\nStay in your limits!",
|
170 |
+
show_alert=True,
|
171 |
+
)
|
172 |
+
return
|
173 |
+
db.rm_all_filters(q.message.chat.id)
|
174 |
+
await q.message.edit_text(f"Cleared all filters for {q.message.chat.title}")
|
175 |
+
LOGGER.info(f"{user_id} removed all filter from {q.message.chat.id}")
|
176 |
+
await q.answer("Cleared all Filters!", show_alert=True)
|
177 |
+
return
|
178 |
+
|
179 |
+
|
180 |
+
async def send_filter_reply(c: Gojo, m: Message, trigger: str):
|
181 |
+
"""Reply with assigned filter for the trigger"""
|
182 |
+
getfilter = db.get_filter(m.chat.id, trigger)
|
183 |
+
if m and not m.from_user:
|
184 |
+
return
|
185 |
+
|
186 |
+
if not getfilter:
|
187 |
+
return await m.reply_text(
|
188 |
+
"<b>Error:</b> Cannot find a type for this filter!!",
|
189 |
+
quote=True,
|
190 |
+
)
|
191 |
+
|
192 |
+
msgtype = getfilter["msgtype"]
|
193 |
+
if not msgtype:
|
194 |
+
return await m.reply_text("<b>Error:</b> Cannot find a type for this filter!!")
|
195 |
+
|
196 |
+
try:
|
197 |
+
# support for random filter texts
|
198 |
+
splitter = "%%%"
|
199 |
+
filter_reply = getfilter["filter_reply"].split(splitter)
|
200 |
+
filter_reply = choice(filter_reply)
|
201 |
+
except KeyError:
|
202 |
+
filter_reply = ""
|
203 |
+
|
204 |
+
parse_words = [
|
205 |
+
"first",
|
206 |
+
"last",
|
207 |
+
"fullname",
|
208 |
+
"id",
|
209 |
+
"mention",
|
210 |
+
"username",
|
211 |
+
"chatname",
|
212 |
+
]
|
213 |
+
text = await escape_mentions_using_curly_brackets(m, filter_reply, parse_words)
|
214 |
+
teks, button = await parse_button(text)
|
215 |
+
button = await build_keyboard(button)
|
216 |
+
button = InlineKeyboardMarkup(button) if button else None
|
217 |
+
textt = teks
|
218 |
+
try:
|
219 |
+
if msgtype == Types.TEXT:
|
220 |
+
if button:
|
221 |
+
try:
|
222 |
+
await m.reply_text(
|
223 |
+
textt,
|
224 |
+
# parse_mode="markdown",
|
225 |
+
reply_markup=button,
|
226 |
+
disable_web_page_preview=True,
|
227 |
+
quote=True,
|
228 |
+
)
|
229 |
+
return
|
230 |
+
except RPCError as ef:
|
231 |
+
await m.reply_text(
|
232 |
+
"An error has occured! Cannot parse note.",
|
233 |
+
quote=True,
|
234 |
+
)
|
235 |
+
LOGGER.error(ef)
|
236 |
+
LOGGER.error(format_exc())
|
237 |
+
return
|
238 |
+
else:
|
239 |
+
await m.reply_text(
|
240 |
+
textt,
|
241 |
+
# parse_mode="markdown",
|
242 |
+
quote=True,
|
243 |
+
disable_web_page_preview=True,
|
244 |
+
)
|
245 |
+
return
|
246 |
+
|
247 |
+
elif msgtype in (
|
248 |
+
Types.STICKER,
|
249 |
+
Types.VIDEO_NOTE,
|
250 |
+
Types.CONTACT,
|
251 |
+
Types.ANIMATED_STICKER,
|
252 |
+
):
|
253 |
+
await (await send_cmd(c, msgtype))(
|
254 |
+
m.chat.id,
|
255 |
+
getfilter["fileid"],
|
256 |
+
reply_markup=button,
|
257 |
+
reply_to_message_id=m.message_id,
|
258 |
+
)
|
259 |
+
else:
|
260 |
+
await (await send_cmd(c, msgtype))(
|
261 |
+
m.chat.id,
|
262 |
+
getfilter["fileid"],
|
263 |
+
caption=textt,
|
264 |
+
# parse_mode="markdown",
|
265 |
+
reply_markup=button,
|
266 |
+
reply_to_message_id=m.message_id,
|
267 |
+
)
|
268 |
+
except Exception as ef:
|
269 |
+
await m.reply_text(f"Error in filters: {ef}")
|
270 |
+
return msgtype
|
271 |
+
|
272 |
+
return msgtype
|
273 |
+
|
274 |
+
|
275 |
+
@Gojo.on_message(filters.text & filters.group & ~filters.bot, group=69)
|
276 |
+
async def filters_watcher(c: Gojo, m: Message):
|
277 |
+
|
278 |
+
chat_filters = db.get_all_filters(m.chat.id)
|
279 |
+
actual_filters = {j for i in chat_filters for j in i.split("|")}
|
280 |
+
|
281 |
+
for trigger in actual_filters:
|
282 |
+
pattern = r"( |^|[^\w])" + re_escape(trigger) + r"( |$|[^\w])"
|
283 |
+
match = await regex_searcher(pattern, m.text.lower())
|
284 |
+
if match:
|
285 |
+
try:
|
286 |
+
msgtype = await send_filter_reply(c, m, trigger)
|
287 |
+
LOGGER.info(f"Replied with {msgtype} to {trigger} in {m.chat.id}")
|
288 |
+
except Exception as ef:
|
289 |
+
await m.reply_text(f"Error: {ef}")
|
290 |
+
LOGGER.error(ef)
|
291 |
+
LOGGER.error(format_exc())
|
292 |
+
break
|
293 |
+
continue
|
294 |
+
return
|
295 |
+
|
296 |
+
|
297 |
+
__PLUGIN__ = "filters"
|
298 |
+
|
299 |
+
_DISABLE_CMDS_ = ["filters"]
|
300 |
+
|
301 |
+
__alt_name__ = ["filters", "autoreply"]
|
Powers/plugins/formatting.py
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import CallbackQuery, Message
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.bot_class import Gojo
|
6 |
+
from Powers.tr_engine import tlang
|
7 |
+
from Powers.utils.custom_filters import command
|
8 |
+
from Powers.utils.kbhelpers import ikb
|
9 |
+
|
10 |
+
|
11 |
+
async def gen_formatting_kb(m):
|
12 |
+
return ikb(
|
13 |
+
[
|
14 |
+
[
|
15 |
+
("Markdown Formatting", "formatting.md_formatting"),
|
16 |
+
("Fillings", "formatting.fillings"),
|
17 |
+
],
|
18 |
+
[("Random Content", "formatting.random_content")],
|
19 |
+
[(("« " + (tlang(m, "general.back_btn"))), "commands")],
|
20 |
+
],
|
21 |
+
)
|
22 |
+
|
23 |
+
|
24 |
+
@Gojo.on_message(
|
25 |
+
command(["markdownhelp", "formatting"]) & filters.private,
|
26 |
+
)
|
27 |
+
async def markdownhelp(_, m: Message):
|
28 |
+
await m.reply_text(
|
29 |
+
tlang(m, f"plugins.{__PLUGIN__}.help"),
|
30 |
+
quote=True,
|
31 |
+
reply_markup=(await gen_formatting_kb(m)),
|
32 |
+
)
|
33 |
+
LOGGER.info(f"{m.from_user.id} used cmd '{m.command}' in {m.chat.id}")
|
34 |
+
return
|
35 |
+
|
36 |
+
|
37 |
+
@Gojo.on_callback_query(filters.regex("^formatting."))
|
38 |
+
async def get_formatting_info(_, q: CallbackQuery):
|
39 |
+
cmd = q.data.split(".")[1]
|
40 |
+
kb = ikb([[((tlang(q, "general.back_btn")), "back.formatting")]])
|
41 |
+
|
42 |
+
if cmd == "md_formatting":
|
43 |
+
await q.message.edit_text(
|
44 |
+
tlang(q, "formatting.md_help"),
|
45 |
+
reply_markup=kb,
|
46 |
+
parse_mode="html",
|
47 |
+
)
|
48 |
+
elif cmd == "fillings":
|
49 |
+
await q.message.edit_text(
|
50 |
+
tlang(q, "formatting.filling_help"),
|
51 |
+
reply_markup=kb,
|
52 |
+
parse_mode="html",
|
53 |
+
)
|
54 |
+
elif cmd == "random_content":
|
55 |
+
await q.message.edit_text(
|
56 |
+
tlang(q, "formatting.random_help"),
|
57 |
+
reply_markup=kb,
|
58 |
+
parse_mode="html",
|
59 |
+
)
|
60 |
+
|
61 |
+
await q.answer()
|
62 |
+
return
|
63 |
+
|
64 |
+
|
65 |
+
@Gojo.on_callback_query(filters.regex("^back."))
|
66 |
+
async def send_mod_help(_, q: CallbackQuery):
|
67 |
+
await q.message.edit_text(
|
68 |
+
(tlang(q, "plugins.formatting.help")),
|
69 |
+
reply_markup=(await gen_formatting_kb(q.message)),
|
70 |
+
)
|
71 |
+
await q.answer()
|
72 |
+
return
|
73 |
+
|
74 |
+
|
75 |
+
__PLUGIN__ = "formatting"
|
76 |
+
|
77 |
+
__alt_name__ = ["formatting", "markdownhelp", "markdown"]
|
78 |
+
__buttons__ = [
|
79 |
+
[
|
80 |
+
("Markdown Formatting", "formatting.md_formatting"),
|
81 |
+
("Fillings", "formatting.fillings"),
|
82 |
+
],
|
83 |
+
[("Random Content", "formatting.random_content")],
|
84 |
+
]
|
Powers/plugins/fun.py
ADDED
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from html import escape
|
2 |
+
from secrets import choice
|
3 |
+
import random
|
4 |
+
|
5 |
+
from pyrogram.errors import MessageTooLong
|
6 |
+
from pyrogram.types import Message
|
7 |
+
|
8 |
+
from Powers import LOGGER, DEV_USERS
|
9 |
+
from Powers.bot_class import Gojo
|
10 |
+
from Powers.tr_engine import tlang
|
11 |
+
from Powers.utils import fun_strings
|
12 |
+
from Powers.utils.custom_filters import command
|
13 |
+
from Powers.utils.extract_user import extract_user
|
14 |
+
|
15 |
+
|
16 |
+
|
17 |
+
@Gojo.on_message(command("shout"))
|
18 |
+
async def fun_shout(_, m: Message):
|
19 |
+
if len(m.text.split()) == 1:
|
20 |
+
await m.reply_text(
|
21 |
+
(tlang(m, "general.check_help")),
|
22 |
+
quote=True,
|
23 |
+
)
|
24 |
+
return
|
25 |
+
try:
|
26 |
+
text = " ".join(m.text.split(None, 1)[1])
|
27 |
+
result = [" ".join(list(text))]
|
28 |
+
for pos, symbol in enumerate(text[1:]):
|
29 |
+
result.append(symbol + " " + " " * pos + symbol)
|
30 |
+
result = list("\n".join(result))
|
31 |
+
result[0] = text[0]
|
32 |
+
result = "".join(result)
|
33 |
+
msg = "```\n" + result + "```"
|
34 |
+
await m.reply_text(msg, parse_mode="markdown")
|
35 |
+
LOGGER.info(f"{m.from_user.id} shouted in {m.chat.id}")
|
36 |
+
return
|
37 |
+
except MessageTooLong as e:
|
38 |
+
await m.reply_text(f"Error: {e}")
|
39 |
+
return
|
40 |
+
|
41 |
+
|
42 |
+
@Gojo.on_message(command("runs"))
|
43 |
+
async def fun_run(_, m: Message):
|
44 |
+
await m.reply_text(choice(fun_strings.RUN_STRINGS))
|
45 |
+
LOGGER.info(f"{m.from_user.id} runed in {m.chat.id}")
|
46 |
+
return
|
47 |
+
|
48 |
+
|
49 |
+
@Gojo.on_message(command("slap"))
|
50 |
+
async def fun_slap(c: Gojo, m: Message):
|
51 |
+
me = await c.get_me()
|
52 |
+
|
53 |
+
reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text
|
54 |
+
|
55 |
+
curr_user = escape(m.from_user.first_name)
|
56 |
+
try:
|
57 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
58 |
+
except Exception:
|
59 |
+
return
|
60 |
+
|
61 |
+
if user_id == me.id:
|
62 |
+
temp = choice(fun_strings.SLAP_GOJO_TEMPLATES)
|
63 |
+
else:
|
64 |
+
temp = choice(fun_strings.SLAP_TEMPLATES)
|
65 |
+
|
66 |
+
if user_id:
|
67 |
+
user1 = curr_user
|
68 |
+
user2 = escape(user_first_name)
|
69 |
+
|
70 |
+
else:
|
71 |
+
user1 = me.first_name
|
72 |
+
user2 = curr_user
|
73 |
+
|
74 |
+
item = choice(fun_strings.ITEMS)
|
75 |
+
hit = choice(fun_strings.HIT)
|
76 |
+
throw = choice(fun_strings.THROW)
|
77 |
+
|
78 |
+
reply = temp.format(user1=user1, user2=user2, item=item, hits=hit, throws=throw)
|
79 |
+
await reply_text(reply)
|
80 |
+
LOGGER.info(f"{m.from_user.id} slaped in {m.chat.id}")
|
81 |
+
return
|
82 |
+
|
83 |
+
|
84 |
+
@Gojo.on_message(command("roll"))
|
85 |
+
async def fun_roll(_, m: Message):
|
86 |
+
reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text
|
87 |
+
await reply_text(choice(range(1, 7)))
|
88 |
+
LOGGER.info(f"{m.from_user.id} roll in {m.chat.id}")
|
89 |
+
return
|
90 |
+
|
91 |
+
|
92 |
+
@Gojo.on_message(command("toss"))
|
93 |
+
async def fun_toss(_, m: Message):
|
94 |
+
reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text
|
95 |
+
await reply_text(choice(fun_strings.TOSS))
|
96 |
+
LOGGER.info(f"{m.from_user.id} tossed in {m.chat.id}")
|
97 |
+
return
|
98 |
+
|
99 |
+
@Gojo.on_message(command("insult"))
|
100 |
+
async def insult(c : Gojo , m: Message):
|
101 |
+
try:
|
102 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
103 |
+
except:
|
104 |
+
return
|
105 |
+
if user_id in DEV_USERS:
|
106 |
+
await m.reply_text("Sorry! I can't insult my devs....")
|
107 |
+
Insult_omp = random.choice(fun_strings.INSULT_STRINGS)
|
108 |
+
reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text
|
109 |
+
await reply_text(Insult_omp)
|
110 |
+
LOGGER.info(f"{m.from_user.id} insulted {user_first_name} in {m.chat.id}")
|
111 |
+
|
112 |
+
|
113 |
+
|
114 |
+
@Gojo.on_message(command("shrug"))
|
115 |
+
async def fun_shrug(_, m: Message):
|
116 |
+
reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text
|
117 |
+
await reply_text(r"¯\_(ツ)_/¯")
|
118 |
+
LOGGER.info(f"{m.from_user.id} shruged in {m.chat.id}")
|
119 |
+
return
|
120 |
+
|
121 |
+
|
122 |
+
@Gojo.on_message(command("bluetext"))
|
123 |
+
async def fun_bluetext(_, m: Message):
|
124 |
+
reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text
|
125 |
+
await reply_text(
|
126 |
+
"/BLUE /TEXT\n/MUST /CLICK\n/I /AM /A /STUPID /ANIMAL /THAT /IS /ATTRACTED /TO /COLORS",
|
127 |
+
)
|
128 |
+
LOGGER.info(f"{m.from_user.id} bluetexted in {m.chat.id}")
|
129 |
+
return
|
130 |
+
|
131 |
+
|
132 |
+
@Gojo.on_message(command("decide"))
|
133 |
+
async def fun_decide(_, m: Message):
|
134 |
+
reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text
|
135 |
+
await reply_text(choice(fun_strings.DECIDE))
|
136 |
+
LOGGER.info(f"{m.from_user.id} decided in {m.chat.id}")
|
137 |
+
return
|
138 |
+
|
139 |
+
|
140 |
+
@Gojo.on_message(command("react"))
|
141 |
+
async def fun_table(_, m: Message):
|
142 |
+
reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text
|
143 |
+
await reply_text(choice(fun_strings.REACTIONS))
|
144 |
+
LOGGER.info(f"{m.from_user.id} reacted in {m.chat.id}")
|
145 |
+
return
|
146 |
+
|
147 |
+
|
148 |
+
@Gojo.on_message(command("weebify"))
|
149 |
+
async def weebify(_, m: Message):
|
150 |
+
if len(m.text.split()) >= 2:
|
151 |
+
args = m.text.split(None, 1)[1]
|
152 |
+
elif m.reply_to_message and len(m.text.split()) == 1:
|
153 |
+
args = m.reply_to_message.text
|
154 |
+
else:
|
155 |
+
await m.reply_text(
|
156 |
+
"Please reply to a message or enter text after command to weebify it.",
|
157 |
+
)
|
158 |
+
return
|
159 |
+
if not args:
|
160 |
+
await m.reply_text(tlang(m, "utils.weebify.weebify_what"))
|
161 |
+
return
|
162 |
+
|
163 |
+
# Use split to convert to list
|
164 |
+
# Not using list itself becuase black changes it to long format...
|
165 |
+
normiefont = "a b c d e f g h i j k l m n o p q r s t u v w x y z".split()
|
166 |
+
weebyfont = "卂 乃 匚 刀 乇 下 厶 卄 工 丁 长 乚 从 𠘨 口 尸 㔿 尺 丂 丅 凵 リ 山 乂 丫 乙".split()
|
167 |
+
|
168 |
+
string = " ".join(args).lower()
|
169 |
+
for normiecharacter in string:
|
170 |
+
if normiecharacter in normiefont:
|
171 |
+
weebycharacter = weebyfont[normiefont.index(normiecharacter)]
|
172 |
+
string = string.replace(normiecharacter, weebycharacter)
|
173 |
+
|
174 |
+
await m.reply_text(
|
175 |
+
(tlang(m, "utils.weebify.weebified_string").format(string=string)),
|
176 |
+
)
|
177 |
+
LOGGER.info(f"{m.from_user.id} weebified '{args}' in {m.chat.id}")
|
178 |
+
return
|
179 |
+
|
180 |
+
|
181 |
+
__PLUGIN__ = "fun"
|
182 |
+
|
183 |
+
_DISABLE_CMDS_ = [
|
184 |
+
"weebify",
|
185 |
+
"decide",
|
186 |
+
"react",
|
187 |
+
"bluetext",
|
188 |
+
"toss",
|
189 |
+
"roll",
|
190 |
+
"slap",
|
191 |
+
"runs",
|
192 |
+
"shout",
|
193 |
+
"insult",
|
194 |
+
"shrug",
|
195 |
+
]
|
Powers/plugins/greetings.py
ADDED
@@ -0,0 +1,479 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from html import escape
|
2 |
+
from secrets import choice
|
3 |
+
|
4 |
+
from pyrogram import filters
|
5 |
+
from pyrogram.errors import ChatAdminRequired, RPCError
|
6 |
+
from pyrogram.types import ChatMemberUpdated, InlineKeyboardMarkup, Message
|
7 |
+
|
8 |
+
from Powers import OWNER_ID
|
9 |
+
from Powers.bot_class import Gojo
|
10 |
+
from Powers.database.antispam_db import GBan
|
11 |
+
from Powers.database.greetings_db import Greetings
|
12 |
+
from Powers.utils.custom_filters import admin_filter, bot_admin_filter, command
|
13 |
+
from Powers.utils.msg_types import Types, get_wlcm_type
|
14 |
+
from Powers.utils.parser import escape_markdown, mention_html
|
15 |
+
from Powers.utils.string import (
|
16 |
+
build_keyboard,
|
17 |
+
escape_invalid_curly_brackets,
|
18 |
+
parse_button,
|
19 |
+
)
|
20 |
+
from Powers.vars import Config
|
21 |
+
|
22 |
+
# Initialize
|
23 |
+
gdb = GBan()
|
24 |
+
|
25 |
+
|
26 |
+
async def escape_mentions_using_curly_brackets_wl(
|
27 |
+
m: ChatMemberUpdated,
|
28 |
+
n: bool,
|
29 |
+
text: str,
|
30 |
+
parse_words: list,
|
31 |
+
) -> str:
|
32 |
+
teks = await escape_invalid_curly_brackets(text, parse_words)
|
33 |
+
if n:
|
34 |
+
user = m.new_chat_member.user if m.new_chat_member else m.from_user
|
35 |
+
else:
|
36 |
+
user = m.old_chat_member.user if m.old_chat_member else m.from_user
|
37 |
+
if teks:
|
38 |
+
teks = teks.format(
|
39 |
+
first=escape(user.first_name),
|
40 |
+
last=escape(user.last_name or user.first_name),
|
41 |
+
fullname=" ".join(
|
42 |
+
[
|
43 |
+
escape(user.first_name),
|
44 |
+
escape(user.last_name),
|
45 |
+
]
|
46 |
+
if user.last_name
|
47 |
+
else [escape(user.first_name)],
|
48 |
+
),
|
49 |
+
username=(
|
50 |
+
"@" + (await escape_markdown(escape(user.username)))
|
51 |
+
if user.username
|
52 |
+
else (await (mention_html(escape(user.first_name), user.id)))
|
53 |
+
),
|
54 |
+
mention=await (mention_html(escape(user.first_name), user.id)),
|
55 |
+
chatname=escape(m.chat.title)
|
56 |
+
if m.chat.type != "private"
|
57 |
+
else escape(user.first_name),
|
58 |
+
id=user.id,
|
59 |
+
)
|
60 |
+
else:
|
61 |
+
teks = ""
|
62 |
+
|
63 |
+
return teks
|
64 |
+
|
65 |
+
|
66 |
+
@Gojo.on_message(command("cleanwelcome") & admin_filter)
|
67 |
+
async def cleanwlcm(_, m: Message):
|
68 |
+
db = Greetings(m.chat.id)
|
69 |
+
status = db.get_current_cleanwelcome_settings()
|
70 |
+
args = m.text.split(" ", 1)
|
71 |
+
|
72 |
+
if len(args) >= 2:
|
73 |
+
if args[1].lower() == "on":
|
74 |
+
db.set_current_cleanwelcome_settings(True)
|
75 |
+
await m.reply_text("Turned on!")
|
76 |
+
return
|
77 |
+
if args[1].lower() == "off":
|
78 |
+
db.set_current_cleanwelcome_settings(False)
|
79 |
+
await m.reply_text("Turned off!")
|
80 |
+
return
|
81 |
+
await m.reply_text("what are you trying to do ??")
|
82 |
+
return
|
83 |
+
await m.reply_text(f"Current settings:- {status}")
|
84 |
+
return
|
85 |
+
|
86 |
+
|
87 |
+
@Gojo.on_message(command("cleangoodbye") & admin_filter)
|
88 |
+
async def cleangdbye(_, m: Message):
|
89 |
+
db = Greetings(m.chat.id)
|
90 |
+
status = db.get_current_cleangoodbye_settings()
|
91 |
+
args = m.text.split(" ", 1)
|
92 |
+
|
93 |
+
if len(args) >= 2:
|
94 |
+
if args[1].lower() == "on":
|
95 |
+
db.set_current_cleangoodbye_settings(True)
|
96 |
+
await m.reply_text("Turned on!")
|
97 |
+
return
|
98 |
+
if args[1].lower() == "off":
|
99 |
+
db.set_current_cleangoodbye_settings(False)
|
100 |
+
await m.reply_text("Turned off!")
|
101 |
+
return
|
102 |
+
await m.reply_text("what are you trying to do ??")
|
103 |
+
return
|
104 |
+
await m.reply_text(f"Current settings:- {status}")
|
105 |
+
return
|
106 |
+
|
107 |
+
|
108 |
+
@Gojo.on_message(command("cleanservice") & admin_filter)
|
109 |
+
async def cleanservice(_, m: Message):
|
110 |
+
db = Greetings(m.chat.id)
|
111 |
+
status = db.get_current_cleanservice_settings()
|
112 |
+
args = m.text.split(" ", 1)
|
113 |
+
|
114 |
+
if len(args) >= 2:
|
115 |
+
if args[1].lower() == "on":
|
116 |
+
db.set_current_cleanservice_settings(True)
|
117 |
+
await m.reply_text("Turned on!")
|
118 |
+
return
|
119 |
+
if args[1].lower() == "off":
|
120 |
+
db.set_current_cleanservice_settings(False)
|
121 |
+
await m.reply_text("Turned off!")
|
122 |
+
return
|
123 |
+
await m.reply_text("what are you trying to do ??")
|
124 |
+
return
|
125 |
+
await m.reply_text(f"Current settings:- {status}")
|
126 |
+
return
|
127 |
+
|
128 |
+
|
129 |
+
@Gojo.on_message(command("setwelcome") & admin_filter & bot_admin_filter)
|
130 |
+
async def save_wlcm(_, m: Message):
|
131 |
+
db = Greetings(m.chat.id)
|
132 |
+
if m and not m.from_user:
|
133 |
+
return
|
134 |
+
args = m.text.split(None, 1)
|
135 |
+
|
136 |
+
if len(args) >= 4096:
|
137 |
+
await m.reply_text(
|
138 |
+
"Word limit exceed !!",
|
139 |
+
)
|
140 |
+
return
|
141 |
+
if not (m.reply_to_message and m.reply_to_message.text) and len(m.command) == 0:
|
142 |
+
await m.reply_text(
|
143 |
+
"Error: There is no text in here! and only text with buttons are supported currently !",
|
144 |
+
)
|
145 |
+
return
|
146 |
+
text, msgtype, _ = await get_wlcm_type(m)
|
147 |
+
|
148 |
+
if not m.reply_to_message and msgtype == Types.TEXT and len(m.command) <= 2:
|
149 |
+
await m.reply_text(f"<code>{m.text}</code>\n\nError: There is no data in here!")
|
150 |
+
return
|
151 |
+
|
152 |
+
if not text and not msgtype:
|
153 |
+
await m.reply_text(
|
154 |
+
"Please provide some data!",
|
155 |
+
)
|
156 |
+
return
|
157 |
+
|
158 |
+
if not msgtype:
|
159 |
+
await m.reply_text("Please provide some data for this to reply with!")
|
160 |
+
return
|
161 |
+
|
162 |
+
db.set_welcome_text(text)
|
163 |
+
await m.reply_text("Saved welcome!")
|
164 |
+
return
|
165 |
+
|
166 |
+
|
167 |
+
@Gojo.on_message(command("setgoodbye") & admin_filter & bot_admin_filter)
|
168 |
+
async def save_gdbye(_, m: Message):
|
169 |
+
db = Greetings(m.chat.id)
|
170 |
+
if m and not m.from_user:
|
171 |
+
return
|
172 |
+
args = m.text.split(None, 1)
|
173 |
+
|
174 |
+
if len(args) >= 4096:
|
175 |
+
await m.reply_text(
|
176 |
+
"Word limit exceeds !!",
|
177 |
+
)
|
178 |
+
return
|
179 |
+
if not (m.reply_to_message and m.reply_to_message.text) and len(m.command) == 0:
|
180 |
+
await m.reply_text(
|
181 |
+
"Error: There is no text in here! and only text with buttons are supported currently !",
|
182 |
+
)
|
183 |
+
return
|
184 |
+
text, msgtype, _ = await get_wlcm_type(m)
|
185 |
+
|
186 |
+
if not m.reply_to_message and msgtype == Types.TEXT and len(m.command) <= 2:
|
187 |
+
await m.reply_text(f"<code>{m.text}</code>\n\nError: There is no data in here!")
|
188 |
+
return
|
189 |
+
|
190 |
+
if not text and not msgtype:
|
191 |
+
await m.reply_text(
|
192 |
+
"Please provide some data!",
|
193 |
+
)
|
194 |
+
return
|
195 |
+
|
196 |
+
if not msgtype:
|
197 |
+
await m.reply_text("Please provide some data for this to reply with!")
|
198 |
+
return
|
199 |
+
|
200 |
+
db.set_goodbye_text(text)
|
201 |
+
await m.reply_text("Saved goodbye!")
|
202 |
+
return
|
203 |
+
|
204 |
+
|
205 |
+
@Gojo.on_message(command("resetgoodbye") & admin_filter & bot_admin_filter)
|
206 |
+
async def resetgb(_, m: Message):
|
207 |
+
db = Greetings(m.chat.id)
|
208 |
+
if m and not m.from_user:
|
209 |
+
return
|
210 |
+
text = "Sad to see you leaving {first}.\nTake Care!"
|
211 |
+
db.set_goodbye_text(text)
|
212 |
+
await m.reply_text("Ok Done!")
|
213 |
+
return
|
214 |
+
|
215 |
+
|
216 |
+
@Gojo.on_message(command("resetwelcome") & admin_filter & bot_admin_filter)
|
217 |
+
async def resetwlcm(_, m: Message):
|
218 |
+
db = Greetings(m.chat.id)
|
219 |
+
if m and not m.from_user:
|
220 |
+
return
|
221 |
+
text = "Hey {first}, welcome to {chatname}!"
|
222 |
+
db.set_welcome_text(text)
|
223 |
+
await m.reply_text("Done!")
|
224 |
+
return
|
225 |
+
|
226 |
+
|
227 |
+
@Gojo.on_message(filters.service & filters.group, group=59)
|
228 |
+
async def cleannnnn(_, m: Message):
|
229 |
+
db = Greetings(m.chat.id)
|
230 |
+
clean = db.get_current_cleanservice_settings()
|
231 |
+
try:
|
232 |
+
if clean:
|
233 |
+
await m.delete()
|
234 |
+
except Exception:
|
235 |
+
pass
|
236 |
+
|
237 |
+
|
238 |
+
@Gojo.on_chat_member_updated(filters.group, group=69)
|
239 |
+
async def member_has_joined(c: Gojo, member: ChatMemberUpdated):
|
240 |
+
|
241 |
+
if (
|
242 |
+
member.new_chat_member
|
243 |
+
and member.new_chat_member.status not in {"banned", "left", "restricted"}
|
244 |
+
and not member.old_chat_member
|
245 |
+
):
|
246 |
+
pass
|
247 |
+
else:
|
248 |
+
return
|
249 |
+
|
250 |
+
user = member.new_chat_member.user if member.new_chat_member else member.from_user
|
251 |
+
|
252 |
+
db = Greetings(member.chat.id)
|
253 |
+
banned_users = gdb.check_gban(user.id)
|
254 |
+
try:
|
255 |
+
if user.id == Config.BOT_ID:
|
256 |
+
return
|
257 |
+
if user.id == OWNER_ID:
|
258 |
+
await c.send_message(
|
259 |
+
member.chat.id,
|
260 |
+
"Wew My Owner has also joined the chat!",
|
261 |
+
)
|
262 |
+
return
|
263 |
+
if banned_users:
|
264 |
+
await member.chat.ban_member(user.id)
|
265 |
+
await c.send_message(
|
266 |
+
member.chat.id,
|
267 |
+
f"{user.mention} was globally banned so i banned!",
|
268 |
+
)
|
269 |
+
return
|
270 |
+
if user.is_bot:
|
271 |
+
return # ignore bots
|
272 |
+
except ChatAdminRequired:
|
273 |
+
return
|
274 |
+
status = db.get_welcome_status()
|
275 |
+
oo = db.get_welcome_text()
|
276 |
+
parse_words = [
|
277 |
+
"first",
|
278 |
+
"last",
|
279 |
+
"fullname",
|
280 |
+
"username",
|
281 |
+
"mention",
|
282 |
+
"id",
|
283 |
+
"chatname",
|
284 |
+
]
|
285 |
+
hmm = await escape_mentions_using_curly_brackets_wl(member, True, oo, parse_words)
|
286 |
+
if status:
|
287 |
+
tek, button = await parse_button(hmm)
|
288 |
+
button = await build_keyboard(button)
|
289 |
+
button = InlineKeyboardMarkup(button) if button else None
|
290 |
+
|
291 |
+
if "%%%" in tek:
|
292 |
+
filter_reply = tek.split("%%%")
|
293 |
+
teks = choice(filter_reply)
|
294 |
+
else:
|
295 |
+
teks = tek
|
296 |
+
ifff = db.get_current_cleanwelcome_id()
|
297 |
+
gg = db.get_current_cleanwelcome_settings()
|
298 |
+
if ifff and gg:
|
299 |
+
try:
|
300 |
+
await c.delete_messages(member.chat.id, int(ifff))
|
301 |
+
except RPCError:
|
302 |
+
pass
|
303 |
+
try:
|
304 |
+
jj = await c.send_message(
|
305 |
+
member.chat.id,
|
306 |
+
text=teks,
|
307 |
+
reply_markup=button,
|
308 |
+
disable_web_page_preview=True,
|
309 |
+
)
|
310 |
+
if jj:
|
311 |
+
db.set_cleanwlcm_id(int(jj.message_id))
|
312 |
+
except RPCError as e:
|
313 |
+
print(e)
|
314 |
+
return
|
315 |
+
else:
|
316 |
+
return
|
317 |
+
|
318 |
+
|
319 |
+
@Gojo.on_chat_member_updated(filters.group, group=99)
|
320 |
+
async def member_has_left(c: Gojo, member: ChatMemberUpdated):
|
321 |
+
|
322 |
+
if (
|
323 |
+
not member.new_chat_member
|
324 |
+
and member.old_chat_member.status not in {"banned", "restricted"}
|
325 |
+
and member.old_chat_member
|
326 |
+
):
|
327 |
+
pass
|
328 |
+
else:
|
329 |
+
return
|
330 |
+
db = Greetings(member.chat.id)
|
331 |
+
status = db.get_goodbye_status()
|
332 |
+
oo = db.get_goodbye_text()
|
333 |
+
parse_words = [
|
334 |
+
"first",
|
335 |
+
"last",
|
336 |
+
"fullname",
|
337 |
+
"id",
|
338 |
+
"username",
|
339 |
+
"mention",
|
340 |
+
"chatname",
|
341 |
+
]
|
342 |
+
|
343 |
+
user = member.old_chat_member.user if member.old_chat_member else member.from_user
|
344 |
+
|
345 |
+
hmm = await escape_mentions_using_curly_brackets_wl(member, False, oo, parse_words)
|
346 |
+
if status:
|
347 |
+
tek, button = await parse_button(hmm)
|
348 |
+
button = await build_keyboard(button)
|
349 |
+
button = InlineKeyboardMarkup(button) if button else None
|
350 |
+
|
351 |
+
if "%%%" in tek:
|
352 |
+
filter_reply = tek.split("%%%")
|
353 |
+
teks = choice(filter_reply)
|
354 |
+
else:
|
355 |
+
teks = tek
|
356 |
+
ifff = db.get_current_cleangoodbye_id()
|
357 |
+
iii = db.get_current_cleangoodbye_settings()
|
358 |
+
if ifff and iii:
|
359 |
+
try:
|
360 |
+
await c.delete_messages(member.chat.id, int(ifff))
|
361 |
+
except RPCError:
|
362 |
+
pass
|
363 |
+
if user.id == OWNER_ID:
|
364 |
+
await c.send_message(
|
365 |
+
member.chat.id,
|
366 |
+
"Will miss you :)",
|
367 |
+
)
|
368 |
+
return
|
369 |
+
try:
|
370 |
+
ooo = await c.send_message(
|
371 |
+
member.chat.id,
|
372 |
+
text=teks,
|
373 |
+
reply_markup=button,
|
374 |
+
disable_web_page_preview=True,
|
375 |
+
)
|
376 |
+
if ooo:
|
377 |
+
db.set_cleangoodbye_id(int(ooo.message_id))
|
378 |
+
return
|
379 |
+
except RPCError as e:
|
380 |
+
print(e)
|
381 |
+
return
|
382 |
+
else:
|
383 |
+
return
|
384 |
+
|
385 |
+
|
386 |
+
@Gojo.on_message(command("welcome") & admin_filter)
|
387 |
+
async def welcome(c: Gojo, m: Message):
|
388 |
+
db = Greetings(m.chat.id)
|
389 |
+
status = db.get_welcome_status()
|
390 |
+
oo = db.get_welcome_text()
|
391 |
+
args = m.text.split(" ", 1)
|
392 |
+
|
393 |
+
if m and not m.from_user:
|
394 |
+
return
|
395 |
+
|
396 |
+
if len(args) >= 2:
|
397 |
+
if args[1].lower() == "noformat":
|
398 |
+
await m.reply_text(
|
399 |
+
f"""Current welcome settings:-
|
400 |
+
Welcome power: {status}
|
401 |
+
Clean Welcome: {db.get_current_cleanwelcome_settings()}
|
402 |
+
Cleaning service: {db.get_current_cleanservice_settings()}
|
403 |
+
Welcome text in no formating:
|
404 |
+
""",
|
405 |
+
)
|
406 |
+
await c.send_message(m.chat.id, text=oo, parse_mode=None)
|
407 |
+
return
|
408 |
+
if args[1].lower() == "on":
|
409 |
+
db.set_current_welcome_settings(True)
|
410 |
+
await m.reply_text("Turned on!")
|
411 |
+
return
|
412 |
+
if args[1].lower() == "off":
|
413 |
+
db.set_current_welcome_settings(False)
|
414 |
+
await m.reply_text("Turned off!")
|
415 |
+
return
|
416 |
+
await m.reply_text("what are you trying to do ??")
|
417 |
+
return
|
418 |
+
await m.reply_text(
|
419 |
+
f"""Current welcome settings:-
|
420 |
+
Welcome power: {status}
|
421 |
+
Clean Welcome: {db.get_current_cleanwelcome_settings()}
|
422 |
+
Cleaning service: {db.get_current_cleanservice_settings()}
|
423 |
+
Welcome text:
|
424 |
+
""",
|
425 |
+
)
|
426 |
+
tek, button = await parse_button(oo)
|
427 |
+
button = await build_keyboard(button)
|
428 |
+
button = InlineKeyboardMarkup(button) if button else None
|
429 |
+
await c.send_message(m.chat.id, text=tek, reply_markup=button)
|
430 |
+
return
|
431 |
+
|
432 |
+
|
433 |
+
@Gojo.on_message(command("goodbye") & admin_filter)
|
434 |
+
async def goodbye(c: Gojo, m: Message):
|
435 |
+
db = Greetings(m.chat.id)
|
436 |
+
status = db.get_goodbye_status()
|
437 |
+
oo = db.get_goodbye_text()
|
438 |
+
args = m.text.split(" ", 1)
|
439 |
+
if m and not m.from_user:
|
440 |
+
return
|
441 |
+
if len(args) >= 2:
|
442 |
+
if args[1].lower() == "noformat":
|
443 |
+
await m.reply_text(
|
444 |
+
f"""Current goodbye settings:-
|
445 |
+
Goodbye power: {status}
|
446 |
+
Clean Goodbye: {db.get_current_cleangoodbye_settings()}
|
447 |
+
Cleaning service: {db.get_current_cleanservice_settings()}
|
448 |
+
Goodbye text in no formating:
|
449 |
+
""",
|
450 |
+
)
|
451 |
+
await c.send_message(m.chat.id, text=oo, parse_mode=None)
|
452 |
+
return
|
453 |
+
if args[1].lower() == "on":
|
454 |
+
db.set_current_goodbye_settings(True)
|
455 |
+
await m.reply_text("Turned on!")
|
456 |
+
return
|
457 |
+
if args[1].lower() == "off":
|
458 |
+
db.set_current_goodbye_settings(False)
|
459 |
+
await m.reply_text("Turned off!")
|
460 |
+
return
|
461 |
+
await m.reply_text("what are you trying to do ??")
|
462 |
+
return
|
463 |
+
await m.reply_text(
|
464 |
+
f"""Current Goodbye settings:-
|
465 |
+
Goodbye power: {status}
|
466 |
+
Clean Goodbye: {db.get_current_cleangoodbye_settings()}
|
467 |
+
Cleaning service: {db.get_current_cleanservice_settings()}
|
468 |
+
Goodbye text:
|
469 |
+
""",
|
470 |
+
)
|
471 |
+
tek, button = await parse_button(oo)
|
472 |
+
button = await build_keyboard(button)
|
473 |
+
button = InlineKeyboardMarkup(button) if button else None
|
474 |
+
await c.send_message(m.chat.id, text=tek, reply_markup=button)
|
475 |
+
return
|
476 |
+
|
477 |
+
|
478 |
+
__PLUGIN__ = "greetings"
|
479 |
+
__alt_name__ = ["welcome", "goodbye", "cleanservice"]
|
Powers/plugins/initial.py
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.errors import RPCError
|
3 |
+
from pyrogram.types import Message
|
4 |
+
|
5 |
+
from Powers import LOGGER
|
6 |
+
from Powers.bot_class import Gojo
|
7 |
+
from Powers.database.approve_db import Approve
|
8 |
+
from Powers.database.blacklist_db import Blacklist
|
9 |
+
from Powers.database.chats_db import Chats
|
10 |
+
from Powers.database.disable_db import Disabling
|
11 |
+
from Powers.database.filters_db import Filters
|
12 |
+
from Powers.database.greetings_db import Greetings
|
13 |
+
from Powers.database.lang_db import Langs
|
14 |
+
from Powers.database.notes_db import Notes, NotesSettings
|
15 |
+
from Powers.database.pins_db import Pins
|
16 |
+
from Powers.database.reporting_db import Reporting
|
17 |
+
from Powers.database.rules_db import Rules
|
18 |
+
from Powers.database.users_db import Users
|
19 |
+
|
20 |
+
|
21 |
+
@Gojo.on_message(filters.group, group=4)
|
22 |
+
async def initial_works(_, m: Message):
|
23 |
+
chatdb = Chats(m.chat.id)
|
24 |
+
try:
|
25 |
+
if m.migrate_to_chat_id or m.migrate_from_chat_id:
|
26 |
+
new_chat = m.migrate_to_chat_id or m.chat.id
|
27 |
+
try:
|
28 |
+
await migrate_chat(m, new_chat)
|
29 |
+
except RPCError as ef:
|
30 |
+
LOGGER.error(ef)
|
31 |
+
return
|
32 |
+
elif m.reply_to_message and not m.forward_from:
|
33 |
+
chatdb.update_chat(
|
34 |
+
m.chat.title,
|
35 |
+
m.reply_to_message.from_user.id,
|
36 |
+
)
|
37 |
+
Users(m.reply_to_message.from_user.id).update_user(
|
38 |
+
(
|
39 |
+
f"{m.reply_to_message.from_user.first_name} {m.reply_to_message.from_user.last_name}"
|
40 |
+
if m.reply_to_message.from_user.last_name
|
41 |
+
else m.reply_to_message.from_user.first_name
|
42 |
+
),
|
43 |
+
m.reply_to_message.from_user.username,
|
44 |
+
)
|
45 |
+
elif m.forward_from and not m.reply_to_message:
|
46 |
+
chatdb.update_chat(
|
47 |
+
m.chat.title,
|
48 |
+
m.forward_from.id,
|
49 |
+
)
|
50 |
+
Users(m.forward_from.id).update_user(
|
51 |
+
(
|
52 |
+
f"{m.forward_from.first_name} {m.forward_from.last_name}"
|
53 |
+
if m.forward_from.last_name
|
54 |
+
else m.forward_from.first_name
|
55 |
+
),
|
56 |
+
m.forward_from.username,
|
57 |
+
)
|
58 |
+
elif m.reply_to_message:
|
59 |
+
chatdb.update_chat(
|
60 |
+
m.chat.title,
|
61 |
+
m.reply_to_message.forward_from.id,
|
62 |
+
)
|
63 |
+
Users(m.forward_from.id).update_user(
|
64 |
+
(
|
65 |
+
f"{m.reply_to_message.forward_from.first_name} {m.reply_to_message.forward_from.last_name}"
|
66 |
+
if m.reply_to_message.forward_from.last_name
|
67 |
+
else m.reply_to_message.forward_from.first_name
|
68 |
+
),
|
69 |
+
m.forward_from.username,
|
70 |
+
)
|
71 |
+
else:
|
72 |
+
chatdb.update_chat(m.chat.title, m.from_user.id)
|
73 |
+
Users(m.from_user.id).update_user(
|
74 |
+
(
|
75 |
+
f"{m.from_user.first_name} {m.from_user.last_name}"
|
76 |
+
if m.from_user.last_name
|
77 |
+
else m.from_user.first_name
|
78 |
+
),
|
79 |
+
m.from_user.username,
|
80 |
+
)
|
81 |
+
except AttributeError:
|
82 |
+
pass # Skip attribute errors!
|
83 |
+
return
|
84 |
+
|
85 |
+
|
86 |
+
async def migrate_chat(m: Message, new_chat: int) -> None:
|
87 |
+
LOGGER.info(f"Migrating from {m.chat.id} to {new_chat}...")
|
88 |
+
langdb = Langs(m.chat.id)
|
89 |
+
notedb = Notes()
|
90 |
+
gdb = Greetings(m.chat.id)
|
91 |
+
ruledb = Rules(m.chat.id)
|
92 |
+
userdb = Users(m.chat.id)
|
93 |
+
chatdb = Chats(m.chat.id)
|
94 |
+
bldb = Blacklist(m.chat.id)
|
95 |
+
approvedb = Approve(m.chat.id)
|
96 |
+
reportdb = Reporting(m.chat.id)
|
97 |
+
notes_settings = NotesSettings()
|
98 |
+
pins_db = Pins(m.chat.id)
|
99 |
+
fldb = Filters()
|
100 |
+
disabl = Disabling(m.chat.id)
|
101 |
+
disabl.migrate_chat(new_chat)
|
102 |
+
gdb.migrate_chat(new_chat)
|
103 |
+
chatdb.migrate_chat(new_chat)
|
104 |
+
userdb.migrate_chat(new_chat)
|
105 |
+
langdb.migrate_chat(new_chat)
|
106 |
+
ruledb.migrate_chat(new_chat)
|
107 |
+
bldb.migrate_chat(new_chat)
|
108 |
+
notedb.migrate_chat(m.chat.id, new_chat)
|
109 |
+
approvedb.migrate_chat(new_chat)
|
110 |
+
reportdb.migrate_chat(new_chat)
|
111 |
+
notes_settings.migrate_chat(m.chat.id, new_chat)
|
112 |
+
pins_db.migrate_chat(new_chat)
|
113 |
+
fldb.migrate_chat(m.chat.id, new_chat)
|
114 |
+
LOGGER.info(f"Successfully migrated from {m.chat.id} to {new_chat}!")
|
Powers/plugins/langs.py
ADDED
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from asyncio import sleep
|
2 |
+
|
3 |
+
from pyrogram import filters
|
4 |
+
from pyrogram.types import CallbackQuery, Message
|
5 |
+
|
6 |
+
from Powers import LOGGER
|
7 |
+
from Powers.bot_class import Gojo
|
8 |
+
from Powers.database.lang_db import Langs
|
9 |
+
from Powers.tr_engine import lang_dict, tlang
|
10 |
+
from Powers.utils.custom_filters import admin_filter, command
|
11 |
+
from Powers.utils.kbhelpers import ikb
|
12 |
+
|
13 |
+
|
14 |
+
async def gen_langs_kb():
|
15 |
+
langs = sorted(list(lang_dict.keys()))
|
16 |
+
return [
|
17 |
+
[
|
18 |
+
(
|
19 |
+
f"{lang_dict[lang]['main']['language_flag']} {lang_dict[lang]['main']['language_name']} ({lang_dict[lang]['main']['lang_sample']})",
|
20 |
+
f"set_lang.{lang}",
|
21 |
+
)
|
22 |
+
for lang in langs
|
23 |
+
],
|
24 |
+
[
|
25 |
+
(
|
26 |
+
"🌎 Help us with translations!",
|
27 |
+
"https://crowdin.com/project/Gojo_Satarou",
|
28 |
+
"url",
|
29 |
+
),
|
30 |
+
],
|
31 |
+
]
|
32 |
+
|
33 |
+
|
34 |
+
@Gojo.on_callback_query(filters.regex("^chlang$"))
|
35 |
+
async def chlang_callback(_, q: CallbackQuery):
|
36 |
+
kb = await gen_langs_kb()
|
37 |
+
kb.append([(f"« {(tlang(q, 'general.back_btn'))}", "start_back")])
|
38 |
+
|
39 |
+
await q.message.edit_text(
|
40 |
+
(tlang(q, "langs.changelang")),
|
41 |
+
reply_markup=ikb(kb),
|
42 |
+
)
|
43 |
+
await q.answer()
|
44 |
+
return
|
45 |
+
|
46 |
+
|
47 |
+
@Gojo.on_callback_query(filters.regex("^close$"), group=3)
|
48 |
+
async def close_btn_callback(_, q: CallbackQuery):
|
49 |
+
await q.message.delete()
|
50 |
+
try:
|
51 |
+
await q.message.reply_to_message.delete()
|
52 |
+
except Exception as ef:
|
53 |
+
LOGGER.error(f"Error: Cannot delete message\n{ef}")
|
54 |
+
await q.answer()
|
55 |
+
return
|
56 |
+
|
57 |
+
|
58 |
+
@Gojo.on_callback_query(filters.regex("^set_lang."))
|
59 |
+
async def set_lang_callback(_, q: CallbackQuery):
|
60 |
+
lang_code = q.data.split(".")[1]
|
61 |
+
|
62 |
+
Langs(q.message.chat.id).set_lang(lang_code)
|
63 |
+
await sleep(0.1)
|
64 |
+
|
65 |
+
if q.message.chat.type == "private":
|
66 |
+
keyboard = ikb([[(f"« {(tlang(q, 'general.back_btn'))}", "start_back")]])
|
67 |
+
else:
|
68 |
+
keyboard = None
|
69 |
+
await q.message.edit_text(
|
70 |
+
f"🌐 {((tlang(q, 'langs.changed')).format(lang_code=lang_code))}",
|
71 |
+
reply_markup=keyboard,
|
72 |
+
)
|
73 |
+
await q.answer()
|
74 |
+
return
|
75 |
+
|
76 |
+
|
77 |
+
@Gojo.on_message(
|
78 |
+
command(["lang", "setlang"]) & (admin_filter | filters.private),
|
79 |
+
group=7,
|
80 |
+
)
|
81 |
+
async def set_lang(_, m: Message):
|
82 |
+
args = m.text.split()
|
83 |
+
|
84 |
+
if len(args) > 2:
|
85 |
+
await m.reply_text(tlang(m, "langs.correct_usage"))
|
86 |
+
return
|
87 |
+
if len(args) == 2:
|
88 |
+
lang_code = args[1]
|
89 |
+
avail_langs = set(lang_dict.keys())
|
90 |
+
if lang_code not in avail_langs:
|
91 |
+
await m.reply_text(
|
92 |
+
f"Please choose a valid language code from: {', '.join(avail_langs)}",
|
93 |
+
)
|
94 |
+
return
|
95 |
+
Langs(m.chat.id).set_lang(lang_code)
|
96 |
+
LOGGER.info(f"{m.from_user.id} change language to {lang_code} in {m.chat.id}")
|
97 |
+
await m.reply_text(
|
98 |
+
f"🌐 {((tlang(m, 'langs.changed')).format(lang_code=lang_code))}",
|
99 |
+
)
|
100 |
+
return
|
101 |
+
await m.reply_text(
|
102 |
+
(tlang(m, "langs.changelang")),
|
103 |
+
reply_markup=ikb(await gen_langs_kb()),
|
104 |
+
)
|
105 |
+
return
|
106 |
+
|
107 |
+
|
108 |
+
__PLUGIN__ = "language"
|
109 |
+
|
110 |
+
__alt_name__ = ["lang", "langs", "languages"]
|
111 |
+
__buttons__ = [
|
112 |
+
[
|
113 |
+
(
|
114 |
+
"🌎 Help us with translations!",
|
115 |
+
"https://t.me/gojo_updates",
|
116 |
+
"url",
|
117 |
+
),
|
118 |
+
],
|
119 |
+
]
|
Powers/plugins/locks.py
ADDED
@@ -0,0 +1,322 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from asyncio import sleep
|
2 |
+
|
3 |
+
from pyrogram.errors import ChatAdminRequired, ChatNotModified, RPCError
|
4 |
+
from pyrogram.types import ChatPermissions, Message
|
5 |
+
|
6 |
+
from Powers import LOGGER
|
7 |
+
from Powers.bot_class import Gojo
|
8 |
+
from Powers.database.approve_db import Approve
|
9 |
+
from Powers.tr_engine import tlang
|
10 |
+
from Powers.utils.custom_filters import command, restrict_filter
|
11 |
+
|
12 |
+
|
13 |
+
@Gojo.on_message(command("locktypes"))
|
14 |
+
async def lock_types(_, m: Message):
|
15 |
+
await m.reply_text(
|
16 |
+
(
|
17 |
+
"**Lock Types:**\n"
|
18 |
+
" - `all` = Everything\n"
|
19 |
+
" - `msg` = Messages\n"
|
20 |
+
" - `media` = Media, such as Photo and Video.\n"
|
21 |
+
" - `polls` = Polls\n"
|
22 |
+
" - `invite` = Add users to Group\n"
|
23 |
+
" - `pin` = Pin Messages\n"
|
24 |
+
" - `info` = Change Group Info\n"
|
25 |
+
" - `webprev` = Web Page Previews\n"
|
26 |
+
" - `inlinebots`, `inline` = Inline bots\n"
|
27 |
+
" - `animations` = Animations\n"
|
28 |
+
" - `games` = Game Bots\n"
|
29 |
+
" - `stickers` = Stickers"
|
30 |
+
),
|
31 |
+
)
|
32 |
+
return
|
33 |
+
|
34 |
+
|
35 |
+
@Gojo.on_message(command("lock") & restrict_filter)
|
36 |
+
async def lock_perm(c: Gojo, m: Message):
|
37 |
+
if len(m.text.split()) < 2:
|
38 |
+
await m.reply_text("Please enter a permission to lock!")
|
39 |
+
return
|
40 |
+
lock_type = m.text.split(None, 1)[1]
|
41 |
+
chat_id = m.chat.id
|
42 |
+
|
43 |
+
if not lock_type:
|
44 |
+
await m.reply_text(tlang(m, "locks.locks_perm_sp"))
|
45 |
+
return
|
46 |
+
|
47 |
+
get_perm = m.chat.permissions
|
48 |
+
|
49 |
+
msg = get_perm.can_send_messages
|
50 |
+
media = get_perm.can_send_media_messages
|
51 |
+
webprev = get_perm.can_add_web_page_previews
|
52 |
+
polls = get_perm.can_send_polls
|
53 |
+
info = get_perm.can_change_info
|
54 |
+
invite = get_perm.can_invite_users
|
55 |
+
pin = get_perm.can_pin_messages
|
56 |
+
stickers = animations = games = inlinebots = None
|
57 |
+
|
58 |
+
if lock_type == "all":
|
59 |
+
try:
|
60 |
+
await c.set_chat_permissions(chat_id, ChatPermissions())
|
61 |
+
LOGGER.info(f"{m.from_user.id} locked all permissions in {m.chat.id}")
|
62 |
+
except ChatNotModified:
|
63 |
+
pass
|
64 |
+
except ChatAdminRequired:
|
65 |
+
await m.reply_text(tlang(m, "general.no_perm_admin"))
|
66 |
+
await m.reply_text("🔒 " + (tlang(m, "locks.lock_all")))
|
67 |
+
await prevent_approved(m)
|
68 |
+
return
|
69 |
+
|
70 |
+
if lock_type == "msg":
|
71 |
+
msg = False
|
72 |
+
perm = "messages"
|
73 |
+
|
74 |
+
elif lock_type == "media":
|
75 |
+
media = False
|
76 |
+
perm = "audios, documents, photos, videos, video notes, voice notes"
|
77 |
+
|
78 |
+
elif lock_type == "stickers":
|
79 |
+
stickers = False
|
80 |
+
perm = "stickers"
|
81 |
+
|
82 |
+
elif lock_type == "animations":
|
83 |
+
animations = False
|
84 |
+
perm = "animations"
|
85 |
+
|
86 |
+
elif lock_type == "games":
|
87 |
+
games = False
|
88 |
+
perm = "games"
|
89 |
+
|
90 |
+
elif lock_type in ("inlinebots", "inline"):
|
91 |
+
inlinebots = False
|
92 |
+
perm = "inline bots"
|
93 |
+
|
94 |
+
elif lock_type == "webprev":
|
95 |
+
webprev = False
|
96 |
+
perm = "web page previews"
|
97 |
+
|
98 |
+
elif lock_type == "polls":
|
99 |
+
polls = False
|
100 |
+
perm = "polls"
|
101 |
+
|
102 |
+
elif lock_type == "info":
|
103 |
+
info = False
|
104 |
+
perm = "info"
|
105 |
+
|
106 |
+
elif lock_type == "invite":
|
107 |
+
invite = False
|
108 |
+
perm = "invite"
|
109 |
+
|
110 |
+
elif lock_type == "pin":
|
111 |
+
pin = False
|
112 |
+
perm = "pin"
|
113 |
+
|
114 |
+
else:
|
115 |
+
await m.reply_text(tlang(m, "locks.invalid_lock"))
|
116 |
+
return
|
117 |
+
|
118 |
+
try:
|
119 |
+
await c.set_chat_permissions(
|
120 |
+
chat_id,
|
121 |
+
ChatPermissions(
|
122 |
+
can_send_messages=msg,
|
123 |
+
can_send_media_messages=media,
|
124 |
+
can_send_other_messages=any([stickers, animations, games, inlinebots]),
|
125 |
+
can_add_web_page_previews=webprev,
|
126 |
+
can_send_polls=polls,
|
127 |
+
can_change_info=info,
|
128 |
+
can_invite_users=invite,
|
129 |
+
can_pin_messages=pin,
|
130 |
+
),
|
131 |
+
)
|
132 |
+
LOGGER.info(f"{m.from_user.id} locked selected permissions in {m.chat.id}")
|
133 |
+
except ChatNotModified:
|
134 |
+
pass
|
135 |
+
except ChatAdminRequired:
|
136 |
+
await m.reply_text(tlang(m, "general.no_perm_admin"))
|
137 |
+
await m.reply_text(
|
138 |
+
"🔒 " + (tlang(m, "locks.locked_perm").format(perm=perm)),
|
139 |
+
)
|
140 |
+
await prevent_approved(m)
|
141 |
+
return
|
142 |
+
|
143 |
+
|
144 |
+
@Gojo.on_message(command("locks") & restrict_filter)
|
145 |
+
async def view_locks(_, m: Message):
|
146 |
+
chkmsg = await m.reply_text(tlang(m, "locks.check_perm_msg"))
|
147 |
+
v_perm = m.chat.permissions
|
148 |
+
|
149 |
+
async def convert_to_emoji(val: bool):
|
150 |
+
if val:
|
151 |
+
return "✅"
|
152 |
+
return "❌"
|
153 |
+
|
154 |
+
vmsg = await convert_to_emoji(v_perm.can_send_messages)
|
155 |
+
vmedia = await convert_to_emoji(v_perm.can_send_media_messages)
|
156 |
+
vother = await convert_to_emoji(v_perm.can_send_other_messages)
|
157 |
+
vwebprev = await convert_to_emoji(v_perm.can_add_web_page_previews)
|
158 |
+
vpolls = await convert_to_emoji(v_perm.can_send_polls)
|
159 |
+
vinfo = await convert_to_emoji(v_perm.can_change_info)
|
160 |
+
vinvite = await convert_to_emoji(v_perm.can_invite_users)
|
161 |
+
vpin = await convert_to_emoji(v_perm.can_pin_messages)
|
162 |
+
|
163 |
+
if v_perm is not None:
|
164 |
+
try:
|
165 |
+
permission_view_str = (tlang(m, "locks.view_perm")).format(
|
166 |
+
vmsg=vmsg,
|
167 |
+
vmedia=vmedia,
|
168 |
+
vother=vother,
|
169 |
+
vwebprev=vwebprev,
|
170 |
+
vpolls=vpolls,
|
171 |
+
vinfo=vinfo,
|
172 |
+
vinvite=vinvite,
|
173 |
+
vpin=vpin,
|
174 |
+
)
|
175 |
+
LOGGER.info(f"{m.from_user.id} used locks cmd in {m.chat.id}")
|
176 |
+
await chkmsg.edit_text(permission_view_str)
|
177 |
+
|
178 |
+
except RPCError as e_f:
|
179 |
+
await chkmsg.edit_text(tlang(m, "general.something_wrong"))
|
180 |
+
await m.reply_text(e_f)
|
181 |
+
return
|
182 |
+
|
183 |
+
|
184 |
+
@Gojo.on_message(command("unlock") & restrict_filter)
|
185 |
+
async def unlock_perm(c: Gojo, m: Message):
|
186 |
+
if len(m.text.split()) < 2:
|
187 |
+
await m.reply_text("Please enter a permission to unlock!")
|
188 |
+
return
|
189 |
+
unlock_type = m.text.split(None, 1)[1]
|
190 |
+
chat_id = m.chat.id
|
191 |
+
|
192 |
+
if not unlock_type:
|
193 |
+
await m.reply_text(tlang(m, "locks.unlocks_perm_sp"))
|
194 |
+
return
|
195 |
+
|
196 |
+
if unlock_type == "all":
|
197 |
+
try:
|
198 |
+
await c.set_chat_permissions(
|
199 |
+
chat_id,
|
200 |
+
ChatPermissions(
|
201 |
+
can_send_messages=True,
|
202 |
+
can_send_media_messages=True,
|
203 |
+
can_send_other_messages=True,
|
204 |
+
can_add_web_page_previews=True,
|
205 |
+
can_send_polls=True,
|
206 |
+
can_change_info=True,
|
207 |
+
can_invite_users=True,
|
208 |
+
can_pin_messages=True,
|
209 |
+
),
|
210 |
+
)
|
211 |
+
LOGGER.info(f"{m.from_user.id} unlocked all permissions in {m.chat.id}")
|
212 |
+
except ChatNotModified:
|
213 |
+
pass
|
214 |
+
except ChatAdminRequired:
|
215 |
+
await m.reply_text(tlang(m, "general.no_perm_admin"))
|
216 |
+
await m.reply_text("🔓 " + (tlang(m, "locks.unlock_all")))
|
217 |
+
await prevent_approved(m)
|
218 |
+
return
|
219 |
+
|
220 |
+
get_uperm = m.chat.permissions
|
221 |
+
|
222 |
+
umsg = get_uperm.can_send_messages
|
223 |
+
umedia = get_uperm.can_send_media_messages
|
224 |
+
uwebprev = get_uperm.can_add_web_page_previews
|
225 |
+
upolls = get_uperm.can_send_polls
|
226 |
+
uinfo = get_uperm.can_change_info
|
227 |
+
uinvite = get_uperm.can_invite_users
|
228 |
+
upin = get_uperm.can_pin_messages
|
229 |
+
ustickers = uanimations = ugames = uinlinebots = None
|
230 |
+
|
231 |
+
if unlock_type == "msg":
|
232 |
+
umsg = True
|
233 |
+
uperm = "messages"
|
234 |
+
|
235 |
+
elif unlock_type == "media":
|
236 |
+
umedia = True
|
237 |
+
uperm = "audios, documents, photos, videos, video notes, voice notes"
|
238 |
+
|
239 |
+
elif unlock_type == "stickers":
|
240 |
+
ustickers = True
|
241 |
+
uperm = "stickers"
|
242 |
+
|
243 |
+
elif unlock_type == "animations":
|
244 |
+
uanimations = True
|
245 |
+
uperm = "animations"
|
246 |
+
|
247 |
+
elif unlock_type == "games":
|
248 |
+
ugames = True
|
249 |
+
uperm = "games"
|
250 |
+
|
251 |
+
elif unlock_type in ("inlinebots", "inline"):
|
252 |
+
uinlinebots = True
|
253 |
+
uperm = "inline bots"
|
254 |
+
|
255 |
+
elif unlock_type == "webprev":
|
256 |
+
uwebprev = True
|
257 |
+
uperm = "web page previews"
|
258 |
+
|
259 |
+
elif unlock_type == "polls":
|
260 |
+
upolls = True
|
261 |
+
uperm = "polls"
|
262 |
+
|
263 |
+
elif unlock_type == "info":
|
264 |
+
uinfo = True
|
265 |
+
uperm = "info"
|
266 |
+
|
267 |
+
elif unlock_type == "invite":
|
268 |
+
uinvite = True
|
269 |
+
uperm = "invite"
|
270 |
+
|
271 |
+
elif unlock_type == "pin":
|
272 |
+
upin = True
|
273 |
+
uperm = "pin"
|
274 |
+
|
275 |
+
else:
|
276 |
+
await m.reply_text(tlang(m, "locks.invalid_lock"))
|
277 |
+
return
|
278 |
+
|
279 |
+
try:
|
280 |
+
LOGGER.info(f"{m.from_user.id} unlocked selected permissions in {m.chat.id}")
|
281 |
+
await c.set_chat_permissions(
|
282 |
+
chat_id,
|
283 |
+
ChatPermissions(
|
284 |
+
can_send_messages=umsg,
|
285 |
+
can_send_media_messages=umedia,
|
286 |
+
can_send_other_messages=any(
|
287 |
+
[ustickers, uanimations, ugames, uinlinebots],
|
288 |
+
),
|
289 |
+
can_add_web_page_previews=uwebprev,
|
290 |
+
can_send_polls=upolls,
|
291 |
+
can_change_info=uinfo,
|
292 |
+
can_invite_users=uinvite,
|
293 |
+
can_pin_messages=upin,
|
294 |
+
),
|
295 |
+
)
|
296 |
+
except ChatNotModified:
|
297 |
+
pass
|
298 |
+
except ChatAdminRequired:
|
299 |
+
await m.reply_text(tlang(m, "general.no_perm_admin"))
|
300 |
+
await m.reply_text(
|
301 |
+
"🔓 " + (tlang(m, "locks.unlocked_perm").format(uperm=uperm)),
|
302 |
+
)
|
303 |
+
await prevent_approved(m)
|
304 |
+
return
|
305 |
+
|
306 |
+
|
307 |
+
async def prevent_approved(m: Message):
|
308 |
+
approved_users = Approve(m.chat.id).list_approved()
|
309 |
+
ul = [user[0] for user in approved_users]
|
310 |
+
for i in ul:
|
311 |
+
try:
|
312 |
+
await m.chat.unban_member(user_id=i)
|
313 |
+
except (ChatAdminRequired, ChatNotModified, RPCError):
|
314 |
+
continue
|
315 |
+
LOGGER.info(f"Approved {i} in {m.chat.id}")
|
316 |
+
await sleep(0.1)
|
317 |
+
return
|
318 |
+
|
319 |
+
|
320 |
+
__PLUGIN__ = "locks"
|
321 |
+
|
322 |
+
__alt_name__ = ["grouplock", "lock", "grouplocks"]
|
Powers/plugins/muting.py
ADDED
@@ -0,0 +1,609 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram.errors import (
|
2 |
+
ChatAdminRequired,
|
3 |
+
RightForbidden,
|
4 |
+
RPCError,
|
5 |
+
UserNotParticipant,
|
6 |
+
)
|
7 |
+
from pyrogram.filters import regex
|
8 |
+
from pyrogram.types import (
|
9 |
+
CallbackQuery,
|
10 |
+
ChatPermissions,
|
11 |
+
InlineKeyboardButton,
|
12 |
+
InlineKeyboardMarkup,
|
13 |
+
Message,
|
14 |
+
)
|
15 |
+
|
16 |
+
from Powers import LOGGER, OWNER_ID, SUPPORT_GROUP, SUPPORT_STAFF
|
17 |
+
from Powers.bot_class import Gojo
|
18 |
+
from Powers.tr_engine import tlang
|
19 |
+
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
20 |
+
from Powers.utils.custom_filters import command, restrict_filter
|
21 |
+
from Powers.utils.extract_user import extract_user
|
22 |
+
from Powers.utils.parser import mention_html
|
23 |
+
from Powers.utils.string import extract_time
|
24 |
+
from Powers.vars import Config
|
25 |
+
|
26 |
+
|
27 |
+
@Gojo.on_message(command("tmute") & restrict_filter)
|
28 |
+
async def tmute_usr(c: Gojo, m: Message):
|
29 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
30 |
+
await m.reply_text("I can't mute nothing!")
|
31 |
+
return
|
32 |
+
|
33 |
+
try:
|
34 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
35 |
+
except Exception:
|
36 |
+
return
|
37 |
+
|
38 |
+
if not user_id:
|
39 |
+
await m.reply_text("Cannot find user to mute !")
|
40 |
+
return
|
41 |
+
if user_id == Config.BOT_ID:
|
42 |
+
await m.reply_text("Huh, why would I mute myself?")
|
43 |
+
return
|
44 |
+
|
45 |
+
if user_id in SUPPORT_STAFF:
|
46 |
+
LOGGER.info(
|
47 |
+
f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
48 |
+
)
|
49 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
50 |
+
return
|
51 |
+
|
52 |
+
try:
|
53 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
54 |
+
except KeyError:
|
55 |
+
admins_group = await admin_cache_reload(m, "mute")
|
56 |
+
|
57 |
+
if user_id in admins_group:
|
58 |
+
await m.reply_text(tlang(m, "admin.mute.admin_cannot_mute"))
|
59 |
+
return
|
60 |
+
|
61 |
+
r_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id
|
62 |
+
|
63 |
+
if m.reply_to_message and len(m.text.split()) >= 2:
|
64 |
+
reason = m.text.split(None, 2)[1]
|
65 |
+
elif not m.reply_to_message and len(m.text.split()) >= 3:
|
66 |
+
reason = m.text.split(None, 2)[2]
|
67 |
+
else:
|
68 |
+
await m.reply_text("Read /help !!")
|
69 |
+
return
|
70 |
+
|
71 |
+
if not reason:
|
72 |
+
await m.reply_text("You haven't specified a time to mute this user for!")
|
73 |
+
return
|
74 |
+
|
75 |
+
split_reason = reason.split(None, 1)
|
76 |
+
time_val = split_reason[0].lower()
|
77 |
+
|
78 |
+
reason = split_reason[1] if len(split_reason) > 1 else ""
|
79 |
+
|
80 |
+
mutetime = await extract_time(m, time_val)
|
81 |
+
|
82 |
+
if not mutetime:
|
83 |
+
return
|
84 |
+
|
85 |
+
try:
|
86 |
+
await m.chat.restrict_member(
|
87 |
+
user_id,
|
88 |
+
ChatPermissions(),
|
89 |
+
mutetime,
|
90 |
+
)
|
91 |
+
LOGGER.info(f"{m.from_user.id} tmuted {user_id} in {m.chat.id}")
|
92 |
+
txt = (tlang(m, "admin.mute.muted_user")).format(
|
93 |
+
admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
94 |
+
muted=(await mention_html(user_first_name, user_id)),
|
95 |
+
)
|
96 |
+
if reason:
|
97 |
+
txt += f"\n<b>Reason</b>: {reason}"
|
98 |
+
keyboard = InlineKeyboardMarkup(
|
99 |
+
[
|
100 |
+
[
|
101 |
+
InlineKeyboardButton(
|
102 |
+
"Unmute",
|
103 |
+
callback_data=f"unmute_={user_id}",
|
104 |
+
),
|
105 |
+
],
|
106 |
+
],
|
107 |
+
)
|
108 |
+
await m.reply_text(txt, reply_markup=keyboard, reply_to_message_id=r_id)
|
109 |
+
except ChatAdminRequired:
|
110 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
111 |
+
except RightForbidden:
|
112 |
+
await m.reply_text(tlang(m, "admin.mute.bot_no_right"))
|
113 |
+
except UserNotParticipant:
|
114 |
+
await m.reply_text("How can I mute a user who is not a part of this chat?")
|
115 |
+
except RPCError as ef:
|
116 |
+
await m.reply_text(
|
117 |
+
(tlang(m, "general.some_error")).format(
|
118 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
119 |
+
ef=ef,
|
120 |
+
),
|
121 |
+
)
|
122 |
+
LOGGER.error(ef)
|
123 |
+
|
124 |
+
return
|
125 |
+
|
126 |
+
|
127 |
+
@Gojo.on_message(command("dtmute") & restrict_filter)
|
128 |
+
async def dtmute_usr(c: Gojo, m: Message):
|
129 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
130 |
+
await m.reply_text("I can't mute nothing!")
|
131 |
+
return
|
132 |
+
|
133 |
+
if not m.reply_to_message:
|
134 |
+
return await m.reply_text("No replied message and user to delete and mute!")
|
135 |
+
|
136 |
+
reason = None
|
137 |
+
user_id = m.reply_to_message.from_user.id
|
138 |
+
user_first_name = m.reply_to_message.from_user.first_name
|
139 |
+
|
140 |
+
if not user_id:
|
141 |
+
await m.reply_text("Cannot find user to mute !")
|
142 |
+
return
|
143 |
+
if user_id == Config.BOT_ID:
|
144 |
+
await m.reply_text("Huh, why would I mute myself?")
|
145 |
+
return
|
146 |
+
|
147 |
+
if user_id in SUPPORT_STAFF:
|
148 |
+
LOGGER.info(
|
149 |
+
f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
150 |
+
)
|
151 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
152 |
+
return
|
153 |
+
|
154 |
+
try:
|
155 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
156 |
+
except KeyError:
|
157 |
+
admins_group = await admin_cache_reload(m, "mute")
|
158 |
+
|
159 |
+
if user_id in admins_group:
|
160 |
+
await m.reply_text(tlang(m, "admin.mute.admin_cannot_mute"))
|
161 |
+
return
|
162 |
+
|
163 |
+
if m.reply_to_message and len(m.text.split()) >= 2:
|
164 |
+
reason = m.text.split(None, 2)[1]
|
165 |
+
elif not m.reply_to_message and len(m.text.split()) >= 3:
|
166 |
+
reason = m.text.split(None, 2)[2]
|
167 |
+
else:
|
168 |
+
await m.reply_text("Read /help !!")
|
169 |
+
return
|
170 |
+
|
171 |
+
if not reason:
|
172 |
+
await m.reply_text("You haven't specified a time to mute this user for!")
|
173 |
+
return
|
174 |
+
|
175 |
+
split_reason = reason.split(None, 1)
|
176 |
+
time_val = split_reason[0].lower()
|
177 |
+
reason = split_reason[1] if len(split_reason) > 1 else ""
|
178 |
+
|
179 |
+
mutetime = await extract_time(m, time_val)
|
180 |
+
|
181 |
+
if not mutetime:
|
182 |
+
return
|
183 |
+
|
184 |
+
try:
|
185 |
+
await m.chat.restrict_member(
|
186 |
+
user_id,
|
187 |
+
ChatPermissions(),
|
188 |
+
mutetime,
|
189 |
+
)
|
190 |
+
LOGGER.info(f"{m.from_user.id} dtmuted {user_id} in {m.chat.id}")
|
191 |
+
await m.reply_to_message.delete()
|
192 |
+
txt = (tlang(m, "admin.mute.muted_user")).format(
|
193 |
+
admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
194 |
+
muted=(await mention_html(user_first_name, user_id)),
|
195 |
+
)
|
196 |
+
if reason:
|
197 |
+
txt += f"\n<b>Reason</b>: {reason}"
|
198 |
+
keyboard = InlineKeyboardMarkup(
|
199 |
+
[
|
200 |
+
[
|
201 |
+
InlineKeyboardButton(
|
202 |
+
"Unmute",
|
203 |
+
callback_data=f"unmute_={user_id}",
|
204 |
+
),
|
205 |
+
],
|
206 |
+
],
|
207 |
+
)
|
208 |
+
await c.send_message(m.chat.id, txt, reply_markup=keyboard)
|
209 |
+
except ChatAdminRequired:
|
210 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
211 |
+
except RightForbidden:
|
212 |
+
await m.reply_text(tlang(m, "admin.mute.bot_no_right"))
|
213 |
+
except UserNotParticipant:
|
214 |
+
await m.reply_text("How can I mute a user who is not a part of this chat?")
|
215 |
+
except RPCError as ef:
|
216 |
+
await m.reply_text(
|
217 |
+
(tlang(m, "general.some_error")).format(
|
218 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
219 |
+
ef=ef,
|
220 |
+
),
|
221 |
+
)
|
222 |
+
LOGGER.error(ef)
|
223 |
+
|
224 |
+
return
|
225 |
+
|
226 |
+
|
227 |
+
@Gojo.on_message(command("stmute") & restrict_filter)
|
228 |
+
async def stmute_usr(c: Gojo, m: Message):
|
229 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
230 |
+
await m.reply_text("I can't mute nothing!")
|
231 |
+
return
|
232 |
+
|
233 |
+
try:
|
234 |
+
user_id, _, _ = await extract_user(c, m)
|
235 |
+
except Exception:
|
236 |
+
return
|
237 |
+
|
238 |
+
if not user_id:
|
239 |
+
await m.reply_text("Cannot find user to mute !")
|
240 |
+
return
|
241 |
+
if user_id == Config.BOT_ID:
|
242 |
+
await m.reply_text("Huh, why would I mute myself?")
|
243 |
+
return
|
244 |
+
|
245 |
+
if user_id in SUPPORT_STAFF:
|
246 |
+
LOGGER.info(
|
247 |
+
f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
248 |
+
)
|
249 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
250 |
+
return
|
251 |
+
|
252 |
+
try:
|
253 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
254 |
+
except KeyError:
|
255 |
+
admins_group = await admin_cache_reload(m, "mute")
|
256 |
+
|
257 |
+
if user_id in admins_group:
|
258 |
+
await m.reply_text(tlang(m, "admin.mute.admin_cannot_mute"))
|
259 |
+
return
|
260 |
+
|
261 |
+
if m.reply_to_message and len(m.text.split()) >= 2:
|
262 |
+
reason = m.text.split(None, 2)[1]
|
263 |
+
elif not m.reply_to_message and len(m.text.split()) >= 3:
|
264 |
+
reason = m.text.split(None, 2)[2]
|
265 |
+
else:
|
266 |
+
await m.reply_text("Read /help !!")
|
267 |
+
return
|
268 |
+
|
269 |
+
if not reason:
|
270 |
+
await m.reply_text("You haven't specified a time to mute this user for!")
|
271 |
+
return
|
272 |
+
|
273 |
+
split_reason = reason.split(None, 1)
|
274 |
+
time_val = split_reason[0].lower()
|
275 |
+
reason = split_reason[1] if len(split_reason) > 1 else ""
|
276 |
+
|
277 |
+
mutetime = await extract_time(m, time_val)
|
278 |
+
|
279 |
+
if not mutetime:
|
280 |
+
return
|
281 |
+
|
282 |
+
try:
|
283 |
+
await m.chat.restrict_member(
|
284 |
+
user_id,
|
285 |
+
ChatPermissions(),
|
286 |
+
mutetime,
|
287 |
+
)
|
288 |
+
LOGGER.info(f"{m.from_user.id} stmuted {user_id} in {m.chat.id}")
|
289 |
+
await m.delete()
|
290 |
+
if m.reply_to_message:
|
291 |
+
await m.reply_to_message.delete()
|
292 |
+
except ChatAdminRequired:
|
293 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
294 |
+
except RightForbidden:
|
295 |
+
await m.reply_text(tlang(m, "admin.mute.bot_no_right"))
|
296 |
+
except UserNotParticipant:
|
297 |
+
await m.reply_text("How can I mute a user who is not a part of this chat?")
|
298 |
+
except RPCError as ef:
|
299 |
+
await m.reply_text(
|
300 |
+
(tlang(m, "general.some_error")).format(
|
301 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
302 |
+
ef=ef,
|
303 |
+
),
|
304 |
+
)
|
305 |
+
LOGGER.error(ef)
|
306 |
+
|
307 |
+
return
|
308 |
+
|
309 |
+
|
310 |
+
@Gojo.on_message(command("mute") & restrict_filter)
|
311 |
+
async def mute_usr(c: Gojo, m: Message):
|
312 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
313 |
+
await m.reply_text("I can't mute nothing!")
|
314 |
+
return
|
315 |
+
|
316 |
+
reason = None
|
317 |
+
if m.reply_to_message:
|
318 |
+
r_id = m.reply_to_message.message_id
|
319 |
+
if len(m.text.split()) >= 2:
|
320 |
+
reason = m.text.split(None, 1)[1]
|
321 |
+
else:
|
322 |
+
r_id = m.message_id
|
323 |
+
if len(m.text.split()) >= 3:
|
324 |
+
reason = m.text.split(None, 2)[2]
|
325 |
+
try:
|
326 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
327 |
+
except Exception:
|
328 |
+
return
|
329 |
+
|
330 |
+
if not user_id:
|
331 |
+
await m.reply_text("Cannot find user to mute")
|
332 |
+
return
|
333 |
+
if user_id == Config.BOT_ID:
|
334 |
+
await m.reply_text("Huh, why would I mute myself?")
|
335 |
+
return
|
336 |
+
|
337 |
+
if user_id in SUPPORT_STAFF:
|
338 |
+
LOGGER.info(
|
339 |
+
f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
340 |
+
)
|
341 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
342 |
+
return
|
343 |
+
|
344 |
+
try:
|
345 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
346 |
+
except KeyError:
|
347 |
+
admins_group = await admin_cache_reload(m, "mute")
|
348 |
+
|
349 |
+
if user_id in admins_group:
|
350 |
+
await m.reply_text(tlang(m, "admin.mute.admin_cannot_mute"))
|
351 |
+
return
|
352 |
+
|
353 |
+
try:
|
354 |
+
await m.chat.restrict_member(
|
355 |
+
user_id,
|
356 |
+
ChatPermissions(),
|
357 |
+
)
|
358 |
+
LOGGER.info(f"{m.from_user.id} muted {user_id} in {m.chat.id}")
|
359 |
+
txt = (tlang(m, "admin.mute.muted_user")).format(
|
360 |
+
admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
361 |
+
muted=(await mention_html(user_first_name, user_id)),
|
362 |
+
)
|
363 |
+
if reason:
|
364 |
+
txt += f"\n<b>Reason</b>: {reason}"
|
365 |
+
keyboard = InlineKeyboardMarkup(
|
366 |
+
[
|
367 |
+
[
|
368 |
+
InlineKeyboardButton(
|
369 |
+
"Unmute",
|
370 |
+
callback_data=f"unmute_={user_id}",
|
371 |
+
),
|
372 |
+
],
|
373 |
+
],
|
374 |
+
)
|
375 |
+
await m.reply_text(txt, reply_markup=keyboard, reply_to_message_id=r_id)
|
376 |
+
except ChatAdminRequired:
|
377 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
378 |
+
except RightForbidden:
|
379 |
+
await m.reply_text(tlang(m, "admin.mute.bot_no_right"))
|
380 |
+
except UserNotParticipant:
|
381 |
+
await m.reply_text("How can I mute a user who is not a part of this chat?")
|
382 |
+
except RPCError as ef:
|
383 |
+
await m.reply_text(
|
384 |
+
(tlang(m, "general.some_error")).format(
|
385 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
386 |
+
ef=ef,
|
387 |
+
),
|
388 |
+
)
|
389 |
+
LOGGER.error(ef)
|
390 |
+
|
391 |
+
return
|
392 |
+
|
393 |
+
|
394 |
+
@Gojo.on_message(command("smute") & restrict_filter)
|
395 |
+
async def smute_usr(c: Gojo, m: Message):
|
396 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
397 |
+
await m.reply_text("I can't mute nothing!")
|
398 |
+
return
|
399 |
+
|
400 |
+
try:
|
401 |
+
user_id, _, _ = await extract_user(c, m)
|
402 |
+
except Exception:
|
403 |
+
return
|
404 |
+
|
405 |
+
if not user_id:
|
406 |
+
await m.reply_text("Cannot find user to mute")
|
407 |
+
return
|
408 |
+
if user_id == Config.BOT_ID:
|
409 |
+
await m.reply_text("Huh, why would I mute myself?")
|
410 |
+
return
|
411 |
+
|
412 |
+
if user_id in SUPPORT_STAFF:
|
413 |
+
LOGGER.info(
|
414 |
+
f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
415 |
+
)
|
416 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
417 |
+
return
|
418 |
+
|
419 |
+
try:
|
420 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
421 |
+
except KeyError:
|
422 |
+
admins_group = await admin_cache_reload(m, "mute")
|
423 |
+
|
424 |
+
if user_id in admins_group:
|
425 |
+
await m.reply_text(tlang(m, "admin.mute.admin_cannot_mute"))
|
426 |
+
return
|
427 |
+
|
428 |
+
try:
|
429 |
+
await m.chat.restrict_member(
|
430 |
+
user_id,
|
431 |
+
ChatPermissions(),
|
432 |
+
)
|
433 |
+
LOGGER.info(f"{m.from_user.id} smuted {user_id} in {m.chat.id}")
|
434 |
+
await m.delete()
|
435 |
+
if m.reply_to_message:
|
436 |
+
await m.reply_to_message.delete()
|
437 |
+
return
|
438 |
+
return
|
439 |
+
except ChatAdminRequired:
|
440 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
441 |
+
except RightForbidden:
|
442 |
+
await m.reply_text(tlang(m, "admin.mute.bot_no_right"))
|
443 |
+
except UserNotParticipant:
|
444 |
+
await m.reply_text("How can I mute a user who is not a part of this chat?")
|
445 |
+
except RPCError as ef:
|
446 |
+
await m.reply_text(
|
447 |
+
(tlang(m, "general.some_error")).format(
|
448 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
449 |
+
ef=ef,
|
450 |
+
),
|
451 |
+
)
|
452 |
+
LOGGER.error(ef)
|
453 |
+
|
454 |
+
return
|
455 |
+
|
456 |
+
|
457 |
+
@Gojo.on_message(command("dmute") & restrict_filter)
|
458 |
+
async def dmute_usr(c: Gojo, m: Message):
|
459 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
460 |
+
await m.reply_text("I can't mute nothing!")
|
461 |
+
return
|
462 |
+
if not m.reply_to_message:
|
463 |
+
return await m.reply_text("No replied message and user to delete and mute!")
|
464 |
+
|
465 |
+
reason = None
|
466 |
+
if m.reply_to_message:
|
467 |
+
if len(m.text.split()) >= 2:
|
468 |
+
reason = m.text.split(None, 1)[1]
|
469 |
+
else:
|
470 |
+
if len(m.text.split()) >= 3:
|
471 |
+
reason = m.text.split(None, 2)[2]
|
472 |
+
user_id = m.reply_to_message.from_user.id
|
473 |
+
user_first_name = m.reply_to_message.from_user.first_name
|
474 |
+
|
475 |
+
if not user_id:
|
476 |
+
await m.reply_text("Cannot find user to mute")
|
477 |
+
return
|
478 |
+
if user_id == Config.BOT_ID:
|
479 |
+
await m.reply_text("Huh, why would I mute myself?")
|
480 |
+
return
|
481 |
+
|
482 |
+
if user_id in SUPPORT_STAFF:
|
483 |
+
LOGGER.info(
|
484 |
+
f"{m.from_user.id} trying to mute {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
485 |
+
)
|
486 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
487 |
+
return
|
488 |
+
|
489 |
+
try:
|
490 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
491 |
+
except KeyError:
|
492 |
+
admins_group = await admin_cache_reload(m, "mute")
|
493 |
+
|
494 |
+
if user_id in admins_group:
|
495 |
+
await m.reply_text(tlang(m, "admin.mute.admin_cannot_mute"))
|
496 |
+
return
|
497 |
+
|
498 |
+
try:
|
499 |
+
await m.chat.restrict_member(
|
500 |
+
user_id,
|
501 |
+
ChatPermissions(),
|
502 |
+
)
|
503 |
+
LOGGER.info(f"{m.from_user.id} dmuted {user_id} in {m.chat.id}")
|
504 |
+
await m.reply_to_message.delete()
|
505 |
+
txt = (tlang(m, "admin.mute.muted_user")).format(
|
506 |
+
admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
507 |
+
muted=(await mention_html(user_first_name, user_id)),
|
508 |
+
)
|
509 |
+
if reason:
|
510 |
+
txt += f"\n<b>Reason</b>: {reason}"
|
511 |
+
keyboard = InlineKeyboardMarkup(
|
512 |
+
[
|
513 |
+
[
|
514 |
+
InlineKeyboardButton(
|
515 |
+
"Unmute",
|
516 |
+
callback_data=f"unmute_={user_id}",
|
517 |
+
),
|
518 |
+
],
|
519 |
+
],
|
520 |
+
)
|
521 |
+
await c.send_message(m.chat.id, txt, reply_markup=keyboard)
|
522 |
+
except ChatAdminRequired:
|
523 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
524 |
+
except RightForbidden:
|
525 |
+
await m.reply_text(tlang(m, "admin.mute.bot_no_right"))
|
526 |
+
except UserNotParticipant:
|
527 |
+
await m.reply_text("How can I mute a user who is not a part of this chat?")
|
528 |
+
except RPCError as ef:
|
529 |
+
await m.reply_text(
|
530 |
+
(tlang(m, "general.some_error")).format(
|
531 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
532 |
+
ef=ef,
|
533 |
+
),
|
534 |
+
)
|
535 |
+
LOGGER.error(ef)
|
536 |
+
|
537 |
+
return
|
538 |
+
|
539 |
+
|
540 |
+
@Gojo.on_message(command("unmute") & restrict_filter)
|
541 |
+
async def unmute_usr(c: Gojo, m: Message):
|
542 |
+
if len(m.text.split()) == 1 and not m.reply_to_message:
|
543 |
+
await m.reply_text("I can't unmute nothing!")
|
544 |
+
return
|
545 |
+
|
546 |
+
try:
|
547 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
548 |
+
except Exception:
|
549 |
+
return
|
550 |
+
|
551 |
+
if user_id == Config.BOT_ID:
|
552 |
+
await m.reply_text("Huh, why would I unmute myself if you are using me?")
|
553 |
+
return
|
554 |
+
|
555 |
+
try:
|
556 |
+
await m.chat.unban_member(user_id)
|
557 |
+
LOGGER.info(f"{m.from_user.id} unmuted {user_id} in {m.chat.id}")
|
558 |
+
await m.reply_text(
|
559 |
+
(tlang(m, "admin.unmute.unmuted_user")).format(
|
560 |
+
admin=(await mention_html(m.from_user.first_name, m.from_user.id)),
|
561 |
+
unmuted=(await mention_html(user_first_name, user_id)),
|
562 |
+
),
|
563 |
+
)
|
564 |
+
except ChatAdminRequired:
|
565 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
566 |
+
except UserNotParticipant:
|
567 |
+
await m.reply_text("How can I unmute a user who is not a part of this chat?")
|
568 |
+
except RightForbidden:
|
569 |
+
await m.reply_text(tlang(m, "admin.unmute.bot_no_right"))
|
570 |
+
except RPCError as ef:
|
571 |
+
await m.reply_text(
|
572 |
+
(tlang(m, "general.some_error")).format(
|
573 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
574 |
+
ef=ef,
|
575 |
+
),
|
576 |
+
)
|
577 |
+
LOGGER.error(ef)
|
578 |
+
return
|
579 |
+
|
580 |
+
|
581 |
+
@Gojo.on_callback_query(regex("^unmute_"))
|
582 |
+
async def unmutebutton(c: Gojo, q: CallbackQuery):
|
583 |
+
splitter = (str(q.data).replace("unmute_", "")).split("=")
|
584 |
+
user_id = int(splitter[1])
|
585 |
+
user = await q.message.chat.get_member(q.from_user.id)
|
586 |
+
|
587 |
+
if not user.can_restrict_members and user.id != OWNER_ID:
|
588 |
+
await q.answer(
|
589 |
+
"You don't have enough permission to do this!\nStay in your limits!",
|
590 |
+
show_alert=True,
|
591 |
+
)
|
592 |
+
return
|
593 |
+
whoo = await c.get_users(user_id)
|
594 |
+
try:
|
595 |
+
await q.message.chat.unban_member(user_id)
|
596 |
+
except RPCError as e:
|
597 |
+
await q.message.edit_text(f"Error: {e}")
|
598 |
+
return
|
599 |
+
await q.message.edit_text(f"{q.from_user.mention} unmuted {whoo.mention}!")
|
600 |
+
return
|
601 |
+
|
602 |
+
|
603 |
+
__PLUGIN__ = "muting"
|
604 |
+
|
605 |
+
__alt_name__ = [
|
606 |
+
"mute",
|
607 |
+
"tmute",
|
608 |
+
"unmute",
|
609 |
+
]
|
Powers/plugins/notes.py
ADDED
@@ -0,0 +1,426 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from secrets import choice
|
2 |
+
from traceback import format_exc
|
3 |
+
|
4 |
+
from pyrogram import filters
|
5 |
+
from pyrogram.errors import RPCError
|
6 |
+
from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, Message
|
7 |
+
|
8 |
+
from Powers import LOGGER
|
9 |
+
from Powers.bot_class import Gojo
|
10 |
+
from Powers.database.notes_db import Notes, NotesSettings
|
11 |
+
from Powers.utils.cmd_senders import send_cmd
|
12 |
+
from Powers.utils.custom_filters import admin_filter, command, owner_filter
|
13 |
+
from Powers.utils.kbhelpers import ikb
|
14 |
+
from Powers.utils.msg_types import Types, get_note_type
|
15 |
+
from Powers.utils.string import (
|
16 |
+
build_keyboard,
|
17 |
+
escape_mentions_using_curly_brackets,
|
18 |
+
parse_button,
|
19 |
+
)
|
20 |
+
from Powers.vars import Config
|
21 |
+
|
22 |
+
# Initialise
|
23 |
+
db = Notes()
|
24 |
+
db_settings = NotesSettings()
|
25 |
+
|
26 |
+
|
27 |
+
@Gojo.on_message(command("save") & admin_filter & ~filters.bot)
|
28 |
+
async def save_note(_, m: Message):
|
29 |
+
existing_notes = {i[0] for i in db.get_all_notes(m.chat.id)}
|
30 |
+
name, text, data_type, content = await get_note_type(m)
|
31 |
+
total_notes = db.get_all_notes(m.chat.id)
|
32 |
+
|
33 |
+
if len(total_notes) >= 1000:
|
34 |
+
await m.reply_text(
|
35 |
+
"Only 1000 Notes are allowed per chat!\nTo add more Notes, remove the existing ones.",
|
36 |
+
)
|
37 |
+
return
|
38 |
+
|
39 |
+
if not name:
|
40 |
+
await m.reply_text(
|
41 |
+
f"<code>{m.text}</code>\n\nError: You must give a name for this note!",
|
42 |
+
)
|
43 |
+
return
|
44 |
+
note_name = name.lower()
|
45 |
+
if note_name in existing_notes:
|
46 |
+
await m.reply_text(f"This note ({note_name}) already exists!")
|
47 |
+
return
|
48 |
+
|
49 |
+
if note_name.startswith("<") or note_name.startswith(">"):
|
50 |
+
await m.reply_text("Cannot save a note which starts with '<' or '>'")
|
51 |
+
return
|
52 |
+
|
53 |
+
if not m.reply_to_message and data_type == Types.TEXT and len(m.text.split()) < 3:
|
54 |
+
await m.reply_text(f"<code>{m.text}</code>\n\nError: There is no text in here!")
|
55 |
+
return
|
56 |
+
|
57 |
+
if not data_type:
|
58 |
+
await m.reply_text(
|
59 |
+
f"<code>{m.text}</code>\n\nError: There is no data in here!",
|
60 |
+
)
|
61 |
+
return
|
62 |
+
|
63 |
+
db.save_note(m.chat.id, note_name, text, data_type, content)
|
64 |
+
LOGGER.info(f"{m.from_user.id} saved note ({note_name}) in {m.chat.id}")
|
65 |
+
await m.reply_text(
|
66 |
+
f"Saved note <code>{note_name}</code>!\nGet it with <code>/get {note_name}</code> or <code>#{note_name}</code>",
|
67 |
+
)
|
68 |
+
return
|
69 |
+
|
70 |
+
|
71 |
+
async def get_note_func(c: Gojo, m: Message, note_name, priv_notes_status):
|
72 |
+
"""Get the note in normal mode, with parsing enabled."""
|
73 |
+
reply_text = m.reply_to_message.reply_text if m.reply_to_message else m.reply_text
|
74 |
+
reply_msg_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id
|
75 |
+
if m and not m.from_user:
|
76 |
+
return
|
77 |
+
|
78 |
+
if priv_notes_status:
|
79 |
+
|
80 |
+
note_hash = next(i[1] for i in db.get_all_notes(m.chat.id) if i[0] == note_name)
|
81 |
+
await reply_text(
|
82 |
+
f"Click on the button to get the note <code>{note_name}</code>",
|
83 |
+
reply_markup=ikb(
|
84 |
+
[
|
85 |
+
[
|
86 |
+
(
|
87 |
+
"Click Me!",
|
88 |
+
f"https://t.me/{Config.BOT_USERNAME}?start=note_{m.chat.id}_{note_hash}",
|
89 |
+
"url",
|
90 |
+
),
|
91 |
+
],
|
92 |
+
],
|
93 |
+
),
|
94 |
+
)
|
95 |
+
return
|
96 |
+
|
97 |
+
getnotes = db.get_note(m.chat.id, note_name)
|
98 |
+
|
99 |
+
msgtype = getnotes["msgtype"]
|
100 |
+
if not msgtype:
|
101 |
+
await reply_text("<b>Error:</b> Cannot find a type for this note!!")
|
102 |
+
return
|
103 |
+
|
104 |
+
try:
|
105 |
+
# support for random notes texts
|
106 |
+
splitter = "%%%"
|
107 |
+
note_reply = getnotes["note_value"].split(splitter)
|
108 |
+
note_reply = choice(note_reply)
|
109 |
+
except KeyError:
|
110 |
+
note_reply = ""
|
111 |
+
|
112 |
+
parse_words = [
|
113 |
+
"first",
|
114 |
+
"last",
|
115 |
+
"fullname",
|
116 |
+
"id",
|
117 |
+
"username",
|
118 |
+
"mention",
|
119 |
+
"chatname",
|
120 |
+
]
|
121 |
+
text = await escape_mentions_using_curly_brackets(m, note_reply, parse_words)
|
122 |
+
teks, button = await parse_button(text)
|
123 |
+
button = await build_keyboard(button)
|
124 |
+
button = InlineKeyboardMarkup(button) if button else None
|
125 |
+
textt = teks
|
126 |
+
|
127 |
+
try:
|
128 |
+
if msgtype == Types.TEXT:
|
129 |
+
if button:
|
130 |
+
try:
|
131 |
+
await reply_text(
|
132 |
+
textt,
|
133 |
+
# parse_mode="markdown",
|
134 |
+
reply_markup=button,
|
135 |
+
disable_web_page_preview=True,
|
136 |
+
quote=True,
|
137 |
+
)
|
138 |
+
return
|
139 |
+
except RPCError as ef:
|
140 |
+
await reply_text(
|
141 |
+
"An error has occured! Cannot parse note.",
|
142 |
+
quote=True,
|
143 |
+
)
|
144 |
+
LOGGER.error(ef)
|
145 |
+
LOGGER.error(format_exc())
|
146 |
+
return
|
147 |
+
else:
|
148 |
+
await reply_text(
|
149 |
+
textt,
|
150 |
+
# parse_mode="markdown",
|
151 |
+
quote=True,
|
152 |
+
disable_web_page_preview=True,
|
153 |
+
)
|
154 |
+
return
|
155 |
+
elif msgtype in (
|
156 |
+
Types.STICKER,
|
157 |
+
Types.VIDEO_NOTE,
|
158 |
+
Types.CONTACT,
|
159 |
+
Types.ANIMATED_STICKER,
|
160 |
+
):
|
161 |
+
await (await send_cmd(c, msgtype))(
|
162 |
+
m.chat.id,
|
163 |
+
getnotes["fileid"],
|
164 |
+
reply_markup=button,
|
165 |
+
reply_to_message_id=reply_msg_id,
|
166 |
+
)
|
167 |
+
elif button:
|
168 |
+
try:
|
169 |
+
await (await send_cmd(c, msgtype))(
|
170 |
+
m.chat.id,
|
171 |
+
getnotes["fileid"],
|
172 |
+
caption=textt,
|
173 |
+
# parse_mode="markdown",
|
174 |
+
reply_markup=button,
|
175 |
+
reply_to_message_id=reply_msg_id,
|
176 |
+
)
|
177 |
+
return
|
178 |
+
except RPCError as ef:
|
179 |
+
await m.reply_text(
|
180 |
+
textt,
|
181 |
+
# parse_mode="markdown",
|
182 |
+
reply_markup=button,
|
183 |
+
disable_web_page_preview=True,
|
184 |
+
reply_to_message_id=reply_msg_id,
|
185 |
+
)
|
186 |
+
LOGGER.error(ef)
|
187 |
+
LOGGER.error(format_exc())
|
188 |
+
return
|
189 |
+
else:
|
190 |
+
await (await send_cmd(c, msgtype))(
|
191 |
+
m.chat.id,
|
192 |
+
getnotes["fileid"],
|
193 |
+
caption=textt,
|
194 |
+
# parse_mode="markdown",
|
195 |
+
reply_markup=button,
|
196 |
+
reply_to_message_id=reply_msg_id,
|
197 |
+
)
|
198 |
+
LOGGER.info(
|
199 |
+
f"{m.from_user.id} fetched note {note_name} (type - {getnotes}) in {m.chat.id}",
|
200 |
+
)
|
201 |
+
except Exception as e:
|
202 |
+
await m.reply_text(f"Error in notes: {e}")
|
203 |
+
return
|
204 |
+
|
205 |
+
|
206 |
+
async def get_raw_note(c: Gojo, m: Message, note: str):
|
207 |
+
"""Get the note in raw format, so it can updated by just copy and pasting."""
|
208 |
+
all_notes = {i[0] for i in db.get_all_notes(m.chat.id)}
|
209 |
+
if m and not m.from_user:
|
210 |
+
return
|
211 |
+
|
212 |
+
if note not in all_notes:
|
213 |
+
await m.reply_text("This note does not exists!")
|
214 |
+
return
|
215 |
+
|
216 |
+
getnotes = db.get_note(m.chat.id, note)
|
217 |
+
msg_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id
|
218 |
+
|
219 |
+
msgtype = getnotes["msgtype"]
|
220 |
+
if not getnotes:
|
221 |
+
await m.reply_text("<b>Error:</b> Cannot find a type for this note!!")
|
222 |
+
return
|
223 |
+
|
224 |
+
if msgtype == Types.TEXT:
|
225 |
+
teks = getnotes["note_value"]
|
226 |
+
await m.reply_text(teks, parse_mode=None, reply_to_message_id=msg_id)
|
227 |
+
elif msgtype in (
|
228 |
+
Types.STICKER,
|
229 |
+
Types.VIDEO_NOTE,
|
230 |
+
Types.CONTACT,
|
231 |
+
Types.ANIMATED_STICKER,
|
232 |
+
):
|
233 |
+
await (await send_cmd(c, msgtype))(
|
234 |
+
m.chat.id,
|
235 |
+
getnotes["fileid"],
|
236 |
+
reply_to_message_id=msg_id,
|
237 |
+
)
|
238 |
+
else:
|
239 |
+
teks = getnotes["note_value"] or ""
|
240 |
+
await (await send_cmd(c, msgtype))(
|
241 |
+
m.chat.id,
|
242 |
+
getnotes["fileid"],
|
243 |
+
caption=teks,
|
244 |
+
parse_mode=None,
|
245 |
+
reply_to_message_id=msg_id,
|
246 |
+
)
|
247 |
+
LOGGER.info(
|
248 |
+
f"{m.from_user.id} fetched raw note {note} (type - {getnotes}) in {m.chat.id}",
|
249 |
+
)
|
250 |
+
return
|
251 |
+
|
252 |
+
|
253 |
+
@Gojo.on_message(filters.regex(r"^#[^\s]+") & filters.group & ~filters.bot)
|
254 |
+
async def hash_get(c: Gojo, m: Message):
|
255 |
+
# If not from user, then return
|
256 |
+
|
257 |
+
try:
|
258 |
+
note = (m.text[1:]).lower()
|
259 |
+
except TypeError:
|
260 |
+
return
|
261 |
+
|
262 |
+
all_notes = {i[0] for i in db.get_all_notes(m.chat.id)}
|
263 |
+
|
264 |
+
if note not in all_notes:
|
265 |
+
# don't reply to all messages starting with #
|
266 |
+
return
|
267 |
+
|
268 |
+
priv_notes_status = db_settings.get_privatenotes(m.chat.id)
|
269 |
+
await get_note_func(c, m, note, priv_notes_status)
|
270 |
+
return
|
271 |
+
|
272 |
+
|
273 |
+
@Gojo.on_message(command("get") & filters.group & ~filters.bot)
|
274 |
+
async def get_note(c: Gojo, m: Message):
|
275 |
+
|
276 |
+
if len(m.text.split()) == 2:
|
277 |
+
priv_notes_status = db_settings.get_privatenotes(m.chat.id)
|
278 |
+
note = ((m.text.split())[1]).lower()
|
279 |
+
all_notes = {i[0] for i in db.get_all_notes(m.chat.id)}
|
280 |
+
|
281 |
+
if note not in all_notes:
|
282 |
+
await m.reply_text("This note does not exists!")
|
283 |
+
return
|
284 |
+
|
285 |
+
await get_note_func(c, m, note, priv_notes_status)
|
286 |
+
elif len(m.text.split()) == 3 and (m.text.split())[2] in ["noformat", "raw"]:
|
287 |
+
note = ((m.text.split())[1]).lower()
|
288 |
+
await get_raw_note(c, m, note)
|
289 |
+
else:
|
290 |
+
await m.reply_text("Give me a note tag!")
|
291 |
+
return
|
292 |
+
|
293 |
+
return
|
294 |
+
|
295 |
+
|
296 |
+
@Gojo.on_message(command(["privnotes", "privatenotes"]) & admin_filter & ~filters.bot)
|
297 |
+
async def priv_notes(_, m: Message):
|
298 |
+
|
299 |
+
chat_id = m.chat.id
|
300 |
+
if len(m.text.split()) == 2:
|
301 |
+
option = (m.text.split())[1]
|
302 |
+
if option in ("on", "yes"):
|
303 |
+
db_settings.set_privatenotes(chat_id, True)
|
304 |
+
LOGGER.info(f"{m.from_user.id} enabled privatenotes in {m.chat.id}")
|
305 |
+
msg = "Set private notes to On"
|
306 |
+
elif option in ("off", "no"):
|
307 |
+
db_settings.set_privatenotes(chat_id, False)
|
308 |
+
LOGGER.info(f"{m.from_user.id} disabled privatenotes in {m.chat.id}")
|
309 |
+
msg = "Set private notes to Off"
|
310 |
+
else:
|
311 |
+
msg = "Enter correct option"
|
312 |
+
await m.reply_text(msg)
|
313 |
+
elif len(m.text.split()) == 1:
|
314 |
+
curr_pref = db_settings.get_privatenotes(m.chat.id)
|
315 |
+
msg = msg = f"Private Notes: {curr_pref}"
|
316 |
+
LOGGER.info(f"{m.from_user.id} fetched privatenotes preference in {m.chat.id}")
|
317 |
+
await m.reply_text(msg)
|
318 |
+
else:
|
319 |
+
await m.replt_text("Check help on how to use this command!")
|
320 |
+
|
321 |
+
return
|
322 |
+
|
323 |
+
|
324 |
+
@Gojo.on_message(command("notes") & filters.group & ~filters.bot)
|
325 |
+
async def local_notes(_, m: Message):
|
326 |
+
LOGGER.info(f"{m.from_user.id} listed all notes in {m.chat.id}")
|
327 |
+
getnotes = db.get_all_notes(m.chat.id)
|
328 |
+
|
329 |
+
if not getnotes:
|
330 |
+
await m.reply_text(f"There are no notes in <b>{m.chat.title}</b>.")
|
331 |
+
return
|
332 |
+
|
333 |
+
msg_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id
|
334 |
+
|
335 |
+
curr_pref = db_settings.get_privatenotes(m.chat.id)
|
336 |
+
if curr_pref:
|
337 |
+
|
338 |
+
pm_kb = ikb(
|
339 |
+
[
|
340 |
+
[
|
341 |
+
(
|
342 |
+
"All Notes",
|
343 |
+
f"https://t.me/{Config.BOT_USERNAME}?start=notes_{m.chat.id}",
|
344 |
+
"url",
|
345 |
+
),
|
346 |
+
],
|
347 |
+
],
|
348 |
+
)
|
349 |
+
await m.reply_text(
|
350 |
+
"Click on the button below to get notes!",
|
351 |
+
quote=True,
|
352 |
+
reply_markup=pm_kb,
|
353 |
+
)
|
354 |
+
return
|
355 |
+
|
356 |
+
rply = f"Notes in <b>{m.chat.title}</b>:\n"
|
357 |
+
for x in getnotes:
|
358 |
+
rply += f"-> <code>#{x[0]}</code>\n"
|
359 |
+
rply += "\nYou can get a note by #notename or <code>/get notename</code>"
|
360 |
+
|
361 |
+
await m.reply_text(rply, reply_to_message_id=msg_id)
|
362 |
+
return
|
363 |
+
|
364 |
+
|
365 |
+
@Gojo.on_message(command("clear") & admin_filter & ~filters.bot)
|
366 |
+
async def clear_note(_, m: Message):
|
367 |
+
|
368 |
+
if len(m.text.split()) <= 1:
|
369 |
+
await m.reply_text("What do you want to clear?")
|
370 |
+
return
|
371 |
+
|
372 |
+
note = m.text.split()[1].lower()
|
373 |
+
getnote = db.rm_note(m.chat.id, note)
|
374 |
+
LOGGER.info(f"{m.from_user.id} cleared note ({note}) in {m.chat.id}")
|
375 |
+
if not getnote:
|
376 |
+
await m.reply_text("This note does not exist!")
|
377 |
+
return
|
378 |
+
|
379 |
+
await m.reply_text(f"Note '`{note}`' deleted!")
|
380 |
+
return
|
381 |
+
|
382 |
+
|
383 |
+
@Gojo.on_message(command("clearall") & owner_filter & ~filters.bot)
|
384 |
+
async def clear_allnote(_, m: Message):
|
385 |
+
|
386 |
+
all_notes = {i[0] for i in db.get_all_notes(m.chat.id)}
|
387 |
+
if not all_notes:
|
388 |
+
await m.reply_text("No notes are there in this chat")
|
389 |
+
return
|
390 |
+
|
391 |
+
await m.reply_text(
|
392 |
+
"Are you sure you want to clear all notes?",
|
393 |
+
reply_markup=ikb(
|
394 |
+
[[("⚠️ Confirm", "clear_notes"), ("❌ Cancel", "close_admin")]],
|
395 |
+
),
|
396 |
+
)
|
397 |
+
return
|
398 |
+
|
399 |
+
|
400 |
+
@Gojo.on_callback_query(filters.regex("^clear_notes$"))
|
401 |
+
async def clearallnotes_callback(_, q: CallbackQuery):
|
402 |
+
user_id = q.from_user.id
|
403 |
+
user_status = (await q.message.chat.get_member(user_id)).status
|
404 |
+
if user_status not in {"creator", "administrator"}:
|
405 |
+
await q.answer(
|
406 |
+
"You're not even an admin, don't try this explosive shit!",
|
407 |
+
show_alert=True,
|
408 |
+
)
|
409 |
+
return
|
410 |
+
if user_status != "creator":
|
411 |
+
await q.answer(
|
412 |
+
"You're just an admin, not owner\nStay in your limits!",
|
413 |
+
show_alert=True,
|
414 |
+
)
|
415 |
+
return
|
416 |
+
db.rm_all_notes(q.message.chat.id)
|
417 |
+
LOGGER.info(f"{user_id} removed all notes in {q.message.chat.id}")
|
418 |
+
await q.message.edit_text("Cleared all notes!")
|
419 |
+
return
|
420 |
+
|
421 |
+
|
422 |
+
__PLUGIN__ = "notes"
|
423 |
+
|
424 |
+
_DISABLE_CMDS_ = ["notes"]
|
425 |
+
|
426 |
+
__alt_name__ = ["groupnotes", "snips", "notes"]
|
Powers/plugins/pin.py
ADDED
@@ -0,0 +1,245 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from html import escape as escape_html
|
2 |
+
|
3 |
+
from pyrogram.errors import ChatAdminRequired, RightForbidden, RPCError
|
4 |
+
from pyrogram.filters import regex
|
5 |
+
from pyrogram.types import CallbackQuery, Message
|
6 |
+
|
7 |
+
from Powers import LOGGER, SUPPORT_GROUP
|
8 |
+
from Powers.bot_class import Gojo
|
9 |
+
from Powers.database.pins_db import Pins
|
10 |
+
from Powers.tr_engine import tlang
|
11 |
+
from Powers.utils.custom_filters import admin_filter, command
|
12 |
+
from Powers.utils.kbhelpers import ikb
|
13 |
+
from Powers.utils.string import build_keyboard, parse_button
|
14 |
+
|
15 |
+
|
16 |
+
@Gojo.on_message(command("pin") & admin_filter)
|
17 |
+
async def pin_message(_, m: Message):
|
18 |
+
pin_args = m.text.split(None, 1)
|
19 |
+
if m.reply_to_message:
|
20 |
+
try:
|
21 |
+
disable_notification = True
|
22 |
+
|
23 |
+
if len(pin_args) >= 2 and pin_args[1] in ["alert", "notify", "loud"]:
|
24 |
+
disable_notification = False
|
25 |
+
|
26 |
+
await m.reply_to_message.pin(
|
27 |
+
disable_notification=disable_notification,
|
28 |
+
)
|
29 |
+
LOGGER.info(
|
30 |
+
f"{m.from_user.id} pinned msgid-{m.reply_to_message.message_id} in {m.chat.id}",
|
31 |
+
)
|
32 |
+
|
33 |
+
if m.chat.username:
|
34 |
+
# If chat has a username, use this format
|
35 |
+
link_chat_id = m.chat.username
|
36 |
+
message_link = (
|
37 |
+
f"https://t.me/{link_chat_id}/{m.reply_to_message.message_id}"
|
38 |
+
)
|
39 |
+
elif (str(m.chat.id)).startswith("-100"):
|
40 |
+
# If chat does not have a username, use this
|
41 |
+
link_chat_id = (str(m.chat.id)).replace("-100", "")
|
42 |
+
message_link = (
|
43 |
+
f"https://t.me/c/{link_chat_id}/{m.reply_to_message.message_id}"
|
44 |
+
)
|
45 |
+
await m.reply_text(
|
46 |
+
tlang(m, "pin.pinned_msg").format(message_link=message_link),
|
47 |
+
disable_web_page_preview=True,
|
48 |
+
)
|
49 |
+
|
50 |
+
except ChatAdminRequired:
|
51 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
52 |
+
except RightForbidden:
|
53 |
+
await m.reply_text(tlang(m, "pin.no_rights_pin"))
|
54 |
+
except RPCError as ef:
|
55 |
+
await m.reply_text(
|
56 |
+
(tlang(m, "general.some_error")).format(
|
57 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
58 |
+
ef=ef,
|
59 |
+
),
|
60 |
+
)
|
61 |
+
LOGGER.error(ef)
|
62 |
+
else:
|
63 |
+
await m.reply_text("Reply to a message to pin it!")
|
64 |
+
|
65 |
+
return
|
66 |
+
|
67 |
+
|
68 |
+
@Gojo.on_message(command("unpin") & admin_filter)
|
69 |
+
async def unpin_message(c: Gojo, m: Message):
|
70 |
+
try:
|
71 |
+
if m.reply_to_message:
|
72 |
+
await c.unpin_chat_message(m.chat.id, m.reply_to_message.message_id)
|
73 |
+
LOGGER.info(
|
74 |
+
f"{m.from_user.id} unpinned msgid: {m.reply_to_message.message_id} in {m.chat.id}",
|
75 |
+
)
|
76 |
+
await m.reply_text(tlang(m, "pin.unpinned_last_msg"))
|
77 |
+
else:
|
78 |
+
await c.unpin_chat_message(m.chat.id)
|
79 |
+
await m.reply_text(tlang(m, "Unpinned last pinned message!"))
|
80 |
+
except ChatAdminRequired:
|
81 |
+
await m.reply_text(tlang(m, "admin.not_admin"))
|
82 |
+
except RightForbidden:
|
83 |
+
await m.reply_text(tlang(m, "pin.no_rights_unpin"))
|
84 |
+
except RPCError as ef:
|
85 |
+
await m.reply_text(
|
86 |
+
(tlang(m, "general.some_error")).format(
|
87 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
88 |
+
ef=ef,
|
89 |
+
),
|
90 |
+
)
|
91 |
+
LOGGER.error(ef)
|
92 |
+
|
93 |
+
return
|
94 |
+
|
95 |
+
|
96 |
+
@Gojo.on_message(command("unpinall") & admin_filter)
|
97 |
+
async def unpinall_message(_, m: Message):
|
98 |
+
await m.reply_text(
|
99 |
+
"Do you really want to unpin all messages in this chat?",
|
100 |
+
reply_markup=ikb([[("Yes", "unpin_all_in_this_chat"), ("No", "close_admin")]]),
|
101 |
+
)
|
102 |
+
return
|
103 |
+
|
104 |
+
|
105 |
+
@Gojo.on_callback_query(regex("^unpin_all_in_this_chat$"))
|
106 |
+
async def unpinall_calllback(c: Gojo, q: CallbackQuery):
|
107 |
+
user_id = q.from_user.id
|
108 |
+
user_status = (await q.message.chat.get_member(user_id)).status
|
109 |
+
if user_status not in {"creator", "administrator"}:
|
110 |
+
await q.answer(
|
111 |
+
"You're not even an admin, don't try this explosive shit!",
|
112 |
+
show_alert=True,
|
113 |
+
)
|
114 |
+
return
|
115 |
+
if user_status != "creator":
|
116 |
+
await q.answer(
|
117 |
+
"You're just an admin, not owner\nStay in your limits!",
|
118 |
+
show_alert=True,
|
119 |
+
)
|
120 |
+
return
|
121 |
+
try:
|
122 |
+
await c.unpin_all_chat_messages(q.message.chat.id)
|
123 |
+
LOGGER.info(f"{q.from_user.id} unpinned all messages in {q.message.chat.id}")
|
124 |
+
await q.message.edit_text(tlang(q, "pin.unpinned_all_msg"))
|
125 |
+
except ChatAdminRequired:
|
126 |
+
await q.message.edit_text(tlang(q, "admin.notadmin"))
|
127 |
+
except RightForbidden:
|
128 |
+
await q.message.edit_text(tlang(q, "pin.no_rights_unpin"))
|
129 |
+
except RPCError as ef:
|
130 |
+
await q.message.edit_text(
|
131 |
+
(tlang(q, "general.some_error")).format(
|
132 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
133 |
+
ef=ef,
|
134 |
+
),
|
135 |
+
)
|
136 |
+
LOGGER.error(ef)
|
137 |
+
return
|
138 |
+
|
139 |
+
|
140 |
+
@Gojo.on_message(command("antichannelpin") & admin_filter)
|
141 |
+
async def anti_channel_pin(_, m: Message):
|
142 |
+
pinsdb = Pins(m.chat.id)
|
143 |
+
|
144 |
+
if len(m.text.split()) == 1:
|
145 |
+
status = pinsdb.get_settings()["antichannelpin"]
|
146 |
+
await m.reply_text(
|
147 |
+
tlang(m, "pin.antichannelpin.current_status").format(
|
148 |
+
status=status,
|
149 |
+
),
|
150 |
+
)
|
151 |
+
return
|
152 |
+
|
153 |
+
if len(m.text.split()) == 2:
|
154 |
+
if m.command[1] in ("yes", "on", "true"):
|
155 |
+
pinsdb.antichannelpin_on()
|
156 |
+
LOGGER.info(f"{m.from_user.id} enabled antichannelpin in {m.chat.id}")
|
157 |
+
msg = tlang(m, "pin.antichannelpin.turned_on")
|
158 |
+
elif m.command[1] in ("no", "off", "false"):
|
159 |
+
pinsdb.antichannelpin_off()
|
160 |
+
LOGGER.info(f"{m.from_user.id} disabled antichannelpin in {m.chat.id}")
|
161 |
+
msg = tlang(m, "pin.antichannelpin.turned_off")
|
162 |
+
else:
|
163 |
+
await m.reply_text(tlang(m, "general.check_help"))
|
164 |
+
return
|
165 |
+
|
166 |
+
await m.reply_text(msg)
|
167 |
+
return
|
168 |
+
|
169 |
+
|
170 |
+
@Gojo.on_message(command("pinned") & admin_filter)
|
171 |
+
async def pinned_message(c: Gojo, m: Message):
|
172 |
+
chat_title = m.chat.title
|
173 |
+
chat = await c.get_chat(chat_id=m.chat.id)
|
174 |
+
msg_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id
|
175 |
+
|
176 |
+
if chat.pinned_message:
|
177 |
+
pinned_id = chat.pinned_message.message_id
|
178 |
+
if m.chat.username:
|
179 |
+
link_chat_id = m.chat.username
|
180 |
+
message_link = f"https://t.me/{link_chat_id}/{pinned_id}"
|
181 |
+
elif (str(m.chat.id)).startswith("-100"):
|
182 |
+
link_chat_id = (str(m.chat.id)).replace("-100", "")
|
183 |
+
message_link = f"https://t.me/c/{link_chat_id}/{pinned_id}"
|
184 |
+
|
185 |
+
await m.reply_text(
|
186 |
+
f"The pinned message of {escape_html(chat_title)} is [here]({message_link}).",
|
187 |
+
reply_to_message_id=msg_id,
|
188 |
+
disable_web_page_preview=True,
|
189 |
+
)
|
190 |
+
else:
|
191 |
+
await m.reply_text(f"There is no pinned message in {escape_html(chat_title)}.")
|
192 |
+
|
193 |
+
|
194 |
+
@Gojo.on_message(command("cleanlinked") & admin_filter)
|
195 |
+
async def clean_linked(_, m: Message):
|
196 |
+
pinsdb = Pins(m.chat.id)
|
197 |
+
|
198 |
+
if len(m.text.split()) == 1:
|
199 |
+
status = pinsdb.get_settings()["cleanlinked"]
|
200 |
+
await m.reply_text(
|
201 |
+
tlang(m, "pin.antichannelpin.current_status").format(
|
202 |
+
status=status,
|
203 |
+
),
|
204 |
+
)
|
205 |
+
return
|
206 |
+
|
207 |
+
if len(m.text.split()) == 2:
|
208 |
+
if m.command[1] in ("yes", "on", "true"):
|
209 |
+
pinsdb.cleanlinked_on()
|
210 |
+
LOGGER.info(f"{m.from_user.id} enabled CleanLinked in {m.chat.id}")
|
211 |
+
msg = "Turned on CleanLinked! Now all the messages from linked channel will be deleted!"
|
212 |
+
elif m.command[1] in ("no", "off", "false"):
|
213 |
+
pinsdb.cleanlinked_off()
|
214 |
+
LOGGER.info(f"{m.from_user.id} disabled CleanLinked in {m.chat.id}")
|
215 |
+
msg = "Turned off CleanLinked! Messages from linked channel will not be deleted!"
|
216 |
+
else:
|
217 |
+
await m.reply_text(tlang(m, "general.check_help"))
|
218 |
+
return
|
219 |
+
|
220 |
+
await m.reply_text(msg)
|
221 |
+
return
|
222 |
+
|
223 |
+
|
224 |
+
@Gojo.on_message(command("permapin") & admin_filter)
|
225 |
+
async def perma_pin(_, m: Message):
|
226 |
+
if m.reply_to_message or len(m.text.split()) > 1:
|
227 |
+
LOGGER.info(f"{m.from_user.id} used permampin in {m.chat.id}")
|
228 |
+
if m.reply_to_message:
|
229 |
+
text = m.reply_to_message.text
|
230 |
+
elif len(m.text.split()) > 1:
|
231 |
+
text = m.text.split(None, 1)[1]
|
232 |
+
teks, button = await parse_button(text)
|
233 |
+
button = await build_keyboard(button)
|
234 |
+
button = ikb(button) if button else None
|
235 |
+
z = await m.reply_text(teks, reply_markup=button)
|
236 |
+
await z.pin()
|
237 |
+
else:
|
238 |
+
await m.reply_text("Reply to a message or enter text to pin it.")
|
239 |
+
await m.delete()
|
240 |
+
return
|
241 |
+
|
242 |
+
|
243 |
+
__PLUGIN__ = "pins"
|
244 |
+
|
245 |
+
__alt_name__ = ["pin", "unpin"]
|
Powers/plugins/purge.py
ADDED
@@ -0,0 +1,121 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from asyncio import sleep
|
2 |
+
|
3 |
+
from pyrogram.errors import MessageDeleteForbidden, RPCError
|
4 |
+
from pyrogram.types import Message
|
5 |
+
|
6 |
+
from Powers import SUPPORT_GROUP
|
7 |
+
from Powers.bot_class import Gojo
|
8 |
+
from Powers.tr_engine import tlang
|
9 |
+
from Powers.utils.custom_filters import admin_filter, command
|
10 |
+
|
11 |
+
|
12 |
+
@Gojo.on_message(command("purge") & admin_filter)
|
13 |
+
async def purge(c: Gojo, m: Message):
|
14 |
+
if m.chat.type != "supergroup":
|
15 |
+
await m.reply_text(tlang(m, "purge.err_basic"))
|
16 |
+
return
|
17 |
+
|
18 |
+
if m.reply_to_message:
|
19 |
+
message_ids = list(range(m.reply_to_message.message_id, m.message_id))
|
20 |
+
|
21 |
+
def divide_chunks(l: list, n: int = 100):
|
22 |
+
for i in range(0, len(l), n):
|
23 |
+
yield l[i : i + n]
|
24 |
+
|
25 |
+
# Dielete messages in chunks of 100 messages
|
26 |
+
m_list = list(divide_chunks(message_ids))
|
27 |
+
|
28 |
+
try:
|
29 |
+
for plist in m_list:
|
30 |
+
await c.delete_messages(
|
31 |
+
chat_id=m.chat.id,
|
32 |
+
message_ids=plist,
|
33 |
+
revoke=True,
|
34 |
+
)
|
35 |
+
await m.delete()
|
36 |
+
except MessageDeleteForbidden:
|
37 |
+
await m.reply_text(tlang(m, "purge.old_msg_err"))
|
38 |
+
return
|
39 |
+
except RPCError as ef:
|
40 |
+
await m.reply_text(
|
41 |
+
(tlang(m, "general.some_error")).format(
|
42 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
43 |
+
ef=ef,
|
44 |
+
),
|
45 |
+
)
|
46 |
+
|
47 |
+
count_del_msg = len(message_ids)
|
48 |
+
|
49 |
+
z = await m.reply_text(
|
50 |
+
(tlang(m, "purge.purge_msg_count")).format(
|
51 |
+
msg_count=count_del_msg,
|
52 |
+
),
|
53 |
+
)
|
54 |
+
await sleep(3)
|
55 |
+
await z.delete()
|
56 |
+
return
|
57 |
+
await m.reply_text("Reply to a message to start purge !")
|
58 |
+
return
|
59 |
+
|
60 |
+
|
61 |
+
@Gojo.on_message(command("spurge") & admin_filter)
|
62 |
+
async def spurge(c: Gojo, m: Message):
|
63 |
+
if m.chat.type != "supergroup":
|
64 |
+
await m.reply_text(tlang(m, "purge.err_basic"))
|
65 |
+
return
|
66 |
+
|
67 |
+
if m.reply_to_message:
|
68 |
+
message_ids = list(range(m.reply_to_message.message_id, m.message_id))
|
69 |
+
|
70 |
+
def divide_chunks(l: list, n: int = 100):
|
71 |
+
for i in range(0, len(l), n):
|
72 |
+
yield l[i : i + n]
|
73 |
+
|
74 |
+
# Dielete messages in chunks of 100 messages
|
75 |
+
m_list = list(divide_chunks(message_ids))
|
76 |
+
|
77 |
+
try:
|
78 |
+
for plist in m_list:
|
79 |
+
await c.delete_messages(
|
80 |
+
chat_id=m.chat.id,
|
81 |
+
message_ids=plist,
|
82 |
+
revoke=True,
|
83 |
+
)
|
84 |
+
await m.delete()
|
85 |
+
except MessageDeleteForbidden:
|
86 |
+
await m.reply_text(tlang(m, "purge.old_msg_err"))
|
87 |
+
return
|
88 |
+
except RPCError as ef:
|
89 |
+
await m.reply_text(
|
90 |
+
(tlang(m, "general.some_error")).format(
|
91 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
92 |
+
ef=ef,
|
93 |
+
),
|
94 |
+
)
|
95 |
+
return
|
96 |
+
await m.reply_text("Reply to a message to start spurge !")
|
97 |
+
return
|
98 |
+
|
99 |
+
|
100 |
+
@Gojo.on_message(
|
101 |
+
command("del") & admin_filter,
|
102 |
+
group=9,
|
103 |
+
)
|
104 |
+
async def del_msg(c: Gojo, m: Message):
|
105 |
+
if m.chat.type != "supergroup":
|
106 |
+
return
|
107 |
+
|
108 |
+
if m.reply_to_message:
|
109 |
+
await m.delete()
|
110 |
+
await c.delete_messages(
|
111 |
+
chat_id=m.chat.id,
|
112 |
+
message_ids=m.reply_to_message.message_id,
|
113 |
+
)
|
114 |
+
else:
|
115 |
+
await m.reply_text(tlang(m, "purge.what_del"))
|
116 |
+
return
|
117 |
+
|
118 |
+
|
119 |
+
__PLUGIN__ = "purges"
|
120 |
+
|
121 |
+
__alt_name__ = ["purge", "del", "spurge"]
|
Powers/plugins/report.py
ADDED
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from traceback import format_exc
|
2 |
+
|
3 |
+
from pyrogram import filters
|
4 |
+
from pyrogram.errors import RPCError
|
5 |
+
from pyrogram.types import CallbackQuery, Message
|
6 |
+
|
7 |
+
from Powers import LOGGER, SUPPORT_STAFF
|
8 |
+
from Powers.bot_class import Gojo
|
9 |
+
from Powers.database.reporting_db import Reporting
|
10 |
+
from Powers.utils.custom_filters import admin_filter, command
|
11 |
+
from Powers.utils.kbhelpers import ikb
|
12 |
+
from Powers.utils.parser import mention_html
|
13 |
+
|
14 |
+
|
15 |
+
@Gojo.on_message(
|
16 |
+
command("reports") & (filters.private | admin_filter),
|
17 |
+
)
|
18 |
+
async def report_setting(_, m: Message):
|
19 |
+
args = m.text.split()
|
20 |
+
db = Reporting(m.chat.id)
|
21 |
+
|
22 |
+
if m.chat.type == "private":
|
23 |
+
if len(args) >= 2:
|
24 |
+
option = args[1].lower()
|
25 |
+
if option in ("yes", "on", "true"):
|
26 |
+
db.set_settings(True)
|
27 |
+
LOGGER.info(f"{m.from_user.id} enabled reports for them")
|
28 |
+
await m.reply_text(
|
29 |
+
"Turned on reporting! You'll be notified whenever anyone reports something in groups you are admin.",
|
30 |
+
)
|
31 |
+
|
32 |
+
elif option in ("no", "off", "false"):
|
33 |
+
db.set_settings(False)
|
34 |
+
LOGGER.info(f"{m.from_user.id} disabled reports for them")
|
35 |
+
await m.reply_text("Turned off reporting! You wont get any reports.")
|
36 |
+
else:
|
37 |
+
await m.reply_text(
|
38 |
+
f"Your current report preference is: `{(db.get_settings())}`",
|
39 |
+
)
|
40 |
+
elif len(args) >= 2:
|
41 |
+
option = args[1].lower()
|
42 |
+
if option in ("yes", "on", "true"):
|
43 |
+
db.set_settings(True)
|
44 |
+
LOGGER.info(f"{m.from_user.id} enabled reports in {m.chat.id}")
|
45 |
+
await m.reply_text(
|
46 |
+
"Turned on reporting! Admins who have turned on reports will be notified when /report "
|
47 |
+
"or @admin is called.",
|
48 |
+
quote=True,
|
49 |
+
)
|
50 |
+
|
51 |
+
elif option in ("no", "off", "false"):
|
52 |
+
db.set_settings(False)
|
53 |
+
LOGGER.info(f"{m.from_user.id} disabled reports in {m.chat.id}")
|
54 |
+
await m.reply_text(
|
55 |
+
"Turned off reporting! No admins will be notified on /report or @admin.",
|
56 |
+
quote=True,
|
57 |
+
)
|
58 |
+
else:
|
59 |
+
await m.reply_text(
|
60 |
+
f"This group's current setting is: `{(db.get_settings())}`",
|
61 |
+
)
|
62 |
+
|
63 |
+
|
64 |
+
@Gojo.on_message(command("report") & filters.group)
|
65 |
+
async def report_watcher(c: Gojo, m: Message):
|
66 |
+
if m.chat.type != "supergroup":
|
67 |
+
return
|
68 |
+
|
69 |
+
if not m.from_user:
|
70 |
+
return
|
71 |
+
|
72 |
+
me = await c.get_me()
|
73 |
+
db = Reporting(m.chat.id)
|
74 |
+
|
75 |
+
if (m.chat and m.reply_to_message) and (db.get_settings()):
|
76 |
+
reported_msg_id = m.reply_to_message.message_id
|
77 |
+
reported_user = m.reply_to_message.from_user
|
78 |
+
chat_name = m.chat.title or m.chat.username
|
79 |
+
admin_list = await c.get_chat_members(m.chat.id, filter="administrators")
|
80 |
+
|
81 |
+
if reported_user.id == me.id:
|
82 |
+
await m.reply_text("Nice try.")
|
83 |
+
return
|
84 |
+
|
85 |
+
if reported_user.id in SUPPORT_STAFF:
|
86 |
+
await m.reply_text("Uh? You reporting my support team?")
|
87 |
+
return
|
88 |
+
|
89 |
+
if m.chat.username:
|
90 |
+
msg = (
|
91 |
+
f"<b>⚠️ Report: </b>{m.chat.title}\n"
|
92 |
+
f"<b> • Report by:</b> {(await mention_html(m.from_user.first_name, m.from_user.id))} (<code>{m.from_user.id}</code>)\n"
|
93 |
+
f"<b> • Reported user:</b> {(await mention_html(reported_user.first_name, reported_user.id))} (<code>{reported_user.id}</code>)\n"
|
94 |
+
)
|
95 |
+
|
96 |
+
else:
|
97 |
+
msg = f"{(await mention_html(m.from_user.first_name, m.from_user.id))} is calling for admins in '{chat_name}'!\n"
|
98 |
+
|
99 |
+
link_chat_id = str(m.chat.id).replace("-100", "")
|
100 |
+
link = f"https://t.me/c/{link_chat_id}/{reported_msg_id}" # message link
|
101 |
+
|
102 |
+
reply_markup = ikb(
|
103 |
+
[
|
104 |
+
[("➡ Message", link, "url")],
|
105 |
+
[
|
106 |
+
(
|
107 |
+
"⚠ Kick",
|
108 |
+
f"report_{m.chat.id}=kick={reported_user.id}={reported_msg_id}",
|
109 |
+
),
|
110 |
+
(
|
111 |
+
"⛔️ Ban",
|
112 |
+
f"report_{m.chat.id}=ban={reported_user.id}={reported_msg_id}",
|
113 |
+
),
|
114 |
+
],
|
115 |
+
[
|
116 |
+
(
|
117 |
+
"❎ Delete Message",
|
118 |
+
f"report_{m.chat.id}=del={reported_user.id}={reported_msg_id}",
|
119 |
+
),
|
120 |
+
],
|
121 |
+
],
|
122 |
+
)
|
123 |
+
|
124 |
+
LOGGER.info(
|
125 |
+
f"{m.from_user.id} reported msgid-{m.reply_to_message.message_id} to admins in {m.chat.id}",
|
126 |
+
)
|
127 |
+
await m.reply_text(
|
128 |
+
(
|
129 |
+
f"{(await mention_html(m.from_user.first_name, m.from_user.id))} "
|
130 |
+
"reported the message to the admins."
|
131 |
+
),
|
132 |
+
quote=True,
|
133 |
+
)
|
134 |
+
|
135 |
+
for admin in admin_list:
|
136 |
+
if (
|
137 |
+
admin.user.is_bot or admin.user.is_deleted
|
138 |
+
): # can't message bots or deleted accounts
|
139 |
+
continue
|
140 |
+
if Reporting(admin.user.id).get_settings():
|
141 |
+
try:
|
142 |
+
await c.send_message(
|
143 |
+
admin.user.id,
|
144 |
+
msg,
|
145 |
+
reply_markup=reply_markup,
|
146 |
+
disable_web_page_preview=True,
|
147 |
+
)
|
148 |
+
try:
|
149 |
+
await m.reply_to_message.forward(admin.user.id)
|
150 |
+
if len(m.text.split()) > 1:
|
151 |
+
await m.forward(admin.user.id)
|
152 |
+
except Exception:
|
153 |
+
pass
|
154 |
+
except Exception:
|
155 |
+
pass
|
156 |
+
except RPCError as ef:
|
157 |
+
LOGGER.error(ef)
|
158 |
+
LOGGER.error(format_exc())
|
159 |
+
return ""
|
160 |
+
|
161 |
+
|
162 |
+
@Gojo.on_callback_query(filters.regex("^report_"))
|
163 |
+
async def report_buttons(c: Gojo, q: CallbackQuery):
|
164 |
+
splitter = (str(q.data).replace("report_", "")).split("=")
|
165 |
+
chat_id = int(splitter[0])
|
166 |
+
action = str(splitter[1])
|
167 |
+
user_id = int(splitter[2])
|
168 |
+
message_id = int(splitter[3])
|
169 |
+
if action == "kick":
|
170 |
+
try:
|
171 |
+
await c.ban_chat_member(chat_id, user_id)
|
172 |
+
await q.answer("✅ Succesfully kicked")
|
173 |
+
await c.unban_chat_member(chat_id, user_id)
|
174 |
+
return
|
175 |
+
except RPCError as err:
|
176 |
+
await q.answer(
|
177 |
+
f"🛑 Failed to Kick\n<b>Error:</b>\n</code>{err}</code>",
|
178 |
+
show_alert=True,
|
179 |
+
)
|
180 |
+
elif action == "ban":
|
181 |
+
try:
|
182 |
+
await c.ban_chat_member(chat_id, user_id)
|
183 |
+
await q.answer("✅ Succesfully Banned")
|
184 |
+
return
|
185 |
+
except RPCError as err:
|
186 |
+
await q.answer(f"🛑 Failed to Ban\n<b>Error:</b>\n`{err}`", show_alert=True)
|
187 |
+
elif action == "del":
|
188 |
+
try:
|
189 |
+
await c.delete_messages(chat_id, message_id)
|
190 |
+
await q.answer("✅ Message Deleted")
|
191 |
+
return
|
192 |
+
except RPCError as err:
|
193 |
+
await q.answer(
|
194 |
+
f"🛑 Failed to delete message!\n<b>Error:</b>\n`{err}`",
|
195 |
+
show_alert=True,
|
196 |
+
)
|
197 |
+
return
|
198 |
+
|
199 |
+
|
200 |
+
__PLUGIN__ = "reporting"
|
201 |
+
|
202 |
+
__alt_name__ = ["reports", "report"]
|
Powers/plugins/rules.py
ADDED
@@ -0,0 +1,153 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.types import CallbackQuery, Message
|
3 |
+
|
4 |
+
from Powers import LOGGER
|
5 |
+
from Powers.bot_class import Gojo
|
6 |
+
from Powers.database.rules_db import Rules
|
7 |
+
from Powers.tr_engine import tlang
|
8 |
+
from Powers.utils.custom_filters import admin_filter, command
|
9 |
+
from Powers.utils.kbhelpers import ikb
|
10 |
+
from Powers.vars import Config
|
11 |
+
|
12 |
+
|
13 |
+
@Gojo.on_message(command("rules") & filters.group)
|
14 |
+
async def get_rules(_, m: Message):
|
15 |
+
db = Rules(m.chat.id)
|
16 |
+
msg_id = m.reply_to_message.message_id if m.reply_to_message else m.message_id
|
17 |
+
|
18 |
+
rules = db.get_rules()
|
19 |
+
LOGGER.info(f"{m.from_user.id} fetched rules in {m.chat.id}")
|
20 |
+
if m and not m.from_user:
|
21 |
+
return
|
22 |
+
|
23 |
+
if not rules:
|
24 |
+
await m.reply_text(
|
25 |
+
(tlang(m, "rules.no_rules")),
|
26 |
+
quote=True,
|
27 |
+
)
|
28 |
+
return
|
29 |
+
|
30 |
+
priv_rules_status = db.get_privrules()
|
31 |
+
|
32 |
+
if priv_rules_status:
|
33 |
+
pm_kb = ikb(
|
34 |
+
[
|
35 |
+
[
|
36 |
+
(
|
37 |
+
"Rules",
|
38 |
+
f"https://t.me/{Config.BOT_USERNAME}?start=rules_{m.chat.id}",
|
39 |
+
"url",
|
40 |
+
),
|
41 |
+
],
|
42 |
+
],
|
43 |
+
)
|
44 |
+
await m.reply_text(
|
45 |
+
(tlang(m, "rules.pm_me")),
|
46 |
+
quote=True,
|
47 |
+
reply_markup=pm_kb,
|
48 |
+
reply_to_message_id=msg_id,
|
49 |
+
)
|
50 |
+
return
|
51 |
+
|
52 |
+
formated = rules
|
53 |
+
|
54 |
+
await m.reply_text(
|
55 |
+
(tlang(m, "rules.get_rules")).format(
|
56 |
+
chat=f"<b>{m.chat.title}</b>",
|
57 |
+
rules=formated,
|
58 |
+
),
|
59 |
+
disable_web_page_preview=True,
|
60 |
+
reply_to_message_id=msg_id,
|
61 |
+
)
|
62 |
+
return
|
63 |
+
|
64 |
+
|
65 |
+
@Gojo.on_message(command("setrules") & admin_filter)
|
66 |
+
async def set_rules(_, m: Message):
|
67 |
+
db = Rules(m.chat.id)
|
68 |
+
if m and not m.from_user:
|
69 |
+
return
|
70 |
+
|
71 |
+
if m.reply_to_message and m.reply_to_message.text:
|
72 |
+
rules = m.reply_to_message.text.markdown
|
73 |
+
elif (not m.reply_to_message) and len(m.text.split()) >= 2:
|
74 |
+
rules = m.text.split(None, 1)[1]
|
75 |
+
else:
|
76 |
+
return await m.reply_text("Provide some text to set as rules !!")
|
77 |
+
|
78 |
+
if len(rules) > 4000:
|
79 |
+
rules = rules[0:3949] # Split Rules if len > 4000 chars
|
80 |
+
await m.reply_text("Rules are truncated to 3950 characters!")
|
81 |
+
|
82 |
+
db.set_rules(rules)
|
83 |
+
LOGGER.info(f"{m.from_user.id} set rules in {m.chat.id}")
|
84 |
+
await m.reply_text(tlang(m, "rules.set_rules"))
|
85 |
+
return
|
86 |
+
|
87 |
+
|
88 |
+
@Gojo.on_message(
|
89 |
+
command(["pmrules", "privaterules"]) & admin_filter,
|
90 |
+
)
|
91 |
+
async def priv_rules(_, m: Message):
|
92 |
+
db = Rules(m.chat.id)
|
93 |
+
if m and not m.from_user:
|
94 |
+
return
|
95 |
+
|
96 |
+
if len(m.text.split()) == 2:
|
97 |
+
option = (m.text.split())[1]
|
98 |
+
if option in ("on", "yes"):
|
99 |
+
db.set_privrules(True)
|
100 |
+
LOGGER.info(f"{m.from_user.id} enabled privaterules in {m.chat.id}")
|
101 |
+
msg = tlang(m, "rules.priv_rules.turned_on").format(chat_name=m.chat.title)
|
102 |
+
elif option in ("off", "no"):
|
103 |
+
db.set_privrules(False)
|
104 |
+
LOGGER.info(f"{m.from_user.id} disbaled privaterules in {m.chat.id}")
|
105 |
+
msg = tlang(m, "rules.priv_rules.turned_off").format(chat_name=m.chat.title)
|
106 |
+
else:
|
107 |
+
msg = tlang(m, "rules.priv_rules.no_option")
|
108 |
+
await m.reply_text(msg)
|
109 |
+
elif len(m.text.split()) == 1:
|
110 |
+
curr_pref = db.get_privrules()
|
111 |
+
msg = tlang(m, "rules.priv_rules.current_preference").format(
|
112 |
+
current_option=curr_pref,
|
113 |
+
)
|
114 |
+
LOGGER.info(f"{m.from_user.id} fetched privaterules preference in {m.chat.id}")
|
115 |
+
await m.reply_text(msg)
|
116 |
+
else:
|
117 |
+
await m.replt_text(tlang(m, "general.check_help"))
|
118 |
+
|
119 |
+
return
|
120 |
+
|
121 |
+
|
122 |
+
@Gojo.on_message(command("clearrules") & admin_filter)
|
123 |
+
async def clear_rules(_, m: Message):
|
124 |
+
db = Rules(m.chat.id)
|
125 |
+
if m and not m.from_user:
|
126 |
+
return
|
127 |
+
|
128 |
+
rules = db.get_rules()
|
129 |
+
if not rules:
|
130 |
+
await m.reply_text(tlang(m, "rules.no_rules"))
|
131 |
+
return
|
132 |
+
|
133 |
+
await m.reply_text(
|
134 |
+
(tlang(m, "rules.clear_rules")),
|
135 |
+
reply_markup=ikb(
|
136 |
+
[[("⚠️ Confirm", "clear_rules"), ("❌ Cancel", "close_admin")]],
|
137 |
+
),
|
138 |
+
)
|
139 |
+
return
|
140 |
+
|
141 |
+
|
142 |
+
@Gojo.on_callback_query(filters.regex("^clear_rules$"))
|
143 |
+
async def clearrules_callback(_, q: CallbackQuery):
|
144 |
+
Rules(q.message.chat.id).clear_rules()
|
145 |
+
await q.message.edit_text(tlang(q, "rules.cleared"))
|
146 |
+
LOGGER.info(f"{q.from_user.id} cleared rules in {q.message.chat.id}")
|
147 |
+
await q.answer("Rules for the chat have been cleared!", show_alert=True)
|
148 |
+
return
|
149 |
+
|
150 |
+
|
151 |
+
__PLUGIN__ = "rules"
|
152 |
+
|
153 |
+
__alt_name__ = ["rule"]
|
Powers/plugins/start.py
ADDED
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram import filters
|
2 |
+
from pyrogram.errors import MessageNotModified, QueryIdInvalid, UserIsBlocked
|
3 |
+
from pyrogram.types import CallbackQuery, Message
|
4 |
+
|
5 |
+
from Powers import HELP_COMMANDS, LOGGER
|
6 |
+
from Powers.bot_class import Gojo
|
7 |
+
from Powers.tr_engine import tlang
|
8 |
+
from Powers.utils.custom_filters import command
|
9 |
+
from Powers.utils.kbhelpers import ikb
|
10 |
+
from Powers.utils.start_utils import (
|
11 |
+
gen_cmds_kb,
|
12 |
+
gen_start_kb,
|
13 |
+
get_help_msg,
|
14 |
+
get_private_note,
|
15 |
+
get_private_rules,
|
16 |
+
)
|
17 |
+
from Powers.vars import Config
|
18 |
+
|
19 |
+
|
20 |
+
@Gojo.on_message(
|
21 |
+
command("donate") & (filters.group | filters.private),
|
22 |
+
)
|
23 |
+
async def donate(_, m: Message):
|
24 |
+
LOGGER.info(f"{m.from_user.id} fetched donation text in {m.chat.id}")
|
25 |
+
await m.reply_text(tlang(m, "general.donate_owner"))
|
26 |
+
return
|
27 |
+
|
28 |
+
|
29 |
+
@Gojo.on_callback_query(filters.regex("^close_admin$"))
|
30 |
+
async def close_admin_callback(_, q: CallbackQuery):
|
31 |
+
user_id = q.from_user.id
|
32 |
+
user_status = (await q.message.chat.get_member(user_id)).status
|
33 |
+
if user_status not in {"creator", "administrator"}:
|
34 |
+
await q.answer(
|
35 |
+
"You're not even an admin, don't try this explosive shit!",
|
36 |
+
show_alert=True,
|
37 |
+
)
|
38 |
+
return
|
39 |
+
if user_status != "creator":
|
40 |
+
await q.answer(
|
41 |
+
"You're just an admin, not owner\nStay in your limits!",
|
42 |
+
show_alert=True,
|
43 |
+
)
|
44 |
+
return
|
45 |
+
await q.message.edit_text("Closed!")
|
46 |
+
await q.answer("Closed menu!", show_alert=True)
|
47 |
+
return
|
48 |
+
|
49 |
+
|
50 |
+
@Gojo.on_message(
|
51 |
+
command("start") & (filters.group | filters.private),
|
52 |
+
)
|
53 |
+
async def start(c: Gojo, m: Message):
|
54 |
+
if m.chat.type == "private":
|
55 |
+
if len(m.text.split()) > 1:
|
56 |
+
help_option = (m.text.split(None, 1)[1]).lower()
|
57 |
+
|
58 |
+
if help_option.startswith("note") and (
|
59 |
+
help_option not in ("note", "notes")
|
60 |
+
):
|
61 |
+
await get_private_note(c, m, help_option)
|
62 |
+
return
|
63 |
+
if help_option.startswith("rules"):
|
64 |
+
LOGGER.info(f"{m.from_user.id} fetched privaterules in {m.chat.id}")
|
65 |
+
await get_private_rules(c, m, help_option)
|
66 |
+
return
|
67 |
+
|
68 |
+
help_msg, help_kb = await get_help_msg(m, help_option)
|
69 |
+
|
70 |
+
if not help_msg:
|
71 |
+
return
|
72 |
+
|
73 |
+
await m.reply_text(
|
74 |
+
help_msg,
|
75 |
+
parse_mode="markdown",
|
76 |
+
reply_markup=ikb(help_kb),
|
77 |
+
quote=True,
|
78 |
+
disable_web_page_preview=True,
|
79 |
+
)
|
80 |
+
return
|
81 |
+
try:
|
82 |
+
await m.reply_text(
|
83 |
+
(tlang(m, "start.private")),
|
84 |
+
reply_markup=(await gen_start_kb(m)),
|
85 |
+
quote=True,
|
86 |
+
disable_web_page_preview=True,
|
87 |
+
)
|
88 |
+
except UserIsBlocked:
|
89 |
+
LOGGER.warning(f"Bot blocked by {m.from_user.id}")
|
90 |
+
else:
|
91 |
+
await m.reply_text(
|
92 |
+
(tlang(m, "start.group")),
|
93 |
+
quote=True,
|
94 |
+
)
|
95 |
+
return
|
96 |
+
|
97 |
+
|
98 |
+
@Gojo.on_callback_query(filters.regex("^start_back$"))
|
99 |
+
async def start_back(_, q: CallbackQuery):
|
100 |
+
try:
|
101 |
+
await q.message.edit_text(
|
102 |
+
(tlang(q, "start.private")),
|
103 |
+
reply_markup=(await gen_start_kb(q.message)),
|
104 |
+
disable_web_page_preview=True,
|
105 |
+
)
|
106 |
+
except MessageNotModified:
|
107 |
+
pass
|
108 |
+
await q.answer()
|
109 |
+
return
|
110 |
+
|
111 |
+
|
112 |
+
@Gojo.on_callback_query(filters.regex("^commands$"))
|
113 |
+
async def commands_menu(_, q: CallbackQuery):
|
114 |
+
keyboard = ikb(
|
115 |
+
[
|
116 |
+
*(await gen_cmds_kb(q)),
|
117 |
+
[(f"« {(tlang(q, 'general.back_btn'))}", "start_back")],
|
118 |
+
],
|
119 |
+
)
|
120 |
+
try:
|
121 |
+
await q.message.edit_text(
|
122 |
+
(tlang(q, "general.commands_available")),
|
123 |
+
reply_markup=keyboard,
|
124 |
+
)
|
125 |
+
except MessageNotModified:
|
126 |
+
pass
|
127 |
+
except QueryIdInvalid:
|
128 |
+
await q.message.reply_text(
|
129 |
+
(tlang(q, "general.commands_available")),
|
130 |
+
reply_markup=keyboard,
|
131 |
+
)
|
132 |
+
await q.answer()
|
133 |
+
return
|
134 |
+
|
135 |
+
|
136 |
+
@Gojo.on_message(command("help"))
|
137 |
+
async def help_menu(_, m: Message):
|
138 |
+
if len(m.text.split()) >= 2:
|
139 |
+
help_option = (m.text.split(None, 1)[1]).lower()
|
140 |
+
help_msg, help_kb = await get_help_msg(m, help_option)
|
141 |
+
|
142 |
+
if not help_msg:
|
143 |
+
LOGGER.error(f"No help_msg found for help_option - {help_option}!!")
|
144 |
+
return
|
145 |
+
|
146 |
+
LOGGER.info(
|
147 |
+
f"{m.from_user.id} fetched help for '{help_option}' text in {m.chat.id}",
|
148 |
+
)
|
149 |
+
if m.chat.type == "private":
|
150 |
+
await m.reply_text(
|
151 |
+
help_msg,
|
152 |
+
parse_mode="markdown",
|
153 |
+
reply_markup=ikb(help_kb),
|
154 |
+
quote=True,
|
155 |
+
disable_web_page_preview=True,
|
156 |
+
)
|
157 |
+
else:
|
158 |
+
await m.reply_text(
|
159 |
+
(tlang(m, "start.public_help").format(help_option=help_option)),
|
160 |
+
reply_markup=ikb(
|
161 |
+
[
|
162 |
+
[
|
163 |
+
(
|
164 |
+
"Help",
|
165 |
+
f"t.me/{Config.BOT_USERNAME}?start={help_option}",
|
166 |
+
"url",
|
167 |
+
),
|
168 |
+
],
|
169 |
+
],
|
170 |
+
),
|
171 |
+
)
|
172 |
+
else:
|
173 |
+
if m.chat.type == "private":
|
174 |
+
keyboard = ikb(
|
175 |
+
[
|
176 |
+
*(await gen_cmds_kb(m)),
|
177 |
+
[(f"« {(tlang(m, 'general.back_btn'))}", "start_back")],
|
178 |
+
],
|
179 |
+
)
|
180 |
+
msg = tlang(m, "general.commands_available")
|
181 |
+
else:
|
182 |
+
keyboard = ikb(
|
183 |
+
[[("Help", f"t.me/{Config.BOT_USERNAME}?start=help", "url")]],
|
184 |
+
)
|
185 |
+
msg = tlang(m, "start.pm_for_help")
|
186 |
+
|
187 |
+
await m.reply_text(
|
188 |
+
msg,
|
189 |
+
reply_markup=keyboard,
|
190 |
+
)
|
191 |
+
|
192 |
+
return
|
193 |
+
|
194 |
+
|
195 |
+
@Gojo.on_callback_query(filters.regex("^get_mod."))
|
196 |
+
async def get_module_info(_, q: CallbackQuery):
|
197 |
+
module = q.data.split(".", 1)[1]
|
198 |
+
|
199 |
+
help_msg = f"**{(tlang(q, str(module)))}:**\n\n" + tlang(
|
200 |
+
q,
|
201 |
+
HELP_COMMANDS[module]["help_msg"],
|
202 |
+
)
|
203 |
+
|
204 |
+
help_kb = HELP_COMMANDS[module]["buttons"] + [
|
205 |
+
[("« " + (tlang(q, "general.back_btn")), "commands")],
|
206 |
+
]
|
207 |
+
await q.message.edit_text(
|
208 |
+
help_msg,
|
209 |
+
parse_mode="markdown",
|
210 |
+
reply_markup=ikb(help_kb),
|
211 |
+
)
|
212 |
+
await q.answer()
|
213 |
+
return
|
Powers/plugins/stats.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pyrogram.types import Message
|
2 |
+
|
3 |
+
from Powers.bot_class import Gojo
|
4 |
+
from Powers.database.antispam_db import GBan
|
5 |
+
from Powers.database.approve_db import Approve
|
6 |
+
from Powers.database.blacklist_db import Blacklist
|
7 |
+
from Powers.database.chats_db import Chats
|
8 |
+
from Powers.database.disable_db import Disabling
|
9 |
+
from Powers.database.filters_db import Filters
|
10 |
+
from Powers.database.greetings_db import Greetings
|
11 |
+
from Powers.database.notes_db import Notes, NotesSettings
|
12 |
+
from Powers.database.pins_db import Pins
|
13 |
+
from Powers.database.rules_db import Rules
|
14 |
+
from Powers.database.users_db import Users
|
15 |
+
from Powers.database.warns_db import Warns, WarnSettings
|
16 |
+
from Powers.utils.custom_filters import command
|
17 |
+
|
18 |
+
|
19 |
+
@Gojo.on_message(command("stats", dev_cmd=True))
|
20 |
+
async def get_stats(_, m: Message):
|
21 |
+
# initialise
|
22 |
+
bldb = Blacklist
|
23 |
+
gbandb = GBan()
|
24 |
+
notesdb = Notes()
|
25 |
+
rulesdb = Rules
|
26 |
+
grtdb = Greetings
|
27 |
+
userdb = Users
|
28 |
+
dsbl = Disabling
|
29 |
+
appdb = Approve
|
30 |
+
chatdb = Chats
|
31 |
+
fldb = Filters()
|
32 |
+
pinsdb = Pins
|
33 |
+
notesettings_db = NotesSettings()
|
34 |
+
warns_db = Warns
|
35 |
+
warns_settings_db = WarnSettings
|
36 |
+
|
37 |
+
replymsg = await m.reply_text("<b><i>Fetching Stats...</i></b>", quote=True)
|
38 |
+
rply = (
|
39 |
+
f"<b>Users:</b> <code>{(userdb.count_users())}</code> in <code>{(chatdb.count_chats())}</code> chats\n"
|
40 |
+
f"<b>Anti Channel Pin:</b> <code>{(pinsdb.count_chats('antichannelpin'))}</code> enabled chats\n"
|
41 |
+
f"<b>Clean Linked:</b> <code>{(pinsdb.count_chats('cleanlinked'))}</code> enabled chats\n"
|
42 |
+
f"<b>Filters:</b> <code>{(fldb.count_filters_all())}</code> in <code>{(fldb.count_filters_chats())}</code> chats\n"
|
43 |
+
f" <b>Aliases:</b> <code>{(fldb.count_filter_aliases())}</code>\n"
|
44 |
+
f"<b>Blacklists:</b> <code>{(bldb.count_blacklists_all())}</code> in <code>{(bldb.count_blackists_chats())}</code> chats\n"
|
45 |
+
f" <b>Action Specific:</b>\n"
|
46 |
+
f" <b>None:</b> <code>{(bldb.count_action_bl_all('none'))}</code> chats\n"
|
47 |
+
f" <b>Kick</b> <code>{(bldb.count_action_bl_all('kick'))}</code> chats\n"
|
48 |
+
f" <b>Warn:</b> <code>{(bldb.count_action_bl_all('warn'))}</code> chats\n"
|
49 |
+
f" <b>Ban</b> <code>{(bldb.count_action_bl_all('ban'))}</code> chats\n"
|
50 |
+
f"<b>Rules:</b> Set in <code>{(rulesdb.count_chats_with_rules())}</code> chats\n"
|
51 |
+
f" <b>Private Rules:</b> <code>{(rulesdb.count_privrules_chats())}</code> chats\n"
|
52 |
+
f"<b>Warns:</b> <code>{(warns_db.count_warns_total())}</code> in <code>{(warns_db.count_all_chats_using_warns())}</code> chats\n"
|
53 |
+
f" <b>Users Warned:</b> <code>{(warns_db.count_warned_users())}</code> users\n"
|
54 |
+
f" <b>Action Specific:</b>\n"
|
55 |
+
f" <b>Kick</b>: <code>{(warns_settings_db.count_action_chats('kick'))}</code>\n"
|
56 |
+
f" <b>Mute</b>: <code>{(warns_settings_db.count_action_chats('mute'))}</code>\n"
|
57 |
+
f" <b>Ban</b>: <code>{warns_settings_db.count_action_chats('ban')}</code>\n"
|
58 |
+
f"<b>Notes:</b> <code>{(notesdb.count_all_notes())}</code> in <code>{(notesdb.count_notes_chats())}</code> chats\n"
|
59 |
+
f" <b>Private Notes:</b> <code>{(notesettings_db.count_chats())}</code> chats\n"
|
60 |
+
f"<b>GBanned Users:</b> <code>{(gbandb.count_gbans())}</code>\n"
|
61 |
+
f"<b>Welcoming Users in:</b> <code>{(grtdb.count_chats('welcome'))}</code> chats"
|
62 |
+
f"<b>Approved People</b>: <code>{(appdb.count_all_approved())}</code> in <code>{(appdb.count_approved_chats())}</code> chats\n"
|
63 |
+
f"<b>Disabling:</b> <code>{(dsbl.count_disabled_all())}</code> items in <code>{(dsbl.count_disabling_chats())}</code> chats.\n"
|
64 |
+
"<b>Action:</b>\n"
|
65 |
+
f" <b>Del:</b> Applied in <code>{(dsbl.count_action_dis_all('del'))}</code> chats.\n"
|
66 |
+
)
|
67 |
+
await replymsg.edit_text(rply, parse_mode="html")
|
68 |
+
return
|
Powers/plugins/utils.py
ADDED
@@ -0,0 +1,393 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from html import escape
|
2 |
+
from io import BytesIO
|
3 |
+
from os import remove
|
4 |
+
|
5 |
+
from gpytranslate import Translator
|
6 |
+
from pyrogram import filters
|
7 |
+
from pyrogram.errors import MessageTooLong, PeerIdInvalid, RPCError
|
8 |
+
from pyrogram.types import Message
|
9 |
+
from tswift import Song
|
10 |
+
from wikipedia import summary
|
11 |
+
from wikipedia.exceptions import DisambiguationError, PageError
|
12 |
+
|
13 |
+
from Powers import (
|
14 |
+
DEV_USERS,
|
15 |
+
LOGGER,
|
16 |
+
OWNER_ID,
|
17 |
+
SUDO_USERS,
|
18 |
+
SUPPORT_GROUP,
|
19 |
+
SUPPORT_STAFF,
|
20 |
+
WHITELIST_USERS,
|
21 |
+
)
|
22 |
+
from Powers.bot_class import Gojo
|
23 |
+
from Powers.database.antispam_db import GBan
|
24 |
+
from Powers.database.users_db import Users
|
25 |
+
from Powers.tr_engine import tlang
|
26 |
+
from Powers.utils.clean_file import remove_markdown_and_html
|
27 |
+
from Powers.utils.custom_filters import command
|
28 |
+
from Powers.utils.extract_user import extract_user
|
29 |
+
from Powers.utils.http_helper import HTTPx, http
|
30 |
+
from Powers.utils.kbhelpers import ikb
|
31 |
+
from Powers.utils.parser import mention_html
|
32 |
+
from Powers.vars import Config
|
33 |
+
|
34 |
+
gban_db = GBan()
|
35 |
+
|
36 |
+
|
37 |
+
@Gojo.on_message(command("wiki"))
|
38 |
+
async def wiki(_, m: Message):
|
39 |
+
LOGGER.info(f"{m.from_user.id} used wiki cmd in {m.chat.id}")
|
40 |
+
|
41 |
+
if len(m.text.split()) <= 1:
|
42 |
+
return await m.reply_text(tlang(m, "general.check_help"))
|
43 |
+
|
44 |
+
search = m.text.split(None, 1)[1]
|
45 |
+
try:
|
46 |
+
res = summary(search)
|
47 |
+
except DisambiguationError as de:
|
48 |
+
return await m.reply_text(
|
49 |
+
f"Disambiguated pages found! Adjust your query accordingly.\n<i>{de}</i>",
|
50 |
+
parse_mode="html",
|
51 |
+
)
|
52 |
+
except PageError as pe:
|
53 |
+
return await m.reply_text(f"<code>{pe}</code>", parse_mode="html")
|
54 |
+
if res:
|
55 |
+
result = f"<b>{search}</b>\n\n"
|
56 |
+
result += f"<i>{res}</i>\n"
|
57 |
+
result += f"""<a href="https://en.wikipedia.org/wiki/{search.replace(" ", "%20")}">Read more...</a>"""
|
58 |
+
try:
|
59 |
+
return await m.reply_text(
|
60 |
+
result,
|
61 |
+
parse_mode="html",
|
62 |
+
disable_web_page_preview=True,
|
63 |
+
)
|
64 |
+
except MessageTooLong:
|
65 |
+
with BytesIO(str.encode(await remove_markdown_and_html(result))) as f:
|
66 |
+
f.name = "result.txt"
|
67 |
+
return await m.reply_document(
|
68 |
+
document=f,
|
69 |
+
quote=True,
|
70 |
+
parse_mode="html",
|
71 |
+
)
|
72 |
+
await m.stop_propagation()
|
73 |
+
|
74 |
+
|
75 |
+
@Gojo.on_message(command("gdpr"))
|
76 |
+
async def gdpr_remove(_, m: Message):
|
77 |
+
if m.from_user.id in SUPPORT_STAFF:
|
78 |
+
await m.reply_text(
|
79 |
+
"You're in my support staff, I cannot do that unless you are no longer a part of it!",
|
80 |
+
)
|
81 |
+
return
|
82 |
+
|
83 |
+
Users(m.from_user.id).delete_user()
|
84 |
+
await m.reply_text(
|
85 |
+
"Your personal data has been deleted.\n"
|
86 |
+
"Note that this will not unban you from any chats, as that is telegram data, not Gojo data."
|
87 |
+
" Flooding, warns, and gbans are also preserved, as of "
|
88 |
+
"[this](https://ico.org.uk/for-organisations/guide-to-the-general-data-protection-regulation-gdpr/individual-rights/right-to-erasure/),"
|
89 |
+
" which clearly states that the right to erasure does not apply 'for the performance of a task carried out in the public interest', "
|
90 |
+
"as is the case for the aforementioned pieces of data.",
|
91 |
+
disable_web_page_preview=True,
|
92 |
+
)
|
93 |
+
await m.stop_propagation()
|
94 |
+
|
95 |
+
|
96 |
+
@Gojo.on_message(
|
97 |
+
command("lyrics") & (filters.group | filters.private),
|
98 |
+
)
|
99 |
+
async def get_lyrics(_, m: Message):
|
100 |
+
if len(m.text.split()) <= 1:
|
101 |
+
await m.reply_text(tlang(m, "general.check_help"))
|
102 |
+
return
|
103 |
+
|
104 |
+
query = m.text.split(None, 1)[1]
|
105 |
+
LOGGER.info(f"{m.from_user.id} used lyrics cmd in {m.chat.id}")
|
106 |
+
song = ""
|
107 |
+
if not query:
|
108 |
+
await m.edit_text(tlang(m, "utils.song.no_song_given"))
|
109 |
+
return
|
110 |
+
|
111 |
+
em = await m.reply_text(
|
112 |
+
(tlang(m, "utils.song.searching").format(song_name=query)),
|
113 |
+
)
|
114 |
+
song = Song.find_song(query)
|
115 |
+
if song:
|
116 |
+
if song.lyrics:
|
117 |
+
reply = song.format()
|
118 |
+
else:
|
119 |
+
reply = tlang(m, "utils.song.no_lyrics_found")
|
120 |
+
else:
|
121 |
+
reply = tlang(m, "utils.song.song_not_found")
|
122 |
+
try:
|
123 |
+
await em.edit_text(reply)
|
124 |
+
except MessageTooLong:
|
125 |
+
with BytesIO(str.encode(await remove_markdown_and_html(reply))) as f:
|
126 |
+
f.name = "lyrics.txt"
|
127 |
+
await m.reply_document(
|
128 |
+
document=f,
|
129 |
+
)
|
130 |
+
await em.delete()
|
131 |
+
return
|
132 |
+
|
133 |
+
|
134 |
+
@Gojo.on_message(
|
135 |
+
command("id") & (filters.group | filters.private),
|
136 |
+
)
|
137 |
+
async def id_info(c: Gojo, m: Message):
|
138 |
+
LOGGER.info(f"{m.from_user.id} used id cmd in {m.chat.id}")
|
139 |
+
|
140 |
+
if m.chat.type == "supergroup" and not m.reply_to_message:
|
141 |
+
await m.reply_text((tlang(m, "utils.id.group_id")).format(group_id=m.chat.id))
|
142 |
+
return
|
143 |
+
|
144 |
+
if m.chat.type == "private" and not m.reply_to_message:
|
145 |
+
await m.reply_text((tlang(m, "utils.id.my_id")).format(my_id=m.chat.id))
|
146 |
+
return
|
147 |
+
|
148 |
+
user_id, _, _ = await extract_user(c, m)
|
149 |
+
if user_id:
|
150 |
+
if m.reply_to_message and m.reply_to_message.forward_from:
|
151 |
+
user1 = m.reply_to_message.from_user
|
152 |
+
user2 = m.reply_to_message.forward_from
|
153 |
+
await m.reply_text(
|
154 |
+
(tlang(m, "utils.id.id_main")).format(
|
155 |
+
orig_sender=(await mention_html(user2.first_name, user2.id)),
|
156 |
+
orig_id=f"<code>{user2.id}</code>",
|
157 |
+
fwd_sender=(await mention_html(user1.first_name, user1.id)),
|
158 |
+
fwd_id=f"<code>{user1.id}</code>",
|
159 |
+
),
|
160 |
+
parse_mode="HTML",
|
161 |
+
)
|
162 |
+
else:
|
163 |
+
try:
|
164 |
+
user = await c.get_users(user_id)
|
165 |
+
except PeerIdInvalid:
|
166 |
+
await m.reply_text(tlang(m, "utils.no_user_db"))
|
167 |
+
return
|
168 |
+
|
169 |
+
await m.reply_text(
|
170 |
+
f"{(await mention_html(user.first_name, user.id))}'s ID is <code>{user.id}</code>.",
|
171 |
+
parse_mode="HTML",
|
172 |
+
)
|
173 |
+
elif m.chat.type == "private":
|
174 |
+
await m.reply_text(
|
175 |
+
(tlang(m, "utils.id.my_id")).format(
|
176 |
+
my_id=f"<code>{m.chat.id}</code>",
|
177 |
+
),
|
178 |
+
)
|
179 |
+
else:
|
180 |
+
await m.reply_text(
|
181 |
+
(tlang(m, "utils.id.group_id")).format(
|
182 |
+
group_id=f"<code>{m.chat.id}</code>",
|
183 |
+
),
|
184 |
+
)
|
185 |
+
return
|
186 |
+
|
187 |
+
|
188 |
+
@Gojo.on_message(
|
189 |
+
command("gifid") & (filters.group | filters.private),
|
190 |
+
)
|
191 |
+
async def get_gifid(_, m: Message):
|
192 |
+
if m.reply_to_message and m.reply_to_message.animation:
|
193 |
+
LOGGER.info(f"{m.from_user.id} used gifid cmd in {m.chat.id}")
|
194 |
+
await m.reply_text(
|
195 |
+
f"Gif ID:\n<code>{m.reply_to_message.animation.file_id}</code>",
|
196 |
+
parse_mode="html",
|
197 |
+
)
|
198 |
+
else:
|
199 |
+
await m.reply_text(tlang(m, "utils.gif_id.reply_gif"))
|
200 |
+
return
|
201 |
+
|
202 |
+
|
203 |
+
@Gojo.on_message(
|
204 |
+
command("github") & (filters.group | filters.private),
|
205 |
+
)
|
206 |
+
async def github(_, m: Message):
|
207 |
+
if len(m.text.split()) == 2:
|
208 |
+
username = m.text.split(None, 1)[1]
|
209 |
+
LOGGER.info(f"{m.from_user.id} used github cmd in {m.chat.id}")
|
210 |
+
else:
|
211 |
+
await m.reply_text(
|
212 |
+
f"Usage: <code>{Config.PREFIX_HANDLER}github username</code>",
|
213 |
+
)
|
214 |
+
return
|
215 |
+
|
216 |
+
URL = f"https://api.github.com/users/{username}"
|
217 |
+
r = await HTTPx.get(URL)
|
218 |
+
if r.status_code == 404:
|
219 |
+
await m.reply_text(f"<code>{username}</code> not found", quote=True)
|
220 |
+
return
|
221 |
+
|
222 |
+
r_json = r.json()
|
223 |
+
url = r_json.get("html_url", None)
|
224 |
+
name = r_json.get("name", None)
|
225 |
+
company = r_json.get("company", None)
|
226 |
+
followers = r_json.get("followers", 0)
|
227 |
+
following = r_json.get("following", 0)
|
228 |
+
public_repos = r_json.get("public_repos", 0)
|
229 |
+
bio = r_json.get("bio", None)
|
230 |
+
created_at = r_json.get("created_at", "Not Found")
|
231 |
+
|
232 |
+
REPLY = (
|
233 |
+
f"<b>GitHub Info for @{username}:</b>"
|
234 |
+
f"\n<b>Name:</b> <code>{name}</code>\n"
|
235 |
+
f"<b>Bio:</b> <code>{bio}</code>\n"
|
236 |
+
f"<b>URL:</b> {url}\n"
|
237 |
+
f"<b>Public Repos:</b> {public_repos}\n"
|
238 |
+
f"<b>Followers:</b> {followers}\n"
|
239 |
+
f"<b>Following:</b> {following}\n"
|
240 |
+
f"<b>Company:</b> <code>{company}</code>\n"
|
241 |
+
f"<b>Created at:</b> <code>{created_at}</code>"
|
242 |
+
)
|
243 |
+
|
244 |
+
await m.reply_text(REPLY, quote=True, disable_web_page_preview=True)
|
245 |
+
return
|
246 |
+
|
247 |
+
|
248 |
+
@Gojo.on_message(
|
249 |
+
command("info") & (filters.group | filters.private),
|
250 |
+
)
|
251 |
+
async def my_info(c: Gojo, m: Message):
|
252 |
+
try:
|
253 |
+
user_id, name, user_name = await extract_user(c, m)
|
254 |
+
except PeerIdInvalid:
|
255 |
+
await m.reply_text(tlang(m, "utils.user_info.peer_id_error"))
|
256 |
+
return
|
257 |
+
except ValueError as ef:
|
258 |
+
if "Peer id invalid" in str(ef):
|
259 |
+
await m.reply_text(tlang(m, "utils.user_info.id_not_found"))
|
260 |
+
return
|
261 |
+
try:
|
262 |
+
user = Users.get_user_info(int(user_id))
|
263 |
+
name = user["name"]
|
264 |
+
user_name = user["username"]
|
265 |
+
user_id = user["_id"]
|
266 |
+
except KeyError:
|
267 |
+
LOGGER.warning(f"Calling api to fetch info about user {user_id}")
|
268 |
+
user = await c.get_users(user_id)
|
269 |
+
name = (
|
270 |
+
escape(user["first_name"] + " " + user["last_name"])
|
271 |
+
if user["last_name"]
|
272 |
+
else user["first_name"]
|
273 |
+
)
|
274 |
+
user_name = user["username"]
|
275 |
+
user_id = user["id"]
|
276 |
+
except PeerIdInvalid:
|
277 |
+
await m.reply_text(tlang(m, "utils.no_user_db"))
|
278 |
+
return
|
279 |
+
except (RPCError, Exception) as ef:
|
280 |
+
await m.reply_text(
|
281 |
+
(tlang(m, "general.some_error")).format(
|
282 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
283 |
+
ef=ef,
|
284 |
+
),
|
285 |
+
)
|
286 |
+
return
|
287 |
+
|
288 |
+
gbanned, reason_gban = gban_db.get_gban(user_id)
|
289 |
+
LOGGER.info(f"{m.from_user.id} used info cmd for {user_id} in {m.chat.id}")
|
290 |
+
|
291 |
+
text = (tlang(m, "utils.user_info.info_text.main")).format(
|
292 |
+
user_id=user_id,
|
293 |
+
user_name=name,
|
294 |
+
)
|
295 |
+
|
296 |
+
if user_name:
|
297 |
+
text += (tlang(m, "utils.user_info.info_text.username")).format(
|
298 |
+
username=user_name,
|
299 |
+
)
|
300 |
+
|
301 |
+
text += (tlang(m, "utils.user_info.info_text.perma_link")).format(
|
302 |
+
perma_link=(await mention_html("Click Here", user_id)),
|
303 |
+
)
|
304 |
+
|
305 |
+
if gbanned:
|
306 |
+
text += f"\nThis user is Globally banned beacuse: {reason_gban}\n"
|
307 |
+
|
308 |
+
if user_id == OWNER_ID:
|
309 |
+
text += tlang(m, "utils.user_info.support_user.owner")
|
310 |
+
elif user_id in DEV_USERS:
|
311 |
+
text += tlang(m, "utils.user_info.support_user.dev")
|
312 |
+
elif user_id in SUDO_USERS:
|
313 |
+
text += tlang(m, "utils.user_info.support_user.sudo")
|
314 |
+
elif user_id in WHITELIST_USERS:
|
315 |
+
text += tlang(m, "utils.user_info.support_user.whitelist")
|
316 |
+
|
317 |
+
await m.reply_text(text, parse_mode="html", disable_web_page_preview=True)
|
318 |
+
return
|
319 |
+
|
320 |
+
|
321 |
+
@Gojo.on_message(command("paste"))
|
322 |
+
async def paste_it(_, m: Message):
|
323 |
+
replymsg = await m.reply_text((tlang(m, "utils.paste.pasting")), quote=True)
|
324 |
+
try:
|
325 |
+
if m.reply_to_message:
|
326 |
+
if m.reply_to_message.document:
|
327 |
+
dl_loc = await m.reply_to_message.download()
|
328 |
+
with open(dl_loc) as f:
|
329 |
+
txt = f.read()
|
330 |
+
remove(dl_loc)
|
331 |
+
else:
|
332 |
+
txt = m.reply_to_message.text
|
333 |
+
else:
|
334 |
+
txt = m.text.split(None, 1)[1]
|
335 |
+
ur = "https://hastebin.com/documents"
|
336 |
+
r = await http.post(ur, json={"content": txt})
|
337 |
+
url = f"https://hastebin.com/{r.json().get('key')}"
|
338 |
+
await replymsg.edit_text(
|
339 |
+
(tlang(m, "utils.paste.pasted_nekobin")),
|
340 |
+
reply_markup=ikb([[((tlang(m, "utils.paste.nekobin_btn")), url, "url")]]),
|
341 |
+
)
|
342 |
+
LOGGER.info(f"{m.from_user.id} used paste cmd in {m.chat.id}")
|
343 |
+
except Exception as e:
|
344 |
+
await replymsg.edit_text(f"Error: {e}")
|
345 |
+
return
|
346 |
+
return
|
347 |
+
|
348 |
+
|
349 |
+
@Gojo.on_message(command("tr"))
|
350 |
+
async def translate(_, m: Message):
|
351 |
+
trl = Translator()
|
352 |
+
if m.reply_to_message and (m.reply_to_message.text or m.reply_to_message.caption):
|
353 |
+
if len(m.text.split()) == 1:
|
354 |
+
target_lang = "en"
|
355 |
+
else:
|
356 |
+
target_lang = m.text.split()[1]
|
357 |
+
if m.reply_to_message.text:
|
358 |
+
text = m.reply_to_message.text
|
359 |
+
else:
|
360 |
+
text = m.reply_to_message.caption
|
361 |
+
else:
|
362 |
+
if len(m.text.split()) <= 2:
|
363 |
+
await m.reply_text(
|
364 |
+
"Provide lang code.\n[Available options](https://telegra.ph/Lang-Codes-11-08).\n<b>Usage:</b> <code>/tr en</code>",
|
365 |
+
)
|
366 |
+
return
|
367 |
+
target_lang = m.text.split(None, 2)[1]
|
368 |
+
text = m.text.split(None, 2)[2]
|
369 |
+
detectlang = await trl.detect(text)
|
370 |
+
try:
|
371 |
+
tekstr = await trl(text, targetlang=target_lang)
|
372 |
+
except ValueError as err:
|
373 |
+
await m.reply_text(f"Error: <code>{str(err)}</code>")
|
374 |
+
return
|
375 |
+
LOGGER.info(f"{m.from_user.id} used translate cmd in {m.chat.id}")
|
376 |
+
return await m.reply_text(
|
377 |
+
f"<b>Translated:</b> from {detectlang} to {target_lang} \n<code>``{tekstr.text}``</code>",
|
378 |
+
)
|
379 |
+
|
380 |
+
|
381 |
+
__PLUGIN__ = "utils"
|
382 |
+
_DISABLE_CMDS_ = [
|
383 |
+
"paste",
|
384 |
+
"wiki",
|
385 |
+
"id",
|
386 |
+
"gifid",
|
387 |
+
"lyrics",
|
388 |
+
"tr",
|
389 |
+
"github",
|
390 |
+
"git",
|
391 |
+
"info",
|
392 |
+
]
|
393 |
+
__alt_name__ = ["util", "misc", "tools"]
|
Powers/plugins/warns.py
ADDED
@@ -0,0 +1,370 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from time import time
|
2 |
+
|
3 |
+
from pyrogram import filters
|
4 |
+
from pyrogram.errors import RPCError
|
5 |
+
from pyrogram.types import (
|
6 |
+
CallbackQuery,
|
7 |
+
ChatPermissions,
|
8 |
+
InlineKeyboardButton,
|
9 |
+
InlineKeyboardMarkup,
|
10 |
+
Message,
|
11 |
+
)
|
12 |
+
|
13 |
+
from Powers import LOGGER, SUPPORT_STAFF
|
14 |
+
from Powers.bot_class import Gojo
|
15 |
+
from Powers.database.rules_db import Rules
|
16 |
+
from Powers.database.users_db import Users
|
17 |
+
from Powers.database.warns_db import Warns, WarnSettings
|
18 |
+
from Powers.tr_engine import tlang
|
19 |
+
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
20 |
+
from Powers.utils.custom_filters import admin_filter, command, restrict_filter
|
21 |
+
from Powers.utils.extract_user import extract_user
|
22 |
+
from Powers.utils.parser import mention_html
|
23 |
+
from Powers.vars import Config
|
24 |
+
|
25 |
+
|
26 |
+
@Gojo.on_message(
|
27 |
+
command(["warn", "swarn", "dwarn"]) & restrict_filter,
|
28 |
+
)
|
29 |
+
async def warn(c: Gojo, m: Message):
|
30 |
+
if m.reply_to_message:
|
31 |
+
r_id = m.reply_to_message.message_id
|
32 |
+
if len(m.text.split()) >= 2:
|
33 |
+
reason = m.text.split(None, 1)[1]
|
34 |
+
else:
|
35 |
+
reason = None
|
36 |
+
elif not m.reply_to_message:
|
37 |
+
r_id = m.message_id
|
38 |
+
if len(m.text.split()) >= 3:
|
39 |
+
reason = m.text.split(None, 2)[2]
|
40 |
+
else:
|
41 |
+
reason = None
|
42 |
+
else:
|
43 |
+
reason = None
|
44 |
+
|
45 |
+
if not len(m.command) > 1 and not m.reply_to_message:
|
46 |
+
await m.reply_text("I can't warn nothing! Tell me user whom I should warn")
|
47 |
+
return
|
48 |
+
|
49 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
50 |
+
|
51 |
+
if user_id == Config.BOT_ID:
|
52 |
+
await m.reply_text("Huh, why would I warn myself?")
|
53 |
+
return
|
54 |
+
|
55 |
+
if user_id in SUPPORT_STAFF:
|
56 |
+
await m.reply_text(tlang(m, "admin.support_cannot_restrict"))
|
57 |
+
LOGGER.info(
|
58 |
+
f"{m.from_user.id} trying to warn {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
59 |
+
)
|
60 |
+
return
|
61 |
+
|
62 |
+
try:
|
63 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
64 |
+
except KeyError:
|
65 |
+
admins_group = {i[0] for i in (await admin_cache_reload(m, "warn_user"))}
|
66 |
+
|
67 |
+
if user_id in admins_group:
|
68 |
+
await m.reply_text("This user is admin in this chat, I can't warn them!")
|
69 |
+
return
|
70 |
+
|
71 |
+
warn_db = Warns(m.chat.id)
|
72 |
+
warn_settings_db = WarnSettings(m.chat.id)
|
73 |
+
|
74 |
+
_, num = warn_db.warn_user(user_id, reason)
|
75 |
+
warn_settings = warn_settings_db.get_warnings_settings()
|
76 |
+
if num >= warn_settings["warn_limit"]:
|
77 |
+
if warn_settings["warn_mode"] == "kick":
|
78 |
+
await m.chat.ban_member(user_id, until_date=int(time() + 45))
|
79 |
+
action = "kicked"
|
80 |
+
elif warn_settings["warn_mode"] == "ban":
|
81 |
+
await m.chat.ban_member(user_id)
|
82 |
+
action = "banned"
|
83 |
+
elif warn_settings["warn_mode"] == "mute":
|
84 |
+
await m.chat.restrict_member(user_id, ChatPermissions())
|
85 |
+
action = "muted"
|
86 |
+
await m.reply_text(
|
87 |
+
(
|
88 |
+
f"Warnings {num}/{warn_settings['warn_limit']}!"
|
89 |
+
f"\n<b>Reason for last warn</b>:\n{reason}"
|
90 |
+
if reason
|
91 |
+
else "\n"
|
92 |
+
f"{(await mention_html(user_first_name, user_id))} has been <b>{action}!</b>"
|
93 |
+
),
|
94 |
+
reply_to_message_id=r_id,
|
95 |
+
)
|
96 |
+
await m.stop_propagation()
|
97 |
+
|
98 |
+
rules = Rules(m.chat.id).get_rules()
|
99 |
+
if rules:
|
100 |
+
kb = InlineKeyboardButton(
|
101 |
+
"Rules 📋",
|
102 |
+
url=f"https://t.me/{Config.BOT_USERNAME}?start=rules_{m.chat.id}",
|
103 |
+
)
|
104 |
+
else:
|
105 |
+
kb = InlineKeyboardButton(
|
106 |
+
"Kick ⚠️",
|
107 |
+
callback_data=f"warn.kick.{user_id}",
|
108 |
+
)
|
109 |
+
|
110 |
+
if m.text.split()[0] == "/swarn":
|
111 |
+
await m.delete()
|
112 |
+
await m.stop_propagation()
|
113 |
+
if m.text.split()[0] == "/dwarn":
|
114 |
+
if not m.reply_to_message:
|
115 |
+
await m.reply_text("Reply to a message to delete it and ban the user!")
|
116 |
+
await m.stop_propagation()
|
117 |
+
await m.reply_to_message.delete()
|
118 |
+
txt = f"{(await mention_html(user_first_name, user_id))} has {num}/{warn_settings['warn_limit']} warnings!"
|
119 |
+
txt += f"\n<b>Reason for last warn</b>:\n{reason}" if reason else ""
|
120 |
+
await m.reply_text(
|
121 |
+
txt,
|
122 |
+
reply_markup=InlineKeyboardMarkup(
|
123 |
+
[
|
124 |
+
[
|
125 |
+
InlineKeyboardButton(
|
126 |
+
"Remove Warn ❌",
|
127 |
+
callback_data=f"warn.remove.{user_id}",
|
128 |
+
),
|
129 |
+
]
|
130 |
+
+ [kb],
|
131 |
+
],
|
132 |
+
),
|
133 |
+
reply_to_message_id=r_id,
|
134 |
+
)
|
135 |
+
await m.stop_propagation()
|
136 |
+
|
137 |
+
|
138 |
+
@Gojo.on_message(command("resetwarns") & restrict_filter)
|
139 |
+
async def reset_warn(c: Gojo, m: Message):
|
140 |
+
|
141 |
+
if not len(m.command) > 1 and not m.reply_to_message:
|
142 |
+
await m.reply_text("I can't warn nothing! Tell me user whom I should warn")
|
143 |
+
return
|
144 |
+
|
145 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
146 |
+
|
147 |
+
if user_id == Config.BOT_ID:
|
148 |
+
await m.reply_text("Huh, why would I warn myself?")
|
149 |
+
return
|
150 |
+
|
151 |
+
if user_id in SUPPORT_STAFF:
|
152 |
+
await m.reply_text(
|
153 |
+
"They are support users, cannot be restriced, how am I then supposed to unrestrict them?",
|
154 |
+
)
|
155 |
+
LOGGER.info(
|
156 |
+
f"{m.from_user.id} trying to resetwarn {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
157 |
+
)
|
158 |
+
return
|
159 |
+
|
160 |
+
try:
|
161 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
162 |
+
except KeyError:
|
163 |
+
admins_group = {i[0] for i in (await admin_cache_reload(m, "reset_warns"))}
|
164 |
+
|
165 |
+
if user_id in admins_group:
|
166 |
+
await m.reply_text("This user is admin in this chat, I can't warn them!")
|
167 |
+
return
|
168 |
+
|
169 |
+
warn_db = Warns(m.chat.id)
|
170 |
+
warn_db.reset_warns(user_id)
|
171 |
+
await m.reply_text(
|
172 |
+
f"Warnings have been reset for {(await mention_html(user_first_name, user_id))}",
|
173 |
+
)
|
174 |
+
return
|
175 |
+
|
176 |
+
|
177 |
+
@Gojo.on_message(command("warns") & filters.group)
|
178 |
+
async def list_warns(c: Gojo, m: Message):
|
179 |
+
|
180 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
181 |
+
|
182 |
+
if user_id == Config.BOT_ID:
|
183 |
+
await m.reply_text("Huh, why would I warn myself?")
|
184 |
+
return
|
185 |
+
|
186 |
+
if user_id in SUPPORT_STAFF:
|
187 |
+
await m.reply_text("This user has no warns!")
|
188 |
+
LOGGER.info(
|
189 |
+
f"{m.from_user.id} trying to check warns of {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
190 |
+
)
|
191 |
+
return
|
192 |
+
|
193 |
+
try:
|
194 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
195 |
+
except KeyError:
|
196 |
+
admins_group = {i[0] for i in (await admin_cache_reload(m, "warns"))}
|
197 |
+
|
198 |
+
if user_id in admins_group:
|
199 |
+
await m.reply_text(
|
200 |
+
"This user is admin in this chat, they don't have any warns!",
|
201 |
+
)
|
202 |
+
return
|
203 |
+
|
204 |
+
warn_db = Warns(m.chat.id)
|
205 |
+
warn_settings_db = WarnSettings(m.chat.id)
|
206 |
+
warns, num_warns = warn_db.get_warns(user_id)
|
207 |
+
warn_settings = warn_settings_db.get_warnings_settings()
|
208 |
+
if not warns:
|
209 |
+
await m.reply_text("This user has no warns!")
|
210 |
+
return
|
211 |
+
msg = f"{(await mention_html(user_first_name,user_id))} has <b>{num_warns}/{warn_settings['warn_limit']}</b> warns!\n\n<b>Reasons:</b>\n"
|
212 |
+
msg += "\n".join([("- No reason" if i is None else f" - {i}") for i in warns])
|
213 |
+
await m.reply_text(msg)
|
214 |
+
return
|
215 |
+
|
216 |
+
|
217 |
+
@Gojo.on_message(
|
218 |
+
command(["rmwarn", "removewarn"]) & restrict_filter,
|
219 |
+
)
|
220 |
+
async def remove_warn(c: Gojo, m: Message):
|
221 |
+
|
222 |
+
if not len(m.command) > 1 and not m.reply_to_message:
|
223 |
+
await m.reply_text(
|
224 |
+
"I can't remove warns of nothing! Tell me user whose warn should be removed!",
|
225 |
+
)
|
226 |
+
return
|
227 |
+
|
228 |
+
user_id, user_first_name, _ = await extract_user(c, m)
|
229 |
+
|
230 |
+
if user_id == Config.BOT_ID:
|
231 |
+
await m.reply_text("Huh, why would I warn myself?")
|
232 |
+
return
|
233 |
+
|
234 |
+
if user_id in SUPPORT_STAFF:
|
235 |
+
await m.reply_text("This user has no warns!")
|
236 |
+
LOGGER.info(
|
237 |
+
f"{m.from_user.id} trying to remove warns of {user_id} (SUPPORT_STAFF) in {m.chat.id}",
|
238 |
+
)
|
239 |
+
return
|
240 |
+
|
241 |
+
try:
|
242 |
+
admins_group = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
243 |
+
except KeyError:
|
244 |
+
admins_group = {i[0] for i in (await admin_cache_reload(m, "rmwarn"))}
|
245 |
+
|
246 |
+
if user_id in admins_group:
|
247 |
+
await m.reply_text(
|
248 |
+
"This user is admin in this chat, they don't have any warns!",
|
249 |
+
)
|
250 |
+
return
|
251 |
+
|
252 |
+
warn_db = Warns(m.chat.id)
|
253 |
+
warns, _ = warn_db.get_warns(user_id)
|
254 |
+
if not warns:
|
255 |
+
await m.reply_text("This user has no warnings!")
|
256 |
+
return
|
257 |
+
|
258 |
+
_, num_warns = warn_db.remove_warn(user_id)
|
259 |
+
await m.reply_text(
|
260 |
+
(
|
261 |
+
f"{(await mention_html(user_first_name,user_id))} now has <b>{num_warns}</b> warnings!\n"
|
262 |
+
"Their last warn was removed."
|
263 |
+
),
|
264 |
+
)
|
265 |
+
return
|
266 |
+
|
267 |
+
|
268 |
+
@Gojo.on_callback_query(filters.regex("^warn."))
|
269 |
+
async def remove_last_warn_btn(c: Gojo, q: CallbackQuery):
|
270 |
+
|
271 |
+
try:
|
272 |
+
admins_group = {i[0] for i in ADMIN_CACHE[q.message.chat.id]}
|
273 |
+
except KeyError:
|
274 |
+
admins_group = {i[0] for i in (await admin_cache_reload(q, "warn_btn"))}
|
275 |
+
|
276 |
+
if q.from_user.id not in admins_group:
|
277 |
+
await q.answer("You are not allowed to use this!", show_alert=True)
|
278 |
+
return
|
279 |
+
|
280 |
+
args = q.data.split(".")
|
281 |
+
action = args[1]
|
282 |
+
user_id = int(args[2])
|
283 |
+
chat_id = int(q.message.chat.id)
|
284 |
+
user = Users.get_user_info(int(user_id))
|
285 |
+
user_first_name = user["name"]
|
286 |
+
|
287 |
+
if action == "remove":
|
288 |
+
warn_db = Warns(q.message.chat.id)
|
289 |
+
_, num_warns = warn_db.remove_warn(user_id)
|
290 |
+
await q.message.edit_text(
|
291 |
+
(
|
292 |
+
f"Admin {(await mention_html(q.from_user.first_name, q.from_user.id))} "
|
293 |
+
"removed last warn for "
|
294 |
+
f"{(await mention_html(user_first_name, user_id))}\n"
|
295 |
+
f"<b>Current Warnings:</b> {num_warns}"
|
296 |
+
),
|
297 |
+
)
|
298 |
+
if action == "kick":
|
299 |
+
try:
|
300 |
+
await c.kick_chat_member(chat_id, user_id, until_date=int(time() + 45))
|
301 |
+
await q.message.edit_text(
|
302 |
+
(
|
303 |
+
f"Admin {(await mention_html(q.from_user.first_name, q.from_user.id))} "
|
304 |
+
"kicked user "
|
305 |
+
f"{(await mention_html(user_first_name, user_id))} for last warning!"
|
306 |
+
),
|
307 |
+
)
|
308 |
+
except RPCError as err:
|
309 |
+
await q.message.edit_text(
|
310 |
+
f"🛑 Failed to Kick\n<b>Error:</b>\n</code>{err}</code>",
|
311 |
+
)
|
312 |
+
|
313 |
+
await q.answer()
|
314 |
+
return
|
315 |
+
|
316 |
+
|
317 |
+
@Gojo.on_message(command(["warnings", "warnsettings"]) & admin_filter)
|
318 |
+
async def get_settings(_, m: Message):
|
319 |
+
warn_settings_db = WarnSettings(m.chat.id)
|
320 |
+
settings = warn_settings_db.get_warnings_settings()
|
321 |
+
await m.reply_text(
|
322 |
+
(
|
323 |
+
"This group has these following settings:\n"
|
324 |
+
f"<b>Warn Limit:</b> <code>{settings['warn_limit']}</code>\n"
|
325 |
+
f"<b>Warn Mode:</b> <code>{settings['warn_mode']}</code>"
|
326 |
+
),
|
327 |
+
)
|
328 |
+
return
|
329 |
+
|
330 |
+
|
331 |
+
@Gojo.on_message(command("warnmode") & admin_filter)
|
332 |
+
async def warnmode(_, m: Message):
|
333 |
+
warn_settings_db = WarnSettings(m.chat.id)
|
334 |
+
if len(m.text.split()) > 1:
|
335 |
+
wm = (m.text.split(None, 1)[1]).lower()
|
336 |
+
if wm not in ("kick", "ban", "mute"):
|
337 |
+
await m.reply_text(
|
338 |
+
(
|
339 |
+
"Please choose a valid warn mode!"
|
340 |
+
"Valid options are: <code>ban</code>,<code>kick</code>,<code>mute</code>"
|
341 |
+
),
|
342 |
+
)
|
343 |
+
return
|
344 |
+
warnmode_var = warn_settings_db.set_warnmode(wm)
|
345 |
+
await m.reply_text(f"Warn Mode has been set to: {warnmode_var}")
|
346 |
+
return
|
347 |
+
warnmode_var = warn_settings_db.get_warnmode()
|
348 |
+
await m.reply_text(f"This chats current Warn Mode is: {warnmode_var}")
|
349 |
+
return
|
350 |
+
|
351 |
+
|
352 |
+
@Gojo.on_message(command("warnlimit") & admin_filter)
|
353 |
+
async def warnlimit(_, m: Message):
|
354 |
+
warn_settings_db = WarnSettings(m.chat.id)
|
355 |
+
if len(m.text.split()) > 1:
|
356 |
+
wl = int(m.text.split(None, 1)[1])
|
357 |
+
if not isinstance(wl, int):
|
358 |
+
await m.reply_text("Warn Limit can only be a number!")
|
359 |
+
return
|
360 |
+
warnlimit_var = warn_settings_db.set_warnlimit(wl)
|
361 |
+
await m.reply_text(f"Warn Limit has been set to: {warnlimit_var}")
|
362 |
+
return
|
363 |
+
warnlimit_var = warn_settings_db.get_warnlimit()
|
364 |
+
await m.reply_text(f"This chats current Warn Limit is: {warnlimit_var}")
|
365 |
+
return
|
366 |
+
|
367 |
+
|
368 |
+
__PLUGIN__ = "warnings"
|
369 |
+
|
370 |
+
__alt_name__ = ["warn", "warning", "warns"]
|
Powers/plugins/watchers.py
ADDED
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from re import escape as re_escape
|
2 |
+
from time import time
|
3 |
+
from traceback import format_exc
|
4 |
+
|
5 |
+
from pyrogram import filters
|
6 |
+
from pyrogram.errors import ChatAdminRequired, RPCError, UserAdminInvalid
|
7 |
+
from pyrogram.types import ChatPermissions, Message
|
8 |
+
|
9 |
+
from Powers import LOGGER, MESSAGE_DUMP, SUPPORT_STAFF
|
10 |
+
from Powers.bot_class import Gojo
|
11 |
+
from Powers.database.antispam_db import ANTISPAM_BANNED, GBan
|
12 |
+
from Powers.database.approve_db import Approve
|
13 |
+
from Powers.database.blacklist_db import Blacklist
|
14 |
+
from Powers.database.group_blacklist import BLACKLIST_CHATS
|
15 |
+
from Powers.database.pins_db import Pins
|
16 |
+
from Powers.database.warns_db import Warns, WarnSettings
|
17 |
+
from Powers.tr_engine import tlang
|
18 |
+
from Powers.utils.caching import ADMIN_CACHE, admin_cache_reload
|
19 |
+
from Powers.utils.parser import mention_html
|
20 |
+
from Powers.utils.regex_utils import regex_searcher
|
21 |
+
|
22 |
+
# Initialise
|
23 |
+
gban_db = GBan()
|
24 |
+
|
25 |
+
|
26 |
+
@Gojo.on_message(filters.linked_channel)
|
27 |
+
async def antichanpin_cleanlinked(c: Gojo, m: Message):
|
28 |
+
try:
|
29 |
+
msg_id = m.message_id
|
30 |
+
pins_db = Pins(m.chat.id)
|
31 |
+
curr = pins_db.get_settings()
|
32 |
+
if curr["antichannelpin"]:
|
33 |
+
await c.unpin_chat_message(chat_id=m.chat.id, message_id=msg_id)
|
34 |
+
LOGGER.info(f"AntiChannelPin: msgid-{m.message_id} unpinned in {m.chat.id}")
|
35 |
+
if curr["cleanlinked"]:
|
36 |
+
await c.delete_messages(m.chat.id, msg_id)
|
37 |
+
LOGGER.info(f"CleanLinked: msgid-{m.message_id} cleaned in {m.chat.id}")
|
38 |
+
except ChatAdminRequired:
|
39 |
+
await m.reply_text(
|
40 |
+
"Disabled antichannelpin as I don't have enough admin rights!",
|
41 |
+
)
|
42 |
+
pins_db.antichannelpin_off()
|
43 |
+
LOGGER.warning(f"Disabled antichannelpin in {m.chat.id} as i'm not an admin.")
|
44 |
+
except Exception as ef:
|
45 |
+
LOGGER.error(ef)
|
46 |
+
LOGGER.error(format_exc())
|
47 |
+
|
48 |
+
return
|
49 |
+
|
50 |
+
|
51 |
+
@Gojo.on_message(filters.text & filters.group, group=5)
|
52 |
+
async def bl_watcher(_, m: Message):
|
53 |
+
if m and not m.from_user:
|
54 |
+
return
|
55 |
+
|
56 |
+
bl_db = Blacklist(m.chat.id)
|
57 |
+
|
58 |
+
async def perform_action_blacklist(m: Message, action: str, trigger: str):
|
59 |
+
if action == "kick":
|
60 |
+
await m.chat.kick_member(m.from_user.id, int(time() + 45))
|
61 |
+
await m.reply_text(
|
62 |
+
tlang(m, "blacklist.bl_watcher.action_kick").format(
|
63 |
+
user=m.from_user.username or f"<b>{m.from_user.first_name}</b>",
|
64 |
+
),
|
65 |
+
)
|
66 |
+
|
67 |
+
elif action == "ban":
|
68 |
+
(
|
69 |
+
await m.chat.kick_member(
|
70 |
+
m.from_user.id,
|
71 |
+
)
|
72 |
+
)
|
73 |
+
await m.reply_text(
|
74 |
+
tlang(m, "blacklist.bl_watcher.action_ban").format(
|
75 |
+
user=m.from_user.username or f"<b>{m.from_user.first_name}</b>",
|
76 |
+
),
|
77 |
+
)
|
78 |
+
|
79 |
+
elif action == "mute":
|
80 |
+
await m.chat.restrict_member(
|
81 |
+
m.from_user.id,
|
82 |
+
ChatPermissions(),
|
83 |
+
)
|
84 |
+
|
85 |
+
await m.reply_text(
|
86 |
+
tlang(m, "blacklist.bl_watcher.action_mute").format(
|
87 |
+
user=m.from_user.username or f"<b>{m.from_user.first_name}</b>",
|
88 |
+
),
|
89 |
+
)
|
90 |
+
|
91 |
+
elif action == "warn":
|
92 |
+
warns_settings_db = WarnSettings(m.chat.id)
|
93 |
+
warns_db = Warns(m.chat.id)
|
94 |
+
warn_settings = warns_settings_db.get_warnings_settings()
|
95 |
+
warn_reason = bl_db.get_reason()
|
96 |
+
_, num = warns_db.warn_user(m.from_user.id, warn_reason)
|
97 |
+
if num >= warn_settings["warn_limit"]:
|
98 |
+
if warn_settings["warn_mode"] == "kick":
|
99 |
+
await m.chat.ban_member(
|
100 |
+
m.from_user.id,
|
101 |
+
until_date=int(time() + 45),
|
102 |
+
)
|
103 |
+
action = "kicked"
|
104 |
+
elif warn_settings["warn_mode"] == "ban":
|
105 |
+
await m.chat.ban_member(m.from_user.id)
|
106 |
+
action = "banned"
|
107 |
+
elif warn_settings["warn_mode"] == "mute":
|
108 |
+
await m.chat.restrict_member(m.from_user.id, ChatPermissions())
|
109 |
+
action = "muted"
|
110 |
+
await m.reply_text(
|
111 |
+
(
|
112 |
+
f"Warnings {num}/{warn_settings['warn_limit']}\n"
|
113 |
+
f"{(await mention_html(m.from_user.first_name, m.from_user.id))} has been <b>{action}!</b>"
|
114 |
+
),
|
115 |
+
)
|
116 |
+
return
|
117 |
+
await m.reply_text(
|
118 |
+
(
|
119 |
+
f"{(await mention_html(m.from_user.first_name, m.from_user.id))} warned {num}/{warn_settings['warn_limit']}\n"
|
120 |
+
# f"Last warn was for:\n<i>{warn_reason}</i>"
|
121 |
+
f"Last warn was for:\n<i>{warn_reason.format(trigger)}</i>"
|
122 |
+
),
|
123 |
+
)
|
124 |
+
return
|
125 |
+
|
126 |
+
if m.from_user.id in SUPPORT_STAFF:
|
127 |
+
# Don't work on Support Staff!
|
128 |
+
return
|
129 |
+
|
130 |
+
# If no blacklists, then return
|
131 |
+
chat_blacklists = bl_db.get_blacklists()
|
132 |
+
if not chat_blacklists:
|
133 |
+
return
|
134 |
+
|
135 |
+
# Get admins from admin_cache, reduces api calls
|
136 |
+
try:
|
137 |
+
admin_ids = {i[0] for i in ADMIN_CACHE[m.chat.id]}
|
138 |
+
except KeyError:
|
139 |
+
admin_ids = await admin_cache_reload(m, "blacklist_watcher")
|
140 |
+
|
141 |
+
if m.from_user.id in admin_ids:
|
142 |
+
return
|
143 |
+
|
144 |
+
# Get approved user from cache/database
|
145 |
+
app_users = Approve(m.chat.id).list_approved()
|
146 |
+
if m.from_user.id in {i[0] for i in app_users}:
|
147 |
+
return
|
148 |
+
|
149 |
+
# Get action for blacklist
|
150 |
+
action = bl_db.get_action()
|
151 |
+
for trigger in chat_blacklists:
|
152 |
+
pattern = r"( |^|[^\w])" + re_escape(trigger) + r"( |$|[^\w])"
|
153 |
+
match = await regex_searcher(pattern, m.text.lower())
|
154 |
+
if not match:
|
155 |
+
continue
|
156 |
+
if match:
|
157 |
+
try:
|
158 |
+
await perform_action_blacklist(m, action, trigger)
|
159 |
+
LOGGER.info(
|
160 |
+
f"{m.from_user.id} {action}ed for using blacklisted word {trigger} in {m.chat.id}",
|
161 |
+
)
|
162 |
+
await m.delete()
|
163 |
+
except RPCError as ef:
|
164 |
+
LOGGER.error(ef)
|
165 |
+
LOGGER.error(format_exc())
|
166 |
+
break
|
167 |
+
return
|
168 |
+
|
169 |
+
|
170 |
+
@Gojo.on_message(filters.user(list(ANTISPAM_BANNED)) & filters.group)
|
171 |
+
async def gban_watcher(c: Gojo, m: Message):
|
172 |
+
from Powers import SUPPORT_GROUP
|
173 |
+
|
174 |
+
if m and not m.from_user:
|
175 |
+
return
|
176 |
+
|
177 |
+
try:
|
178 |
+
_banned = gban_db.check_gban(m.from_user.id)
|
179 |
+
except Exception as ef:
|
180 |
+
LOGGER.error(ef)
|
181 |
+
LOGGER.error(format_exc())
|
182 |
+
return
|
183 |
+
|
184 |
+
if _banned:
|
185 |
+
try:
|
186 |
+
await m.chat.ban_member(m.from_user.id)
|
187 |
+
await m.delete(m.message_id) # Delete users message!
|
188 |
+
await m.reply_text(
|
189 |
+
(tlang(m, "antispam.watcher_banned")).format(
|
190 |
+
user_gbanned=(
|
191 |
+
await mention_html(m.from_user.first_name, m.from_user.id)
|
192 |
+
),
|
193 |
+
SUPPORT_GROUP=SUPPORT_GROUP,
|
194 |
+
),
|
195 |
+
)
|
196 |
+
LOGGER.info(f"Banned user {m.from_user.id} in {m.chat.id} due to antispam")
|
197 |
+
return
|
198 |
+
except (ChatAdminRequired, UserAdminInvalid):
|
199 |
+
# Bot not admin in group and hence cannot ban users!
|
200 |
+
# TO-DO - Improve Error Detection
|
201 |
+
LOGGER.info(
|
202 |
+
f"User ({m.from_user.id}) is admin in group {m.chat.title} ({m.chat.id})",
|
203 |
+
)
|
204 |
+
except RPCError as ef:
|
205 |
+
await c.send_message(
|
206 |
+
MESSAGE_DUMP,
|
207 |
+
tlang(m, "antispam.gban.gban_error_log").format(
|
208 |
+
chat_id=m.chat.id,
|
209 |
+
ef=ef,
|
210 |
+
),
|
211 |
+
)
|
212 |
+
return
|
213 |
+
|
214 |
+
|
215 |
+
@Gojo.on_message(filters.chat(BLACKLIST_CHATS))
|
216 |
+
async def bl_chats_watcher(c: Gojo, m: Message):
|
217 |
+
from Powers import SUPPORT_GROUP
|
218 |
+
|
219 |
+
await c.send_message(
|
220 |
+
m.chat.id,
|
221 |
+
(
|
222 |
+
"This is a blacklisted group!\n"
|
223 |
+
f"For Support, Join @{SUPPORT_GROUP}\n"
|
224 |
+
"Now, I'm outta here!"
|
225 |
+
),
|
226 |
+
)
|
227 |
+
await c.leave_chat(m.chat.id)
|
228 |
+
LOGGER.info(f"Joined and Left blacklisted chat {m.chat.id}")
|
229 |
+
return
|