Spaces:
Paused
Paused
iamgojoof6eyes
commited on
Commit
·
7956eb0
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
|