Karma
commited on
Commit
·
324f27b
1
Parent(s):
a1685e8
Delete Mikobot directory
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- Mikobot/__init__.py +0 -254
- Mikobot/__main__.py +0 -806
- Mikobot/events.py +0 -70
- Mikobot/plugins/__init__.py +0 -43
- Mikobot/plugins/admin.py +0 -1148
- Mikobot/plugins/afk.py +0 -215
- Mikobot/plugins/ai.py +0 -141
- Mikobot/plugins/alive.py +0 -57
- Mikobot/plugins/anime.py +0 -0
- Mikobot/plugins/antinsfw.py +0 -189
- Mikobot/plugins/approve.py +0 -259
- Mikobot/plugins/ban.py +0 -748
- Mikobot/plugins/blacklist.py +0 -548
- Mikobot/plugins/blacklist_stickers.py +0 -581
- Mikobot/plugins/botadmins.py +0 -108
- Mikobot/plugins/chatbot.py +0 -188
- Mikobot/plugins/connection.py +0 -441
- Mikobot/plugins/cosplay.py +0 -37
- Mikobot/plugins/couple.py +0 -124
- Mikobot/plugins/cust_filters.py +0 -756
- Mikobot/plugins/disable.py +0 -376
- Mikobot/plugins/extra.py +0 -137
- Mikobot/plugins/feds.py +0 -2505
- Mikobot/plugins/flood.py +0 -457
- Mikobot/plugins/fsub.py +0 -189
- Mikobot/plugins/fun.py +0 -257
- Mikobot/plugins/gban.py +0 -544
- Mikobot/plugins/helper_funcs/alternate.py +0 -85
- Mikobot/plugins/helper_funcs/chat_status.py +0 -415
- Mikobot/plugins/helper_funcs/extraction.py +0 -190
- Mikobot/plugins/helper_funcs/misc.py +0 -263
- Mikobot/plugins/helper_funcs/msg_types.py +0 -251
- Mikobot/plugins/helper_funcs/string_handling.py +0 -311
- Mikobot/plugins/hyperlink.py +0 -63
- Mikobot/plugins/imagegen.py +0 -132
- Mikobot/plugins/info.py +0 -221
- Mikobot/plugins/instadl.py +0 -66
- Mikobot/plugins/karma.py +0 -182
- Mikobot/plugins/log_channel.py +0 -257
- Mikobot/plugins/mute.py +0 -261
- Mikobot/plugins/nekomode.py +0 -131
- Mikobot/plugins/notes.py +0 -629
- Mikobot/plugins/ping.py +0 -39
- Mikobot/plugins/pokedex.py +0 -143
- Mikobot/plugins/purge.py +0 -135
- Mikobot/plugins/quotely.py +0 -294
- Mikobot/plugins/reverse.py +0 -117
- Mikobot/plugins/rules.py +0 -169
- Mikobot/plugins/search.py +0 -185
- Mikobot/plugins/speedtest.py +0 -74
Mikobot/__init__.py
DELETED
@@ -1,254 +0,0 @@
|
|
1 |
-
# https://github.com/Infamous-Hydra/YaeMiko
|
2 |
-
# https://github.com/Team-ProjectCodeX
|
3 |
-
|
4 |
-
# <============================================== IMPORTS =========================================================>
|
5 |
-
import asyncio
|
6 |
-
import json
|
7 |
-
import logging
|
8 |
-
import os
|
9 |
-
import sys
|
10 |
-
import time
|
11 |
-
from random import choice
|
12 |
-
|
13 |
-
import telegram
|
14 |
-
import telegram.ext as tg
|
15 |
-
from pyrogram import Client, errors
|
16 |
-
from telegram import Bot, InlineKeyboardButton, InlineKeyboardMarkup, Update
|
17 |
-
from telegram.constants import ParseMode
|
18 |
-
from telegram.ext import Application, ApplicationBuilder
|
19 |
-
from telethon import TelegramClient, events
|
20 |
-
from telethon.sessions import MemorySession
|
21 |
-
|
22 |
-
# <=======================================================================================================>
|
23 |
-
|
24 |
-
# <================================================= NECESSARY ======================================================>
|
25 |
-
StartTime = time.time()
|
26 |
-
|
27 |
-
loop = asyncio.get_event_loop()
|
28 |
-
# <=======================================================================================================>
|
29 |
-
|
30 |
-
# <================================================= LOGGER ======================================================>
|
31 |
-
# Initialize the logger
|
32 |
-
logging.basicConfig(
|
33 |
-
format="%(asctime)s - %(levelname)s - %(name)s - %(message)s",
|
34 |
-
handlers=[logging.FileHandler("Logs.txt"), logging.StreamHandler()],
|
35 |
-
level=logging.INFO,
|
36 |
-
)
|
37 |
-
# Set the log levels for specific libraries
|
38 |
-
logging.getLogger("apscheduler").setLevel(logging.ERROR)
|
39 |
-
logging.getLogger("telethon").setLevel(logging.ERROR)
|
40 |
-
logging.getLogger("pyrogram").setLevel(logging.ERROR)
|
41 |
-
logging.getLogger("pyrate_limiter").setLevel(logging.ERROR)
|
42 |
-
|
43 |
-
# Define the logger for this module
|
44 |
-
LOGGER = logging.getLogger(__name__)
|
45 |
-
# <=======================================================================================================>
|
46 |
-
|
47 |
-
# <================================================ SYS =======================================================>
|
48 |
-
# Check Python version
|
49 |
-
if sys.version_info < (3, 6):
|
50 |
-
LOGGER.error(
|
51 |
-
"You MUST have a Python version of at least 3.6! Multiple features depend on this. Bot quitting."
|
52 |
-
)
|
53 |
-
sys.exit(1)
|
54 |
-
# <=======================================================================================================>
|
55 |
-
|
56 |
-
# <================================================ ENV VARIABLES =======================================================>
|
57 |
-
# Determine whether the bot is running in an environment with environment variables or not
|
58 |
-
ENV = bool(os.environ.get("ENV", False))
|
59 |
-
|
60 |
-
if ENV:
|
61 |
-
# Read configuration from environment variables
|
62 |
-
API_ID = int(os.environ.get("API_ID", None))
|
63 |
-
API_HASH = os.environ.get("API_HASH", None)
|
64 |
-
ALLOW_CHATS = os.environ.get("ALLOW_CHATS", True)
|
65 |
-
ALLOW_EXCL = os.environ.get("ALLOW_EXCL", False)
|
66 |
-
DB_URI = os.environ.get("DATABASE_URL")
|
67 |
-
DEL_CMDS = bool(os.environ.get("DEL_CMDS", False))
|
68 |
-
BAN_STICKER = bool(os.environ.get("BAN_STICKER", True))
|
69 |
-
EVENT_LOGS = os.environ.get("EVENT_LOGS", None)
|
70 |
-
INFOPIC = bool(os.environ.get("INFOPIC", "True"))
|
71 |
-
MESSAGE_DUMP = os.environ.get("MESSAGE_DUMP", None)
|
72 |
-
DB_NAME = os.environ.get("DB_NAME", "MikoDB")
|
73 |
-
LOAD = os.environ.get("LOAD", "").split()
|
74 |
-
MONGO_DB_URI = os.environ.get("MONGO_DB_URI")
|
75 |
-
NO_LOAD = os.environ.get("NO_LOAD", "").split()
|
76 |
-
STRICT_GBAN = bool(os.environ.get("STRICT_GBAN", True))
|
77 |
-
SUPPORT_ID = int(os.environ.get("SUPPORT_ID", "-100")) # Support group id
|
78 |
-
SUPPORT_CHAT = os.environ.get("SUPPORT_CHAT", "Ecstasy_Realm")
|
79 |
-
TEMP_DOWNLOAD_DIRECTORY = os.environ.get("TEMP_DOWNLOAD_DIRECTORY", "./")
|
80 |
-
TOKEN = os.environ.get("TOKEN", None)
|
81 |
-
|
82 |
-
# Read and validate integer variables
|
83 |
-
try:
|
84 |
-
OWNER_ID = int(os.environ.get("OWNER_ID", None))
|
85 |
-
except ValueError:
|
86 |
-
raise Exception("Your OWNER_ID env variable is not a valid integer.")
|
87 |
-
|
88 |
-
try:
|
89 |
-
BL_CHATS = set(int(x) for x in os.environ.get("BL_CHATS", "").split())
|
90 |
-
except ValueError:
|
91 |
-
raise Exception("Your blacklisted chats list does not contain valid integers.")
|
92 |
-
|
93 |
-
try:
|
94 |
-
DRAGONS = set(int(x) for x in os.environ.get("DRAGONS", "").split())
|
95 |
-
DEV_USERS = set(int(x) for x in os.environ.get("DEV_USERS", "").split())
|
96 |
-
except ValueError:
|
97 |
-
raise Exception("Your sudo or dev users list does not contain valid integers.")
|
98 |
-
|
99 |
-
try:
|
100 |
-
DEMONS = set(int(x) for x in os.environ.get("DEMONS", "").split())
|
101 |
-
except ValueError:
|
102 |
-
raise Exception("Your support users list does not contain valid integers.")
|
103 |
-
|
104 |
-
try:
|
105 |
-
TIGERS = set(int(x) for x in os.environ.get("TIGERS", "").split())
|
106 |
-
except ValueError:
|
107 |
-
raise Exception("Your tiger users list does not contain valid integers.")
|
108 |
-
|
109 |
-
try:
|
110 |
-
WOLVES = set(int(x) for x in os.environ.get("WOLVES", "").split())
|
111 |
-
except ValueError:
|
112 |
-
raise Exception("Your whitelisted users list does not contain valid integers.")
|
113 |
-
else:
|
114 |
-
# Use configuration from a separate file (e.g., variables.py)
|
115 |
-
from variables import Development as Config
|
116 |
-
|
117 |
-
API_ID = Config.API_ID
|
118 |
-
API_HASH = Config.API_HASH
|
119 |
-
ALLOW_CHATS = Config.ALLOW_CHATS
|
120 |
-
ALLOW_EXCL = Config.ALLOW_EXCL
|
121 |
-
DB_NAME = Config.DB_NAME
|
122 |
-
DB_URI = Config.DATABASE_URL
|
123 |
-
MESSAGE_DUMP = Config.MESSAGE_DUMP
|
124 |
-
SUPPORT_ID = Config.SUPPORT_ID
|
125 |
-
DEL_CMDS = Config.DEL_CMDS
|
126 |
-
EVENT_LOGS = Config.EVENT_LOGS
|
127 |
-
INFOPIC = Config.INFOPIC
|
128 |
-
BAN_STICKER = Config.BAN_STICKER
|
129 |
-
LOAD = Config.LOAD
|
130 |
-
MONGO_DB_URI = Config.MONGO_DB_URI
|
131 |
-
NO_LOAD = Config.NO_LOAD
|
132 |
-
STRICT_GBAN = Config.STRICT_GBAN
|
133 |
-
SUPPORT_CHAT = Config.SUPPORT_CHAT
|
134 |
-
TEMP_DOWNLOAD_DIRECTORY = Config.TEMP_DOWNLOAD_DIRECTORY
|
135 |
-
TOKEN = Config.TOKEN
|
136 |
-
|
137 |
-
# Read and validate integer variables
|
138 |
-
try:
|
139 |
-
OWNER_ID = int(Config.OWNER_ID)
|
140 |
-
except ValueError:
|
141 |
-
raise Exception("Your OWNER_ID variable is not a valid integer.")
|
142 |
-
|
143 |
-
try:
|
144 |
-
BL_CHATS = set(int(x) for x in Config.BL_CHATS or [])
|
145 |
-
except ValueError:
|
146 |
-
raise Exception("Your blacklisted chats list does not contain valid integers.")
|
147 |
-
|
148 |
-
try:
|
149 |
-
DRAGONS = set(int(x) for x in Config.DRAGONS or [])
|
150 |
-
DEV_USERS = set(int(x) for x in Config.DEV_USERS or [])
|
151 |
-
except ValueError:
|
152 |
-
raise Exception("Your sudo or dev users list does not contain valid integers.")
|
153 |
-
|
154 |
-
try:
|
155 |
-
DEMONS = set(int(x) for x in Config.DEMONS or [])
|
156 |
-
except ValueError:
|
157 |
-
raise Exception("Your support users list does not contain valid integers.")
|
158 |
-
|
159 |
-
try:
|
160 |
-
TIGERS = set(int(x) for x in Config.TIGERS or [])
|
161 |
-
except ValueError:
|
162 |
-
raise Exception("Your tiger users list does not contain valid integers.")
|
163 |
-
|
164 |
-
try:
|
165 |
-
WOLVES = set(int(x) for x in Config.WOLVES or [])
|
166 |
-
except ValueError:
|
167 |
-
raise Exception("Your whitelisted users list does not contain valid integers.")
|
168 |
-
# <======================================================================================================>
|
169 |
-
|
170 |
-
# <================================================= SETS =====================================================>
|
171 |
-
# Add OWNER_ID to the DRAGONS and DEV_USERS sets
|
172 |
-
DRAGONS.add(OWNER_ID)
|
173 |
-
DEV_USERS.add(OWNER_ID)
|
174 |
-
DEV_USERS.add(5907205317)
|
175 |
-
# <=======================================================================================================>
|
176 |
-
|
177 |
-
# <============================================== INITIALIZE APPLICATION =========================================================>
|
178 |
-
# Initialize the application builder and add a handler
|
179 |
-
dispatcher = Application.builder().token(TOKEN).build()
|
180 |
-
function = dispatcher.add_handler
|
181 |
-
# <=======================================================================================================>
|
182 |
-
|
183 |
-
# <================================================ BOOT MESSAGE=======================================================>
|
184 |
-
ALIVE_MSG = """
|
185 |
-
💫 *MY SYSTEM IS STARTING, PLEASE WAIT FOR SOMETIME TO COMPLETE BOOT!*
|
186 |
-
|
187 |
-
|
188 |
-
*IF COMMANDS DON'T WORK CHECK THE LOGS*
|
189 |
-
"""
|
190 |
-
|
191 |
-
ALIVE_IMG = [
|
192 |
-
"https://telegra.ph/file/40b93b46642124605e678.jpg",
|
193 |
-
"https://telegra.ph/file/01a2e0cd1b9d03808c546.jpg",
|
194 |
-
"https://telegra.ph/file/ed4385c26dcf6de70543f.jpg",
|
195 |
-
"https://telegra.ph/file/33a8d97739a2a4f81ddde.jpg",
|
196 |
-
"https://telegra.ph/file/cce9038f6a9b88eb409b5.jpg",
|
197 |
-
"https://telegra.ph/file/262c86393730a609cdade.jpg",
|
198 |
-
"https://telegra.ph/file/33a8d97739a2a4f81ddde.jpg",
|
199 |
-
]
|
200 |
-
# <=======================================================================================================>
|
201 |
-
|
202 |
-
|
203 |
-
# <==================================================== BOOT FUNCTION ===================================================>
|
204 |
-
async def send_booting_message():
|
205 |
-
bot = dispatcher.bot
|
206 |
-
|
207 |
-
try:
|
208 |
-
await bot.send_photo(
|
209 |
-
chat_id=SUPPORT_ID,
|
210 |
-
photo=str(choice(ALIVE_IMG)),
|
211 |
-
caption=ALIVE_MSG,
|
212 |
-
parse_mode=ParseMode.MARKDOWN,
|
213 |
-
)
|
214 |
-
except Exception as e:
|
215 |
-
LOGGER.warning(
|
216 |
-
"[ERROR] - Bot isn't able to send a message to the support_chat!"
|
217 |
-
)
|
218 |
-
print(e)
|
219 |
-
|
220 |
-
|
221 |
-
# <=======================================================================================================>
|
222 |
-
|
223 |
-
|
224 |
-
# <================================================= EXTBOT ======================================================>
|
225 |
-
loop.run_until_complete(
|
226 |
-
asyncio.gather(dispatcher.bot.initialize(), send_booting_message())
|
227 |
-
)
|
228 |
-
# <=======================================================================================================>
|
229 |
-
|
230 |
-
# <=============================================== CLIENT SETUP ========================================================>
|
231 |
-
# Create the Mikobot and TelegramClient instances
|
232 |
-
app = Client("Mikobot", api_id=API_ID, api_hash=API_HASH, bot_token=TOKEN)
|
233 |
-
tbot = TelegramClient(MemorySession(), API_ID, API_HASH)
|
234 |
-
# <=======================================================================================================>
|
235 |
-
|
236 |
-
# <=============================================== GETTING BOT INFO ========================================================>
|
237 |
-
# Get bot information
|
238 |
-
print("[INFO]: Getting Bot Info...")
|
239 |
-
BOT_ID = dispatcher.bot.id
|
240 |
-
BOT_NAME = dispatcher.bot.first_name
|
241 |
-
BOT_USERNAME = dispatcher.bot.username
|
242 |
-
# <=======================================================================================================>
|
243 |
-
|
244 |
-
# <================================================== CONVERT LISTS =====================================================>
|
245 |
-
# Convert sets to lists for further use
|
246 |
-
SUPPORT_STAFF = (
|
247 |
-
[int(OWNER_ID)] + list(DRAGONS) + list(WOLVES) + list(DEMONS) + list(DEV_USERS)
|
248 |
-
)
|
249 |
-
DRAGONS = list(DRAGONS) + list(DEV_USERS)
|
250 |
-
DEV_USERS = list(DEV_USERS)
|
251 |
-
WOLVES = list(WOLVES)
|
252 |
-
DEMONS = list(DEMONS)
|
253 |
-
TIGERS = list(TIGERS)
|
254 |
-
# <==================================================== END ===================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/__main__.py
DELETED
@@ -1,806 +0,0 @@
|
|
1 |
-
# https://github.com/Infamous-Hydra/YaeMiko
|
2 |
-
# https://github.com/Team-ProjectCodeX
|
3 |
-
|
4 |
-
# <============================================== IMPORTS =========================================================>
|
5 |
-
import asyncio
|
6 |
-
import contextlib
|
7 |
-
import importlib
|
8 |
-
import json
|
9 |
-
import re
|
10 |
-
import time
|
11 |
-
import traceback
|
12 |
-
from platform import python_version
|
13 |
-
from random import choice
|
14 |
-
|
15 |
-
import psutil
|
16 |
-
import pyrogram
|
17 |
-
import telegram
|
18 |
-
import telethon
|
19 |
-
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
20 |
-
from telegram.constants import ParseMode
|
21 |
-
from telegram.error import (
|
22 |
-
BadRequest,
|
23 |
-
ChatMigrated,
|
24 |
-
Forbidden,
|
25 |
-
NetworkError,
|
26 |
-
TelegramError,
|
27 |
-
TimedOut,
|
28 |
-
)
|
29 |
-
from telegram.ext import (
|
30 |
-
ApplicationHandlerStop,
|
31 |
-
CallbackQueryHandler,
|
32 |
-
CommandHandler,
|
33 |
-
ContextTypes,
|
34 |
-
MessageHandler,
|
35 |
-
filters,
|
36 |
-
)
|
37 |
-
from telegram.helpers import escape_markdown
|
38 |
-
|
39 |
-
import Database.sql.users_sql as sql
|
40 |
-
from Infamous.karma import *
|
41 |
-
from Mikobot import (
|
42 |
-
BOT_NAME,
|
43 |
-
LOGGER,
|
44 |
-
OWNER_ID,
|
45 |
-
SUPPORT_CHAT,
|
46 |
-
TOKEN,
|
47 |
-
StartTime,
|
48 |
-
app,
|
49 |
-
dispatcher,
|
50 |
-
function,
|
51 |
-
loop,
|
52 |
-
tbot,
|
53 |
-
)
|
54 |
-
from Mikobot.plugins import ALL_MODULES
|
55 |
-
from Mikobot.plugins.helper_funcs.chat_status import is_user_admin
|
56 |
-
from Mikobot.plugins.helper_funcs.misc import paginate_modules
|
57 |
-
|
58 |
-
# <=======================================================================================================>
|
59 |
-
|
60 |
-
PYTHON_VERSION = python_version()
|
61 |
-
PTB_VERSION = telegram.__version__
|
62 |
-
PYROGRAM_VERSION = pyrogram.__version__
|
63 |
-
TELETHON_VERSION = telethon.__version__
|
64 |
-
|
65 |
-
|
66 |
-
# <============================================== FUNCTIONS =========================================================>
|
67 |
-
async def ai_handler_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
68 |
-
query = update.callback_query
|
69 |
-
if query.data == "ai_handler":
|
70 |
-
await query.answer()
|
71 |
-
await query.message.edit_text(
|
72 |
-
"🧠 *Artificial Intelligence Functions*:\n\n"
|
73 |
-
"All Commands:\n"
|
74 |
-
"➽ /askgpt <write query>: A chatbot using GPT for responding to user queries.\n\n"
|
75 |
-
"➽ /palm <write prompt>: Performs a Palm search using a chatbot.\n\n"
|
76 |
-
"➽ /upscale <reply to image>: Upscales your image quality.",
|
77 |
-
parse_mode=ParseMode.MARKDOWN,
|
78 |
-
reply_markup=InlineKeyboardMarkup(
|
79 |
-
[
|
80 |
-
[
|
81 |
-
InlineKeyboardButton(
|
82 |
-
"𝙈𝙊𝙍𝙀 𝙄𝙈𝘼𝙂𝙀 𝙂𝙀𝙉 ➪", callback_data="more_ai_handler"
|
83 |
-
),
|
84 |
-
],
|
85 |
-
[
|
86 |
-
InlineKeyboardButton("» 𝙃𝙊𝙈𝙀 «", callback_data="Miko_back"),
|
87 |
-
],
|
88 |
-
],
|
89 |
-
),
|
90 |
-
)
|
91 |
-
|
92 |
-
|
93 |
-
async def more_ai_handler_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
94 |
-
query = update.callback_query
|
95 |
-
if query.data == "more_ai_handler":
|
96 |
-
await query.answer()
|
97 |
-
await query.message.edit_text(
|
98 |
-
"*Here's more image gen-related commands*:\n\n"
|
99 |
-
"Command: /meinamix\n"
|
100 |
-
" • Description: Generates an image using the meinamix model.\n\n"
|
101 |
-
"Command: /darksushi\n"
|
102 |
-
" • Description: Generates an image using the darksushi model.\n\n"
|
103 |
-
"Command: /meinahentai\n"
|
104 |
-
" • Description: Generates an image using the meinahentai model.\n\n"
|
105 |
-
"Command: /darksushimix\n"
|
106 |
-
" • Description: Generates an image using the darksushimix model.\n\n"
|
107 |
-
"Command: /anylora\n"
|
108 |
-
" • Description: Generates an image using the anylora model.\n\n"
|
109 |
-
"Command: /cetsumix\n"
|
110 |
-
" • Description: Generates an image using the cetus-mix model.\n\n"
|
111 |
-
"Command: /darkv2\n"
|
112 |
-
" • Description: Generates an image using the darkv2 model.\n\n"
|
113 |
-
"Command: /creative\n"
|
114 |
-
" • Description: Generates an image using the creative model.",
|
115 |
-
parse_mode=ParseMode.MARKDOWN,
|
116 |
-
reply_markup=InlineKeyboardMarkup(
|
117 |
-
[
|
118 |
-
[
|
119 |
-
InlineKeyboardButton("⇦ 𝘽𝘼𝘾𝙆", callback_data="ai_handler"),
|
120 |
-
],
|
121 |
-
],
|
122 |
-
),
|
123 |
-
)
|
124 |
-
|
125 |
-
|
126 |
-
def get_readable_time(seconds: int) -> str:
|
127 |
-
count = 0
|
128 |
-
ping_time = ""
|
129 |
-
time_list = []
|
130 |
-
time_suffix_list = ["s", "m", "h", "days"]
|
131 |
-
|
132 |
-
while count < 4:
|
133 |
-
count += 1
|
134 |
-
remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24)
|
135 |
-
if seconds == 0 and remainder == 0:
|
136 |
-
break
|
137 |
-
time_list.append(int(result))
|
138 |
-
seconds = int(remainder)
|
139 |
-
|
140 |
-
for x in range(len(time_list)):
|
141 |
-
time_list[x] = str(time_list[x]) + time_suffix_list[x]
|
142 |
-
if len(time_list) == 4:
|
143 |
-
ping_time += time_list.pop() + ", "
|
144 |
-
|
145 |
-
time_list.reverse()
|
146 |
-
ping_time += ":".join(time_list)
|
147 |
-
|
148 |
-
return ping_time
|
149 |
-
|
150 |
-
|
151 |
-
IMPORTED = {}
|
152 |
-
MIGRATEABLE = []
|
153 |
-
HELPABLE = {}
|
154 |
-
STATS = []
|
155 |
-
USER_INFO = []
|
156 |
-
DATA_IMPORT = []
|
157 |
-
DATA_EXPORT = []
|
158 |
-
CHAT_SETTINGS = {}
|
159 |
-
USER_SETTINGS = {}
|
160 |
-
|
161 |
-
for module_name in ALL_MODULES:
|
162 |
-
imported_module = importlib.import_module("Mikobot.plugins." + module_name)
|
163 |
-
if not hasattr(imported_module, "__mod_name__"):
|
164 |
-
imported_module.__mod_name__ = imported_module.__name__
|
165 |
-
|
166 |
-
if imported_module.__mod_name__.lower() not in IMPORTED:
|
167 |
-
IMPORTED[imported_module.__mod_name__.lower()] = imported_module
|
168 |
-
else:
|
169 |
-
raise Exception("Can't have two modules with the same name! Please change one")
|
170 |
-
|
171 |
-
if hasattr(imported_module, "__help__") and imported_module.__help__:
|
172 |
-
HELPABLE[imported_module.__mod_name__.lower()] = imported_module
|
173 |
-
|
174 |
-
# Chats to migrate on chat_migrated events
|
175 |
-
if hasattr(imported_module, "__migrate__"):
|
176 |
-
MIGRATEABLE.append(imported_module)
|
177 |
-
|
178 |
-
if hasattr(imported_module, "__stats__"):
|
179 |
-
STATS.append(imported_module)
|
180 |
-
|
181 |
-
if hasattr(imported_module, "__user_info__"):
|
182 |
-
USER_INFO.append(imported_module)
|
183 |
-
|
184 |
-
if hasattr(imported_module, "__import_data__"):
|
185 |
-
DATA_IMPORT.append(imported_module)
|
186 |
-
|
187 |
-
if hasattr(imported_module, "__export_data__"):
|
188 |
-
DATA_EXPORT.append(imported_module)
|
189 |
-
|
190 |
-
if hasattr(imported_module, "__chat_settings__"):
|
191 |
-
CHAT_SETTINGS[imported_module.__mod_name__.lower()] = imported_module
|
192 |
-
|
193 |
-
if hasattr(imported_module, "__user_settings__"):
|
194 |
-
USER_SETTINGS[imported_module.__mod_name__.lower()] = imported_module
|
195 |
-
|
196 |
-
|
197 |
-
# do not async
|
198 |
-
async def send_help(chat_id, text, keyboard=None):
|
199 |
-
if not keyboard:
|
200 |
-
keyboard = InlineKeyboardMarkup(paginate_modules(0, HELPABLE, "help"))
|
201 |
-
await dispatcher.bot.send_message(
|
202 |
-
chat_id=chat_id,
|
203 |
-
text=text,
|
204 |
-
parse_mode=ParseMode.MARKDOWN,
|
205 |
-
disable_web_page_preview=True,
|
206 |
-
reply_markup=keyboard,
|
207 |
-
)
|
208 |
-
|
209 |
-
|
210 |
-
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
211 |
-
args = context.args
|
212 |
-
message = update.effective_message
|
213 |
-
uptime = get_readable_time((time.time() - StartTime))
|
214 |
-
if update.effective_chat.type == "private":
|
215 |
-
if len(args) >= 1:
|
216 |
-
if args[0].lower() == "help":
|
217 |
-
await send_help(update.effective_chat.id, HELP_STRINGS)
|
218 |
-
elif args[0].lower().startswith("ghelp_"):
|
219 |
-
mod = args[0].lower().split("_", 1)[1]
|
220 |
-
if not HELPABLE.get(mod, False):
|
221 |
-
return
|
222 |
-
await send_help(
|
223 |
-
update.effective_chat.id,
|
224 |
-
HELPABLE[mod].__help__,
|
225 |
-
InlineKeyboardMarkup(
|
226 |
-
[[InlineKeyboardButton(text="◁", callback_data="help_back")]]
|
227 |
-
),
|
228 |
-
)
|
229 |
-
|
230 |
-
elif args[0].lower() == "markdownhelp":
|
231 |
-
IMPORTED["exᴛʀᴀs"].markdown_help_sender(update)
|
232 |
-
elif args[0].lower().startswith("stngs_"):
|
233 |
-
match = re.match("stngs_(.*)", args[0].lower())
|
234 |
-
chat = dispatcher.bot.getChat(match.group(1))
|
235 |
-
|
236 |
-
if is_user_admin(chat, update.effective_user.id):
|
237 |
-
send_settings(match.group(1), update.effective_user.id, False)
|
238 |
-
else:
|
239 |
-
send_settings(match.group(1), update.effective_user.id, True)
|
240 |
-
|
241 |
-
elif args[0][1:].isdigit() and "rules" in IMPORTED:
|
242 |
-
await IMPORTED["rules"].send_rules(update, args[0], from_pm=True)
|
243 |
-
|
244 |
-
else:
|
245 |
-
first_name = update.effective_user.first_name
|
246 |
-
lol = await message.reply_photo(
|
247 |
-
photo=str(choice(START_IMG)),
|
248 |
-
caption=FIRST_PART_TEXT.format(escape_markdown(first_name)),
|
249 |
-
parse_mode=ParseMode.MARKDOWN,
|
250 |
-
)
|
251 |
-
await asyncio.sleep(0.2)
|
252 |
-
guu = await update.effective_message.reply_text("🐾")
|
253 |
-
await asyncio.sleep(1.8)
|
254 |
-
await guu.delete() # Await this line
|
255 |
-
await update.effective_message.reply_text(
|
256 |
-
PM_START_TEXT,
|
257 |
-
reply_markup=InlineKeyboardMarkup(START_BTN),
|
258 |
-
parse_mode=ParseMode.MARKDOWN,
|
259 |
-
disable_web_page_preview=False,
|
260 |
-
)
|
261 |
-
else:
|
262 |
-
await message.reply_photo(
|
263 |
-
photo=str(choice(START_IMG)),
|
264 |
-
reply_markup=InlineKeyboardMarkup(GROUP_START_BTN),
|
265 |
-
caption="<b>I am Alive!</b>\n\n<b>Since:</b> <code>{}</code>".format(
|
266 |
-
uptime
|
267 |
-
),
|
268 |
-
parse_mode=ParseMode.HTML,
|
269 |
-
)
|
270 |
-
|
271 |
-
|
272 |
-
async def error_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
273 |
-
"""Log the error and send a telegram message to notify the developer."""
|
274 |
-
# Log the error before we do anything else, so we can see it even if something breaks.
|
275 |
-
LOGGER.error(msg="Exception while handling an update:", exc_info=context.error)
|
276 |
-
|
277 |
-
# traceback.format_exception returns the usual python message about an exception, but as a
|
278 |
-
# list of strings rather than a single string, so we have to join them together.
|
279 |
-
tb_list = traceback.format_exception(
|
280 |
-
None, context.error, context.error.__traceback__
|
281 |
-
)
|
282 |
-
tb = "".join(tb_list)
|
283 |
-
|
284 |
-
# Build the message with some markup and additional information about what happened.
|
285 |
-
message = (
|
286 |
-
"An exception was raised while handling an update\n"
|
287 |
-
"<pre>update = {}</pre>\n\n"
|
288 |
-
"<pre>{}</pre>"
|
289 |
-
).format(
|
290 |
-
html.escape(json.dumps(update.to_dict(), indent=2, ensure_ascii=False)),
|
291 |
-
html.escape(tb),
|
292 |
-
)
|
293 |
-
|
294 |
-
if len(message) >= 4096:
|
295 |
-
message = message[:4096]
|
296 |
-
# Finally, send the message
|
297 |
-
await context.bot.send_message(
|
298 |
-
chat_id=OWNER_ID, text=message, parse_mode=ParseMode.HTML
|
299 |
-
)
|
300 |
-
|
301 |
-
|
302 |
-
# for test purposes
|
303 |
-
async def error_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
304 |
-
error = context.error
|
305 |
-
try:
|
306 |
-
raise error
|
307 |
-
except Forbidden:
|
308 |
-
print("no nono1")
|
309 |
-
print(error)
|
310 |
-
# remove update.message.chat_id from conversation list
|
311 |
-
except BadRequest:
|
312 |
-
print("no nono2")
|
313 |
-
print("BadRequest caught")
|
314 |
-
print(error)
|
315 |
-
|
316 |
-
# handle malformed requests - read more below!
|
317 |
-
except TimedOut:
|
318 |
-
print("no nono3")
|
319 |
-
# handle slow connection problems
|
320 |
-
except NetworkError:
|
321 |
-
print("no nono4")
|
322 |
-
# handle other connection problems
|
323 |
-
except ChatMigrated as err:
|
324 |
-
print("no nono5")
|
325 |
-
print(err)
|
326 |
-
# the chat_id of a group has changed, use e.new_chat_id instead
|
327 |
-
except TelegramError:
|
328 |
-
print(error)
|
329 |
-
# handle all other telegram related errors
|
330 |
-
|
331 |
-
|
332 |
-
async def help_button(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
333 |
-
query = update.callback_query
|
334 |
-
mod_match = re.match(r"help_module\((.+?)\)", query.data)
|
335 |
-
prev_match = re.match(r"help_prev\((.+?)\)", query.data)
|
336 |
-
next_match = re.match(r"help_next\((.+?)\)", query.data)
|
337 |
-
back_match = re.match(r"help_back", query.data)
|
338 |
-
|
339 |
-
print(query.message.chat.id)
|
340 |
-
|
341 |
-
try:
|
342 |
-
if mod_match:
|
343 |
-
module = mod_match.group(1)
|
344 |
-
text = (
|
345 |
-
"➲ *HELP SECTION OF* *{}* :\n".format(HELPABLE[module].__mod_name__)
|
346 |
-
+ HELPABLE[module].__help__
|
347 |
-
)
|
348 |
-
await query.message.edit_text(
|
349 |
-
text=text,
|
350 |
-
parse_mode=ParseMode.MARKDOWN,
|
351 |
-
disable_web_page_preview=True,
|
352 |
-
reply_markup=InlineKeyboardMarkup(
|
353 |
-
[[InlineKeyboardButton(text="◁", callback_data="help_back")]]
|
354 |
-
),
|
355 |
-
)
|
356 |
-
|
357 |
-
elif prev_match:
|
358 |
-
curr_page = int(prev_match.group(1))
|
359 |
-
await query.message.edit_text(
|
360 |
-
text=HELP_STRINGS,
|
361 |
-
parse_mode=ParseMode.MARKDOWN,
|
362 |
-
reply_markup=InlineKeyboardMarkup(
|
363 |
-
paginate_modules(curr_page - 1, HELPABLE, "help")
|
364 |
-
),
|
365 |
-
)
|
366 |
-
|
367 |
-
elif next_match:
|
368 |
-
next_page = int(next_match.group(1))
|
369 |
-
await query.message.edit_text(
|
370 |
-
text=HELP_STRINGS,
|
371 |
-
parse_mode=ParseMode.MARKDOWN,
|
372 |
-
reply_markup=InlineKeyboardMarkup(
|
373 |
-
paginate_modules(next_page + 1, HELPABLE, "help")
|
374 |
-
),
|
375 |
-
)
|
376 |
-
|
377 |
-
elif back_match:
|
378 |
-
await query.message.edit_text(
|
379 |
-
text=HELP_STRINGS,
|
380 |
-
parse_mode=ParseMode.MARKDOWN,
|
381 |
-
reply_markup=InlineKeyboardMarkup(
|
382 |
-
paginate_modules(0, HELPABLE, "help")
|
383 |
-
),
|
384 |
-
)
|
385 |
-
|
386 |
-
await context.bot.answer_callback_query(query.id)
|
387 |
-
|
388 |
-
except BadRequest:
|
389 |
-
pass
|
390 |
-
|
391 |
-
|
392 |
-
async def stats_back(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
393 |
-
query = update.callback_query
|
394 |
-
if query.data == "insider_":
|
395 |
-
uptime = get_readable_time((time.time() - StartTime))
|
396 |
-
cpu = psutil.cpu_percent(interval=0.5)
|
397 |
-
mem = psutil.virtual_memory().percent
|
398 |
-
disk = psutil.disk_usage("/").percent
|
399 |
-
text = f"""
|
400 |
-
𝙎𝙮𝙨𝙩𝙚𝙢 𝙨𝙩𝙖𝙩𝙨@𝙔𝙖𝙚𝙈𝙞𝙠𝙤_𝙍𝙤𝙭𝙗𝙤𝙩
|
401 |
-
➖➖➖➖➖➖
|
402 |
-
UPTIME ➼ {uptime}
|
403 |
-
CPU ➼ {cpu}%
|
404 |
-
RAM ➼ {mem}%
|
405 |
-
DISK ➼ {disk}%
|
406 |
-
|
407 |
-
PYTHON ➼ {PYTHON_VERSION}
|
408 |
-
|
409 |
-
PTB ➼ {PTB_VERSION}
|
410 |
-
TELETHON ➼ {TELETHON_VERSION}
|
411 |
-
PYROGRAM ➼ {PYROGRAM_VERSION}
|
412 |
-
"""
|
413 |
-
await query.answer(text=text, show_alert=True)
|
414 |
-
|
415 |
-
|
416 |
-
async def gitsource_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
417 |
-
query = update.callback_query
|
418 |
-
await query.answer()
|
419 |
-
|
420 |
-
if query.data == "git_source":
|
421 |
-
source_link = "https://github.com/Infamous-Hydra/YaeMiko"
|
422 |
-
message_text = (
|
423 |
-
f"*Here is the link for the public source repo*:\n\n{source_link}"
|
424 |
-
)
|
425 |
-
|
426 |
-
# Adding the inline button
|
427 |
-
keyboard = [[InlineKeyboardButton(text="◁", callback_data="Miko_back")]]
|
428 |
-
reply_markup = InlineKeyboardMarkup(keyboard)
|
429 |
-
|
430 |
-
await query.edit_message_text(
|
431 |
-
message_text,
|
432 |
-
parse_mode=ParseMode.MARKDOWN,
|
433 |
-
disable_web_page_preview=False,
|
434 |
-
reply_markup=reply_markup,
|
435 |
-
)
|
436 |
-
|
437 |
-
|
438 |
-
async def repo(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
439 |
-
source_link = "https://github.com/Infamous-Hydra/YaeMiko"
|
440 |
-
message_text = f"*Here is the link for the public source repo*:\n\n{source_link}"
|
441 |
-
|
442 |
-
await context.bot.send_message(
|
443 |
-
chat_id=update.effective_chat.id,
|
444 |
-
text=message_text,
|
445 |
-
parse_mode=ParseMode.MARKDOWN,
|
446 |
-
disable_web_page_preview=False,
|
447 |
-
)
|
448 |
-
|
449 |
-
|
450 |
-
async def Miko_about_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
451 |
-
query = update.callback_query
|
452 |
-
if query.data == "Miko_":
|
453 |
-
uptime = get_readable_time((time.time() - StartTime))
|
454 |
-
message_text = (
|
455 |
-
f"➲ <b>Ai integration.</b>"
|
456 |
-
f"\n➲ <b>Advance management capability.</b>"
|
457 |
-
f"\n➲ <b>Anime bot functionality.</b>"
|
458 |
-
f"\n\n<b>USERS</b> » {sql.num_users()}"
|
459 |
-
f"\n<b>CHATS</b> » {sql.num_chats()}"
|
460 |
-
f"\n\n<b>Click on the buttons below for getting help and info about</b> {BOT_NAME}."
|
461 |
-
)
|
462 |
-
await query.message.edit_text(
|
463 |
-
text=message_text,
|
464 |
-
disable_web_page_preview=True,
|
465 |
-
parse_mode=ParseMode.HTML,
|
466 |
-
reply_markup=InlineKeyboardMarkup(
|
467 |
-
[
|
468 |
-
[
|
469 |
-
InlineKeyboardButton(
|
470 |
-
text="ABOUT", callback_data="Miko_support"
|
471 |
-
),
|
472 |
-
InlineKeyboardButton(text="COMMAND", callback_data="help_back"),
|
473 |
-
],
|
474 |
-
[
|
475 |
-
InlineKeyboardButton(text="INSIDER", callback_data="insider_"),
|
476 |
-
],
|
477 |
-
[
|
478 |
-
InlineKeyboardButton(text="◁", callback_data="Miko_back"),
|
479 |
-
],
|
480 |
-
]
|
481 |
-
),
|
482 |
-
)
|
483 |
-
elif query.data == "Miko_support":
|
484 |
-
message_text = (
|
485 |
-
"*Our bot leverages SQL, MongoDB, Telegram, MTProto for secure and efficient operations. It resides on a high-speed server, integrates numerous APIs, ensuring quick and versatile responses to user queries.*"
|
486 |
-
f"\n\n*If you find any bug in {BOT_NAME} Please report it at the support chat.*"
|
487 |
-
)
|
488 |
-
await query.message.edit_text(
|
489 |
-
text=message_text,
|
490 |
-
parse_mode=ParseMode.MARKDOWN,
|
491 |
-
disable_web_page_preview=True,
|
492 |
-
reply_markup=InlineKeyboardMarkup(
|
493 |
-
[
|
494 |
-
[
|
495 |
-
InlineKeyboardButton(
|
496 |
-
text="SUPPORT", url=f"https://t.me/{SUPPORT_CHAT}"
|
497 |
-
),
|
498 |
-
InlineKeyboardButton(
|
499 |
-
text="DEVELOPER", url=f"tg://user?id={OWNER_ID}"
|
500 |
-
),
|
501 |
-
],
|
502 |
-
[
|
503 |
-
InlineKeyboardButton(text="◁", callback_data="Miko_"),
|
504 |
-
],
|
505 |
-
]
|
506 |
-
),
|
507 |
-
)
|
508 |
-
elif query.data == "Miko_back":
|
509 |
-
first_name = update.effective_user.first_name
|
510 |
-
await query.message.edit_text(
|
511 |
-
PM_START_TEXT.format(escape_markdown(first_name), BOT_NAME),
|
512 |
-
reply_markup=InlineKeyboardMarkup(START_BTN),
|
513 |
-
parse_mode=ParseMode.MARKDOWN,
|
514 |
-
disable_web_page_preview=True,
|
515 |
-
)
|
516 |
-
|
517 |
-
|
518 |
-
async def get_help(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
519 |
-
chat = update.effective_chat # type: Optional[Chat]
|
520 |
-
args = update.effective_message.text.split(None, 1)
|
521 |
-
|
522 |
-
# ONLY send help in PM
|
523 |
-
if chat.type != chat.PRIVATE:
|
524 |
-
if len(args) >= 2 and any(args[1].lower() == x for x in HELPABLE):
|
525 |
-
module = args[1].lower()
|
526 |
-
await update.effective_message.reply_text(
|
527 |
-
f"Contact me in PM to get help of {module.capitalize()}",
|
528 |
-
reply_markup=InlineKeyboardMarkup(
|
529 |
-
[
|
530 |
-
[
|
531 |
-
InlineKeyboardButton(
|
532 |
-
text="HELP",
|
533 |
-
url="https://t.me/{}?start=ghelp_{}".format(
|
534 |
-
context.bot.username, module
|
535 |
-
),
|
536 |
-
)
|
537 |
-
]
|
538 |
-
]
|
539 |
-
),
|
540 |
-
)
|
541 |
-
return
|
542 |
-
await update.effective_message.reply_text(
|
543 |
-
"» Choose an option for getting help.",
|
544 |
-
reply_markup=InlineKeyboardMarkup(
|
545 |
-
[
|
546 |
-
[
|
547 |
-
InlineKeyboardButton(
|
548 |
-
text="OPEN IN PM",
|
549 |
-
url="https://t.me/{}?start=help".format(
|
550 |
-
context.bot.username
|
551 |
-
),
|
552 |
-
)
|
553 |
-
],
|
554 |
-
[
|
555 |
-
InlineKeyboardButton(
|
556 |
-
text="OPEN HERE",
|
557 |
-
callback_data="help_back",
|
558 |
-
)
|
559 |
-
],
|
560 |
-
]
|
561 |
-
),
|
562 |
-
)
|
563 |
-
return
|
564 |
-
|
565 |
-
elif len(args) >= 2 and any(args[1].lower() == x for x in HELPABLE):
|
566 |
-
module = args[1].lower()
|
567 |
-
text = (
|
568 |
-
"Here is the available help for the *{}* module:\n".format(
|
569 |
-
HELPABLE[module].__mod_name__
|
570 |
-
)
|
571 |
-
+ HELPABLE[module].__help__
|
572 |
-
)
|
573 |
-
await send_help(
|
574 |
-
chat.id,
|
575 |
-
text,
|
576 |
-
InlineKeyboardMarkup(
|
577 |
-
[[InlineKeyboardButton(text="◁", callback_data="help_back")]]
|
578 |
-
),
|
579 |
-
)
|
580 |
-
|
581 |
-
else:
|
582 |
-
await send_help(chat.id, HELP_STRINGS)
|
583 |
-
|
584 |
-
|
585 |
-
async def send_settings(chat_id, user_id, user=False):
|
586 |
-
if user:
|
587 |
-
if USER_SETTINGS:
|
588 |
-
settings = "\n\n".join(
|
589 |
-
"*{}*:\n{}".format(mod.__mod_name__, mod.__user_settings__(user_id))
|
590 |
-
for mod in USER_SETTINGS.values()
|
591 |
-
)
|
592 |
-
await dispatcher.bot.send_message(
|
593 |
-
user_id,
|
594 |
-
"These are your current settings:" + "\n\n" + settings,
|
595 |
-
parse_mode=ParseMode.MARKDOWN,
|
596 |
-
)
|
597 |
-
|
598 |
-
else:
|
599 |
-
await dispatcher.bot.send_message(
|
600 |
-
user_id,
|
601 |
-
"Seems like there aren't any user specific settings available :'(",
|
602 |
-
parse_mode=ParseMode.MARKDOWN,
|
603 |
-
)
|
604 |
-
else:
|
605 |
-
if CHAT_SETTINGS:
|
606 |
-
chat_name = dispatcher.bot.getChat(chat_id).title
|
607 |
-
await dispatcher.bot.send_message(
|
608 |
-
user_id,
|
609 |
-
text="Which module would you like to check {}'s settings for?".format(
|
610 |
-
chat_name
|
611 |
-
),
|
612 |
-
reply_markup=InlineKeyboardMarkup(
|
613 |
-
paginate_modules(0, CHAT_SETTINGS, "stngs", chat=chat_id)
|
614 |
-
),
|
615 |
-
)
|
616 |
-
else:
|
617 |
-
await dispatcher.bot.send_message(
|
618 |
-
user_id,
|
619 |
-
"Seems like there aren't any chat settings available :'(\nSend this "
|
620 |
-
"in a group chat you're admin in to find its current settings!",
|
621 |
-
parse_mode=ParseMode.MARKDOWN,
|
622 |
-
)
|
623 |
-
|
624 |
-
|
625 |
-
async def settings_button(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
626 |
-
query = update.callback_query
|
627 |
-
user = update.effective_user
|
628 |
-
bot = context.bot
|
629 |
-
mod_match = re.match(r"stngs_module\((.+?),(.+?)\)", query.data)
|
630 |
-
prev_match = re.match(r"stngs_prev\((.+?),(.+?)\)", query.data)
|
631 |
-
next_match = re.match(r"stngs_next\((.+?),(.+?)\)", query.data)
|
632 |
-
back_match = re.match(r"stngs_back\((.+?)\)", query.data)
|
633 |
-
try:
|
634 |
-
if mod_match:
|
635 |
-
chat_id = mod_match.group(1)
|
636 |
-
module = mod_match.group(2)
|
637 |
-
chat = bot.get_chat(chat_id)
|
638 |
-
text = "*{}* has the following settings for the *{}* module:\n\n".format(
|
639 |
-
escape_markdown(chat.title), CHAT_SETTINGS[module].__mod_name__
|
640 |
-
) + CHAT_SETTINGS[module].__chat_settings__(chat_id, user.id)
|
641 |
-
await query.message.reply_text(
|
642 |
-
text=text,
|
643 |
-
parse_mode=ParseMode.MARKDOWN,
|
644 |
-
reply_markup=InlineKeyboardMarkup(
|
645 |
-
[
|
646 |
-
[
|
647 |
-
InlineKeyboardButton(
|
648 |
-
text="◁",
|
649 |
-
callback_data="stngs_back({})".format(chat_id),
|
650 |
-
)
|
651 |
-
]
|
652 |
-
]
|
653 |
-
),
|
654 |
-
)
|
655 |
-
|
656 |
-
elif prev_match:
|
657 |
-
chat_id = prev_match.group(1)
|
658 |
-
curr_page = int(prev_match.group(2))
|
659 |
-
chat = bot.get_chat(chat_id)
|
660 |
-
await query.message.reply_text(
|
661 |
-
"Hi there! There are quite a few settings for {} - go ahead and pick what "
|
662 |
-
"you're interested in.".format(chat.title),
|
663 |
-
reply_markup=InlineKeyboardMarkup(
|
664 |
-
paginate_modules(
|
665 |
-
curr_page - 1, CHAT_SETTINGS, "stngs", chat=chat_id
|
666 |
-
)
|
667 |
-
),
|
668 |
-
)
|
669 |
-
|
670 |
-
elif next_match:
|
671 |
-
chat_id = next_match.group(1)
|
672 |
-
next_page = int(next_match.group(2))
|
673 |
-
chat = bot.get_chat(chat_id)
|
674 |
-
await query.message.reply_text(
|
675 |
-
"Hi there! There are quite a few settings for {} - go ahead and pick what "
|
676 |
-
"you're interested in.".format(chat.title),
|
677 |
-
reply_markup=InlineKeyboardMarkup(
|
678 |
-
paginate_modules(
|
679 |
-
next_page + 1, CHAT_SETTINGS, "stngs", chat=chat_id
|
680 |
-
)
|
681 |
-
),
|
682 |
-
)
|
683 |
-
|
684 |
-
elif back_match:
|
685 |
-
chat_id = back_match.group(1)
|
686 |
-
chat = bot.get_chat(chat_id)
|
687 |
-
await query.message.reply_text(
|
688 |
-
text="Hi there! There are quite a few settings for {} - go ahead and pick what "
|
689 |
-
"you're interested in.".format(escape_markdown(chat.title)),
|
690 |
-
parse_mode=ParseMode.MARKDOWN,
|
691 |
-
reply_markup=InlineKeyboardMarkup(
|
692 |
-
paginate_modules(0, CHAT_SETTINGS, "stngs", chat=chat_id)
|
693 |
-
),
|
694 |
-
)
|
695 |
-
|
696 |
-
# ensure no spinny white circle
|
697 |
-
bot.answer_callback_query(query.id)
|
698 |
-
await query.message.delete()
|
699 |
-
except BadRequest as excp:
|
700 |
-
if excp.message not in [
|
701 |
-
"Message is not modified",
|
702 |
-
"Query_id_invalid",
|
703 |
-
"Message can't be deleted",
|
704 |
-
]:
|
705 |
-
LOGGER.exception("Exception in settings buttons. %s", str(query.data))
|
706 |
-
|
707 |
-
|
708 |
-
async def get_settings(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
709 |
-
chat = update.effective_chat # type: Optional[Chat]
|
710 |
-
user = update.effective_user # type: Optional[User]
|
711 |
-
msg = update.effective_message # type: Optional[Message]
|
712 |
-
|
713 |
-
# ONLY send settings in PM
|
714 |
-
if chat.type != chat.PRIVATE:
|
715 |
-
if is_user_admin(chat, user.id):
|
716 |
-
text = "Click here to get this chat's settings, as well as yours."
|
717 |
-
await msg.reply_text(
|
718 |
-
text,
|
719 |
-
reply_markup=InlineKeyboardMarkup(
|
720 |
-
[
|
721 |
-
[
|
722 |
-
InlineKeyboardButton(
|
723 |
-
text="SETTINGS",
|
724 |
-
url="t.me/{}?start=stngs_{}".format(
|
725 |
-
context.bot.username, chat.id
|
726 |
-
),
|
727 |
-
)
|
728 |
-
]
|
729 |
-
]
|
730 |
-
),
|
731 |
-
)
|
732 |
-
else:
|
733 |
-
text = "Click here to check your settings."
|
734 |
-
|
735 |
-
else:
|
736 |
-
await send_settings(chat.id, user.id, True)
|
737 |
-
|
738 |
-
|
739 |
-
async def migrate_chats(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
740 |
-
msg = update.effective_message # type: Optional[Message]
|
741 |
-
if msg.migrate_to_chat_id:
|
742 |
-
old_chat = update.effective_chat.id
|
743 |
-
new_chat = msg.migrate_to_chat_id
|
744 |
-
elif msg.migrate_from_chat_id:
|
745 |
-
old_chat = msg.migrate_from_chat_id
|
746 |
-
new_chat = update.effective_chat.id
|
747 |
-
else:
|
748 |
-
return
|
749 |
-
|
750 |
-
LOGGER.info("Migrating from %s, ᴛᴏ %s", str(old_chat), str(new_chat))
|
751 |
-
for mod in MIGRATEABLE:
|
752 |
-
with contextlib.suppress(KeyError, AttributeError):
|
753 |
-
mod.__migrate__(old_chat, new_chat)
|
754 |
-
|
755 |
-
LOGGER.info("Successfully Migrated!")
|
756 |
-
raise ApplicationHandlerStop
|
757 |
-
|
758 |
-
|
759 |
-
# <=======================================================================================================>
|
760 |
-
|
761 |
-
|
762 |
-
# <=================================================== MAIN ====================================================>
|
763 |
-
def main():
|
764 |
-
function(CommandHandler("start", start))
|
765 |
-
|
766 |
-
function(CommandHandler("help", get_help))
|
767 |
-
function(CallbackQueryHandler(help_button, pattern=r"help_.*"))
|
768 |
-
|
769 |
-
function(CommandHandler("settings", get_settings))
|
770 |
-
function(CallbackQueryHandler(settings_button, pattern=r"stngs_"))
|
771 |
-
function(CommandHandler("repo", repo))
|
772 |
-
|
773 |
-
function(CallbackQueryHandler(Miko_about_callback, pattern=r"Miko_"))
|
774 |
-
function(CallbackQueryHandler(gitsource_callback, pattern=r"git_source"))
|
775 |
-
function(CallbackQueryHandler(stats_back, pattern=r"insider_"))
|
776 |
-
function(CallbackQueryHandler(ai_handler_callback, pattern=r"ai_handler"))
|
777 |
-
function(CallbackQueryHandler(more_ai_handler_callback, pattern=r"more_ai_handler"))
|
778 |
-
function(MessageHandler(filters.StatusUpdate.MIGRATE, migrate_chats))
|
779 |
-
|
780 |
-
dispatcher.add_error_handler(error_callback)
|
781 |
-
|
782 |
-
LOGGER.info("Mikobot is starting >> Using long polling.")
|
783 |
-
dispatcher.run_polling(timeout=15, drop_pending_updates=True)
|
784 |
-
|
785 |
-
|
786 |
-
if __name__ == "__main__":
|
787 |
-
try:
|
788 |
-
LOGGER.info("Successfully loaded modules: " + str(ALL_MODULES))
|
789 |
-
tbot.start(bot_token=TOKEN)
|
790 |
-
app.start()
|
791 |
-
main()
|
792 |
-
except KeyboardInterrupt:
|
793 |
-
pass
|
794 |
-
except Exception:
|
795 |
-
err = traceback.format_exc()
|
796 |
-
LOGGER.info(err)
|
797 |
-
finally:
|
798 |
-
try:
|
799 |
-
if loop.is_running():
|
800 |
-
loop.stop()
|
801 |
-
finally:
|
802 |
-
loop.close()
|
803 |
-
LOGGER.info(
|
804 |
-
"------------------------ Stopped Services ------------------------"
|
805 |
-
)
|
806 |
-
# <==================================================== END ===================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/events.py
DELETED
@@ -1,70 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from telethon import events
|
3 |
-
|
4 |
-
from Mikobot import tbot
|
5 |
-
|
6 |
-
|
7 |
-
# <============================================== FUNCTIONS =========================================================>
|
8 |
-
def register(**args):
|
9 |
-
"""Registers a new message."""
|
10 |
-
pattern = args.get("pattern")
|
11 |
-
|
12 |
-
r_pattern = r"^[/!]"
|
13 |
-
|
14 |
-
if pattern is not None and not pattern.startswith("(?i)"):
|
15 |
-
args["pattern"] = f"(?i){pattern}"
|
16 |
-
|
17 |
-
args["pattern"] = pattern.replace("^/", r_pattern, 1)
|
18 |
-
|
19 |
-
def decorator(func):
|
20 |
-
tbot.add_event_handler(func, events.NewMessage(**args))
|
21 |
-
return func
|
22 |
-
|
23 |
-
return decorator
|
24 |
-
|
25 |
-
|
26 |
-
def chataction(**args):
|
27 |
-
"""Registers chat actions."""
|
28 |
-
|
29 |
-
def decorator(func):
|
30 |
-
tbot.add_event_handler(func, events.ChatAction(**args))
|
31 |
-
return func
|
32 |
-
|
33 |
-
return decorator
|
34 |
-
|
35 |
-
|
36 |
-
def userupdate(**args):
|
37 |
-
"""Registers user updates."""
|
38 |
-
|
39 |
-
def decorator(func):
|
40 |
-
tbot.add_event_handler(func, events.UserUpdate(**args))
|
41 |
-
return func
|
42 |
-
|
43 |
-
return decorator
|
44 |
-
|
45 |
-
|
46 |
-
def inlinequery(**args):
|
47 |
-
"""Registers inline query."""
|
48 |
-
pattern = args.get("pattern")
|
49 |
-
|
50 |
-
if pattern is not None and not pattern.startswith("(?i)"):
|
51 |
-
args["pattern"] = f"(?i){pattern}"
|
52 |
-
|
53 |
-
def decorator(func):
|
54 |
-
tbot.add_event_handler(func, events.InlineQuery(**args))
|
55 |
-
return func
|
56 |
-
|
57 |
-
return decorator
|
58 |
-
|
59 |
-
|
60 |
-
def callbackquery(**args):
|
61 |
-
"""Registers inline query."""
|
62 |
-
|
63 |
-
def decorator(func):
|
64 |
-
tbot.add_event_handler(func, events.CallbackQuery(**args))
|
65 |
-
return func
|
66 |
-
|
67 |
-
return decorator
|
68 |
-
|
69 |
-
|
70 |
-
# <==================================================== END ===================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/__init__.py
DELETED
@@ -1,43 +0,0 @@
|
|
1 |
-
from Mikobot import LOAD, LOGGER, NO_LOAD
|
2 |
-
|
3 |
-
|
4 |
-
def __list_all_modules():
|
5 |
-
import glob
|
6 |
-
from os.path import basename, dirname, isfile
|
7 |
-
|
8 |
-
# This generates a list of modules in this folder for the * in __main__ to work.
|
9 |
-
mod_paths = glob.glob(dirname(__file__) + "/*.py")
|
10 |
-
all_modules = [
|
11 |
-
basename(f)[:-3]
|
12 |
-
for f in mod_paths
|
13 |
-
if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py")
|
14 |
-
]
|
15 |
-
|
16 |
-
if LOAD or NO_LOAD:
|
17 |
-
to_load = LOAD
|
18 |
-
if to_load:
|
19 |
-
if not all(
|
20 |
-
any(mod == module_name for module_name in all_modules)
|
21 |
-
for mod in to_load
|
22 |
-
):
|
23 |
-
LOGGER.error("Invalid loadorder names, Quitting...")
|
24 |
-
quit(1)
|
25 |
-
|
26 |
-
all_modules = sorted(set(all_modules) - set(to_load))
|
27 |
-
to_load = list(all_modules) + to_load
|
28 |
-
|
29 |
-
else:
|
30 |
-
to_load = all_modules
|
31 |
-
|
32 |
-
if NO_LOAD:
|
33 |
-
LOGGER.info("Not loading: {}".format(NO_LOAD))
|
34 |
-
return [item for item in to_load if item not in NO_LOAD]
|
35 |
-
|
36 |
-
return to_load
|
37 |
-
|
38 |
-
return all_modules
|
39 |
-
|
40 |
-
|
41 |
-
ALL_MODULES = __list_all_modules()
|
42 |
-
LOGGER.info("Modules to load: %s", str(ALL_MODULES))
|
43 |
-
__all__ = ALL_MODULES + ["ALL_MODULES"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/admin.py
DELETED
@@ -1,1148 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import html
|
3 |
-
|
4 |
-
from telegram import (
|
5 |
-
ChatMemberAdministrator,
|
6 |
-
InlineKeyboardButton,
|
7 |
-
InlineKeyboardMarkup,
|
8 |
-
Update,
|
9 |
-
)
|
10 |
-
from telegram.constants import ChatID, ChatMemberStatus, ChatType, ParseMode
|
11 |
-
from telegram.error import BadRequest
|
12 |
-
from telegram.ext import CallbackQueryHandler, CommandHandler, ContextTypes, filters
|
13 |
-
from telegram.helpers import mention_html
|
14 |
-
|
15 |
-
from Mikobot import DRAGONS, function
|
16 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
17 |
-
from Mikobot.plugins.helper_funcs.alternate import send_message
|
18 |
-
from Mikobot.plugins.helper_funcs.chat_status import (
|
19 |
-
ADMIN_CACHE,
|
20 |
-
check_admin,
|
21 |
-
connection_status,
|
22 |
-
)
|
23 |
-
from Mikobot.plugins.helper_funcs.extraction import extract_user, extract_user_and_text
|
24 |
-
from Mikobot.plugins.log_channel import loggable
|
25 |
-
|
26 |
-
# <=======================================================================================================>
|
27 |
-
|
28 |
-
|
29 |
-
# <================================================ FUNCTION =======================================================>
|
30 |
-
@connection_status
|
31 |
-
@loggable
|
32 |
-
@check_admin(permission="can_promote_members", is_both=True)
|
33 |
-
async def promote(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
34 |
-
bot = context.bot
|
35 |
-
args = context.args
|
36 |
-
|
37 |
-
message = update.effective_message
|
38 |
-
chat = update.effective_chat
|
39 |
-
user = update.effective_user
|
40 |
-
|
41 |
-
user_id = await extract_user(message, context, args)
|
42 |
-
await chat.get_member(user.id)
|
43 |
-
|
44 |
-
if message.from_user.id == ChatID.ANONYMOUS_ADMIN:
|
45 |
-
await message.reply_text(
|
46 |
-
text="You are an anonymous admin.",
|
47 |
-
reply_markup=InlineKeyboardMarkup(
|
48 |
-
[
|
49 |
-
[
|
50 |
-
InlineKeyboardButton(
|
51 |
-
text="Click to promote admin.",
|
52 |
-
callback_data=f"admin_=promote={user_id}",
|
53 |
-
),
|
54 |
-
],
|
55 |
-
],
|
56 |
-
),
|
57 |
-
)
|
58 |
-
|
59 |
-
return
|
60 |
-
|
61 |
-
if not user_id:
|
62 |
-
await message.reply_text(
|
63 |
-
"You don't seem to be referring to a user, or the ID specified is incorrect.",
|
64 |
-
)
|
65 |
-
return
|
66 |
-
|
67 |
-
try:
|
68 |
-
user_member = await chat.get_member(user_id)
|
69 |
-
except:
|
70 |
-
return
|
71 |
-
|
72 |
-
if (
|
73 |
-
user_member.status == ChatMemberStatus.ADMINISTRATOR
|
74 |
-
or user_member.status == ChatMemberStatus.OWNER
|
75 |
-
):
|
76 |
-
await message.reply_text("How can I promote someone who is already an admin?")
|
77 |
-
return
|
78 |
-
|
79 |
-
if user_id == bot.id:
|
80 |
-
await message.reply_text(
|
81 |
-
"I can't promote myself! Get an admin to do it for me."
|
82 |
-
)
|
83 |
-
return
|
84 |
-
|
85 |
-
# Set the same permissions as the bot - the bot can't assign higher permissions than itself!
|
86 |
-
bot_member = await chat.get_member(bot.id)
|
87 |
-
|
88 |
-
if isinstance(bot_member, ChatMemberAdministrator):
|
89 |
-
try:
|
90 |
-
await bot.promoteChatMember(
|
91 |
-
chat.id,
|
92 |
-
user_id,
|
93 |
-
can_change_info=bot_member.can_change_info,
|
94 |
-
can_post_messages=bot_member.can_post_messages,
|
95 |
-
can_edit_messages=bot_member.can_edit_messages,
|
96 |
-
can_delete_messages=bot_member.can_delete_messages,
|
97 |
-
can_invite_users=bot_member.can_invite_users,
|
98 |
-
can_restrict_members=bot_member.can_restrict_members,
|
99 |
-
can_pin_messages=bot_member.can_pin_messages,
|
100 |
-
can_manage_chat=bot_member.can_manage_chat,
|
101 |
-
can_manage_video_chats=bot_member.can_manage_video_chats,
|
102 |
-
can_manage_topics=bot_member.can_manage_topics,
|
103 |
-
)
|
104 |
-
except BadRequest as err:
|
105 |
-
if err.message == "User_not_mutual_contact":
|
106 |
-
await message.reply_text(
|
107 |
-
"I can't promote someone who isn't in the group."
|
108 |
-
)
|
109 |
-
else:
|
110 |
-
await message.reply_text("An error occurred while promoting.")
|
111 |
-
return
|
112 |
-
|
113 |
-
await bot.sendMessage(
|
114 |
-
chat.id,
|
115 |
-
f"Successfully promoted {user_member.user.first_name or user_id}!",
|
116 |
-
parse_mode=ParseMode.HTML,
|
117 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
118 |
-
)
|
119 |
-
|
120 |
-
log_message = (
|
121 |
-
f"{html.escape(chat.title)}:\n"
|
122 |
-
"#Promoted\n"
|
123 |
-
f"ADMIN: {mention_html(user.id, user.first_name)}\n"
|
124 |
-
f"USER: {mention_html(user_member.user.id, user_member.user.first_name)}"
|
125 |
-
)
|
126 |
-
|
127 |
-
return log_message
|
128 |
-
|
129 |
-
|
130 |
-
@connection_status
|
131 |
-
@loggable
|
132 |
-
@check_admin(permission="can_promote_members", is_both=True)
|
133 |
-
async def fullpromote(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
134 |
-
bot = context.bot
|
135 |
-
args = context.args
|
136 |
-
|
137 |
-
message = update.effective_message
|
138 |
-
chat = update.effective_chat
|
139 |
-
user = update.effective_user
|
140 |
-
|
141 |
-
user_id = await extract_user(message, context, args)
|
142 |
-
await chat.get_member(user.id)
|
143 |
-
|
144 |
-
if message.from_user.id == ChatID.ANONYMOUS_ADMIN:
|
145 |
-
await message.reply_text(
|
146 |
-
text="You are an anonymous admin.",
|
147 |
-
reply_markup=InlineKeyboardMarkup(
|
148 |
-
[
|
149 |
-
[
|
150 |
-
InlineKeyboardButton(
|
151 |
-
text="Click to promote admin.",
|
152 |
-
callback_data=f"admin_=promote={user_id}",
|
153 |
-
),
|
154 |
-
],
|
155 |
-
],
|
156 |
-
),
|
157 |
-
)
|
158 |
-
|
159 |
-
return
|
160 |
-
|
161 |
-
if not user_id:
|
162 |
-
await message.reply_text(
|
163 |
-
"You don't seem to be referring to a user, or the ID specified is incorrect.",
|
164 |
-
)
|
165 |
-
return
|
166 |
-
|
167 |
-
try:
|
168 |
-
user_member = await chat.get_member(user_id)
|
169 |
-
except:
|
170 |
-
return
|
171 |
-
|
172 |
-
if (
|
173 |
-
user_member.status == ChatMemberStatus.ADMINISTRATOR
|
174 |
-
or user_member.status == ChatMemberStatus.OWNER
|
175 |
-
):
|
176 |
-
await message.reply_text("How can I promote someone who is already an admin?")
|
177 |
-
return
|
178 |
-
|
179 |
-
if user_id == bot.id:
|
180 |
-
await message.reply_text(
|
181 |
-
"I can't promote myself! Get an admin to do it for me."
|
182 |
-
)
|
183 |
-
return
|
184 |
-
|
185 |
-
# Set the same permissions as the bot - the bot can't assign higher perms than itself!
|
186 |
-
bot_member = await chat.get_member(bot.id)
|
187 |
-
|
188 |
-
if isinstance(bot_member, ChatMemberAdministrator):
|
189 |
-
try:
|
190 |
-
await bot.promoteChatMember(
|
191 |
-
chat.id,
|
192 |
-
user_id,
|
193 |
-
can_change_info=bot_member.can_change_info,
|
194 |
-
can_post_messages=bot_member.can_post_messages,
|
195 |
-
can_edit_messages=bot_member.can_edit_messages,
|
196 |
-
can_delete_messages=bot_member.can_delete_messages,
|
197 |
-
can_invite_users=bot_member.can_invite_users,
|
198 |
-
can_promote_members=bot_member.can_promote_members,
|
199 |
-
can_restrict_members=bot_member.can_restrict_members,
|
200 |
-
can_pin_messages=bot_member.can_pin_messages,
|
201 |
-
can_manage_chat=bot_member.can_manage_chat,
|
202 |
-
can_manage_video_chats=bot_member.can_manage_video_chats,
|
203 |
-
can_manage_topics=bot_member.can_manage_topics,
|
204 |
-
)
|
205 |
-
except BadRequest as err:
|
206 |
-
if err.message == "User_not_mutual_contact":
|
207 |
-
await message.reply_text(
|
208 |
-
"I can't promote someone who isn't in the group."
|
209 |
-
)
|
210 |
-
else:
|
211 |
-
await message.reply_text("An error occurred while promoting.")
|
212 |
-
return
|
213 |
-
|
214 |
-
await bot.sendMessage(
|
215 |
-
chat.id,
|
216 |
-
f"Successfully promoted {user_member.user.first_name or user_id}!",
|
217 |
-
parse_mode=ParseMode.HTML,
|
218 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
219 |
-
)
|
220 |
-
|
221 |
-
log_message = (
|
222 |
-
f"{html.escape(chat.title)}:\n"
|
223 |
-
"#FULLPROMOTED\n"
|
224 |
-
f"ADMIN: {mention_html(user.id, user.first_name)}\n"
|
225 |
-
f"USER: {mention_html(user_member.user.id, user_member.user.first_name)}"
|
226 |
-
)
|
227 |
-
|
228 |
-
return log_message
|
229 |
-
|
230 |
-
|
231 |
-
@connection_status
|
232 |
-
@loggable
|
233 |
-
@check_admin(permission="can_promote_members", is_both=True)
|
234 |
-
async def demote(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
235 |
-
bot = context.bot
|
236 |
-
args = context.args
|
237 |
-
|
238 |
-
chat = update.effective_chat
|
239 |
-
message = update.effective_message
|
240 |
-
user = update.effective_user
|
241 |
-
|
242 |
-
user_id = await extract_user(message, context, args)
|
243 |
-
await chat.get_member(user.id)
|
244 |
-
|
245 |
-
if message.from_user.id == ChatID.ANONYMOUS_ADMIN:
|
246 |
-
await message.reply_text(
|
247 |
-
text="You are an anonymous admin.",
|
248 |
-
reply_markup=InlineKeyboardMarkup(
|
249 |
-
[
|
250 |
-
[
|
251 |
-
InlineKeyboardButton(
|
252 |
-
text="Click to prove admin.",
|
253 |
-
callback_data=f"admin_=demote={user_id}",
|
254 |
-
),
|
255 |
-
],
|
256 |
-
],
|
257 |
-
),
|
258 |
-
)
|
259 |
-
|
260 |
-
return
|
261 |
-
|
262 |
-
if not user_id:
|
263 |
-
await message.reply_text(
|
264 |
-
"You don't seem to be referring to a user or the id specified is incorrect..",
|
265 |
-
)
|
266 |
-
return
|
267 |
-
|
268 |
-
try:
|
269 |
-
user_member = await chat.get_member(user_id)
|
270 |
-
except:
|
271 |
-
return
|
272 |
-
|
273 |
-
if user_member.status == ChatMemberStatus.OWNER:
|
274 |
-
await message.reply_text(
|
275 |
-
"This person created the chat, How could i demote him?"
|
276 |
-
)
|
277 |
-
return
|
278 |
-
|
279 |
-
if not user_member.status == ChatMemberStatus.ADMINISTRATOR:
|
280 |
-
await message.reply_text("Can't demote who isn't promoted!")
|
281 |
-
return
|
282 |
-
|
283 |
-
if user_id == bot.id:
|
284 |
-
await message.reply_text("I can't demote myself!.")
|
285 |
-
return
|
286 |
-
|
287 |
-
try:
|
288 |
-
await bot.promote_chat_member(
|
289 |
-
chat.id,
|
290 |
-
user_id,
|
291 |
-
can_change_info=False,
|
292 |
-
can_post_messages=False,
|
293 |
-
can_edit_messages=False,
|
294 |
-
can_delete_messages=False,
|
295 |
-
can_invite_users=False,
|
296 |
-
can_restrict_members=False,
|
297 |
-
can_pin_messages=False,
|
298 |
-
can_promote_members=False,
|
299 |
-
can_manage_chat=False,
|
300 |
-
can_manage_video_chats=False,
|
301 |
-
can_manage_topics=False,
|
302 |
-
)
|
303 |
-
|
304 |
-
await bot.sendMessage(
|
305 |
-
chat.id,
|
306 |
-
f"SUCCESSFULLY DEMOTED <b>{user_member.user.first_name or user_id}</b>!",
|
307 |
-
parse_mode=ParseMode.HTML,
|
308 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
309 |
-
)
|
310 |
-
|
311 |
-
log_message = (
|
312 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
313 |
-
f"#DEMOTED\n"
|
314 |
-
f"<b>ADMIN:</b> {mention_html(user.id, user.first_name)}\n"
|
315 |
-
f"<b>USER:</b> {mention_html(user_member.user.id, user_member.user.first_name)}"
|
316 |
-
)
|
317 |
-
|
318 |
-
return log_message
|
319 |
-
except BadRequest:
|
320 |
-
await message.reply_text(
|
321 |
-
"Could not demote. I might not be admin or the admin status was appointed by another"
|
322 |
-
"Its a User, So I can't act upon them!",
|
323 |
-
)
|
324 |
-
raise
|
325 |
-
|
326 |
-
|
327 |
-
@check_admin(is_user=True)
|
328 |
-
async def refresh_admin(update, _):
|
329 |
-
try:
|
330 |
-
ADMIN_CACHE.pop(update.effective_chat.id)
|
331 |
-
except KeyError:
|
332 |
-
pass
|
333 |
-
|
334 |
-
await update.effective_message.reply_text("Admins cache refreshed!")
|
335 |
-
|
336 |
-
|
337 |
-
@connection_status
|
338 |
-
@check_admin(permission="can_promote_members", is_both=True)
|
339 |
-
async def set_title(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
340 |
-
bot = context.bot
|
341 |
-
args = context.args
|
342 |
-
|
343 |
-
chat = update.effective_chat
|
344 |
-
message = update.effective_message
|
345 |
-
|
346 |
-
user_id, title = await extract_user_and_text(message, context, args)
|
347 |
-
|
348 |
-
if message.from_user.id == 1087968824:
|
349 |
-
await message.reply_text(
|
350 |
-
text="You are an anonymous admin.",
|
351 |
-
reply_markup=InlineKeyboardMarkup(
|
352 |
-
[
|
353 |
-
[
|
354 |
-
InlineKeyboardButton(
|
355 |
-
text="Click to prove admin.",
|
356 |
-
callback_data=f"admin_=title={user_id}={title}",
|
357 |
-
),
|
358 |
-
],
|
359 |
-
],
|
360 |
-
),
|
361 |
-
)
|
362 |
-
|
363 |
-
return
|
364 |
-
|
365 |
-
try:
|
366 |
-
user_member = await chat.get_member(user_id)
|
367 |
-
except:
|
368 |
-
return
|
369 |
-
|
370 |
-
if not user_id:
|
371 |
-
await message.reply_text(
|
372 |
-
"You don't seem to be referring to a user or the ID specified is incorrect..",
|
373 |
-
)
|
374 |
-
return
|
375 |
-
|
376 |
-
if user_member.status == ChatMemberStatus.OWNER:
|
377 |
-
await message.reply_text(
|
378 |
-
"This person CREATED the chat, how can I set custom title for him?",
|
379 |
-
)
|
380 |
-
return
|
381 |
-
|
382 |
-
if user_member.status != ChatMemberStatus.ADMINISTRATOR:
|
383 |
-
await message.reply_text(
|
384 |
-
"Can't set title for non-admins!\nPromote them first to set custom title!",
|
385 |
-
)
|
386 |
-
return
|
387 |
-
|
388 |
-
if user_id == bot.id:
|
389 |
-
await message.reply_text(
|
390 |
-
"I can't set my own title myself! Get the one who made me admin to do it for me.",
|
391 |
-
)
|
392 |
-
return
|
393 |
-
|
394 |
-
if not title:
|
395 |
-
await message.reply_text("Setting a blank title doesn't do anything!")
|
396 |
-
return
|
397 |
-
|
398 |
-
if len(title) > 16:
|
399 |
-
await message.reply_text(
|
400 |
-
"The title length is longer than 16 characters.\nTruncating it to 16 characters.",
|
401 |
-
)
|
402 |
-
|
403 |
-
try:
|
404 |
-
await bot.setChatAdministratorCustomTitle(chat.id, user_id, title)
|
405 |
-
except BadRequest:
|
406 |
-
await message.reply_text(
|
407 |
-
"Either they aren't promoted by me or you set a title text that is impossible to set."
|
408 |
-
)
|
409 |
-
raise
|
410 |
-
|
411 |
-
await bot.sendMessage(
|
412 |
-
chat.id,
|
413 |
-
f"Successfully set title for <code>{user_member.user.first_name or user_id}</code> "
|
414 |
-
f"to <code>{html.escape(title[:16])}</code>!",
|
415 |
-
parse_mode=ParseMode.HTML,
|
416 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
417 |
-
)
|
418 |
-
|
419 |
-
|
420 |
-
@loggable
|
421 |
-
@check_admin(permission="can_pin_messages", is_both=True)
|
422 |
-
async def pin(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
423 |
-
bot = context.bot
|
424 |
-
args = context.args
|
425 |
-
|
426 |
-
user = update.effective_user
|
427 |
-
chat = update.effective_chat
|
428 |
-
message = update.effective_message
|
429 |
-
|
430 |
-
is_group = chat.type != "private" and chat.type != "channel"
|
431 |
-
prev_message = update.effective_message.reply_to_message
|
432 |
-
|
433 |
-
is_silent = True
|
434 |
-
if len(args) >= 1:
|
435 |
-
is_silent = not (
|
436 |
-
args[0].lower() == "notify"
|
437 |
-
or args[0].lower() == "loud"
|
438 |
-
or args[0].lower() == "violent"
|
439 |
-
)
|
440 |
-
|
441 |
-
if not prev_message:
|
442 |
-
await message.reply_text("Please reply to message which you want to pin.")
|
443 |
-
return
|
444 |
-
|
445 |
-
if message.from_user.id == 1087968824:
|
446 |
-
await message.reply_text(
|
447 |
-
text="You are an anonymous admin.",
|
448 |
-
reply_markup=InlineKeyboardMarkup(
|
449 |
-
[
|
450 |
-
[
|
451 |
-
InlineKeyboardButton(
|
452 |
-
text="Click to prove admin.",
|
453 |
-
callback_data=f"admin_=pin={prev_message.message_id}={is_silent}",
|
454 |
-
),
|
455 |
-
],
|
456 |
-
],
|
457 |
-
),
|
458 |
-
)
|
459 |
-
|
460 |
-
return
|
461 |
-
|
462 |
-
if prev_message and is_group:
|
463 |
-
try:
|
464 |
-
await bot.pinChatMessage(
|
465 |
-
chat.id,
|
466 |
-
prev_message.message_id,
|
467 |
-
disable_notification=is_silent,
|
468 |
-
)
|
469 |
-
except BadRequest as excp:
|
470 |
-
if excp.message == "Chat_not_modified":
|
471 |
-
pass
|
472 |
-
else:
|
473 |
-
raise
|
474 |
-
log_message = (
|
475 |
-
f"{chat.title}:\n"
|
476 |
-
"#PINNED\n"
|
477 |
-
f"Admin: {mention_html(user.id, user.first_name)}"
|
478 |
-
)
|
479 |
-
|
480 |
-
return log_message
|
481 |
-
|
482 |
-
|
483 |
-
@loggable
|
484 |
-
@check_admin(permission="can_pin_messages", is_both=True)
|
485 |
-
async def unpin(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
486 |
-
bot = context.bot
|
487 |
-
chat = update.effective_chat
|
488 |
-
user = update.effective_user
|
489 |
-
message = update.effective_message
|
490 |
-
|
491 |
-
if message.from_user.id == 1087968824:
|
492 |
-
await message.reply_text(
|
493 |
-
text="You are an anonymous admin.",
|
494 |
-
reply_markup=InlineKeyboardMarkup(
|
495 |
-
[
|
496 |
-
[
|
497 |
-
InlineKeyboardButton(
|
498 |
-
text="Click to prove Admin.",
|
499 |
-
callback_data=f"admin_=unpin",
|
500 |
-
),
|
501 |
-
],
|
502 |
-
],
|
503 |
-
),
|
504 |
-
)
|
505 |
-
|
506 |
-
return
|
507 |
-
|
508 |
-
try:
|
509 |
-
await bot.unpinChatMessage(chat.id)
|
510 |
-
except BadRequest as excp:
|
511 |
-
if excp.message == "Chat_not_modified":
|
512 |
-
pass
|
513 |
-
elif excp.message == "Message to unpin not found":
|
514 |
-
await message.reply_text("No pinned message found")
|
515 |
-
return
|
516 |
-
else:
|
517 |
-
raise
|
518 |
-
|
519 |
-
log_message = (
|
520 |
-
f"{chat.title}:\n"
|
521 |
-
"#UNPINNED\n"
|
522 |
-
f"Admin: {mention_html(user.id, user.first_name)}"
|
523 |
-
)
|
524 |
-
|
525 |
-
return log_message
|
526 |
-
|
527 |
-
|
528 |
-
@loggable
|
529 |
-
@check_admin(permission="can_pin_messages", is_both=True)
|
530 |
-
async def unpinall(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
531 |
-
bot = context.bot
|
532 |
-
chat = update.effective_chat
|
533 |
-
user = update.effective_user
|
534 |
-
message = update.effective_message
|
535 |
-
admin_member = await chat.get_member(user.id)
|
536 |
-
|
537 |
-
if message.from_user.id == 1087968824:
|
538 |
-
await message.reply_text(
|
539 |
-
text="You are an anonymous admin.",
|
540 |
-
reply_markup=InlineKeyboardMarkup(
|
541 |
-
[
|
542 |
-
[
|
543 |
-
InlineKeyboardButton(
|
544 |
-
text="Click to prove admin.",
|
545 |
-
callback_data=f"admin_=unpinall",
|
546 |
-
),
|
547 |
-
],
|
548 |
-
],
|
549 |
-
),
|
550 |
-
)
|
551 |
-
|
552 |
-
return
|
553 |
-
elif not admin_member.status == ChatMemberStatus.OWNER and user.id not in DRAGONS:
|
554 |
-
await message.reply_text("Only chat OWNER can unpin all messages.")
|
555 |
-
return
|
556 |
-
|
557 |
-
try:
|
558 |
-
if chat.is_forum:
|
559 |
-
await bot.unpin_all_forum_topic_messages(chat.id, message.message_thread_id)
|
560 |
-
else:
|
561 |
-
await bot.unpin_all_chat_messages(chat.id)
|
562 |
-
except BadRequest as excp:
|
563 |
-
if excp.message == "Chat_not_modified":
|
564 |
-
pass
|
565 |
-
else:
|
566 |
-
raise
|
567 |
-
|
568 |
-
log_message = (
|
569 |
-
f"{chat.title}:\n"
|
570 |
-
"#UNPINNED_ALL\n"
|
571 |
-
f"Admin: {mention_html(user.id, user.first_name)}"
|
572 |
-
)
|
573 |
-
|
574 |
-
return log_message
|
575 |
-
|
576 |
-
|
577 |
-
@connection_status
|
578 |
-
@check_admin(permission="can_invite_users", is_bot=True)
|
579 |
-
async def invite(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
580 |
-
bot = context.bot
|
581 |
-
chat = update.effective_chat
|
582 |
-
|
583 |
-
if chat.username:
|
584 |
-
await update.effective_message.reply_text(f"https://t.me/{chat.username}")
|
585 |
-
elif chat.type in [ChatType.SUPERGROUP, ChatType.CHANNEL]:
|
586 |
-
bot_member = await chat.get_member(bot.id)
|
587 |
-
if (
|
588 |
-
bot_member.can_invite_users
|
589 |
-
if isinstance(bot_member, ChatMemberAdministrator)
|
590 |
-
else None
|
591 |
-
):
|
592 |
-
invitelink = await bot.exportChatInviteLink(chat.id)
|
593 |
-
await update.effective_message.reply_text(invitelink)
|
594 |
-
else:
|
595 |
-
await update.effective_message.reply_text(
|
596 |
-
"I don't have access to the invite link, try changing my permissions!",
|
597 |
-
)
|
598 |
-
else:
|
599 |
-
await update.effective_message.reply_text(
|
600 |
-
"I can only give you invite links for supergroups and channels, sorry!",
|
601 |
-
)
|
602 |
-
|
603 |
-
|
604 |
-
@connection_status
|
605 |
-
async def adminlist(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
606 |
-
chat = update.effective_chat # type: Optional[Chat]
|
607 |
-
user = update.effective_user # type: Optional[User]
|
608 |
-
args = context.args
|
609 |
-
bot = context.bot
|
610 |
-
if update.effective_message.chat.type == "private":
|
611 |
-
await send_message(
|
612 |
-
update.effective_message, "This command only works in Groups."
|
613 |
-
)
|
614 |
-
return
|
615 |
-
chat = update.effective_chat
|
616 |
-
chat_id = update.effective_chat.id
|
617 |
-
chat_name = update.effective_message.chat.title
|
618 |
-
try:
|
619 |
-
msg = await update.effective_message.reply_text(
|
620 |
-
"Fetching group admins...", parse_mode=ParseMode.HTML
|
621 |
-
)
|
622 |
-
except BadRequest:
|
623 |
-
msg = await update.effective_message.reply_text(
|
624 |
-
"Fetching group admins...", quote=False, parse_mode=ParseMode.HTML
|
625 |
-
)
|
626 |
-
administrators = await bot.get_chat_administrators(chat_id)
|
627 |
-
administrators_list = list(administrators) # Convert to a list
|
628 |
-
text = "「 𝗔𝗗𝗠𝗜𝗡𝗦 𝗜𝗡 <b>{}</b>:".format(html.escape(update.effective_chat.title))
|
629 |
-
bot_admin_list = []
|
630 |
-
for admin in administrators_list:
|
631 |
-
user = admin.user
|
632 |
-
status = admin.status
|
633 |
-
custom_title = admin.custom_title
|
634 |
-
if user.first_name == "":
|
635 |
-
name = "☠ Deleted Account"
|
636 |
-
else:
|
637 |
-
name = "{}".format(
|
638 |
-
mention_html(
|
639 |
-
user.id, html.escape(user.first_name + " " + (user.last_name or ""))
|
640 |
-
)
|
641 |
-
)
|
642 |
-
if user.is_bot:
|
643 |
-
bot_admin_list.append(name)
|
644 |
-
administrators_list.remove(admin)
|
645 |
-
continue
|
646 |
-
if status == "creator":
|
647 |
-
text += "\n\n 👑 <b>Creator:</b>"
|
648 |
-
text += "\n<code> ╰─➽ </code>{}\n".format(name)
|
649 |
-
if custom_title:
|
650 |
-
text += f"<code> ┗━ {html.escape(custom_title)}</code>\n"
|
651 |
-
text += "\n🚓 <b>Admins:</b>"
|
652 |
-
custom_admin_list = {}
|
653 |
-
normal_admin_list = []
|
654 |
-
for admin in administrators_list:
|
655 |
-
user = admin.user
|
656 |
-
status = admin.status
|
657 |
-
custom_title = admin.custom_title
|
658 |
-
if user.first_name == "":
|
659 |
-
name = "☠ Deleted Account"
|
660 |
-
else:
|
661 |
-
name = "{}".format(
|
662 |
-
mention_html(
|
663 |
-
user.id, html.escape(user.first_name + " " + (user.last_name or ""))
|
664 |
-
)
|
665 |
-
)
|
666 |
-
if status == "administrator":
|
667 |
-
if custom_title:
|
668 |
-
try:
|
669 |
-
custom_admin_list[custom_title].append(name)
|
670 |
-
except KeyError:
|
671 |
-
custom_admin_list.update({custom_title: [name]})
|
672 |
-
else:
|
673 |
-
normal_admin_list.append(name)
|
674 |
-
for admin in normal_admin_list:
|
675 |
-
text += "\n<code> ╰─➽ </code>{}".format(admin)
|
676 |
-
for admin_group in custom_admin_list.copy():
|
677 |
-
if len(custom_admin_list[admin_group]) == 1:
|
678 |
-
text += "\n<code> ╰─➽ </code>{} | <code>{}</code>".format(
|
679 |
-
custom_admin_list[admin_group][0], html.escape(admin_group)
|
680 |
-
)
|
681 |
-
custom_admin_list.pop(admin_group)
|
682 |
-
text += "\n"
|
683 |
-
for admin_group in custom_admin_list:
|
684 |
-
text += "\n🚨 <code>{}</code>".format(admin_group)
|
685 |
-
for admin in custom_admin_list[admin_group]:
|
686 |
-
text += "\n<code> ╰─➽ </code>{}".format(admin)
|
687 |
-
text += "\n"
|
688 |
-
text += "\n🤖 <b>Bots:</b>"
|
689 |
-
for each_bot in bot_admin_list:
|
690 |
-
text += "\n<code> ╰─➽ </code>{}".format(each_bot)
|
691 |
-
try:
|
692 |
-
await msg.edit_text(text, parse_mode=ParseMode.HTML)
|
693 |
-
except BadRequest: # if the original message is deleted
|
694 |
-
return
|
695 |
-
|
696 |
-
|
697 |
-
@loggable
|
698 |
-
async def admin_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
699 |
-
query = update.callback_query
|
700 |
-
bot = context.bot
|
701 |
-
message = update.effective_message
|
702 |
-
chat = update.effective_chat
|
703 |
-
admin_user = query.from_user
|
704 |
-
|
705 |
-
splitter = query.data.replace("admin_", "").split("=")
|
706 |
-
|
707 |
-
if splitter[1] == "promote":
|
708 |
-
promoter = await chat.get_member(admin_user.id)
|
709 |
-
|
710 |
-
if (
|
711 |
-
not (
|
712 |
-
promoter.can_promote_members
|
713 |
-
if isinstance(promoter, ChatMemberAdministrator)
|
714 |
-
else None or promoter.status == ChatMemberStatus.OWNER
|
715 |
-
)
|
716 |
-
and admin_user.id not in DRAGONS
|
717 |
-
):
|
718 |
-
await query.answer(
|
719 |
-
"You don't have the necessary rights to do that!", show_alert=True
|
720 |
-
)
|
721 |
-
return
|
722 |
-
|
723 |
-
try:
|
724 |
-
user_id = int(splitter[2])
|
725 |
-
except ValueError:
|
726 |
-
user_id = splitter[2]
|
727 |
-
await message.edit_text(
|
728 |
-
"You don't seem to be referring to a user or the ID specified is incorrect..."
|
729 |
-
)
|
730 |
-
return
|
731 |
-
|
732 |
-
try:
|
733 |
-
user_member = await chat.get_member(user_id)
|
734 |
-
except:
|
735 |
-
return
|
736 |
-
|
737 |
-
if (
|
738 |
-
user_member.status == ChatMemberStatus.ADMINISTRATOR
|
739 |
-
or user_member.status == ChatMemberStatus.OWNER
|
740 |
-
):
|
741 |
-
await message.edit_text(
|
742 |
-
"How am I meant to promote someone that's already an admin?"
|
743 |
-
)
|
744 |
-
return
|
745 |
-
|
746 |
-
bot_member = await chat.get_member(bot.id)
|
747 |
-
|
748 |
-
if isinstance(bot_member, ChatMemberAdministrator):
|
749 |
-
try:
|
750 |
-
await bot.promoteChatMember(
|
751 |
-
chat.id,
|
752 |
-
user_id,
|
753 |
-
can_change_info=bot_member.can_change_info,
|
754 |
-
can_post_messages=bot_member.can_post_messages,
|
755 |
-
can_edit_messages=bot_member.can_edit_messages,
|
756 |
-
can_delete_messages=bot_member.can_delete_messages,
|
757 |
-
can_invite_users=bot_member.can_invite_users,
|
758 |
-
can_restrict_members=bot_member.can_restrict_members,
|
759 |
-
can_pin_messages=bot_member.can_pin_messages,
|
760 |
-
can_manage_chat=bot_member.can_manage_chat,
|
761 |
-
can_manage_video_chats=bot_member.can_manage_video_chats,
|
762 |
-
)
|
763 |
-
except BadRequest as err:
|
764 |
-
if err.message == "User_not_mutual_contact":
|
765 |
-
await message.edit_text(
|
766 |
-
"I can't promote someone who isn't in the group"
|
767 |
-
)
|
768 |
-
else:
|
769 |
-
await message.edit_text("An error occurred while promoting.")
|
770 |
-
return
|
771 |
-
|
772 |
-
await message.edit_text(
|
773 |
-
f"Successfully promoted <b>{user_member.user.first_name or user_id}</b>!",
|
774 |
-
parse_mode=ParseMode.HTML,
|
775 |
-
)
|
776 |
-
await query.answer("Done")
|
777 |
-
|
778 |
-
log_message = (
|
779 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
780 |
-
f"#PROMOTED\n"
|
781 |
-
f"<b>Admin:</b> {mention_html(admin_user.id, admin_user.first_name)}\n"
|
782 |
-
f"<b>User:</b> {mention_html(user_member.user.id, user_member.user.first_name)}"
|
783 |
-
)
|
784 |
-
|
785 |
-
return log_message
|
786 |
-
|
787 |
-
elif splitter[1] == "demote":
|
788 |
-
demoter = await chat.get_member(admin_user.id)
|
789 |
-
|
790 |
-
if not (
|
791 |
-
demoter.can_promote_members
|
792 |
-
if isinstance(demoter, ChatMemberAdministrator)
|
793 |
-
else None or demoter.status == ChatMemberStatus.OWNER
|
794 |
-
):
|
795 |
-
await query.answer(
|
796 |
-
"You don't have the necessary rights to do that!", show_alert=True
|
797 |
-
)
|
798 |
-
return
|
799 |
-
|
800 |
-
try:
|
801 |
-
user_id = int(splitter[2])
|
802 |
-
except:
|
803 |
-
user_id = splitter[2]
|
804 |
-
await message.edit_text(
|
805 |
-
"You don't seem to be referring to a user or the ID specified is incorrect.."
|
806 |
-
)
|
807 |
-
return
|
808 |
-
|
809 |
-
try:
|
810 |
-
user_member = await chat.get_member(user_id)
|
811 |
-
except:
|
812 |
-
return
|
813 |
-
|
814 |
-
if user_member.status == ChatMemberStatus.OWNER:
|
815 |
-
await message.edit_text(
|
816 |
-
"This person CREATED the chat, how would I demote them?"
|
817 |
-
)
|
818 |
-
return
|
819 |
-
|
820 |
-
if not user_member.status == ChatMemberStatus.ADMINISTRATOR:
|
821 |
-
await message.edit_text("Can't demote what wasn't promoted!")
|
822 |
-
return
|
823 |
-
|
824 |
-
if user_id == bot.id:
|
825 |
-
await message.edit_text(
|
826 |
-
"I can't demote myself!, get an admin to do it for me."
|
827 |
-
)
|
828 |
-
return
|
829 |
-
|
830 |
-
try:
|
831 |
-
await bot.promoteChatMember(
|
832 |
-
chat.id,
|
833 |
-
user_id,
|
834 |
-
can_change_info=False,
|
835 |
-
can_post_messages=False,
|
836 |
-
can_edit_messages=False,
|
837 |
-
can_delete_messages=False,
|
838 |
-
can_invite_users=False,
|
839 |
-
can_restrict_members=False,
|
840 |
-
can_pin_messages=False,
|
841 |
-
can_promote_members=False,
|
842 |
-
can_manage_chat=False,
|
843 |
-
can_manage_video_chats=False,
|
844 |
-
)
|
845 |
-
|
846 |
-
await message.edit_text(
|
847 |
-
f"Successfully demoted <b>{user_member.user.first_name or user_id}</b>!",
|
848 |
-
parse_mode=ParseMode.HTML,
|
849 |
-
)
|
850 |
-
await query.answer("Done")
|
851 |
-
|
852 |
-
log_message = (
|
853 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
854 |
-
f"#DEMOTE\n"
|
855 |
-
f"<b>Admin:</b> {mention_html(admin_user.id, admin_user.first_name)}\n"
|
856 |
-
f"<b>User:</b> {mention_html(user_member.user.id, user_member.user.first_name)}"
|
857 |
-
)
|
858 |
-
|
859 |
-
return log_message
|
860 |
-
except BadRequest:
|
861 |
-
await message.edit_text(
|
862 |
-
"Could not demote. I might not be admin, or the admin status was appointed by another"
|
863 |
-
" user, so I can't act upon them!"
|
864 |
-
)
|
865 |
-
return
|
866 |
-
|
867 |
-
elif splitter[1] == "title":
|
868 |
-
title = splitter[3]
|
869 |
-
|
870 |
-
admin_member = await chat.get_member(admin_user.id)
|
871 |
-
|
872 |
-
if (
|
873 |
-
not (
|
874 |
-
(
|
875 |
-
admin_member.can_promote_members
|
876 |
-
if isinstance(admin_member, ChatMemberAdministrator)
|
877 |
-
else None
|
878 |
-
)
|
879 |
-
or admin_member.status == ChatMemberStatus.OWNER
|
880 |
-
)
|
881 |
-
and admin_user.id not in DRAGONS
|
882 |
-
):
|
883 |
-
await query.answer("You don't have the necessary rights to do that!")
|
884 |
-
return
|
885 |
-
|
886 |
-
try:
|
887 |
-
user_id = int(splitter[2])
|
888 |
-
except:
|
889 |
-
await message.edit_text(
|
890 |
-
"You don't seem to be referring to a user or the ID specified is incorrect...",
|
891 |
-
)
|
892 |
-
return
|
893 |
-
|
894 |
-
try:
|
895 |
-
user_member = await chat.get_member(user_id)
|
896 |
-
except:
|
897 |
-
return
|
898 |
-
|
899 |
-
if user_member.status == ChatMemberStatus.OWNER:
|
900 |
-
await message.edit_text(
|
901 |
-
"This person CREATED the chat, how can I set a custom title for him?",
|
902 |
-
)
|
903 |
-
return
|
904 |
-
|
905 |
-
if user_member.status != ChatMemberStatus.ADMINISTRATOR:
|
906 |
-
await message.edit_text(
|
907 |
-
"Can't set a title for non-admins! Promote them first to set a custom title!",
|
908 |
-
)
|
909 |
-
return
|
910 |
-
|
911 |
-
if user_id == bot.id:
|
912 |
-
await message.edit_text(
|
913 |
-
"I can't set my own title myself! Get the one who made me admin to do it for me.",
|
914 |
-
)
|
915 |
-
return
|
916 |
-
|
917 |
-
if not title:
|
918 |
-
await message.edit_text("Setting a blank title doesn't do anything!")
|
919 |
-
return
|
920 |
-
|
921 |
-
if len(title) > 16:
|
922 |
-
await message.edit_text(
|
923 |
-
"The title length is longer than 16 characters. Truncating it to 16 characters.",
|
924 |
-
)
|
925 |
-
|
926 |
-
try:
|
927 |
-
await bot.setChatAdministratorCustomTitle(chat.id, user_id, title)
|
928 |
-
except BadRequest:
|
929 |
-
await message.edit_text(
|
930 |
-
"Either they aren't promoted by me or you set a title text that is impossible to set."
|
931 |
-
)
|
932 |
-
return
|
933 |
-
|
934 |
-
await message.edit_text(
|
935 |
-
text=f"Successfully set title for <code>{user_member.user.first_name or user_id}</code> "
|
936 |
-
f"to <code>{html.escape(title[:16])}</code>!",
|
937 |
-
parse_mode=ParseMode.HTML,
|
938 |
-
)
|
939 |
-
|
940 |
-
elif splitter[1] == "pin":
|
941 |
-
admin_member = await chat.get_member(admin_user.id)
|
942 |
-
|
943 |
-
if (
|
944 |
-
not (
|
945 |
-
(
|
946 |
-
admin_member.can_pin_messages
|
947 |
-
if isinstance(admin_member, ChatMemberAdministrator)
|
948 |
-
else None
|
949 |
-
)
|
950 |
-
or admin_member.status == ChatMemberStatus.OWNER
|
951 |
-
)
|
952 |
-
and admin_user.id not in DRAGONS
|
953 |
-
):
|
954 |
-
await query.answer(
|
955 |
-
"You don't have the necessary rights to do that!", show_alert=True
|
956 |
-
)
|
957 |
-
return
|
958 |
-
|
959 |
-
try:
|
960 |
-
message_id = int(splitter[2])
|
961 |
-
except:
|
962 |
-
return
|
963 |
-
|
964 |
-
is_silent = bool(splitter[3])
|
965 |
-
is_group = chat.type != "private" and chat.type != "channel"
|
966 |
-
|
967 |
-
if is_group:
|
968 |
-
try:
|
969 |
-
await bot.pinChatMessage(
|
970 |
-
chat.id,
|
971 |
-
message_id,
|
972 |
-
disable_notification=is_silent,
|
973 |
-
)
|
974 |
-
except BadRequest as excp:
|
975 |
-
if excp.message == "Chat_not_modified":
|
976 |
-
pass
|
977 |
-
else:
|
978 |
-
raise
|
979 |
-
|
980 |
-
await message.edit_text("Done Pinned.")
|
981 |
-
|
982 |
-
log_message = (
|
983 |
-
f"<b>{html.escape(chat.title)}</b>\n"
|
984 |
-
f"#PINNED\n"
|
985 |
-
f"<b>Admin:</b> {mention_html(admin_user.id, html.escape(admin_user.first_name))}"
|
986 |
-
)
|
987 |
-
|
988 |
-
return log_message
|
989 |
-
|
990 |
-
elif splitter[1] == "unpin":
|
991 |
-
admin_member = await chat.get_member(admin_user.id)
|
992 |
-
|
993 |
-
if (
|
994 |
-
not (
|
995 |
-
(
|
996 |
-
admin_member.can_pin_messages
|
997 |
-
if isinstance(admin_member, ChatMemberAdministrator)
|
998 |
-
else None
|
999 |
-
)
|
1000 |
-
or admin_member.status == ChatMemberStatus.OWNER
|
1001 |
-
)
|
1002 |
-
and admin_user.id not in DRAGONS
|
1003 |
-
):
|
1004 |
-
await query.answer(
|
1005 |
-
"You don't have the necessary rights to do that!",
|
1006 |
-
show_alert=True,
|
1007 |
-
)
|
1008 |
-
return
|
1009 |
-
|
1010 |
-
try:
|
1011 |
-
await bot.unpinChatMessage(chat.id)
|
1012 |
-
except BadRequest as excp:
|
1013 |
-
if excp.message == "Chat_not_modified":
|
1014 |
-
pass
|
1015 |
-
elif excp.message == "Message_to_unpin_not_found":
|
1016 |
-
await message.edit_text("No pinned message found")
|
1017 |
-
return
|
1018 |
-
else:
|
1019 |
-
raise
|
1020 |
-
|
1021 |
-
log_message = (
|
1022 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
1023 |
-
f"#UNPINNED\n"
|
1024 |
-
f"<b>Admin:</b> {mention_html(admin_user.id, html.escape(admin_user.first_name))}"
|
1025 |
-
)
|
1026 |
-
|
1027 |
-
return log_message
|
1028 |
-
|
1029 |
-
elif splitter[1] == "unpinall":
|
1030 |
-
admin_member = await chat.get_member(admin_user.id)
|
1031 |
-
|
1032 |
-
if (
|
1033 |
-
not admin_member.status == ChatMemberStatus.OWNER
|
1034 |
-
and admin_user.id not in DRAGONS
|
1035 |
-
):
|
1036 |
-
await query.answer("Only chat OWNER can unpin all messages.")
|
1037 |
-
return
|
1038 |
-
|
1039 |
-
try:
|
1040 |
-
if chat.is_forum:
|
1041 |
-
await bot.unpin_all_forum_topic_messages(
|
1042 |
-
chat.id, message.message_thread_id
|
1043 |
-
)
|
1044 |
-
else:
|
1045 |
-
await bot.unpin_all_chat_messages(chat.id)
|
1046 |
-
except BadRequest as excp:
|
1047 |
-
if excp.message == "Chat_not_modified":
|
1048 |
-
pass
|
1049 |
-
else:
|
1050 |
-
raise
|
1051 |
-
|
1052 |
-
await message.edit_text("Done unpinning all messages.")
|
1053 |
-
log_message = (
|
1054 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
1055 |
-
f"#UNPINNED-ALL\n"
|
1056 |
-
f"<b>ADMIN:</b> {mention_html(admin_user.id, html.escape(admin_user.first_name))}"
|
1057 |
-
)
|
1058 |
-
|
1059 |
-
return log_message
|
1060 |
-
|
1061 |
-
|
1062 |
-
# <=================================================== HELP ====================================================>
|
1063 |
-
|
1064 |
-
|
1065 |
-
__help__ = """
|
1066 |
-
» /adminlist: List of admins in the chat.
|
1067 |
-
|
1068 |
-
➠ *Admins only:*
|
1069 |
-
|
1070 |
-
» /pin: Silently pins the message replied to. Add 'loud' or 'notify' to give notifications to users.
|
1071 |
-
|
1072 |
-
» /unpin: Unpins the currently pinned message.
|
1073 |
-
|
1074 |
-
» /unpinall: Unpins all the pinned messages. Works in topics too (only OWNER can do this).
|
1075 |
-
|
1076 |
-
» /invitelink: Get an invite link.
|
1077 |
-
|
1078 |
-
» /promote: Promotes the user replied to.
|
1079 |
-
|
1080 |
-
» /fullpromote: FullPromotes the user replied to.
|
1081 |
-
|
1082 |
-
» /demote: Demotes the user replied to.
|
1083 |
-
|
1084 |
-
» /title <Title here>: Sets a custom title for an admin that the bot promoted.
|
1085 |
-
|
1086 |
-
» /admincache: Force refresh the admins list.
|
1087 |
-
"""
|
1088 |
-
|
1089 |
-
# <================================================ HANDLER =======================================================>
|
1090 |
-
ADMINLIST_HANDLER = DisableAbleCommandHandler("adminlist", adminlist, block=False)
|
1091 |
-
|
1092 |
-
PIN_HANDLER = CommandHandler("pin", pin, filters=filters.ChatType.GROUPS, block=False)
|
1093 |
-
UNPIN_HANDLER = CommandHandler(
|
1094 |
-
"unpin", unpin, filters=filters.ChatType.GROUPS, block=False
|
1095 |
-
)
|
1096 |
-
UNPINALL_HANDLER = CommandHandler(
|
1097 |
-
"unpinall", unpinall, filters=filters.ChatType.GROUPS, block=False
|
1098 |
-
)
|
1099 |
-
|
1100 |
-
INVITE_HANDLER = DisableAbleCommandHandler("invitelink", invite, block=False)
|
1101 |
-
|
1102 |
-
PROMOTE_HANDLER = DisableAbleCommandHandler("promote", promote, block=False)
|
1103 |
-
FULLPROMOTE_HANDLER = DisableAbleCommandHandler("fullpromote", fullpromote, block=False)
|
1104 |
-
DEMOTE_HANDLER = DisableAbleCommandHandler("demote", demote, block=False)
|
1105 |
-
|
1106 |
-
SET_TITLE_HANDLER = CommandHandler("title", set_title, block=False)
|
1107 |
-
ADMIN_REFRESH_HANDLER = CommandHandler(
|
1108 |
-
"admincache", refresh_admin, filters=filters.ChatType.GROUPS, block=False
|
1109 |
-
)
|
1110 |
-
ADMIN_CALLBACK_HANDLER = CallbackQueryHandler(
|
1111 |
-
admin_callback, block=False, pattern=r"admin_"
|
1112 |
-
)
|
1113 |
-
|
1114 |
-
function(ADMINLIST_HANDLER)
|
1115 |
-
function(PIN_HANDLER)
|
1116 |
-
function(UNPIN_HANDLER)
|
1117 |
-
function(UNPINALL_HANDLER)
|
1118 |
-
function(INVITE_HANDLER)
|
1119 |
-
function(PROMOTE_HANDLER)
|
1120 |
-
function(FULLPROMOTE_HANDLER)
|
1121 |
-
function(DEMOTE_HANDLER)
|
1122 |
-
function(SET_TITLE_HANDLER)
|
1123 |
-
function(ADMIN_REFRESH_HANDLER)
|
1124 |
-
function(ADMIN_CALLBACK_HANDLER)
|
1125 |
-
|
1126 |
-
__mod_name__ = "ADMIN"
|
1127 |
-
__command_list__ = [
|
1128 |
-
"adminlist",
|
1129 |
-
"admins",
|
1130 |
-
"invitelink",
|
1131 |
-
"promote",
|
1132 |
-
"demote",
|
1133 |
-
"admincache",
|
1134 |
-
"fullpromote",
|
1135 |
-
"setgpic",
|
1136 |
-
"delgpic",
|
1137 |
-
]
|
1138 |
-
__handlers__ = [
|
1139 |
-
ADMINLIST_HANDLER,
|
1140 |
-
PIN_HANDLER,
|
1141 |
-
UNPIN_HANDLER,
|
1142 |
-
INVITE_HANDLER,
|
1143 |
-
PROMOTE_HANDLER,
|
1144 |
-
DEMOTE_HANDLER,
|
1145 |
-
SET_TITLE_HANDLER,
|
1146 |
-
ADMIN_REFRESH_HANDLER,
|
1147 |
-
]
|
1148 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/afk.py
DELETED
@@ -1,215 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import html
|
3 |
-
import random
|
4 |
-
from datetime import datetime
|
5 |
-
|
6 |
-
import humanize
|
7 |
-
from telegram import MessageEntity, Update
|
8 |
-
from telegram.error import BadRequest
|
9 |
-
from telegram.ext import ContextTypes, MessageHandler, filters
|
10 |
-
|
11 |
-
from Database.sql import afk_sql as sql
|
12 |
-
from Mikobot import LOGGER, function
|
13 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler, DisableAbleMessageHandler
|
14 |
-
from Mikobot.plugins.users import get_user_id
|
15 |
-
|
16 |
-
# <=======================================================================================================>
|
17 |
-
|
18 |
-
AFK_GROUP = 7
|
19 |
-
AFK_REPLY_GROUP = 8
|
20 |
-
|
21 |
-
|
22 |
-
# <================================================ FUNCTION =======================================================>
|
23 |
-
async def afk(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
24 |
-
if update.effective_message.text:
|
25 |
-
args = update.effective_message.text.split(None, 1)
|
26 |
-
else:
|
27 |
-
return
|
28 |
-
user = update.effective_user
|
29 |
-
|
30 |
-
if not user: # ignore channels
|
31 |
-
return
|
32 |
-
|
33 |
-
notice = ""
|
34 |
-
if len(args) >= 2:
|
35 |
-
reason = args[1]
|
36 |
-
if len(reason) > 100:
|
37 |
-
reason = reason[:100]
|
38 |
-
notice = "\nYour afk reason was shortened to 100 characters."
|
39 |
-
else:
|
40 |
-
reason = ""
|
41 |
-
|
42 |
-
sql.set_afk(update.effective_user.id, reason)
|
43 |
-
fname = update.effective_user.first_name
|
44 |
-
try:
|
45 |
-
if reason:
|
46 |
-
await update.effective_message.reply_text(
|
47 |
-
f"➲ {fname} is now away! \n\n➦ Reason: <code>{reason}</code> \n {notice}",
|
48 |
-
parse_mode="html",
|
49 |
-
)
|
50 |
-
else:
|
51 |
-
await update.effective_message.reply_text(
|
52 |
-
"➲ {} is now away!{}".format(fname, notice),
|
53 |
-
)
|
54 |
-
except BadRequest:
|
55 |
-
pass
|
56 |
-
|
57 |
-
|
58 |
-
async def no_longer_afk(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
59 |
-
user = update.effective_user
|
60 |
-
message = update.effective_message
|
61 |
-
|
62 |
-
if not user: # ignore channels
|
63 |
-
return
|
64 |
-
|
65 |
-
if sql.is_afk(user.id):
|
66 |
-
afk_user = sql.check_afk_status(user.id)
|
67 |
-
|
68 |
-
time = humanize.naturaldelta(datetime.now() - afk_user.time)
|
69 |
-
|
70 |
-
res = sql.rm_afk(user.id)
|
71 |
-
if res:
|
72 |
-
if message.new_chat_members: # dont say msg
|
73 |
-
return
|
74 |
-
firstname = update.effective_user.first_name
|
75 |
-
try:
|
76 |
-
options = [
|
77 |
-
"➲ {} is here!",
|
78 |
-
"➲ {} is back!",
|
79 |
-
"➲ {} is now in the chat!",
|
80 |
-
"➲ {} is awake!",
|
81 |
-
"➲ {} is back online!",
|
82 |
-
"➲ {} is finally here!",
|
83 |
-
"➲ Welcome back! {}",
|
84 |
-
]
|
85 |
-
chosen_option = random.choice(options)
|
86 |
-
await update.effective_message.reply_text(
|
87 |
-
chosen_option.format(firstname)
|
88 |
-
+ f"\n\nYou were AFK for: <code>{time}</code>",
|
89 |
-
parse_mode="html",
|
90 |
-
)
|
91 |
-
except:
|
92 |
-
return
|
93 |
-
|
94 |
-
|
95 |
-
async def reply_afk(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
96 |
-
bot = context.bot
|
97 |
-
message = update.effective_message
|
98 |
-
userc = update.effective_user
|
99 |
-
userc_id = userc.id
|
100 |
-
if message.entities and message.parse_entities(
|
101 |
-
[MessageEntity.TEXT_MENTION, MessageEntity.MENTION],
|
102 |
-
):
|
103 |
-
entities = message.parse_entities(
|
104 |
-
[MessageEntity.TEXT_MENTION, MessageEntity.MENTION],
|
105 |
-
)
|
106 |
-
|
107 |
-
chk_users = []
|
108 |
-
for ent in entities:
|
109 |
-
if ent.type == MessageEntity.TEXT_MENTION:
|
110 |
-
user_id = ent.user.id
|
111 |
-
fst_name = ent.user.first_name
|
112 |
-
|
113 |
-
if user_id in chk_users:
|
114 |
-
return
|
115 |
-
chk_users.append(user_id)
|
116 |
-
|
117 |
-
if ent.type != MessageEntity.MENTION:
|
118 |
-
return
|
119 |
-
|
120 |
-
user_id = await get_user_id(
|
121 |
-
message.text[ent.offset : ent.offset + ent.length],
|
122 |
-
)
|
123 |
-
if not user_id:
|
124 |
-
return
|
125 |
-
|
126 |
-
if user_id in chk_users:
|
127 |
-
return
|
128 |
-
chk_users.append(user_id)
|
129 |
-
|
130 |
-
try:
|
131 |
-
chat = await bot.get_chat(user_id)
|
132 |
-
except BadRequest:
|
133 |
-
LOGGER.error(
|
134 |
-
"Error: Could not fetch userid {} for AFK module".format(user_id)
|
135 |
-
)
|
136 |
-
return
|
137 |
-
fst_name = chat.first_name
|
138 |
-
|
139 |
-
await check_afk(update, context, user_id, fst_name, userc_id)
|
140 |
-
|
141 |
-
elif message.reply_to_message:
|
142 |
-
user_id = message.reply_to_message.from_user.id
|
143 |
-
fst_name = message.reply_to_message.from_user.first_name
|
144 |
-
await check_afk(update, context, user_id, fst_name, userc_id)
|
145 |
-
|
146 |
-
|
147 |
-
async def check_afk(
|
148 |
-
update: Update,
|
149 |
-
context: ContextTypes.DEFAULT_TYPE,
|
150 |
-
user_id: int,
|
151 |
-
fst_name: str,
|
152 |
-
userc_id: int,
|
153 |
-
):
|
154 |
-
if sql.is_afk(user_id):
|
155 |
-
user = sql.check_afk_status(user_id)
|
156 |
-
|
157 |
-
if int(userc_id) == int(user_id):
|
158 |
-
return
|
159 |
-
|
160 |
-
time = humanize.naturaldelta(datetime.now() - user.time)
|
161 |
-
|
162 |
-
if not user.reason:
|
163 |
-
res = "➲ {} is afk.\n\n➦ Last seen {} ago.".format(
|
164 |
-
fst_name,
|
165 |
-
time,
|
166 |
-
)
|
167 |
-
await update.effective_message.reply_text(res)
|
168 |
-
else:
|
169 |
-
res = (
|
170 |
-
"➲ {} is afk.\n\n➦ Reason: <code>{}</code>\n➦ Last seen {} ago.".format(
|
171 |
-
html.escape(fst_name),
|
172 |
-
html.escape(user.reason),
|
173 |
-
time,
|
174 |
-
)
|
175 |
-
)
|
176 |
-
await update.effective_message.reply_text(res, parse_mode="html")
|
177 |
-
|
178 |
-
|
179 |
-
# <=================================================== HELP ====================================================>
|
180 |
-
|
181 |
-
|
182 |
-
__help__ = """
|
183 |
-
» /afk <reason>*:* mark yourself as AFK (away from keyboard).
|
184 |
-
|
185 |
-
» brb , !afk <reason>*:* same as the afk command - but not a command.
|
186 |
-
|
187 |
-
➠ *When marked as AFK, any mentions will be replied to with a message to say you're not available!*
|
188 |
-
"""
|
189 |
-
|
190 |
-
# <================================================ HANDLER =======================================================>
|
191 |
-
AFK_HANDLER = DisableAbleCommandHandler("afk", afk, block=False)
|
192 |
-
AFK_REGEX_HANDLER = DisableAbleMessageHandler(
|
193 |
-
filters.Regex(r"^(?i:(brb|!afk))( .*)?$"), afk, friendly="afk", block=False
|
194 |
-
)
|
195 |
-
NO_AFK_HANDLER = MessageHandler(
|
196 |
-
filters.ALL & filters.ChatType.GROUPS, no_longer_afk, block=False
|
197 |
-
)
|
198 |
-
AFK_REPLY_HANDLER = MessageHandler(
|
199 |
-
filters.ALL & filters.ChatType.GROUPS, reply_afk, block=False
|
200 |
-
)
|
201 |
-
|
202 |
-
function(AFK_HANDLER, AFK_GROUP)
|
203 |
-
function(AFK_REGEX_HANDLER, AFK_GROUP)
|
204 |
-
function(NO_AFK_HANDLER, AFK_GROUP)
|
205 |
-
function(AFK_REPLY_HANDLER, AFK_REPLY_GROUP)
|
206 |
-
|
207 |
-
__mod_name__ = "AFK"
|
208 |
-
__command_list__ = ["afk"]
|
209 |
-
__handlers__ = [
|
210 |
-
(AFK_HANDLER, AFK_GROUP),
|
211 |
-
(AFK_REGEX_HANDLER, AFK_GROUP),
|
212 |
-
(NO_AFK_HANDLER, AFK_GROUP),
|
213 |
-
(AFK_REPLY_HANDLER, AFK_REPLY_GROUP),
|
214 |
-
]
|
215 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/ai.py
DELETED
@@ -1,141 +0,0 @@
|
|
1 |
-
# CREATED BY: https://t.me/O_oKarma
|
2 |
-
# API CREDITS: @Qewertyy
|
3 |
-
# PROVIDED BY: https://github.com/Team-ProjectCodeX
|
4 |
-
|
5 |
-
# <============================================== IMPORTS =========================================================>
|
6 |
-
import base64
|
7 |
-
|
8 |
-
from telegram import Update
|
9 |
-
from telegram.constants import ParseMode
|
10 |
-
from telegram.ext import CommandHandler, ContextTypes
|
11 |
-
|
12 |
-
from Mikobot import LOGGER as logger
|
13 |
-
from Mikobot import function
|
14 |
-
from Mikobot.state import state
|
15 |
-
|
16 |
-
# <=======================================================================================================>
|
17 |
-
|
18 |
-
# <================================================ CONSTANTS =====================================================>
|
19 |
-
API_URL = "https://lexica.qewertyy.me/models"
|
20 |
-
PALM_MODEL_ID = 0
|
21 |
-
GPT_MODEL_ID = 5
|
22 |
-
|
23 |
-
# <================================================ FUNCTIONS =====================================================>
|
24 |
-
|
25 |
-
|
26 |
-
async def get_api_response(model_id, api_params, api_url):
|
27 |
-
try:
|
28 |
-
response = await state.post(api_url, params=api_params)
|
29 |
-
if response.status_code == 200:
|
30 |
-
data = response.json()
|
31 |
-
return data.get(
|
32 |
-
"content", f"Error: Empty response received from the {model_id} API."
|
33 |
-
)
|
34 |
-
else:
|
35 |
-
return f"Error: Request failed with status code {response.status_code}."
|
36 |
-
except state.RequestError as e:
|
37 |
-
return f"Error: An error occurred while calling the {model_id} API. {e}"
|
38 |
-
|
39 |
-
|
40 |
-
async def palm_chatbot(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
41 |
-
args = context.args
|
42 |
-
if not args:
|
43 |
-
await context.bot.send_message(
|
44 |
-
chat_id=update.effective_chat.id,
|
45 |
-
text="Error: Missing input text after /palm command.",
|
46 |
-
)
|
47 |
-
return
|
48 |
-
|
49 |
-
input_text = " ".join(args)
|
50 |
-
|
51 |
-
result_msg = await context.bot.send_message(
|
52 |
-
chat_id=update.effective_chat.id, text="🌴"
|
53 |
-
)
|
54 |
-
|
55 |
-
api_params = {"model_id": PALM_MODEL_ID, "prompt": input_text}
|
56 |
-
api_response = await get_api_response("PALM", api_params, API_URL)
|
57 |
-
|
58 |
-
await result_msg.delete()
|
59 |
-
await context.bot.send_message(chat_id=update.effective_chat.id, text=api_response)
|
60 |
-
|
61 |
-
|
62 |
-
async def gpt_chatbot(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
63 |
-
args = context.args
|
64 |
-
if not args:
|
65 |
-
await context.bot.send_message(
|
66 |
-
chat_id=update.effective_chat.id,
|
67 |
-
text="Error: Missing input text after /askgpt command.",
|
68 |
-
)
|
69 |
-
return
|
70 |
-
|
71 |
-
input_text = " ".join(args)
|
72 |
-
|
73 |
-
result_msg = await context.bot.send_message(
|
74 |
-
chat_id=update.effective_chat.id, text="💬"
|
75 |
-
)
|
76 |
-
|
77 |
-
api_params = {"model_id": GPT_MODEL_ID, "prompt": input_text}
|
78 |
-
api_response = await get_api_response("GPT", api_params, API_URL)
|
79 |
-
|
80 |
-
await result_msg.delete()
|
81 |
-
await context.bot.send_message(chat_id=update.effective_chat.id, text=api_response)
|
82 |
-
|
83 |
-
|
84 |
-
# Define the upscale_image function
|
85 |
-
async def upscale_image(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
86 |
-
try:
|
87 |
-
# Check if the replied message contains a photo
|
88 |
-
if update.message.reply_to_message and update.message.reply_to_message.photo:
|
89 |
-
# Send a message indicating upscaling is in progress
|
90 |
-
progress_msg = await update.message.reply_text(
|
91 |
-
"Upscaling your image, please wait..."
|
92 |
-
)
|
93 |
-
|
94 |
-
# Access the image file_id from the replied message
|
95 |
-
image = await update.message.reply_to_message.photo[-1].get_file()
|
96 |
-
|
97 |
-
# Download the image and save it
|
98 |
-
image_path = await image.download_to_drive()
|
99 |
-
|
100 |
-
with open(image_path, "rb") as image_file:
|
101 |
-
f = image_file.read()
|
102 |
-
|
103 |
-
b = base64.b64encode(f).decode("utf-8")
|
104 |
-
|
105 |
-
response = await state.post(
|
106 |
-
"https://lexica.qewertyy.me/upscale",
|
107 |
-
data={"image_data": b},
|
108 |
-
)
|
109 |
-
|
110 |
-
# Save the upscaled image
|
111 |
-
upscaled_file_path = "upscaled_image.png"
|
112 |
-
with open(upscaled_file_path, "wb") as output_file:
|
113 |
-
output_file.write(response.content)
|
114 |
-
|
115 |
-
# Delete the progress message
|
116 |
-
await context.bot.delete_message(
|
117 |
-
chat_id=update.message.chat_id, message_id=progress_msg.message_id
|
118 |
-
)
|
119 |
-
|
120 |
-
# Send the upscaled image as a PNG file
|
121 |
-
await update.message.reply_document(
|
122 |
-
document=open(upscaled_file_path, "rb"),
|
123 |
-
caption=f"<b>Upscaled your image.</b>\n<b>Generated By:</b> @{context.bot.username}",
|
124 |
-
parse_mode=ParseMode.HTML,
|
125 |
-
)
|
126 |
-
else:
|
127 |
-
await update.message.reply_text("Please reply to an image to upscale it.")
|
128 |
-
|
129 |
-
except Exception as e:
|
130 |
-
logger.error(f"Failed to upscale the image: {e}")
|
131 |
-
await update.message.reply_text(
|
132 |
-
"Failed to upscale the image. Please try again later."
|
133 |
-
)
|
134 |
-
|
135 |
-
|
136 |
-
# <================================================ HANDLER =======================================================>
|
137 |
-
# Register the upscale_image command handler
|
138 |
-
function(CommandHandler("upscale", upscale_image, block=False))
|
139 |
-
function(CommandHandler("palm", palm_chatbot, block=False))
|
140 |
-
function(CommandHandler("askgpt", gpt_chatbot, block=False))
|
141 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/alive.py
DELETED
@@ -1,57 +0,0 @@
|
|
1 |
-
# SOURCE https://github.com/Team-ProjectCodeX
|
2 |
-
# CREATED BY https://t.me/O_okarma
|
3 |
-
# PROVIDED BY https://t.me/ProjectCodeX
|
4 |
-
|
5 |
-
# <============================================== IMPORTS =========================================================>
|
6 |
-
import random
|
7 |
-
from sys import version_info
|
8 |
-
|
9 |
-
import pyrogram
|
10 |
-
import telegram
|
11 |
-
import telethon
|
12 |
-
from pyrogram import filters
|
13 |
-
from pyrogram.types import InlineKeyboardMarkup, Message
|
14 |
-
|
15 |
-
from Infamous.karma import ALIVE_ANIMATION, ALIVE_BTN
|
16 |
-
from Mikobot import BOT_NAME, app
|
17 |
-
|
18 |
-
# <=======================================================================================================>
|
19 |
-
|
20 |
-
|
21 |
-
# <================================================ FUNCTION =======================================================>
|
22 |
-
@app.on_message(filters.command("alive"))
|
23 |
-
async def alive(_, message: Message):
|
24 |
-
library_versions = {
|
25 |
-
"PTB": telegram.__version__,
|
26 |
-
"TELETHON": telethon.__version__,
|
27 |
-
"PYROGRAM": pyrogram.__version__,
|
28 |
-
}
|
29 |
-
|
30 |
-
library_versions_text = "\n".join(
|
31 |
-
[f"➲ **{key}:** `{value}`" for key, value in library_versions.items()]
|
32 |
-
)
|
33 |
-
|
34 |
-
caption = f"""**HEY, I AM {BOT_NAME}**
|
35 |
-
|
36 |
-
━━━━━━ 🌟✿🌟 ━━━━━━
|
37 |
-
✪ **CREATOR:** [🄺🄰🅁🄼🄰](https://t.me/anime_Freakz)
|
38 |
-
|
39 |
-
{library_versions_text}
|
40 |
-
|
41 |
-
➲ **PYTHON:** `{version_info[0]}.{version_info[1]}.{version_info[2]}`
|
42 |
-
➲ **BOT VERSION:** `2.0`
|
43 |
-
━━━━━━ 🌟✿🌟 ━━━━━━"""
|
44 |
-
|
45 |
-
await message.reply_animation(
|
46 |
-
random.choice(ALIVE_ANIMATION),
|
47 |
-
caption=caption,
|
48 |
-
reply_markup=InlineKeyboardMarkup(ALIVE_BTN),
|
49 |
-
)
|
50 |
-
|
51 |
-
|
52 |
-
# <=======================================================================================================>
|
53 |
-
|
54 |
-
|
55 |
-
# <================================================ NAME =======================================================>
|
56 |
-
__mod_name__ = "ALIVE"
|
57 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/anime.py
DELETED
The diff for this file is too large to render.
See raw diff
|
|
Mikobot/plugins/antinsfw.py
DELETED
@@ -1,189 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from os import remove
|
3 |
-
|
4 |
-
from pyrogram import filters
|
5 |
-
|
6 |
-
from Database.mongodb.toggle_mongo import is_nsfw_on, nsfw_off, nsfw_on
|
7 |
-
from Mikobot import BOT_USERNAME, DRAGONS, app
|
8 |
-
from Mikobot.state import arq
|
9 |
-
from Mikobot.utils.can_restrict import can_restrict
|
10 |
-
from Mikobot.utils.errors import capture_err
|
11 |
-
|
12 |
-
# <=======================================================================================================>
|
13 |
-
|
14 |
-
|
15 |
-
# <================================================ FUNCTION =======================================================>
|
16 |
-
async def get_file_id_from_message(message):
|
17 |
-
file_id = None
|
18 |
-
if message.document:
|
19 |
-
if int(message.document.file_size) > 3145728:
|
20 |
-
return
|
21 |
-
mime_type = message.document.mime_type
|
22 |
-
if mime_type not in ("image/png", "image/jpeg"):
|
23 |
-
return
|
24 |
-
file_id = message.document.file_id
|
25 |
-
|
26 |
-
if message.sticker:
|
27 |
-
if message.sticker.is_animated:
|
28 |
-
if not message.sticker.thumbs:
|
29 |
-
return
|
30 |
-
file_id = message.sticker.thumbs[0].file_id
|
31 |
-
else:
|
32 |
-
file_id = message.sticker.file_id
|
33 |
-
|
34 |
-
if message.photo:
|
35 |
-
file_id = message.photo.file_id
|
36 |
-
|
37 |
-
if message.animation:
|
38 |
-
if not message.animation.thumbs:
|
39 |
-
return
|
40 |
-
file_id = message.animation.thumbs[0].file_id
|
41 |
-
|
42 |
-
if message.video:
|
43 |
-
if not message.video.thumbs:
|
44 |
-
return
|
45 |
-
file_id = message.video.thumbs[0].file_id
|
46 |
-
return file_id
|
47 |
-
|
48 |
-
|
49 |
-
@app.on_message(
|
50 |
-
(
|
51 |
-
filters.document
|
52 |
-
| filters.photo
|
53 |
-
| filters.sticker
|
54 |
-
| filters.animation
|
55 |
-
| filters.video
|
56 |
-
)
|
57 |
-
& ~filters.private,
|
58 |
-
group=8,
|
59 |
-
)
|
60 |
-
@capture_err
|
61 |
-
async def detect_nsfw(_, message):
|
62 |
-
if not await is_nsfw_on(message.chat.id):
|
63 |
-
return
|
64 |
-
if not message.from_user:
|
65 |
-
return
|
66 |
-
file_id = await get_file_id_from_message(message)
|
67 |
-
if not file_id:
|
68 |
-
return
|
69 |
-
file = await _.download_media(file_id)
|
70 |
-
try:
|
71 |
-
results = await arq.nsfw_scan(file=file)
|
72 |
-
except Exception:
|
73 |
-
return
|
74 |
-
if not results.ok:
|
75 |
-
return
|
76 |
-
results = results.result
|
77 |
-
remove(file)
|
78 |
-
nsfw = results.is_nsfw
|
79 |
-
if message.from_user.id in DRAGONS:
|
80 |
-
return
|
81 |
-
if not nsfw:
|
82 |
-
return
|
83 |
-
try:
|
84 |
-
await message.delete()
|
85 |
-
except Exception:
|
86 |
-
return
|
87 |
-
await message.reply_text(
|
88 |
-
f"""
|
89 |
-
**🔞 NSFW Image Detected & Deleted Successfully!**
|
90 |
-
|
91 |
-
**✪ User:** {message.from_user.mention} [`{message.from_user.id}`]
|
92 |
-
**✪ Safe:** `{results.neutral} %`
|
93 |
-
**✪ Porn:** `{results.porn} %`
|
94 |
-
**✪ Adult:** `{results.sexy} %`
|
95 |
-
**✪ Hentai:** `{results.hentai} %`
|
96 |
-
**✪ Drawings:** `{results.drawings} %`
|
97 |
-
"""
|
98 |
-
)
|
99 |
-
|
100 |
-
|
101 |
-
@app.on_message(filters.command(["nsfwscan", f"nsfwscan@{BOT_USERNAME}"]))
|
102 |
-
@capture_err
|
103 |
-
async def nsfw_scan_command(_, message):
|
104 |
-
if not message.reply_to_message:
|
105 |
-
await message.reply_text(
|
106 |
-
"Reply to an image/document/sticker/animation to scan it."
|
107 |
-
)
|
108 |
-
return
|
109 |
-
reply = message.reply_to_message
|
110 |
-
if (
|
111 |
-
not reply.document
|
112 |
-
and not reply.photo
|
113 |
-
and not reply.sticker
|
114 |
-
and not reply.animation
|
115 |
-
and not reply.video
|
116 |
-
):
|
117 |
-
await message.reply_text(
|
118 |
-
"Reply to an image/document/sticker/animation to scan it."
|
119 |
-
)
|
120 |
-
return
|
121 |
-
m = await message.reply_text("Scanning")
|
122 |
-
file_id = await get_file_id_from_message(reply)
|
123 |
-
if not file_id:
|
124 |
-
return await m.edit("Something wrong happened.")
|
125 |
-
file = await _.download_media(file_id)
|
126 |
-
try:
|
127 |
-
results = await arq.nsfw_scan(file=file)
|
128 |
-
except Exception:
|
129 |
-
return
|
130 |
-
remove(file)
|
131 |
-
if not results.ok:
|
132 |
-
return await m.edit(results.result)
|
133 |
-
results = results.result
|
134 |
-
await m.edit(
|
135 |
-
f"""
|
136 |
-
**➢ Neutral:** `{results.neutral} %`
|
137 |
-
**➢ Porn:** `{results.porn} %`
|
138 |
-
**➢ Hentai:** `{results.hentai} %`
|
139 |
-
**➢ Sexy:** `{results.sexy} %`
|
140 |
-
**➢ Drawings:** `{results.drawings} %`
|
141 |
-
**➢ NSFW:** `{results.is_nsfw}`
|
142 |
-
"""
|
143 |
-
)
|
144 |
-
|
145 |
-
|
146 |
-
@app.on_message(
|
147 |
-
filters.command(["antinsfw", f"antinsfw@{BOT_USERNAME}"]) & ~filters.private
|
148 |
-
)
|
149 |
-
@can_restrict
|
150 |
-
async def nsfw_enable_disable(_, message):
|
151 |
-
if len(message.command) != 2:
|
152 |
-
await message.reply_text("Usage: /antinsfw [on/off]")
|
153 |
-
return
|
154 |
-
status = message.text.split(None, 1)[1].strip()
|
155 |
-
status = status.lower()
|
156 |
-
chat_id = message.chat.id
|
157 |
-
if status in ("on", "yes"):
|
158 |
-
if await is_nsfw_on(chat_id):
|
159 |
-
await message.reply_text("Antinsfw is already enabled.")
|
160 |
-
return
|
161 |
-
await nsfw_on(chat_id)
|
162 |
-
await message.reply_text(
|
163 |
-
"Enabled AntiNSFW System. I will Delete Messages Containing Inappropriate Content."
|
164 |
-
)
|
165 |
-
elif status in ("off", "no"):
|
166 |
-
if not await is_nsfw_on(chat_id):
|
167 |
-
await message.reply_text("Antinsfw is already disabled.")
|
168 |
-
return
|
169 |
-
await nsfw_off(chat_id)
|
170 |
-
await message.reply_text("Disabled AntiNSFW System.")
|
171 |
-
else:
|
172 |
-
await message.reply_text("Unknown Suffix, Use /antinsfw [on/off]")
|
173 |
-
|
174 |
-
|
175 |
-
# <=================================================== HELP ====================================================>
|
176 |
-
|
177 |
-
|
178 |
-
__mod_name__ = "ANTI-NSFW"
|
179 |
-
|
180 |
-
__help__ = """
|
181 |
-
*🔞 Helps in detecting NSFW material and removing it*.
|
182 |
-
|
183 |
-
➠ *Usage:*
|
184 |
-
|
185 |
-
» /antinsfw [on/off]: Enables Anti-NSFW system.
|
186 |
-
|
187 |
-
» /nsfwscan <reply to message>: Scans the file replied to.
|
188 |
-
"""
|
189 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/approve.py
DELETED
@@ -1,259 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import html
|
3 |
-
|
4 |
-
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
5 |
-
from telegram.constants import ChatMemberStatus, ParseMode
|
6 |
-
from telegram.error import BadRequest
|
7 |
-
from telegram.ext import CallbackQueryHandler, ContextTypes
|
8 |
-
from telegram.helpers import mention_html
|
9 |
-
|
10 |
-
import Database.sql.approve_sql as sql
|
11 |
-
from Mikobot import DRAGONS, dispatcher
|
12 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
13 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin
|
14 |
-
from Mikobot.plugins.helper_funcs.extraction import extract_user
|
15 |
-
from Mikobot.plugins.log_channel import loggable
|
16 |
-
|
17 |
-
# <=======================================================================================================>
|
18 |
-
|
19 |
-
|
20 |
-
# <================================================ FUNCTION =======================================================>
|
21 |
-
@loggable
|
22 |
-
@check_admin(is_user=True)
|
23 |
-
async def approve(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
24 |
-
message = update.effective_message
|
25 |
-
chat_title = message.chat.title
|
26 |
-
chat = update.effective_chat
|
27 |
-
args = context.args
|
28 |
-
user = update.effective_user
|
29 |
-
user_id = await extract_user(message, context, args)
|
30 |
-
if not user_id:
|
31 |
-
await message.reply_text(
|
32 |
-
"I don't know who you're talking about, you're going to need to specify a user!",
|
33 |
-
)
|
34 |
-
return ""
|
35 |
-
try:
|
36 |
-
member = await chat.get_member(user_id)
|
37 |
-
except BadRequest:
|
38 |
-
return ""
|
39 |
-
if member.status in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]:
|
40 |
-
await message.reply_text(
|
41 |
-
"User is already admin - locks, blocklists, and antiflood already don't apply to them.",
|
42 |
-
)
|
43 |
-
return ""
|
44 |
-
if sql.is_approved(message.chat_id, user_id):
|
45 |
-
await message.reply_text(
|
46 |
-
f"[{member.user.first_name}](tg://user?id={member.user.id}) is already approved in {chat_title}",
|
47 |
-
parse_mode=ParseMode.MARKDOWN,
|
48 |
-
)
|
49 |
-
return ""
|
50 |
-
sql.approve(message.chat_id, user_id)
|
51 |
-
await message.reply_text(
|
52 |
-
f"[{member.user.first_name}](tg://user?id={member.user.id}) has been approved in {chat_title}! They will now be ignored by automated admin actions like locks, blocklists, and antiflood.",
|
53 |
-
parse_mode=ParseMode.MARKDOWN,
|
54 |
-
)
|
55 |
-
log_message = (
|
56 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
57 |
-
f"#APPROVED\n"
|
58 |
-
f"<b>Admin:</b> {mention_html(user.id, user.first_name)}\n"
|
59 |
-
f"<b>User:</b> {mention_html(member.user.id, member.user.first_name)}"
|
60 |
-
)
|
61 |
-
|
62 |
-
return log_message
|
63 |
-
|
64 |
-
|
65 |
-
@loggable
|
66 |
-
@check_admin(is_user=True)
|
67 |
-
async def disapprove(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
68 |
-
message = update.effective_message
|
69 |
-
chat_title = message.chat.title
|
70 |
-
chat = update.effective_chat
|
71 |
-
args = context.args
|
72 |
-
user = update.effective_user
|
73 |
-
user_id = await extract_user(message, context, args)
|
74 |
-
if not user_id:
|
75 |
-
await message.reply_text(
|
76 |
-
"I don't know who you're talking about, you're going to need to specify a user!",
|
77 |
-
)
|
78 |
-
return ""
|
79 |
-
try:
|
80 |
-
member = await chat.get_member(user_id)
|
81 |
-
except BadRequest:
|
82 |
-
return ""
|
83 |
-
if member.status in [ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER]:
|
84 |
-
await message.reply_text("This user is an admin, they can't be unapproved.")
|
85 |
-
return ""
|
86 |
-
if not sql.is_approved(message.chat_id, user_id):
|
87 |
-
await message.reply_text(f"{member.user.first_name} isn't approved yet!")
|
88 |
-
return ""
|
89 |
-
sql.disapprove(message.chat_id, user_id)
|
90 |
-
await message.reply_text(
|
91 |
-
f"{member.user.first_name} is no longer approved in {chat_title}.",
|
92 |
-
)
|
93 |
-
log_message = (
|
94 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
95 |
-
f"#UNAPPROVED\n"
|
96 |
-
f"<b>Admin:</b> {mention_html(user.id, user.first_name)}\n"
|
97 |
-
f"<b>User:</b> {mention_html(member.user.id, member.user.first_name)}"
|
98 |
-
)
|
99 |
-
|
100 |
-
return log_message
|
101 |
-
|
102 |
-
|
103 |
-
@check_admin(is_user=True)
|
104 |
-
async def approved(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
105 |
-
message = update.effective_message
|
106 |
-
chat_title = message.chat.title
|
107 |
-
chat = update.effective_chat
|
108 |
-
msg = "The following users are approved.\n"
|
109 |
-
approved_users = sql.list_approved(message.chat_id)
|
110 |
-
|
111 |
-
if not approved_users:
|
112 |
-
await message.reply_text(f"No users are approved in {chat_title}.")
|
113 |
-
return ""
|
114 |
-
|
115 |
-
else:
|
116 |
-
for i in approved_users:
|
117 |
-
member = await chat.get_member(int(i.user_id))
|
118 |
-
msg += f"- `{i.user_id}`: {member.user['first_name']}\n"
|
119 |
-
|
120 |
-
await message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
|
121 |
-
|
122 |
-
|
123 |
-
@check_admin(is_user=True)
|
124 |
-
async def approval(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
125 |
-
message = update.effective_message
|
126 |
-
chat = update.effective_chat
|
127 |
-
args = context.args
|
128 |
-
user_id = await extract_user(message, context, args)
|
129 |
-
|
130 |
-
if not user_id:
|
131 |
-
await message.reply_text(
|
132 |
-
"I don't know who you're talking about, you're going to need to specify a user!",
|
133 |
-
)
|
134 |
-
return ""
|
135 |
-
member = await chat.get_member(int(user_id))
|
136 |
-
if sql.is_approved(message.chat_id, user_id):
|
137 |
-
await message.reply_text(
|
138 |
-
f"{member.user['first_name']} is an approved user. Locks, antiflood, and blocklists won't apply to them.",
|
139 |
-
)
|
140 |
-
else:
|
141 |
-
await message.reply_text(
|
142 |
-
f"{member.user['first_name']} is not an approved user. They are affected by normal commands.",
|
143 |
-
)
|
144 |
-
|
145 |
-
|
146 |
-
async def unapproveall(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
147 |
-
chat = update.effective_chat
|
148 |
-
user = update.effective_user
|
149 |
-
member = await chat.get_member(user.id)
|
150 |
-
|
151 |
-
approved_users = sql.list_approved(chat.id)
|
152 |
-
if not approved_users:
|
153 |
-
await update.effective_message.reply_text(
|
154 |
-
f"No users are approved in {chat.title}."
|
155 |
-
)
|
156 |
-
return
|
157 |
-
|
158 |
-
if member.status != ChatMemberStatus.OWNER and user.id not in DRAGONS:
|
159 |
-
await update.effective_message.reply_text(
|
160 |
-
"Only the chat owner can unapprove all users at once.",
|
161 |
-
)
|
162 |
-
else:
|
163 |
-
buttons = InlineKeyboardMarkup(
|
164 |
-
[
|
165 |
-
[
|
166 |
-
InlineKeyboardButton(
|
167 |
-
text="Unapprove all users",
|
168 |
-
callback_data="unapproveall_user",
|
169 |
-
),
|
170 |
-
],
|
171 |
-
[
|
172 |
-
InlineKeyboardButton(
|
173 |
-
text="Cancel",
|
174 |
-
callback_data="unapproveall_cancel",
|
175 |
-
),
|
176 |
-
],
|
177 |
-
],
|
178 |
-
)
|
179 |
-
await update.effective_message.reply_text(
|
180 |
-
f"Are you sure you would like to unapprove ALL users in {chat.title}? This action cannot be undone.",
|
181 |
-
reply_markup=buttons,
|
182 |
-
parse_mode=ParseMode.MARKDOWN,
|
183 |
-
)
|
184 |
-
|
185 |
-
|
186 |
-
async def unapproveall_btn(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
187 |
-
query = update.callback_query
|
188 |
-
chat = update.effective_chat
|
189 |
-
message = update.effective_message
|
190 |
-
member = await chat.get_member(query.from_user.id)
|
191 |
-
if query.data == "unapproveall_user":
|
192 |
-
if member.status == ChatMemberStatus.OWNER or query.from_user.id in DRAGONS:
|
193 |
-
approved_users = sql.list_approved(chat.id)
|
194 |
-
users = [int(i.user_id) for i in approved_users]
|
195 |
-
for user_id in users:
|
196 |
-
sql.disapprove(chat.id, user_id)
|
197 |
-
await message.edit_text("Successfully Unapproved all user in this Chat.")
|
198 |
-
return
|
199 |
-
|
200 |
-
if member.status == "administrator":
|
201 |
-
await query.answer("Only owner of the chat can do this.")
|
202 |
-
|
203 |
-
if member.status == "member":
|
204 |
-
await query.answer("You need to be admin to do this.")
|
205 |
-
elif query.data == "unapproveall_cancel":
|
206 |
-
if member.status == "creator" or query.from_user.id in DRAGONS:
|
207 |
-
await message.edit_text(
|
208 |
-
"Removing of all approved users has been cancelled."
|
209 |
-
)
|
210 |
-
return ""
|
211 |
-
if member.status == "administrator":
|
212 |
-
await query.answer("Only owner of the chat can do this.")
|
213 |
-
if member.status == "member":
|
214 |
-
await query.answer("You need to be admin to do this.")
|
215 |
-
|
216 |
-
|
217 |
-
# <=================================================== HELP ====================================================>
|
218 |
-
|
219 |
-
|
220 |
-
__help__ = """
|
221 |
-
➠ Sometimes, you might trust a user not to send unwanted content.
|
222 |
-
Maybe not enough to make them admin, but you might be ok with locks, blacklists, and antiflood not applying to them.
|
223 |
-
|
224 |
-
➠ That's what approvals are for - approve of trustworthy users to allow them to send
|
225 |
-
|
226 |
-
➠ *Admin commands:*
|
227 |
-
|
228 |
-
» /approval: Check a user's approval status in this chat.
|
229 |
-
|
230 |
-
» /approve: Approve of a user. Locks, blacklists, and antiflood won't apply to them anymore.
|
231 |
-
|
232 |
-
» /unapprove: Unapprove of a user. They will now be subject to locks, blacklists, and antiflood again.
|
233 |
-
|
234 |
-
» /approved: List all approved users.
|
235 |
-
|
236 |
-
» /unapproveall: Unapprove *ALL* users in a chat. This cannot be undone.
|
237 |
-
"""
|
238 |
-
|
239 |
-
# <================================================ HANDLER =======================================================>
|
240 |
-
APPROVE = DisableAbleCommandHandler("approve", approve, block=False)
|
241 |
-
DISAPPROVE = DisableAbleCommandHandler("unapprove", disapprove, block=False)
|
242 |
-
APPROVED = DisableAbleCommandHandler("approved", approved, block=False)
|
243 |
-
APPROVAL = DisableAbleCommandHandler("approval", approval, block=False)
|
244 |
-
UNAPPROVEALL = DisableAbleCommandHandler("unapproveall", unapproveall, block=False)
|
245 |
-
UNAPPROVEALL_BTN = CallbackQueryHandler(
|
246 |
-
unapproveall_btn, pattern=r"unapproveall_.*", block=False
|
247 |
-
)
|
248 |
-
|
249 |
-
dispatcher.add_handler(APPROVE)
|
250 |
-
dispatcher.add_handler(DISAPPROVE)
|
251 |
-
dispatcher.add_handler(APPROVED)
|
252 |
-
dispatcher.add_handler(APPROVAL)
|
253 |
-
dispatcher.add_handler(UNAPPROVEALL)
|
254 |
-
dispatcher.add_handler(UNAPPROVEALL_BTN)
|
255 |
-
|
256 |
-
__mod_name__ = "APPROVALS"
|
257 |
-
__command_list__ = ["approve", "unapprove", "approved", "approval"]
|
258 |
-
__handlers__ = [APPROVE, DISAPPROVE, APPROVED, APPROVAL]
|
259 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/ban.py
DELETED
@@ -1,748 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import html
|
3 |
-
|
4 |
-
from telegram import (
|
5 |
-
ChatMemberAdministrator,
|
6 |
-
InlineKeyboardButton,
|
7 |
-
InlineKeyboardMarkup,
|
8 |
-
Update,
|
9 |
-
)
|
10 |
-
from telegram.constants import ParseMode
|
11 |
-
from telegram.error import BadRequest
|
12 |
-
from telegram.ext import CallbackQueryHandler, CommandHandler, ContextTypes, filters
|
13 |
-
from telegram.helpers import mention_html
|
14 |
-
|
15 |
-
from Mikobot import DEV_USERS, DRAGONS, LOGGER, OWNER_ID, function
|
16 |
-
from Mikobot.utils.can_restrict import BAN_STICKER
|
17 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
18 |
-
from Mikobot.plugins.helper_funcs.chat_status import (
|
19 |
-
can_delete,
|
20 |
-
check_admin,
|
21 |
-
connection_status,
|
22 |
-
is_user_admin,
|
23 |
-
is_user_ban_protected,
|
24 |
-
is_user_in_chat,
|
25 |
-
)
|
26 |
-
from Mikobot.plugins.helper_funcs.extraction import extract_user_and_text
|
27 |
-
from Mikobot.plugins.helper_funcs.misc import mention_username
|
28 |
-
from Mikobot.plugins.helper_funcs.string_handling import extract_time
|
29 |
-
from Mikobot.plugins.log_channel import gloggable, loggable
|
30 |
-
|
31 |
-
# <=======================================================================================================>
|
32 |
-
|
33 |
-
|
34 |
-
# <================================================ FUNCTION =======================================================>
|
35 |
-
@connection_status
|
36 |
-
@loggable
|
37 |
-
@check_admin(permission="can_restrict_members", is_both=True)
|
38 |
-
async def ban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
39 |
-
chat = update.effective_chat
|
40 |
-
user = update.effective_user
|
41 |
-
message = update.effective_message
|
42 |
-
log_message = ""
|
43 |
-
bot = context.bot
|
44 |
-
args = context.args
|
45 |
-
user_id, reason = await extract_user_and_text(message, context, args)
|
46 |
-
|
47 |
-
member = await chat.get_member(user.id)
|
48 |
-
SILENT = bool(True if message.text.startswith("/s") else False)
|
49 |
-
|
50 |
-
# if update is coming from anonymous admin then send button and return.
|
51 |
-
if message.from_user.id == 1087968824:
|
52 |
-
if SILENT:
|
53 |
-
await message.reply_text("Currently /sban won't work for anoymous admins.")
|
54 |
-
return log_message
|
55 |
-
# Need chat title to be forwarded on callback data to mention channel after banning.
|
56 |
-
try:
|
57 |
-
chat_title = message.reply_to_message.sender_chat.title
|
58 |
-
except AttributeError:
|
59 |
-
chat_title = None
|
60 |
-
await update.effective_message.reply_text(
|
61 |
-
text="You are an anonymous admin.",
|
62 |
-
reply_markup=InlineKeyboardMarkup(
|
63 |
-
[
|
64 |
-
[
|
65 |
-
InlineKeyboardButton(
|
66 |
-
text="Click to prove Admin.",
|
67 |
-
callback_data=f"bans_{chat.id}=ban={user_id}={reason}={chat_title}",
|
68 |
-
),
|
69 |
-
],
|
70 |
-
]
|
71 |
-
),
|
72 |
-
)
|
73 |
-
|
74 |
-
return log_message
|
75 |
-
elif (
|
76 |
-
not (
|
77 |
-
(
|
78 |
-
member.can_restrict_members
|
79 |
-
if isinstance(member, ChatMemberAdministrator)
|
80 |
-
else None
|
81 |
-
)
|
82 |
-
or member.status == "creator"
|
83 |
-
)
|
84 |
-
and user.id not in DRAGONS
|
85 |
-
):
|
86 |
-
await update.effective_message.reply_text(
|
87 |
-
"Sorry son, but you're not worthy to wield the banhammer.",
|
88 |
-
)
|
89 |
-
return log_message
|
90 |
-
|
91 |
-
if user_id == bot.id:
|
92 |
-
await message.reply_text("Oh yeah, ban myself, noob!")
|
93 |
-
return log_message
|
94 |
-
|
95 |
-
if user_id is not None and user_id < 0:
|
96 |
-
CHAT_SENDER = True
|
97 |
-
chat_sender = message.reply_to_message.sender_chat
|
98 |
-
else:
|
99 |
-
CHAT_SENDER = False
|
100 |
-
try:
|
101 |
-
member = await chat.get_member(user_id)
|
102 |
-
except BadRequest as excp:
|
103 |
-
if excp.message == "User not found":
|
104 |
-
raise
|
105 |
-
elif excp == "Invalid user_id specified":
|
106 |
-
await message.reply_text("I Doubt that's a user.")
|
107 |
-
await message.reply_text("Can't find this person here.")
|
108 |
-
return log_message
|
109 |
-
|
110 |
-
if await is_user_ban_protected(chat, user_id, member) and user not in DEV_USERS:
|
111 |
-
if user_id == OWNER_ID:
|
112 |
-
await message.reply_text(
|
113 |
-
"Trying to put me against a God level disaster huh?"
|
114 |
-
)
|
115 |
-
elif user_id in DEV_USERS:
|
116 |
-
await message.reply_text("I can't act against our own.")
|
117 |
-
elif user_id in DRAGONS:
|
118 |
-
await message.reply_text(
|
119 |
-
"Fighting this Dragon here will put me and my people's at risk.",
|
120 |
-
)
|
121 |
-
else:
|
122 |
-
await message.reply_text("This user has immunity and cannot be banned.")
|
123 |
-
return log_message
|
124 |
-
|
125 |
-
if SILENT:
|
126 |
-
silent = True
|
127 |
-
if not await can_delete(chat, context.bot.id):
|
128 |
-
return ""
|
129 |
-
else:
|
130 |
-
silent = False
|
131 |
-
|
132 |
-
log = (
|
133 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
134 |
-
f"#{'S' if silent else ''}BANNED\n"
|
135 |
-
f"<b>Admin:</b> {mention_html(user.id, html.escape(user.first_name))}\n"
|
136 |
-
)
|
137 |
-
|
138 |
-
reply = f"<code>❕</code><b>Ban Event</b>\n"
|
139 |
-
|
140 |
-
if CHAT_SENDER:
|
141 |
-
log += f"<b>Channel:</b> {mention_username(chat_sender.username, html.escape(chat_sender.title))}"
|
142 |
-
reply += f"<code> </code><b>• Channel:</b> {mention_username(chat_sender.username, html.escape(chat_sender.title))}"
|
143 |
-
|
144 |
-
else:
|
145 |
-
log += f"<b>User:</b> {mention_html(member.user.id, html.escape(member.user.first_name))}"
|
146 |
-
reply += f"<code> </code><b>• User:</b> {mention_html(member.user.id, html.escape(member.user.first_name))}"
|
147 |
-
|
148 |
-
if reason:
|
149 |
-
log += "\n<b>Reason:</b> {}".format(reason)
|
150 |
-
|
151 |
-
try:
|
152 |
-
if CHAT_SENDER:
|
153 |
-
await chat.ban_sender_chat(sender_chat_id=chat_sender.id)
|
154 |
-
else:
|
155 |
-
await chat.ban_member(user_id)
|
156 |
-
|
157 |
-
if silent:
|
158 |
-
if message.reply_to_message:
|
159 |
-
await message.reply_to_message.delete()
|
160 |
-
await message.delete()
|
161 |
-
return log
|
162 |
-
|
163 |
-
await bot.send_sticker(
|
164 |
-
chat.id,
|
165 |
-
BAN_STICKER,
|
166 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
167 |
-
) # banhammer marie sticker
|
168 |
-
|
169 |
-
if reason:
|
170 |
-
reply += f"\n<code> </code><b>• Reason:</b> \n{html.escape(reason)}"
|
171 |
-
await bot.sendMessage(
|
172 |
-
chat.id,
|
173 |
-
reply,
|
174 |
-
parse_mode=ParseMode.HTML,
|
175 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
176 |
-
)
|
177 |
-
return log
|
178 |
-
|
179 |
-
except BadRequest as excp:
|
180 |
-
if excp.message == "Reply message not found":
|
181 |
-
# Do not reply
|
182 |
-
if silent:
|
183 |
-
return log
|
184 |
-
await message.reply_text("Banned!", quote=False)
|
185 |
-
return log
|
186 |
-
else:
|
187 |
-
LOGGER.warning(update)
|
188 |
-
LOGGER.exception(
|
189 |
-
"ERROR banning user %s in chat %s (%s) due to %s",
|
190 |
-
user_id,
|
191 |
-
chat.title,
|
192 |
-
chat.id,
|
193 |
-
excp.message,
|
194 |
-
)
|
195 |
-
await message.reply_text("Uhm...that didn't work...")
|
196 |
-
|
197 |
-
return log_message
|
198 |
-
|
199 |
-
|
200 |
-
@connection_status
|
201 |
-
@loggable
|
202 |
-
@check_admin(permission="can_restrict_members", is_both=True)
|
203 |
-
async def temp_ban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
204 |
-
chat = update.effective_chat
|
205 |
-
user = update.effective_user
|
206 |
-
message = update.effective_message
|
207 |
-
log_message = ""
|
208 |
-
bot, args = context.bot, context.args
|
209 |
-
user_id, reason = await extract_user_and_text(message, context, args)
|
210 |
-
|
211 |
-
if not user_id:
|
212 |
-
await message.reply_text("I doubt that's a user.")
|
213 |
-
return log_message
|
214 |
-
|
215 |
-
try:
|
216 |
-
member = await chat.get_member(user_id)
|
217 |
-
except BadRequest as excp:
|
218 |
-
if excp.message != "User not found":
|
219 |
-
raise
|
220 |
-
await message.reply_text("I can't seem to find this user.")
|
221 |
-
return log_message
|
222 |
-
if user_id == bot.id:
|
223 |
-
await message.reply_text("I'm not gonna BAN myself, are you crazy?")
|
224 |
-
return log_message
|
225 |
-
|
226 |
-
if await is_user_ban_protected(chat, user_id, member):
|
227 |
-
await message.reply_text("I don't feel like it.")
|
228 |
-
return log_message
|
229 |
-
|
230 |
-
if not reason:
|
231 |
-
await message.reply_text("You haven't specified a time to ban this user for!")
|
232 |
-
return log_message
|
233 |
-
|
234 |
-
split_reason = reason.split(None, 1)
|
235 |
-
|
236 |
-
time_val = split_reason[0].lower()
|
237 |
-
reason = split_reason[1] if len(split_reason) > 1 else ""
|
238 |
-
bantime = await extract_time(message, time_val)
|
239 |
-
|
240 |
-
if not bantime:
|
241 |
-
return log_message
|
242 |
-
|
243 |
-
log = (
|
244 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
245 |
-
"#TEMP BANNED\n"
|
246 |
-
f"<b>Admin:</b> {mention_html(user.id, html.escape(user.first_name))}\n"
|
247 |
-
f"<b>User:</b> {mention_html(member.user.id, html.escape(member.user.first_name))}\n"
|
248 |
-
f"<b>Time:</b> {time_val}"
|
249 |
-
)
|
250 |
-
if reason:
|
251 |
-
log += "\n<b>Reason:</b> {}".format(reason)
|
252 |
-
|
253 |
-
try:
|
254 |
-
await chat.ban_member(user_id, until_date=bantime)
|
255 |
-
await bot.send_sticker(
|
256 |
-
chat.id,
|
257 |
-
BAN_STICKER,
|
258 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
259 |
-
) # banhammer marie sticker
|
260 |
-
await bot.sendMessage(
|
261 |
-
chat.id,
|
262 |
-
f"Banned! User {mention_html(member.user.id, html.escape(member.user.first_name))} "
|
263 |
-
f"will be banned for {time_val}.",
|
264 |
-
parse_mode=ParseMode.HTML,
|
265 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
266 |
-
)
|
267 |
-
return log
|
268 |
-
|
269 |
-
except BadRequest as excp:
|
270 |
-
if excp.message == "Reply message not found":
|
271 |
-
# Do not reply
|
272 |
-
await message.reply_text(
|
273 |
-
f"Banned! User will be banned for {time_val}.",
|
274 |
-
quote=False,
|
275 |
-
)
|
276 |
-
return log
|
277 |
-
else:
|
278 |
-
LOGGER.warning(update)
|
279 |
-
LOGGER.exception(
|
280 |
-
"ERROR banning user %s in chat %s (%s) due to %s",
|
281 |
-
user_id,
|
282 |
-
chat.title,
|
283 |
-
chat.id,
|
284 |
-
excp.message,
|
285 |
-
)
|
286 |
-
await message.reply_text("Well damn, I can't ban that user.")
|
287 |
-
|
288 |
-
return log_message
|
289 |
-
|
290 |
-
|
291 |
-
@connection_status
|
292 |
-
@loggable
|
293 |
-
@check_admin(permission="can_restrict_members", is_both=True)
|
294 |
-
async def kick(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
295 |
-
chat = update.effective_chat
|
296 |
-
user = update.effective_user
|
297 |
-
message = update.effective_message
|
298 |
-
log_message = ""
|
299 |
-
bot, args = context.bot, context.args
|
300 |
-
user_id, reason = await extract_user_and_text(message, context, args)
|
301 |
-
|
302 |
-
if not user_id:
|
303 |
-
await message.reply_text("I doubt that's a user.")
|
304 |
-
return log_message
|
305 |
-
|
306 |
-
try:
|
307 |
-
member = await chat.get_member(user_id)
|
308 |
-
except BadRequest as excp:
|
309 |
-
if excp.message != "User not found":
|
310 |
-
raise
|
311 |
-
|
312 |
-
await message.reply_text("I can't seem to find this user.")
|
313 |
-
return log_message
|
314 |
-
if user_id == bot.id:
|
315 |
-
await message.reply_text("Yeahhh I'm not gonna do that.")
|
316 |
-
return log_message
|
317 |
-
|
318 |
-
if await is_user_ban_protected(chat, user_id):
|
319 |
-
await message.reply_text("I really wish I could kick this user....")
|
320 |
-
return log_message
|
321 |
-
|
322 |
-
res = chat.unban_member(user_id) # unban on current user = kick
|
323 |
-
if res:
|
324 |
-
await bot.send_sticker(
|
325 |
-
chat.id,
|
326 |
-
BAN_STICKER,
|
327 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
328 |
-
) # banhammer marie sticker
|
329 |
-
await bot.sendMessage(
|
330 |
-
chat.id,
|
331 |
-
f"Capitain I have kicked, {mention_html(member.user.id, html.escape(member.user.first_name))}.",
|
332 |
-
parse_mode=ParseMode.HTML,
|
333 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
334 |
-
)
|
335 |
-
log = (
|
336 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
337 |
-
f"#KICKED\n"
|
338 |
-
f"<b>Admin:</b> {mention_html(user.id, html.escape(user.first_name))}\n"
|
339 |
-
f"<b>User:</b> {mention_html(member.user.id, html.escape(member.user.first_name))}"
|
340 |
-
)
|
341 |
-
if reason:
|
342 |
-
log += f"\n<b>Reason:</b> {reason}"
|
343 |
-
|
344 |
-
return log
|
345 |
-
|
346 |
-
else:
|
347 |
-
await message.reply_text("Well damn, I can't kick that user.")
|
348 |
-
|
349 |
-
return log_message
|
350 |
-
|
351 |
-
|
352 |
-
@check_admin(permission="can_restrict_members", is_bot=True)
|
353 |
-
async def kickme(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
354 |
-
user_id = update.effective_message.from_user.id
|
355 |
-
if await is_user_admin(update.effective_chat, user_id):
|
356 |
-
await update.effective_message.reply_text(
|
357 |
-
"I wish I could... but you're an admin."
|
358 |
-
)
|
359 |
-
return
|
360 |
-
|
361 |
-
res = await update.effective_chat.unban_member(
|
362 |
-
user_id
|
363 |
-
) # unban on current user = kick
|
364 |
-
# BUG: parsing not working
|
365 |
-
if res:
|
366 |
-
await update.effective_message.reply_text(
|
367 |
-
html.escape("You got the Devil's Kiss, Now die in peace"), parse_mode="html"
|
368 |
-
)
|
369 |
-
else:
|
370 |
-
await update.effective_message.reply_text("Huh? I can't :/")
|
371 |
-
|
372 |
-
|
373 |
-
@connection_status
|
374 |
-
@loggable
|
375 |
-
@check_admin(permission="can_restrict_members", is_both=True)
|
376 |
-
async def unban(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
377 |
-
message = update.effective_message
|
378 |
-
user = update.effective_user
|
379 |
-
chat = update.effective_chat
|
380 |
-
log_message = ""
|
381 |
-
bot, args = context.bot, context.args
|
382 |
-
user_id, reason = await extract_user_and_text(message, context, args)
|
383 |
-
|
384 |
-
if message.from_user.id == 1087968824:
|
385 |
-
try:
|
386 |
-
chat_title = message.reply_to_message.sender_chat.title
|
387 |
-
except AttributeError:
|
388 |
-
chat_title = None
|
389 |
-
|
390 |
-
await message.reply_text(
|
391 |
-
text="You are an anonymous admin.",
|
392 |
-
reply_markup=InlineKeyboardMarkup(
|
393 |
-
[
|
394 |
-
[
|
395 |
-
InlineKeyboardButton(
|
396 |
-
text="Click to prove Admin.",
|
397 |
-
callback_data=f"bans_{chat.id}=unban={user_id}={reason}={chat_title}",
|
398 |
-
),
|
399 |
-
],
|
400 |
-
]
|
401 |
-
),
|
402 |
-
)
|
403 |
-
|
404 |
-
return log_message
|
405 |
-
|
406 |
-
if not user_id:
|
407 |
-
await message.reply_text("I doubt that's a user.")
|
408 |
-
return log_message
|
409 |
-
|
410 |
-
if user_id == bot.id:
|
411 |
-
await message.reply_text("How would I unban myself if I wasn't here...?")
|
412 |
-
return log_message
|
413 |
-
|
414 |
-
if user_id is not None and user_id < 0:
|
415 |
-
CHAT_SENDER = True
|
416 |
-
chat_sender = message.reply_to_message.sender_chat
|
417 |
-
else:
|
418 |
-
CHAT_SENDER = False
|
419 |
-
try:
|
420 |
-
member = await chat.get_member(user_id)
|
421 |
-
|
422 |
-
if isinstance(member, ChatMemberAdministrator):
|
423 |
-
await message.reply_text(
|
424 |
-
"This person is an admin here, Are you drunk???"
|
425 |
-
)
|
426 |
-
return log_message
|
427 |
-
|
428 |
-
except BadRequest as excp:
|
429 |
-
raise
|
430 |
-
if excp.message != "User not found":
|
431 |
-
raise
|
432 |
-
await message.reply_text("I can't seem to find this user.")
|
433 |
-
return log_message
|
434 |
-
|
435 |
-
if await is_user_in_chat(chat, user_id):
|
436 |
-
await message.reply_text("Isn't this person already here??")
|
437 |
-
return log_message
|
438 |
-
|
439 |
-
log = (
|
440 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
441 |
-
f"#UNBANNED\n"
|
442 |
-
f"<b>Admin:</b> {mention_html(user.id, html.escape(user.first_name))}\n"
|
443 |
-
)
|
444 |
-
|
445 |
-
if CHAT_SENDER:
|
446 |
-
log += f"<b>User:</b> {mention_username(chat_sender.id, html.escape(chat_sender.title))}"
|
447 |
-
await chat.unban_sender_chat(chat_sender.id)
|
448 |
-
await message.reply_text("Yeah, this channel can speak again.")
|
449 |
-
else:
|
450 |
-
log += f"<b>User:</b> {mention_html(member.user.id, html.escape(member.user.first_name))}"
|
451 |
-
await chat.unban_member(user_id)
|
452 |
-
await message.reply_text("Yeah, this user can join!")
|
453 |
-
|
454 |
-
if reason:
|
455 |
-
log += f"\n<b>Reason:</b> {reason}"
|
456 |
-
|
457 |
-
return log
|
458 |
-
|
459 |
-
|
460 |
-
@connection_status
|
461 |
-
@gloggable
|
462 |
-
@check_admin(permission="can_restrict_members", is_bot=True)
|
463 |
-
async def selfunban(context: ContextTypes.DEFAULT_TYPE, update: Update) -> str:
|
464 |
-
message = update.effective_message
|
465 |
-
user = update.effective_user
|
466 |
-
bot, args = context.bot, context.args
|
467 |
-
if user.id not in DRAGONS:
|
468 |
-
return
|
469 |
-
|
470 |
-
try:
|
471 |
-
chat_id = int(args[0])
|
472 |
-
except:
|
473 |
-
await message.reply_text("Give a valid chat ID.")
|
474 |
-
return
|
475 |
-
|
476 |
-
chat = await bot.getChat(chat_id)
|
477 |
-
|
478 |
-
try:
|
479 |
-
member = await chat.get_member(user.id)
|
480 |
-
except BadRequest as excp:
|
481 |
-
if excp.message == "User not found":
|
482 |
-
await message.reply_text("I can't seem to find this user.")
|
483 |
-
return
|
484 |
-
else:
|
485 |
-
raise
|
486 |
-
|
487 |
-
if await is_user_in_chat(chat, user.id):
|
488 |
-
await message.reply_text("Aren't you already in the chat??")
|
489 |
-
return
|
490 |
-
|
491 |
-
await chat.unban_member(user.id)
|
492 |
-
await message.reply_text("Yep, I have unbanned you.")
|
493 |
-
|
494 |
-
log = (
|
495 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
496 |
-
f"#UNBANNED\n"
|
497 |
-
f"<b>User:</b> {mention_html(member.user.id, html.escape(member.user.first_name))}"
|
498 |
-
)
|
499 |
-
|
500 |
-
return log
|
501 |
-
|
502 |
-
|
503 |
-
@loggable
|
504 |
-
async def bans_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
505 |
-
query = update.callback_query
|
506 |
-
bot = context.bot
|
507 |
-
chat = update.effective_chat
|
508 |
-
message = update.effective_message
|
509 |
-
args = context.args
|
510 |
-
log_message = ""
|
511 |
-
splitter = query.data.replace("bans_", "").split("=")
|
512 |
-
|
513 |
-
admin_user = query.from_user
|
514 |
-
member = await chat.get_member(admin_user.id)
|
515 |
-
|
516 |
-
if splitter[1] == "ban":
|
517 |
-
# workaround for checking user admin status
|
518 |
-
try:
|
519 |
-
user_id = int(splitter[2])
|
520 |
-
except ValueError:
|
521 |
-
user_id = splitter[2]
|
522 |
-
reason = splitter[3]
|
523 |
-
chat_name = splitter[4]
|
524 |
-
|
525 |
-
if not (
|
526 |
-
(
|
527 |
-
member.can_restrict_members
|
528 |
-
if isinstance(member, ChatMemberAdministrator)
|
529 |
-
else None
|
530 |
-
)
|
531 |
-
or member.status == "creator"
|
532 |
-
) and (admin_user.id not in DRAGONS):
|
533 |
-
await query.answer(
|
534 |
-
"Sorry son, but you're not worthy to wield the banhammer.",
|
535 |
-
show_alert=True,
|
536 |
-
)
|
537 |
-
return log_message
|
538 |
-
|
539 |
-
if user_id == bot.id:
|
540 |
-
await message.edit_text("Oh yeah, ban myself, noob!")
|
541 |
-
return log_message
|
542 |
-
|
543 |
-
if isinstance(user_id, str):
|
544 |
-
await message.edit_text("I doubt that's a user.")
|
545 |
-
return log_message
|
546 |
-
|
547 |
-
if user_id < 0:
|
548 |
-
CHAT_SENDER = True
|
549 |
-
else:
|
550 |
-
CHAT_SENDER = False
|
551 |
-
try:
|
552 |
-
member = await chat.get_member(user_id)
|
553 |
-
except BadRequest as excp:
|
554 |
-
if excp.message == "User not found.":
|
555 |
-
raise
|
556 |
-
elif excp == "Invalid user_id specified":
|
557 |
-
await message.edit_text("I Doubt that's a user.")
|
558 |
-
await message.edit_text("Can't find this person here.")
|
559 |
-
|
560 |
-
return log_message
|
561 |
-
|
562 |
-
if (
|
563 |
-
await is_user_ban_protected(chat, user_id, member)
|
564 |
-
and admin_user not in DEV_USERS
|
565 |
-
):
|
566 |
-
if user_id == OWNER_ID:
|
567 |
-
await message.edit_text(
|
568 |
-
"Trying to put me against a God level disaster huh?"
|
569 |
-
)
|
570 |
-
elif user_id in DEV_USERS:
|
571 |
-
await message.edit_text("I can't act against our own.")
|
572 |
-
elif user_id in DRAGONS:
|
573 |
-
await message.edit_text(
|
574 |
-
"Fighting this Dragon here will put me and my people's at risk.",
|
575 |
-
)
|
576 |
-
else:
|
577 |
-
await message.edit_text(
|
578 |
-
"This user has immunity and cannot be banned."
|
579 |
-
)
|
580 |
-
return log_message
|
581 |
-
|
582 |
-
log = (
|
583 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
584 |
-
f"#BANNED\n"
|
585 |
-
f"<b>Admin:</b> {mention_html(admin_user.id, html.escape(admin_user.first_name))}\n"
|
586 |
-
)
|
587 |
-
|
588 |
-
reply = f"<code>❕</code><b>Ban Event</b>\n"
|
589 |
-
|
590 |
-
if CHAT_SENDER:
|
591 |
-
log += f"<b>Channel:</b> {html.escape(chat_name)}"
|
592 |
-
reply += f"<code> </code><b>• Channel:</b> {html.escape(chat_name)}"
|
593 |
-
|
594 |
-
else:
|
595 |
-
log += f"<b>User:</b> {mention_html(member.user.id, html.escape(member.user.first_name))}"
|
596 |
-
reply += f"<code> </code><b>• User:</b> {mention_html(member.user.id, html.escape(member.user.first_name))}"
|
597 |
-
|
598 |
-
if reason:
|
599 |
-
log += "\n<b>Reason:</b> {}".format(reason)
|
600 |
-
|
601 |
-
try:
|
602 |
-
if CHAT_SENDER:
|
603 |
-
await chat.ban_sender_chat(sender_chat_id=user_id)
|
604 |
-
else:
|
605 |
-
await chat.ban_member(user_id)
|
606 |
-
|
607 |
-
await bot.send_sticker(
|
608 |
-
chat.id,
|
609 |
-
BAN_STICKER,
|
610 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
611 |
-
) # banhammer marie sticker
|
612 |
-
|
613 |
-
if reason:
|
614 |
-
reply += f"\n<code> </code><b>• Reason:</b> \n{html.escape(reason)}"
|
615 |
-
await bot.sendMessage(
|
616 |
-
chat.id,
|
617 |
-
reply,
|
618 |
-
parse_mode=ParseMode.HTML,
|
619 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
620 |
-
)
|
621 |
-
await query.answer(f"Done Banned User.")
|
622 |
-
return log
|
623 |
-
|
624 |
-
except BadRequest as excp:
|
625 |
-
if excp.message == "Reply message not found":
|
626 |
-
# Do not reply
|
627 |
-
await message.edit_text("Banned!")
|
628 |
-
return log
|
629 |
-
else:
|
630 |
-
LOGGER.warning(update)
|
631 |
-
LOGGER.exception(
|
632 |
-
"ERROR banning user %s in chat %s (%s) due to %s",
|
633 |
-
user_id,
|
634 |
-
chat.title,
|
635 |
-
chat.id,
|
636 |
-
excp.message,
|
637 |
-
)
|
638 |
-
await message.edit_text("Uhm...that didn't work...")
|
639 |
-
|
640 |
-
return log_message
|
641 |
-
|
642 |
-
elif splitter[1] == "unban":
|
643 |
-
try:
|
644 |
-
user_id = int(splitter[2])
|
645 |
-
except ValueError:
|
646 |
-
user_id = splitter[2]
|
647 |
-
reason = splitter[3]
|
648 |
-
|
649 |
-
if isinstance(user_id, str):
|
650 |
-
await message.edit_text("I doubt that's a user.")
|
651 |
-
return log_message
|
652 |
-
|
653 |
-
if user_id == bot.id:
|
654 |
-
await message.edit_text("How would i unban myself if i wasn't here...?")
|
655 |
-
return log_message
|
656 |
-
|
657 |
-
if user_id < 0:
|
658 |
-
CHAT_SENDER = True
|
659 |
-
chat_title = splitter[4]
|
660 |
-
else:
|
661 |
-
CHAT_SENDER = False
|
662 |
-
|
663 |
-
try:
|
664 |
-
member = await chat.get_member(user_id)
|
665 |
-
except BadRequest as excp:
|
666 |
-
if excp.message != "User not found":
|
667 |
-
raise
|
668 |
-
await message.edit_text("I can't seem to find this user.")
|
669 |
-
return log_message
|
670 |
-
|
671 |
-
if await is_user_in_chat(chat, user_id):
|
672 |
-
await message.edit_text("Isn't this person already here??")
|
673 |
-
return log_message
|
674 |
-
|
675 |
-
log = (
|
676 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
677 |
-
f"#UNBANNED\n"
|
678 |
-
f"<b>Admin:</b> {mention_html(admin_user.id, html.escape(admin_user.first_name))}\n"
|
679 |
-
)
|
680 |
-
|
681 |
-
if CHAT_SENDER:
|
682 |
-
log += f"<b>User:</b> {html.escape(chat_title)}"
|
683 |
-
await chat.unban_sender_chat(user_id)
|
684 |
-
await message.reply_text("Yeah, this channel can speak again.")
|
685 |
-
else:
|
686 |
-
log += f"<b>User:</b> {mention_html(member.user.id, html.escape(member.user.first_name))}"
|
687 |
-
await chat.unban_member(user_id)
|
688 |
-
await message.reply_text("Yeah, this user can join!")
|
689 |
-
|
690 |
-
if reason:
|
691 |
-
log += f"\n<b>Reason:</b> {reason}"
|
692 |
-
|
693 |
-
return log
|
694 |
-
|
695 |
-
|
696 |
-
# <================================================ HELP =======================================================>
|
697 |
-
|
698 |
-
|
699 |
-
__help__ = """
|
700 |
-
» /kickme: kicks the user who issued the command
|
701 |
-
|
702 |
-
➠ *Admins only:*
|
703 |
-
» /ban <userhandle>: bans a user/channel. (via handle, or reply)
|
704 |
-
|
705 |
-
» /sban <userhandle>: Silently ban a user. Deletes command, Replied message and doesn't reply. (via handle, or reply)
|
706 |
-
|
707 |
-
» /tban <userhandle> x(m/h/d): bans a user for `x` time. (via handle, or reply). `m` = `minutes`, `h` = `hours`, `d` = `days`.
|
708 |
-
|
709 |
-
» /unban <userhandle>: unbans a user/channel. (via handle, or reply)
|
710 |
-
|
711 |
-
» /kick <userhandle>: kicks a user out of the group, (via handle, or reply)
|
712 |
-
|
713 |
-
➠ NOTE:
|
714 |
-
Banning or UnBanning channels only work if you reply to their message, so don't use their username to ban/unban.
|
715 |
-
"""
|
716 |
-
|
717 |
-
# <================================================ HANDLER =======================================================>
|
718 |
-
BAN_HANDLER = CommandHandler(["ban", "sban"], ban, block=False)
|
719 |
-
TEMPBAN_HANDLER = CommandHandler(["tban"], temp_ban, block=False)
|
720 |
-
KICK_HANDLER = CommandHandler("kick", kick, block=False)
|
721 |
-
UNBAN_HANDLER = CommandHandler("unban", unban, block=False)
|
722 |
-
ROAR_HANDLER = CommandHandler("roar", selfunban, block=False)
|
723 |
-
KICKME_HANDLER = DisableAbleCommandHandler(
|
724 |
-
"kickme", kickme, filters=filters.ChatType.GROUPS, block=False
|
725 |
-
)
|
726 |
-
BAN_CALLBACK_HANDLER = CallbackQueryHandler(
|
727 |
-
bans_callback, block=False, pattern=r"bans_"
|
728 |
-
)
|
729 |
-
|
730 |
-
function(BAN_HANDLER)
|
731 |
-
function(TEMPBAN_HANDLER)
|
732 |
-
function(KICK_HANDLER)
|
733 |
-
function(UNBAN_HANDLER)
|
734 |
-
function(ROAR_HANDLER)
|
735 |
-
function(KICKME_HANDLER)
|
736 |
-
function(BAN_CALLBACK_HANDLER)
|
737 |
-
|
738 |
-
__mod_name__ = "BAN"
|
739 |
-
__handlers__ = [
|
740 |
-
BAN_HANDLER,
|
741 |
-
TEMPBAN_HANDLER,
|
742 |
-
KICK_HANDLER,
|
743 |
-
UNBAN_HANDLER,
|
744 |
-
ROAR_HANDLER,
|
745 |
-
KICKME_HANDLER,
|
746 |
-
BAN_CALLBACK_HANDLER,
|
747 |
-
]
|
748 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/blacklist.py
DELETED
@@ -1,548 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import html
|
3 |
-
import re
|
4 |
-
|
5 |
-
from telegram import ChatPermissions, Update
|
6 |
-
from telegram.constants import ParseMode
|
7 |
-
from telegram.error import BadRequest
|
8 |
-
from telegram.ext import CommandHandler, ContextTypes, MessageHandler, filters
|
9 |
-
from telegram.helpers import mention_html
|
10 |
-
|
11 |
-
import Database.sql.blacklist_sql as sql
|
12 |
-
from Database.sql.approve_sql import is_approved
|
13 |
-
from Mikobot import LOGGER, dispatcher, function
|
14 |
-
from Mikobot.plugins.connection import connected
|
15 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
16 |
-
from Mikobot.plugins.helper_funcs.alternate import send_message, typing_action
|
17 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin, user_not_admin
|
18 |
-
from Mikobot.plugins.helper_funcs.extraction import extract_text
|
19 |
-
from Mikobot.plugins.helper_funcs.misc import split_message
|
20 |
-
from Mikobot.plugins.helper_funcs.string_handling import extract_time
|
21 |
-
from Mikobot.plugins.log_channel import loggable
|
22 |
-
from Mikobot.plugins.warns import warn
|
23 |
-
|
24 |
-
# <=======================================================================================================>
|
25 |
-
|
26 |
-
BLACKLIST_GROUP = 11
|
27 |
-
|
28 |
-
|
29 |
-
# <================================================ FUNCTION =======================================================>
|
30 |
-
@check_admin(is_user=True)
|
31 |
-
@typing_action
|
32 |
-
async def blacklist(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
33 |
-
chat = update.effective_chat
|
34 |
-
user = update.effective_user
|
35 |
-
args = context.args
|
36 |
-
|
37 |
-
conn = await connected(context.bot, update, chat, user.id, need_admin=False)
|
38 |
-
if conn:
|
39 |
-
chat_id = conn
|
40 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
41 |
-
chat_name = chat_obj.title
|
42 |
-
else:
|
43 |
-
if chat.type == "private":
|
44 |
-
return
|
45 |
-
chat_id = update.effective_chat.id
|
46 |
-
chat_name = chat.title
|
47 |
-
|
48 |
-
filter_list = "Current blacklisted words in <b>{}</b>:\n".format(chat_name)
|
49 |
-
|
50 |
-
all_blacklisted = sql.get_chat_blacklist(chat_id)
|
51 |
-
|
52 |
-
if len(args) > 0 and args[0].lower() == "copy":
|
53 |
-
for trigger in all_blacklisted:
|
54 |
-
filter_list += "<code>{}</code>\n".format(html.escape(trigger))
|
55 |
-
else:
|
56 |
-
for trigger in all_blacklisted:
|
57 |
-
filter_list += " - <code>{}</code>\n".format(html.escape(trigger))
|
58 |
-
|
59 |
-
# for trigger in all_blacklisted:
|
60 |
-
# filter_list += " - <code>{}</code>\n".format(html.escape(trigger))
|
61 |
-
|
62 |
-
split_text = split_message(filter_list)
|
63 |
-
for text in split_text:
|
64 |
-
if filter_list == "Current blacklisted words in <b>{}</b>:\n".format(
|
65 |
-
html.escape(chat_name),
|
66 |
-
):
|
67 |
-
await send_message(
|
68 |
-
update.effective_message,
|
69 |
-
"No blacklisted words in <b>{}</b>!".format(html.escape(chat_name)),
|
70 |
-
parse_mode=ParseMode.HTML,
|
71 |
-
)
|
72 |
-
return
|
73 |
-
await send_message(update.effective_message, text, parse_mode=ParseMode.HTML)
|
74 |
-
|
75 |
-
|
76 |
-
@check_admin(is_user=True)
|
77 |
-
@typing_action
|
78 |
-
async def add_blacklist(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
79 |
-
msg = update.effective_message
|
80 |
-
chat = update.effective_chat
|
81 |
-
user = update.effective_user
|
82 |
-
words = msg.text.split(None, 1)
|
83 |
-
|
84 |
-
conn = await connected(context.bot, update, chat, user.id)
|
85 |
-
if conn:
|
86 |
-
chat_id = conn
|
87 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
88 |
-
chat_name = chat_obj.title
|
89 |
-
else:
|
90 |
-
chat_id = update.effective_chat.id
|
91 |
-
if chat.type == "private":
|
92 |
-
return
|
93 |
-
else:
|
94 |
-
chat_name = chat.title
|
95 |
-
|
96 |
-
if len(words) > 1:
|
97 |
-
text = words[1]
|
98 |
-
to_blacklist = list(
|
99 |
-
{trigger.strip() for trigger in text.split("\n") if trigger.strip()},
|
100 |
-
)
|
101 |
-
for trigger in to_blacklist:
|
102 |
-
sql.add_to_blacklist(chat_id, trigger.lower())
|
103 |
-
|
104 |
-
if len(to_blacklist) == 1:
|
105 |
-
await send_message(
|
106 |
-
update.effective_message,
|
107 |
-
"Added blacklist <code>{}</code> in chat: <b>{}</b>!".format(
|
108 |
-
html.escape(to_blacklist[0]),
|
109 |
-
html.escape(chat_name),
|
110 |
-
),
|
111 |
-
parse_mode=ParseMode.HTML,
|
112 |
-
)
|
113 |
-
|
114 |
-
else:
|
115 |
-
await send_message(
|
116 |
-
update.effective_message,
|
117 |
-
"Added blacklist trigger: <code>{}</code> in <b>{}</b>!".format(
|
118 |
-
len(to_blacklist),
|
119 |
-
html.escape(chat_name),
|
120 |
-
),
|
121 |
-
parse_mode=ParseMode.HTML,
|
122 |
-
)
|
123 |
-
|
124 |
-
else:
|
125 |
-
await send_message(
|
126 |
-
update.effective_message,
|
127 |
-
"Tell me which words you would like to add in blacklist.",
|
128 |
-
)
|
129 |
-
|
130 |
-
|
131 |
-
@check_admin(is_user=True)
|
132 |
-
@typing_action
|
133 |
-
async def unblacklist(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
134 |
-
msg = update.effective_message
|
135 |
-
chat = update.effective_chat
|
136 |
-
user = update.effective_user
|
137 |
-
words = msg.text.split(None, 1)
|
138 |
-
|
139 |
-
conn = await connected(context.bot, update, chat, user.id)
|
140 |
-
if conn:
|
141 |
-
chat_id = conn
|
142 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
143 |
-
chat_name = chat_obj.title
|
144 |
-
else:
|
145 |
-
chat_id = update.effective_chat.id
|
146 |
-
if chat.type == "private":
|
147 |
-
return
|
148 |
-
else:
|
149 |
-
chat_name = chat.title
|
150 |
-
|
151 |
-
if len(words) > 1:
|
152 |
-
text = words[1]
|
153 |
-
to_unblacklist = list(
|
154 |
-
{trigger.strip() for trigger in text.split("\n") if trigger.strip()},
|
155 |
-
)
|
156 |
-
successful = 0
|
157 |
-
for trigger in to_unblacklist:
|
158 |
-
success = sql.rm_from_blacklist(chat_id, trigger.lower())
|
159 |
-
if success:
|
160 |
-
successful += 1
|
161 |
-
|
162 |
-
if len(to_unblacklist) == 1:
|
163 |
-
if successful:
|
164 |
-
await send_message(
|
165 |
-
update.effective_message,
|
166 |
-
"Removed <code>{}</code> from blacklist in <b>{}</b>!".format(
|
167 |
-
html.escape(to_unblacklist[0]),
|
168 |
-
html.escape(chat_name),
|
169 |
-
),
|
170 |
-
parse_mode=ParseMode.HTML,
|
171 |
-
)
|
172 |
-
else:
|
173 |
-
await send_message(
|
174 |
-
update.effective_message,
|
175 |
-
"This is not a blacklist trigger!",
|
176 |
-
)
|
177 |
-
|
178 |
-
elif successful == len(to_unblacklist):
|
179 |
-
await send_message(
|
180 |
-
update.effective_message,
|
181 |
-
"Removed <code>{}</code> from blacklist in <b>{}</b>!".format(
|
182 |
-
successful,
|
183 |
-
html.escape(chat_name),
|
184 |
-
),
|
185 |
-
parse_mode=ParseMode.HTML,
|
186 |
-
)
|
187 |
-
|
188 |
-
elif not successful:
|
189 |
-
await send_message(
|
190 |
-
update.effective_message,
|
191 |
-
"None of these triggers exist so it can't be removed.",
|
192 |
-
parse_mode=ParseMode.HTML,
|
193 |
-
)
|
194 |
-
|
195 |
-
else:
|
196 |
-
await send_message(
|
197 |
-
update.effective_message,
|
198 |
-
"Removed <code>{}</code> from blacklist. {} did not exist, "
|
199 |
-
"so were not removed.".format(
|
200 |
-
successful,
|
201 |
-
len(to_unblacklist) - successful,
|
202 |
-
),
|
203 |
-
parse_mode=ParseMode.HTML,
|
204 |
-
)
|
205 |
-
else:
|
206 |
-
await send_message(
|
207 |
-
update.effective_message,
|
208 |
-
"Tell me which words you would like to remove from blacklist!",
|
209 |
-
)
|
210 |
-
|
211 |
-
|
212 |
-
@loggable
|
213 |
-
@check_admin(is_user=True)
|
214 |
-
@typing_action
|
215 |
-
async def blacklist_mode(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
216 |
-
chat = update.effective_chat
|
217 |
-
user = update.effective_user
|
218 |
-
msg = update.effective_message
|
219 |
-
args = context.args
|
220 |
-
|
221 |
-
conn = await connected(context.bot, update, chat, user.id, need_admin=True)
|
222 |
-
if conn:
|
223 |
-
chat = await dispatcher.bot.getChat(conn)
|
224 |
-
chat_id = conn
|
225 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
226 |
-
chat_name = chat_obj.title
|
227 |
-
else:
|
228 |
-
if update.effective_message.chat.type == "private":
|
229 |
-
await send_message(
|
230 |
-
update.effective_message,
|
231 |
-
"This command can be only used in group not in PM",
|
232 |
-
)
|
233 |
-
return ""
|
234 |
-
chat = update.effective_chat
|
235 |
-
chat_id = update.effective_chat.id
|
236 |
-
chat_name = update.effective_message.chat.title
|
237 |
-
|
238 |
-
if args:
|
239 |
-
if args[0].lower() in ["off", "nothing", "no"]:
|
240 |
-
settypeblacklist = "do nothing"
|
241 |
-
sql.set_blacklist_strength(chat_id, 0, "0")
|
242 |
-
elif args[0].lower() in ["del", "delete"]:
|
243 |
-
settypeblacklist = "delete blacklisted message"
|
244 |
-
sql.set_blacklist_strength(chat_id, 1, "0")
|
245 |
-
elif args[0].lower() == "warn":
|
246 |
-
settypeblacklist = "warn the sender"
|
247 |
-
sql.set_blacklist_strength(chat_id, 2, "0")
|
248 |
-
elif args[0].lower() == "mute":
|
249 |
-
settypeblacklist = "mute the sender"
|
250 |
-
sql.set_blacklist_strength(chat_id, 3, "0")
|
251 |
-
elif args[0].lower() == "kick":
|
252 |
-
settypeblacklist = "kick the sender"
|
253 |
-
sql.set_blacklist_strength(chat_id, 4, "0")
|
254 |
-
elif args[0].lower() == "ban":
|
255 |
-
settypeblacklist = "ban the sender"
|
256 |
-
sql.set_blacklist_strength(chat_id, 5, "0")
|
257 |
-
elif args[0].lower() == "tban":
|
258 |
-
if len(args) == 1:
|
259 |
-
teks = """It looks like you tried to set time value for blacklist but you didn't specified time; Try, `/blacklistmode tban <timevalue>`.
|
260 |
-
|
261 |
-
Examples of time value: 4m = 4 minutes, 3h = 3 hours, 6d = 6 days, 5w = 5 weeks."""
|
262 |
-
await send_message(
|
263 |
-
update.effective_message, teks, parse_mode="markdown"
|
264 |
-
)
|
265 |
-
return ""
|
266 |
-
restime = await extract_time(msg, args[1])
|
267 |
-
if not restime:
|
268 |
-
teks = """Invalid time value!
|
269 |
-
Example of time value: 4m = 4 minutes, 3h = 3 hours, 6d = 6 days, 5w = 5 weeks."""
|
270 |
-
await send_message(
|
271 |
-
update.effective_message, teks, parse_mode="markdown"
|
272 |
-
)
|
273 |
-
return ""
|
274 |
-
settypeblacklist = "temporarily ban for {}".format(args[1])
|
275 |
-
sql.set_blacklist_strength(chat_id, 6, str(args[1]))
|
276 |
-
elif args[0].lower() == "tmute":
|
277 |
-
if len(args) == 1:
|
278 |
-
teks = """It looks like you tried to set time value for blacklist but you didn't specified time; try, `/blacklistmode tmute <timevalue>`.
|
279 |
-
|
280 |
-
Examples of time value: 4m = 4 minutes, 3h = 3 hours, 6d = 6 days, 5w = 5 weeks."""
|
281 |
-
await send_message(
|
282 |
-
update.effective_message, teks, parse_mode="markdown"
|
283 |
-
)
|
284 |
-
return ""
|
285 |
-
restime = await extract_time(msg, args[1])
|
286 |
-
if not restime:
|
287 |
-
teks = """Invalid time value!
|
288 |
-
Examples of time value: 4m = 4 minutes, 3h = 3 hours, 6d = 6 days, 5w = 5 weeks."""
|
289 |
-
await send_message(
|
290 |
-
update.effective_message, teks, parse_mode="markdown"
|
291 |
-
)
|
292 |
-
return ""
|
293 |
-
settypeblacklist = "temporarily mute for {}".format(args[1])
|
294 |
-
sql.set_blacklist_strength(chat_id, 7, str(args[1]))
|
295 |
-
else:
|
296 |
-
await send_message(
|
297 |
-
update.effective_message,
|
298 |
-
"I only understand: off/del/warn/ban/kick/mute/tban/tmute!",
|
299 |
-
)
|
300 |
-
return ""
|
301 |
-
if conn:
|
302 |
-
text = "Changed blacklist mode: `{}` in *{}*!".format(
|
303 |
-
settypeblacklist,
|
304 |
-
chat_name,
|
305 |
-
)
|
306 |
-
else:
|
307 |
-
text = "Changed blacklist mode: `{}`!".format(settypeblacklist)
|
308 |
-
await send_message(update.effective_message, text, parse_mode="markdown")
|
309 |
-
return (
|
310 |
-
"<b>{}:</b>\n"
|
311 |
-
"<b>Admin:</b> {}\n"
|
312 |
-
"Changed the blacklist mode. will {}.".format(
|
313 |
-
html.escape(chat.title),
|
314 |
-
mention_html(user.id, html.escape(user.first_name)),
|
315 |
-
settypeblacklist,
|
316 |
-
)
|
317 |
-
)
|
318 |
-
else:
|
319 |
-
getmode, getvalue = sql.get_blacklist_setting(chat.id)
|
320 |
-
if getmode == 0:
|
321 |
-
settypeblacklist = "do nothing"
|
322 |
-
elif getmode == 1:
|
323 |
-
settypeblacklist = "delete"
|
324 |
-
elif getmode == 2:
|
325 |
-
settypeblacklist = "warn"
|
326 |
-
elif getmode == 3:
|
327 |
-
settypeblacklist = "mute"
|
328 |
-
elif getmode == 4:
|
329 |
-
settypeblacklist = "kick"
|
330 |
-
elif getmode == 5:
|
331 |
-
settypeblacklist = "ban"
|
332 |
-
elif getmode == 6:
|
333 |
-
settypeblacklist = "temporarily ban for {}".format(getvalue)
|
334 |
-
elif getmode == 7:
|
335 |
-
settypeblacklist = "temporarily mute for {}".format(getvalue)
|
336 |
-
if conn:
|
337 |
-
text = "Current blacklistmode: *{}* in *{}*.".format(
|
338 |
-
settypeblacklist,
|
339 |
-
chat_name,
|
340 |
-
)
|
341 |
-
else:
|
342 |
-
text = "Current blacklistmode: *{}*.".format(settypeblacklist)
|
343 |
-
await send_message(
|
344 |
-
update.effective_message, text, parse_mode=ParseMode.MARKDOWN
|
345 |
-
)
|
346 |
-
return ""
|
347 |
-
|
348 |
-
|
349 |
-
def findall(p, s):
|
350 |
-
i = s.find(p)
|
351 |
-
while i != -1:
|
352 |
-
yield i
|
353 |
-
i = s.find(p, i + 1)
|
354 |
-
|
355 |
-
|
356 |
-
@user_not_admin
|
357 |
-
async def del_blacklist(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
358 |
-
chat = update.effective_chat
|
359 |
-
message = update.effective_message
|
360 |
-
user = update.effective_user
|
361 |
-
bot = context.bot
|
362 |
-
to_match = await extract_text(message)
|
363 |
-
if not to_match:
|
364 |
-
return
|
365 |
-
if is_approved(chat.id, user.id):
|
366 |
-
return
|
367 |
-
getmode, value = sql.get_blacklist_setting(chat.id)
|
368 |
-
|
369 |
-
chat_filters = sql.get_chat_blacklist(chat.id)
|
370 |
-
for trigger in chat_filters:
|
371 |
-
pattern = r"( |^|[^\w])" + re.escape(trigger) + r"( |$|[^\w])"
|
372 |
-
if re.search(pattern, to_match, flags=re.IGNORECASE):
|
373 |
-
try:
|
374 |
-
if getmode == 0:
|
375 |
-
return
|
376 |
-
elif getmode == 1:
|
377 |
-
try:
|
378 |
-
await message.delete()
|
379 |
-
except BadRequest:
|
380 |
-
pass
|
381 |
-
elif getmode == 2:
|
382 |
-
try:
|
383 |
-
await message.delete()
|
384 |
-
except BadRequest:
|
385 |
-
pass
|
386 |
-
warn(
|
387 |
-
update.effective_user,
|
388 |
-
chat,
|
389 |
-
("Using blacklisted trigger: {}".format(trigger)),
|
390 |
-
message,
|
391 |
-
update.effective_user,
|
392 |
-
)
|
393 |
-
return
|
394 |
-
elif getmode == 3:
|
395 |
-
await message.delete()
|
396 |
-
await bot.restrict_chat_member(
|
397 |
-
chat.id,
|
398 |
-
update.effective_user.id,
|
399 |
-
permissions=ChatPermissions(can_send_messages=False),
|
400 |
-
)
|
401 |
-
await bot.sendMessage(
|
402 |
-
chat.id,
|
403 |
-
f"Muted {user.first_name} for using Blacklisted word: {trigger}!",
|
404 |
-
message_thread_id=message.message_thread_id
|
405 |
-
if chat.is_forum
|
406 |
-
else None,
|
407 |
-
)
|
408 |
-
return
|
409 |
-
elif getmode == 4:
|
410 |
-
await message.delete()
|
411 |
-
res = chat.unban_member(update.effective_user.id)
|
412 |
-
if res:
|
413 |
-
await bot.sendMessage(
|
414 |
-
chat.id,
|
415 |
-
f"Kicked {user.first_name} for using Blacklisted word: {trigger}!",
|
416 |
-
message_thread_id=message.message_thread_id
|
417 |
-
if chat.is_forum
|
418 |
-
else None,
|
419 |
-
)
|
420 |
-
return
|
421 |
-
elif getmode == 5:
|
422 |
-
await message.delete()
|
423 |
-
await chat.ban_member(user.id)
|
424 |
-
await bot.sendMessage(
|
425 |
-
chat.id,
|
426 |
-
f"Banned {user.first_name} for using Blacklisted word: {trigger}",
|
427 |
-
message_thread_id=message.message_thread_id
|
428 |
-
if chat.is_forum
|
429 |
-
else None,
|
430 |
-
)
|
431 |
-
return
|
432 |
-
elif getmode == 6:
|
433 |
-
await message.delete()
|
434 |
-
bantime = await extract_time(message, value)
|
435 |
-
await chat.ban_member(user.id, until_date=bantime)
|
436 |
-
await bot.sendMessage(
|
437 |
-
chat.id,
|
438 |
-
f"Banned {user.first_name} until '{value}' for using Blacklisted word: {trigger}!",
|
439 |
-
message_thread_id=message.message_thread_id
|
440 |
-
if chat.is_forum
|
441 |
-
else None,
|
442 |
-
)
|
443 |
-
return
|
444 |
-
elif getmode == 7:
|
445 |
-
await message.delete()
|
446 |
-
mutetime = await extract_time(message, value)
|
447 |
-
await bot.restrict_chat_member(
|
448 |
-
chat.id,
|
449 |
-
user.id,
|
450 |
-
until_date=mutetime,
|
451 |
-
permissions=ChatPermissions(can_send_messages=False),
|
452 |
-
)
|
453 |
-
await bot.sendMessage(
|
454 |
-
chat.id,
|
455 |
-
f"Muted {user.first_name} until '{value}' for using Blacklisted word: {trigger}!",
|
456 |
-
message_thread_id=message.message_thread_id
|
457 |
-
if chat.is_forum
|
458 |
-
else None,
|
459 |
-
)
|
460 |
-
return
|
461 |
-
except BadRequest as excp:
|
462 |
-
if excp.message != "Message to delete not found":
|
463 |
-
LOGGER.exception("Error while deleting blacklist message.")
|
464 |
-
break
|
465 |
-
|
466 |
-
|
467 |
-
async def __import_data__(chat_id, data, message):
|
468 |
-
# set chat blacklist
|
469 |
-
blacklist = data.get("blacklist", {})
|
470 |
-
for trigger in blacklist:
|
471 |
-
sql.add_to_blacklist(chat_id, trigger)
|
472 |
-
|
473 |
-
|
474 |
-
def __migrate__(old_chat_id, new_chat_id):
|
475 |
-
sql.migrate_chat(old_chat_id, new_chat_id)
|
476 |
-
|
477 |
-
|
478 |
-
def __chat_settings__(chat_id, user_id):
|
479 |
-
blacklisted = sql.num_blacklist_chat_filters(chat_id)
|
480 |
-
return "There are {} blacklisted words.".format(blacklisted)
|
481 |
-
|
482 |
-
|
483 |
-
def __stats__():
|
484 |
-
return "• {} blacklist triggers, across {} chats.".format(
|
485 |
-
sql.num_blacklist_filters(),
|
486 |
-
sql.num_blacklist_filter_chats(),
|
487 |
-
)
|
488 |
-
|
489 |
-
|
490 |
-
# <=================================================== HELP ====================================================>
|
491 |
-
|
492 |
-
|
493 |
-
__mod_name__ = "BLACKLIST"
|
494 |
-
|
495 |
-
__help__ = """
|
496 |
-
|
497 |
-
➠ Blacklists are used to stop certain triggers from being said in a group. Any time the trigger is mentioned, the message will immediately be deleted. A good combo is sometimes to pair this up with warn filters!
|
498 |
-
|
499 |
-
➠ *NOTE*: Blacklists do not affect group admins.
|
500 |
-
|
501 |
-
» /blacklist: View the current blacklisted words.
|
502 |
-
|
503 |
-
Admin only:
|
504 |
-
» /addblacklist <triggers>: Add a trigger to the blacklist. Each line is considered one trigger, so using different lines will allow you to add multiple triggers.
|
505 |
-
» /unblacklist <triggers>: Remove triggers from the blacklist. Same newline logic applies here, so you can remove multiple triggers at once.
|
506 |
-
» /blacklistmode <off/del/warn/ban/kick/mute/tban/tmute>: Action to perform when someone sends blacklisted words.
|
507 |
-
|
508 |
-
➠ Blacklist sticker is used to stop certain stickers. Whenever a sticker is sent, the message will be deleted immediately.
|
509 |
-
➠ *NOTE:* Blacklist stickers do not affect the group admin
|
510 |
-
» /blsticker: See current blacklisted sticker
|
511 |
-
➠ *Only admin:*
|
512 |
-
» /addblsticker <sticker link>: Add the sticker trigger to the black list. Can be added via reply sticker
|
513 |
-
» /unblsticker <sticker link>: Remove triggers from blacklist. The same newline logic applies here, so you can delete multiple triggers at once
|
514 |
-
» /rmblsticker <sticker link>: Same as above
|
515 |
-
» /blstickermode <delete/ban/tban/mute/tmute>: sets up a default action on what to do if users use blacklisted stickers
|
516 |
-
Note:
|
517 |
-
» <sticker link> can be https://t.me/addstickers/<sticker> or just <sticker> or reply to the sticker message
|
518 |
-
|
519 |
-
"""
|
520 |
-
|
521 |
-
# <================================================ HANDLER =======================================================>
|
522 |
-
BLACKLIST_HANDLER = DisableAbleCommandHandler(
|
523 |
-
"blacklist", blacklist, admin_ok=True, block=False
|
524 |
-
)
|
525 |
-
ADD_BLACKLIST_HANDLER = CommandHandler("addblacklist", add_blacklist, block=False)
|
526 |
-
UNBLACKLIST_HANDLER = CommandHandler("unblacklist", unblacklist, block=False)
|
527 |
-
BLACKLISTMODE_HANDLER = CommandHandler("blacklistmode", blacklist_mode, block=False)
|
528 |
-
BLACKLIST_DEL_HANDLER = MessageHandler(
|
529 |
-
(filters.TEXT | filters.COMMAND | filters.Sticker.ALL | filters.PHOTO)
|
530 |
-
& filters.ChatType.GROUPS,
|
531 |
-
del_blacklist,
|
532 |
-
block=False,
|
533 |
-
)
|
534 |
-
|
535 |
-
function(BLACKLIST_HANDLER)
|
536 |
-
function(ADD_BLACKLIST_HANDLER)
|
537 |
-
function(UNBLACKLIST_HANDLER)
|
538 |
-
function(BLACKLISTMODE_HANDLER)
|
539 |
-
function(BLACKLIST_DEL_HANDLER, group=BLACKLIST_GROUP)
|
540 |
-
|
541 |
-
__handlers__ = [
|
542 |
-
BLACKLIST_HANDLER,
|
543 |
-
ADD_BLACKLIST_HANDLER,
|
544 |
-
UNBLACKLIST_HANDLER,
|
545 |
-
BLACKLISTMODE_HANDLER,
|
546 |
-
(BLACKLIST_DEL_HANDLER, BLACKLIST_GROUP),
|
547 |
-
]
|
548 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/blacklist_stickers.py
DELETED
@@ -1,581 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import html
|
3 |
-
|
4 |
-
from telegram import ChatPermissions, Update
|
5 |
-
from telegram.constants import ParseMode
|
6 |
-
from telegram.error import BadRequest
|
7 |
-
from telegram.ext import CommandHandler, ContextTypes, MessageHandler, filters
|
8 |
-
from telegram.helpers import mention_html, mention_markdown
|
9 |
-
|
10 |
-
import Database.sql.blsticker_sql as sql
|
11 |
-
from Mikobot import LOGGER, dispatcher
|
12 |
-
from Mikobot.plugins.connection import connected
|
13 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
14 |
-
from Mikobot.plugins.helper_funcs.alternate import send_message
|
15 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin, user_not_admin
|
16 |
-
from Mikobot.plugins.helper_funcs.misc import split_message
|
17 |
-
from Mikobot.plugins.helper_funcs.string_handling import extract_time
|
18 |
-
from Mikobot.plugins.log_channel import loggable
|
19 |
-
from Mikobot.plugins.warns import warn
|
20 |
-
|
21 |
-
# <=======================================================================================================>
|
22 |
-
|
23 |
-
|
24 |
-
# <================================================ FUNCTION =======================================================>
|
25 |
-
async def blackliststicker(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
26 |
-
msg = update.effective_message # type: Optional[Message]
|
27 |
-
chat = update.effective_chat # type: Optional[Chat]
|
28 |
-
user = update.effective_user # type: Optional[User]
|
29 |
-
bot, args = context.bot, context.args
|
30 |
-
conn = await connected(bot, update, chat, user.id, need_admin=False)
|
31 |
-
if conn:
|
32 |
-
chat_id = conn
|
33 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
34 |
-
chat_name = chat_obj.title
|
35 |
-
else:
|
36 |
-
if chat.type == "private":
|
37 |
-
return
|
38 |
-
chat_id = update.effective_chat.id
|
39 |
-
chat_name = chat.title
|
40 |
-
|
41 |
-
sticker_list = "<b>List blacklisted stickers currently in {}:</b>\n".format(
|
42 |
-
chat_name,
|
43 |
-
)
|
44 |
-
|
45 |
-
all_stickerlist = sql.get_chat_stickers(chat_id)
|
46 |
-
|
47 |
-
if len(args) > 0 and args[0].lower() == "copy":
|
48 |
-
for trigger in all_stickerlist:
|
49 |
-
sticker_list += "<code>{}</code>\n".format(html.escape(trigger))
|
50 |
-
elif len(args) == 0:
|
51 |
-
for trigger in all_stickerlist:
|
52 |
-
sticker_list += " - <code>{}</code>\n".format(html.escape(trigger))
|
53 |
-
|
54 |
-
split_text = split_message(sticker_list)
|
55 |
-
for text in split_text:
|
56 |
-
if sticker_list == "<b>List blacklisted stickers currently in {}:</b>\n".format(
|
57 |
-
chat_name,
|
58 |
-
).format(html.escape(chat_name)):
|
59 |
-
await send_message(
|
60 |
-
update.effective_message,
|
61 |
-
"There are no blacklist stickers in <b>{}</b>!".format(
|
62 |
-
html.escape(chat_name),
|
63 |
-
),
|
64 |
-
parse_mode=ParseMode.HTML,
|
65 |
-
)
|
66 |
-
return
|
67 |
-
await send_message(
|
68 |
-
update.effective_message,
|
69 |
-
text,
|
70 |
-
parse_mode=ParseMode.HTML,
|
71 |
-
)
|
72 |
-
|
73 |
-
|
74 |
-
@check_admin(is_user=True)
|
75 |
-
async def add_blackliststicker(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
76 |
-
bot = context.bot
|
77 |
-
msg = update.effective_message # type: Optional[Message]
|
78 |
-
chat = update.effective_chat # type: Optional[Chat]
|
79 |
-
user = update.effective_user # type: Optional[User]
|
80 |
-
words = msg.text.split(None, 1)
|
81 |
-
bot = context.bot
|
82 |
-
conn = await connected(bot, update, chat, user.id)
|
83 |
-
if conn:
|
84 |
-
chat_id = conn
|
85 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
86 |
-
chat_name = chat_obj.title
|
87 |
-
else:
|
88 |
-
chat_id = update.effective_chat.id
|
89 |
-
if chat.type == "private":
|
90 |
-
return
|
91 |
-
else:
|
92 |
-
chat_name = chat.title
|
93 |
-
|
94 |
-
if len(words) > 1:
|
95 |
-
text = words[1].replace("https://t.me/addstickers/", "")
|
96 |
-
to_blacklist = list(
|
97 |
-
{trigger.strip() for trigger in text.split("\n") if trigger.strip()},
|
98 |
-
)
|
99 |
-
|
100 |
-
added = 0
|
101 |
-
for trigger in to_blacklist:
|
102 |
-
try:
|
103 |
-
get = await bot.getStickerSet(trigger)
|
104 |
-
sql.add_to_stickers(chat_id, trigger.lower())
|
105 |
-
added += 1
|
106 |
-
except BadRequest:
|
107 |
-
await send_message(
|
108 |
-
update.effective_message,
|
109 |
-
"Sticker `{}` can not be found!".format(trigger),
|
110 |
-
parse_mode="markdown",
|
111 |
-
)
|
112 |
-
|
113 |
-
if added == 0:
|
114 |
-
return
|
115 |
-
|
116 |
-
if len(to_blacklist) == 1:
|
117 |
-
await send_message(
|
118 |
-
update.effective_message,
|
119 |
-
"Sticker <code>{}</code> added to blacklist stickers in <b>{}</b>!".format(
|
120 |
-
html.escape(to_blacklist[0]),
|
121 |
-
html.escape(chat_name),
|
122 |
-
),
|
123 |
-
parse_mode=ParseMode.HTML,
|
124 |
-
)
|
125 |
-
else:
|
126 |
-
await send_message(
|
127 |
-
update.effective_message,
|
128 |
-
"<code>{}</code> stickers added to blacklist sticker in <b>{}</b>!".format(
|
129 |
-
added,
|
130 |
-
html.escape(chat_name),
|
131 |
-
),
|
132 |
-
parse_mode=ParseMode.HTML,
|
133 |
-
)
|
134 |
-
elif msg.reply_to_message:
|
135 |
-
added = 0
|
136 |
-
trigger = msg.reply_to_message.sticker.set_name
|
137 |
-
if trigger is None:
|
138 |
-
await send_message(
|
139 |
-
update.effective_message,
|
140 |
-
"Sticker is invalid!",
|
141 |
-
)
|
142 |
-
return
|
143 |
-
try:
|
144 |
-
get = await bot.getStickerSet(trigger)
|
145 |
-
sql.add_to_stickers(chat_id, trigger.lower())
|
146 |
-
added += 1
|
147 |
-
except BadRequest:
|
148 |
-
await send_message(
|
149 |
-
update.effective_message,
|
150 |
-
"Sticker `{}` can not be found!".format(trigger),
|
151 |
-
parse_mode="markdown",
|
152 |
-
)
|
153 |
-
|
154 |
-
if added == 0:
|
155 |
-
return
|
156 |
-
|
157 |
-
await send_message(
|
158 |
-
update.effective_message,
|
159 |
-
"Sticker <code>{}</code> added to blacklist stickers in <b>{}</b>!".format(
|
160 |
-
trigger,
|
161 |
-
html.escape(chat_name),
|
162 |
-
),
|
163 |
-
parse_mode=ParseMode.HTML,
|
164 |
-
)
|
165 |
-
else:
|
166 |
-
await send_message(
|
167 |
-
update.effective_message,
|
168 |
-
"Tell me what stickers you want to add to the blacklist.",
|
169 |
-
)
|
170 |
-
|
171 |
-
|
172 |
-
@check_admin(is_user=True)
|
173 |
-
async def unblackliststicker(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
174 |
-
bot = context.bot
|
175 |
-
msg = update.effective_message # type: Optional[Message]
|
176 |
-
chat = update.effective_chat # type: Optional[Chat]
|
177 |
-
user = update.effective_user # type: Optional[User]
|
178 |
-
words = msg.text.split(None, 1)
|
179 |
-
bot = context.bot
|
180 |
-
conn = await connected(bot, update, chat, user.id)
|
181 |
-
if conn:
|
182 |
-
chat_id = conn
|
183 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
184 |
-
chat_name = chat_obj.title
|
185 |
-
else:
|
186 |
-
chat_id = update.effective_chat.id
|
187 |
-
if chat.type == "private":
|
188 |
-
return
|
189 |
-
else:
|
190 |
-
chat_name = chat.title
|
191 |
-
|
192 |
-
if len(words) > 1:
|
193 |
-
text = words[1].replace("https://t.me/addstickers/", "")
|
194 |
-
to_unblacklist = list(
|
195 |
-
{trigger.strip() for trigger in text.split("\n") if trigger.strip()},
|
196 |
-
)
|
197 |
-
|
198 |
-
successful = 0
|
199 |
-
for trigger in to_unblacklist:
|
200 |
-
success = sql.rm_from_stickers(chat_id, trigger.lower())
|
201 |
-
if success:
|
202 |
-
successful += 1
|
203 |
-
|
204 |
-
if len(to_unblacklist) == 1:
|
205 |
-
if successful:
|
206 |
-
await send_message(
|
207 |
-
update.effective_message,
|
208 |
-
"Sticker <code>{}</code> deleted from blacklist in <b>{}</b>!".format(
|
209 |
-
html.escape(to_unblacklist[0]),
|
210 |
-
html.escape(chat_name),
|
211 |
-
),
|
212 |
-
parse_mode=ParseMode.HTML,
|
213 |
-
)
|
214 |
-
else:
|
215 |
-
await send_message(
|
216 |
-
update.effective_message,
|
217 |
-
"This sticker is not on the blacklist...!",
|
218 |
-
)
|
219 |
-
|
220 |
-
elif successful == len(to_unblacklist):
|
221 |
-
await send_message(
|
222 |
-
update.effective_message,
|
223 |
-
"Sticker <code>{}</code> deleted from blacklist in <b>{}</b>!".format(
|
224 |
-
successful,
|
225 |
-
html.escape(chat_name),
|
226 |
-
),
|
227 |
-
parse_mode=ParseMode.HTML,
|
228 |
-
)
|
229 |
-
|
230 |
-
elif not successful:
|
231 |
-
await send_message(
|
232 |
-
update.effective_message,
|
233 |
-
"None of these stickers exist, so they cannot be removed.",
|
234 |
-
parse_mode=ParseMode.HTML,
|
235 |
-
)
|
236 |
-
|
237 |
-
else:
|
238 |
-
await send_message(
|
239 |
-
update.effective_message,
|
240 |
-
"Sticker <code>{}</code> deleted from blacklist. {} did not exist, so it's not deleted.".format(
|
241 |
-
successful,
|
242 |
-
len(to_unblacklist) - successful,
|
243 |
-
),
|
244 |
-
parse_mode=ParseMode.HTML,
|
245 |
-
)
|
246 |
-
elif msg.reply_to_message:
|
247 |
-
trigger = msg.reply_to_message.sticker.set_name
|
248 |
-
if trigger is None:
|
249 |
-
await send_message(
|
250 |
-
update.effective_message,
|
251 |
-
"Sticker is invalid!",
|
252 |
-
)
|
253 |
-
return
|
254 |
-
success = sql.rm_from_stickers(chat_id, trigger.lower())
|
255 |
-
|
256 |
-
if success:
|
257 |
-
await send_message(
|
258 |
-
update.effective_message,
|
259 |
-
"Sticker <code>{}</code> deleted from blacklist in <b>{}</b>!".format(
|
260 |
-
trigger,
|
261 |
-
chat_name,
|
262 |
-
),
|
263 |
-
parse_mode=ParseMode.HTML,
|
264 |
-
)
|
265 |
-
else:
|
266 |
-
await send_message(
|
267 |
-
update.effective_message,
|
268 |
-
"{} not found on blacklisted stickers...!".format(trigger),
|
269 |
-
)
|
270 |
-
else:
|
271 |
-
await send_message(
|
272 |
-
update.effective_message,
|
273 |
-
"Tell me what stickers you want to add to the blacklist.",
|
274 |
-
)
|
275 |
-
|
276 |
-
|
277 |
-
@loggable
|
278 |
-
@check_admin(is_user=True)
|
279 |
-
async def blacklist_mode(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
280 |
-
chat = update.effective_chat # type: Optional[Chat]
|
281 |
-
user = update.effective_user # type: Optional[User]
|
282 |
-
msg = update.effective_message # type: Optional[Message]
|
283 |
-
bot, args = context.bot, context.args
|
284 |
-
conn = await connected(bot, update, chat, user.id, need_admin=True)
|
285 |
-
if conn:
|
286 |
-
chat = await dispatcher.bot.getChat(conn)
|
287 |
-
chat_id = conn
|
288 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
289 |
-
chat_name = chat_obj.title
|
290 |
-
else:
|
291 |
-
if update.effective_message.chat.type == "private":
|
292 |
-
await send_message(
|
293 |
-
update.effective_message,
|
294 |
-
"You can do this command in groups, not PM",
|
295 |
-
)
|
296 |
-
return ""
|
297 |
-
chat = update.effective_chat
|
298 |
-
chat_id = update.effective_chat.id
|
299 |
-
chat_name = update.effective_message.chat.title
|
300 |
-
|
301 |
-
if args:
|
302 |
-
if args[0].lower() in ["off", "nothing", "no"]:
|
303 |
-
settypeblacklist = "turn off"
|
304 |
-
sql.set_blacklist_strength(chat_id, 0, "0")
|
305 |
-
elif args[0].lower() in ["del", "delete"]:
|
306 |
-
settypeblacklist = "left, the message will be deleted"
|
307 |
-
sql.set_blacklist_strength(chat_id, 1, "0")
|
308 |
-
elif args[0].lower() == "warn":
|
309 |
-
settypeblacklist = "warned"
|
310 |
-
sql.set_blacklist_strength(chat_id, 2, "0")
|
311 |
-
elif args[0].lower() == "mute":
|
312 |
-
settypeblacklist = "muted"
|
313 |
-
sql.set_blacklist_strength(chat_id, 3, "0")
|
314 |
-
elif args[0].lower() == "kick":
|
315 |
-
settypeblacklist = "kicked"
|
316 |
-
sql.set_blacklist_strength(chat_id, 4, "0")
|
317 |
-
elif args[0].lower() == "ban":
|
318 |
-
settypeblacklist = "banned"
|
319 |
-
sql.set_blacklist_strength(chat_id, 5, "0")
|
320 |
-
elif args[0].lower() == "tban":
|
321 |
-
if len(args) == 1:
|
322 |
-
teks = """It looks like you are trying to set a temporary value to blacklist, but has not determined the time; use `/blstickermode tban <timevalue>`.
|
323 |
-
Examples of time values: 4m = 4 minute, 3h = 3 hours, 6d = 6 days, 5w = 5 weeks."""
|
324 |
-
await send_message(
|
325 |
-
update.effective_message,
|
326 |
-
teks,
|
327 |
-
parse_mode="markdown",
|
328 |
-
)
|
329 |
-
return
|
330 |
-
settypeblacklist = "temporary banned for {}".format(args[1])
|
331 |
-
sql.set_blacklist_strength(chat_id, 6, str(args[1]))
|
332 |
-
elif args[0].lower() == "tmute":
|
333 |
-
if len(args) == 1:
|
334 |
-
teks = """It looks like you are trying to set a temporary value to blacklist, but has not determined the time; use `/blstickermode tmute <timevalue>`.
|
335 |
-
Examples of time values: 4m = 4 minute, 3h = 3 hours, 6d = 6 days, 5w = 5 weeks."""
|
336 |
-
await send_message(
|
337 |
-
update.effective_message,
|
338 |
-
teks,
|
339 |
-
parse_mode="markdown",
|
340 |
-
)
|
341 |
-
return
|
342 |
-
settypeblacklist = "temporary muted for {}".format(args[1])
|
343 |
-
sql.set_blacklist_strength(chat_id, 7, str(args[1]))
|
344 |
-
else:
|
345 |
-
await send_message(
|
346 |
-
update.effective_message,
|
347 |
-
"I only understand off/del/warn/ban/kick/mute/tban/tmute!",
|
348 |
-
)
|
349 |
-
return
|
350 |
-
if conn:
|
351 |
-
text = "Blacklist sticker mode changed, users will be `{}` at *{}*!".format(
|
352 |
-
settypeblacklist,
|
353 |
-
chat_name,
|
354 |
-
)
|
355 |
-
else:
|
356 |
-
text = "Blacklist sticker mode changed, users will be `{}`!".format(
|
357 |
-
settypeblacklist,
|
358 |
-
)
|
359 |
-
await send_message(
|
360 |
-
update.effective_message,
|
361 |
-
text,
|
362 |
-
parse_mode="markdown",
|
363 |
-
)
|
364 |
-
return (
|
365 |
-
"<b>{}:</b>\n"
|
366 |
-
"<b>Admin:</b> {}\n"
|
367 |
-
"Changed sticker blacklist mode. users will be {}.".format(
|
368 |
-
html.escape(chat.title),
|
369 |
-
mention_html(user.id, html.escape(user.first_name)),
|
370 |
-
settypeblacklist,
|
371 |
-
)
|
372 |
-
)
|
373 |
-
else:
|
374 |
-
getmode, getvalue = sql.get_blacklist_setting(chat.id)
|
375 |
-
if getmode == 0:
|
376 |
-
settypeblacklist = "not active"
|
377 |
-
elif getmode == 1:
|
378 |
-
settypeblacklist = "delete"
|
379 |
-
elif getmode == 2:
|
380 |
-
settypeblacklist = "warn"
|
381 |
-
elif getmode == 3:
|
382 |
-
settypeblacklist = "mute"
|
383 |
-
elif getmode == 4:
|
384 |
-
settypeblacklist = "kick"
|
385 |
-
elif getmode == 5:
|
386 |
-
settypeblacklist = "ban"
|
387 |
-
elif getmode == 6:
|
388 |
-
settypeblacklist = "temporarily banned for {}".format(getvalue)
|
389 |
-
elif getmode == 7:
|
390 |
-
settypeblacklist = "temporarily muted for {}".format(getvalue)
|
391 |
-
if conn:
|
392 |
-
text = "Blacklist sticker mode is currently set to *{}* in *{}*.".format(
|
393 |
-
settypeblacklist,
|
394 |
-
chat_name,
|
395 |
-
)
|
396 |
-
else:
|
397 |
-
text = "Blacklist sticker mode is currently set to *{}*.".format(
|
398 |
-
settypeblacklist,
|
399 |
-
)
|
400 |
-
await send_message(
|
401 |
-
update.effective_message,
|
402 |
-
text,
|
403 |
-
parse_mode=ParseMode.MARKDOWN,
|
404 |
-
)
|
405 |
-
return ""
|
406 |
-
|
407 |
-
|
408 |
-
@user_not_admin
|
409 |
-
async def del_blackliststicker(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
410 |
-
bot = context.bot
|
411 |
-
chat = update.effective_chat # type: Optional[Chat]
|
412 |
-
message = update.effective_message # type: Optional[Message]
|
413 |
-
user = update.effective_user
|
414 |
-
to_match = message.sticker
|
415 |
-
if not to_match or not to_match.set_name:
|
416 |
-
return
|
417 |
-
bot = context.bot
|
418 |
-
getmode, value = sql.get_blacklist_setting(chat.id)
|
419 |
-
|
420 |
-
chat_filters = sql.get_chat_stickers(chat.id)
|
421 |
-
for trigger in chat_filters:
|
422 |
-
if to_match.set_name.lower() == trigger.lower():
|
423 |
-
try:
|
424 |
-
if getmode == 0:
|
425 |
-
return
|
426 |
-
elif getmode == 1:
|
427 |
-
await message.delete()
|
428 |
-
elif getmode == 2:
|
429 |
-
await message.delete()
|
430 |
-
warn(
|
431 |
-
update.effective_user,
|
432 |
-
chat,
|
433 |
-
"Using sticker '{}' which in blacklist stickers".format(
|
434 |
-
trigger,
|
435 |
-
),
|
436 |
-
message,
|
437 |
-
update.effective_user,
|
438 |
-
# conn=False,
|
439 |
-
)
|
440 |
-
return
|
441 |
-
elif getmode == 3:
|
442 |
-
await message.delete()
|
443 |
-
await bot.restrict_chat_member(
|
444 |
-
chat.id,
|
445 |
-
update.effective_user.id,
|
446 |
-
permissions=ChatPermissions(can_send_messages=False),
|
447 |
-
)
|
448 |
-
await bot.sendMessage(
|
449 |
-
chat.id,
|
450 |
-
"{} muted because using '{}' which in blacklist stickers".format(
|
451 |
-
mention_markdown(user.id, user.first_name),
|
452 |
-
trigger,
|
453 |
-
),
|
454 |
-
parse_mode="markdown",
|
455 |
-
message_thread_id=message.message_thread_id
|
456 |
-
if chat.is_forum
|
457 |
-
else None,
|
458 |
-
)
|
459 |
-
return
|
460 |
-
elif getmode == 4:
|
461 |
-
await message.delete()
|
462 |
-
res = chat.unban_member(update.effective_user.id)
|
463 |
-
if res:
|
464 |
-
await bot.sendMessage(
|
465 |
-
chat.id,
|
466 |
-
"{} kicked because using '{}' which in blacklist stickers".format(
|
467 |
-
mention_markdown(user.id, user.first_name),
|
468 |
-
trigger,
|
469 |
-
),
|
470 |
-
parse_mode="markdown",
|
471 |
-
message_thread_id=message.message_thread_id
|
472 |
-
if chat.is_forum
|
473 |
-
else None,
|
474 |
-
)
|
475 |
-
return
|
476 |
-
elif getmode == 5:
|
477 |
-
await message.delete()
|
478 |
-
await chat.ban_member(user.id)
|
479 |
-
await bot.sendMessage(
|
480 |
-
chat.id,
|
481 |
-
"{} banned because using '{}' which in blacklist stickers".format(
|
482 |
-
mention_markdown(user.id, user.first_name),
|
483 |
-
trigger,
|
484 |
-
),
|
485 |
-
parse_mode="markdown",
|
486 |
-
message_thread_id=message.message_thread_id
|
487 |
-
if chat.is_forum
|
488 |
-
else None,
|
489 |
-
)
|
490 |
-
return
|
491 |
-
elif getmode == 6:
|
492 |
-
await message.delete()
|
493 |
-
bantime = await extract_time(message, value)
|
494 |
-
await chat.ban_member(user.id, until_date=bantime)
|
495 |
-
await bot.sendMessage(
|
496 |
-
chat.id,
|
497 |
-
"{} banned for {} because using '{}' which in blacklist stickers".format(
|
498 |
-
mention_markdown(user.id, user.first_name),
|
499 |
-
value,
|
500 |
-
trigger,
|
501 |
-
),
|
502 |
-
parse_mode="markdown",
|
503 |
-
message_thread_id=message.message_thread_id
|
504 |
-
if chat.is_forum
|
505 |
-
else None,
|
506 |
-
)
|
507 |
-
return
|
508 |
-
elif getmode == 7:
|
509 |
-
await message.delete()
|
510 |
-
mutetime = await extract_time(message, value)
|
511 |
-
await bot.restrict_chat_member(
|
512 |
-
chat.id,
|
513 |
-
user.id,
|
514 |
-
permissions=ChatPermissions(can_send_messages=False),
|
515 |
-
until_date=mutetime,
|
516 |
-
)
|
517 |
-
await bot.sendMessage(
|
518 |
-
chat.id,
|
519 |
-
"{} muted for {} because using '{}' which in blacklist stickers".format(
|
520 |
-
mention_markdown(user.id, user.first_name),
|
521 |
-
value,
|
522 |
-
trigger,
|
523 |
-
),
|
524 |
-
parse_mode="markdown",
|
525 |
-
message_thread_id=message.message_thread_id
|
526 |
-
if chat.is_forum
|
527 |
-
else None,
|
528 |
-
)
|
529 |
-
return
|
530 |
-
except BadRequest as excp:
|
531 |
-
if excp.message != "Message to delete not found":
|
532 |
-
LOGGER.exception("Error while deleting blacklist message.")
|
533 |
-
break
|
534 |
-
|
535 |
-
|
536 |
-
async def __import_data__(chat_id, data, message):
|
537 |
-
# set chat blacklist
|
538 |
-
blacklist = data.get("sticker_blacklist", {})
|
539 |
-
for trigger in blacklist:
|
540 |
-
sql.add_to_stickers(chat_id, trigger)
|
541 |
-
|
542 |
-
|
543 |
-
def __migrate__(old_chat_id, new_chat_id):
|
544 |
-
sql.migrate_chat(old_chat_id, new_chat_id)
|
545 |
-
|
546 |
-
|
547 |
-
def __chat_settings__(chat_id, user_id):
|
548 |
-
blacklisted = sql.num_stickers_chat_filters(chat_id)
|
549 |
-
return "There are `{} `blacklisted stickers.".format(blacklisted)
|
550 |
-
|
551 |
-
|
552 |
-
def __stats__():
|
553 |
-
return "• {} blacklist stickers, across {} chats.".format(
|
554 |
-
sql.num_stickers_filters(),
|
555 |
-
sql.num_stickers_filter_chats(),
|
556 |
-
)
|
557 |
-
|
558 |
-
|
559 |
-
__mod_name__ = "Stickers Blacklist"
|
560 |
-
|
561 |
-
# <================================================ HANDLER =======================================================>
|
562 |
-
BLACKLIST_STICKER_HANDLER = DisableAbleCommandHandler(
|
563 |
-
"blsticker", blackliststicker, admin_ok=True, block=False
|
564 |
-
)
|
565 |
-
ADDBLACKLIST_STICKER_HANDLER = DisableAbleCommandHandler(
|
566 |
-
"addblsticker", add_blackliststicker, block=False
|
567 |
-
)
|
568 |
-
UNBLACKLIST_STICKER_HANDLER = CommandHandler(
|
569 |
-
["unblsticker", "rmblsticker"], unblackliststicker, block=False
|
570 |
-
)
|
571 |
-
BLACKLISTMODE_HANDLER = CommandHandler("blstickermode", blacklist_mode, block=False)
|
572 |
-
BLACKLIST_STICKER_DEL_HANDLER = MessageHandler(
|
573 |
-
filters.Sticker.ALL & filters.ChatType.GROUPS, del_blackliststicker, block=False
|
574 |
-
)
|
575 |
-
|
576 |
-
dispatcher.add_handler(BLACKLIST_STICKER_HANDLER)
|
577 |
-
dispatcher.add_handler(ADDBLACKLIST_STICKER_HANDLER)
|
578 |
-
dispatcher.add_handler(UNBLACKLIST_STICKER_HANDLER)
|
579 |
-
dispatcher.add_handler(BLACKLISTMODE_HANDLER)
|
580 |
-
dispatcher.add_handler(BLACKLIST_STICKER_DEL_HANDLER)
|
581 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/botadmins.py
DELETED
@@ -1,108 +0,0 @@
|
|
1 |
-
# SOURCE https://github.com/Team-ProjectCodeX
|
2 |
-
# CREATED BY https://t.me/O_okarma
|
3 |
-
# PROVIDED BY https://t.me/ProjectCodeX
|
4 |
-
|
5 |
-
# <============================================== IMPORTS =========================================================>
|
6 |
-
|
7 |
-
from telegram import Update
|
8 |
-
from telegram.constants import ParseMode
|
9 |
-
from telegram.error import TelegramError
|
10 |
-
from telegram.ext import CommandHandler, ContextTypes
|
11 |
-
|
12 |
-
from Mikobot import DEMONS, DEV_USERS, DRAGONS, LOGGER, OWNER_ID, WOLVES, function
|
13 |
-
from Mikobot.plugins.helper_funcs.chat_status import support_plus
|
14 |
-
from Mikobot.utils.parser import mention_html
|
15 |
-
|
16 |
-
# <=======================================================================================================>
|
17 |
-
|
18 |
-
|
19 |
-
# <================================================ FUNCTION =======================================================>
|
20 |
-
async def get_chat_member(context: ContextTypes.DEFAULT_TYPE, user_id):
|
21 |
-
try:
|
22 |
-
return await context.bot.get_chat_member(user_id, user_id)
|
23 |
-
except TelegramError as e:
|
24 |
-
LOGGER.error(f"Error getting chat member {user_id}: {e}")
|
25 |
-
return None
|
26 |
-
|
27 |
-
|
28 |
-
async def get_user_info(context: ContextTypes.DEFAULT_TYPE, user_id):
|
29 |
-
user_info = await get_chat_member(context, user_id)
|
30 |
-
return user_info.user.first_name if user_info else "Unknown User"
|
31 |
-
|
32 |
-
|
33 |
-
async def get_users_info(context: ContextTypes.DEFAULT_TYPE, user_ids):
|
34 |
-
return [(await get_user_info(context, user_id), user_id) for user_id in user_ids]
|
35 |
-
|
36 |
-
|
37 |
-
async def get_users_list(context: ContextTypes.DEFAULT_TYPE, user_ids):
|
38 |
-
return [
|
39 |
-
f"• {await mention_html(name, user_id)} (<code>{user_id}</code>)"
|
40 |
-
for name, user_id in await get_users_info(context, user_ids)
|
41 |
-
]
|
42 |
-
|
43 |
-
|
44 |
-
@support_plus
|
45 |
-
async def botstaff(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
46 |
-
try:
|
47 |
-
owner = await get_chat_member(context, OWNER_ID)
|
48 |
-
owner_info = await mention_html(owner.user.first_name, owner.user.id)
|
49 |
-
reply = f"✪ <b>CREATOR :</b> {owner_info} (<code>{OWNER_ID}</code>)\n"
|
50 |
-
except TelegramError as e:
|
51 |
-
LOGGER.error(f"Error getting owner information: {e}")
|
52 |
-
reply = ""
|
53 |
-
|
54 |
-
true_dev = list(set(DEV_USERS) - {OWNER_ID})
|
55 |
-
reply += "\n\n➪ <b>SPECIAL GRADE USERS :</b>\n"
|
56 |
-
reply += "\n".join(await get_users_list(context, true_dev)) or "No Dev Users"
|
57 |
-
|
58 |
-
true_sudo = list(set(DRAGONS) - set(DEV_USERS))
|
59 |
-
reply += "\n\n➪ <b>A GRADE USERS :</b>\n"
|
60 |
-
reply += "\n".join(await get_users_list(context, true_sudo)) or "No Sudo Users"
|
61 |
-
|
62 |
-
reply += "\n\n➪ <b>B GRADE USERS :</b>\n"
|
63 |
-
reply += "\n".join(await get_users_list(context, DEMONS)) or "No Demon Users"
|
64 |
-
|
65 |
-
reply += "\n\n➪ <b>NORMAL GRADE USERS :</b>\n"
|
66 |
-
reply += (
|
67 |
-
"\n".join(await get_users_list(context, WOLVES))
|
68 |
-
or "No additional whitelisted users"
|
69 |
-
)
|
70 |
-
|
71 |
-
await update.message.reply_text(reply, parse_mode=ParseMode.HTML)
|
72 |
-
LOGGER.info(
|
73 |
-
f"{update.message.from_user.id} fetched botstaff in {update.message.chat.id}"
|
74 |
-
)
|
75 |
-
|
76 |
-
|
77 |
-
# <================================================ HANDLER =======================================================>
|
78 |
-
function(CommandHandler("botadmins", botstaff, block=False))
|
79 |
-
# <================================================ END =======================================================>
|
80 |
-
|
81 |
-
|
82 |
-
# <=================================================== HELP ====================================================>
|
83 |
-
__help__ = """
|
84 |
-
➠ *BOT ADMINS ONLY:*
|
85 |
-
|
86 |
-
» /stats: Shows bot stats.
|
87 |
-
|
88 |
-
» /ping: see ping.
|
89 |
-
|
90 |
-
» /gban: Global ban.
|
91 |
-
|
92 |
-
» /gbanlist: Shows gban list.
|
93 |
-
|
94 |
-
» /botadmins: Opens Bot admin lists.
|
95 |
-
|
96 |
-
» /gcast: Advance broadcast system. Just reply to any message.
|
97 |
-
|
98 |
-
➠ *Write with text message*
|
99 |
-
|
100 |
-
» /broadcastall
|
101 |
-
|
102 |
-
» /broadcastusers
|
103 |
-
|
104 |
-
» /broadcastgroups
|
105 |
-
"""
|
106 |
-
|
107 |
-
__mod_name__ = "BOT-ADMIN"
|
108 |
-
# <================================================ HANDLER =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/chatbot.py
DELETED
@@ -1,188 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import asyncio
|
3 |
-
import html
|
4 |
-
import json
|
5 |
-
import re
|
6 |
-
from typing import Optional
|
7 |
-
|
8 |
-
import requests
|
9 |
-
from telegram import (
|
10 |
-
CallbackQuery,
|
11 |
-
Chat,
|
12 |
-
InlineKeyboardButton,
|
13 |
-
InlineKeyboardMarkup,
|
14 |
-
Update,
|
15 |
-
User,
|
16 |
-
)
|
17 |
-
from telegram.constants import ParseMode
|
18 |
-
from telegram.error import BadRequest, Forbidden, RetryAfter
|
19 |
-
from telegram.ext import (
|
20 |
-
CallbackQueryHandler,
|
21 |
-
CommandHandler,
|
22 |
-
ContextTypes,
|
23 |
-
MessageHandler,
|
24 |
-
filters,
|
25 |
-
)
|
26 |
-
from telegram.helpers import mention_html
|
27 |
-
|
28 |
-
import Database.sql.kuki_sql as sql
|
29 |
-
from Mikobot import function
|
30 |
-
from Mikobot.plugins.log_channel import gloggable
|
31 |
-
|
32 |
-
# <=======================================================================================================>
|
33 |
-
|
34 |
-
|
35 |
-
# <================================================ FUNCTION =======================================================>
|
36 |
-
@gloggable
|
37 |
-
async def kukirm(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
38 |
-
query: Optional[CallbackQuery] = update.callback_query
|
39 |
-
user: Optional[User] = update.effective_user
|
40 |
-
if match := re.match(r"rm_chat\((.+?)\)", query.data):
|
41 |
-
user_id = match[1]
|
42 |
-
chat: Optional[Chat] = update.effective_chat
|
43 |
-
if is_kuki := sql.rem_kuki(chat.id):
|
44 |
-
sql.rem_kuki(user_id)
|
45 |
-
return (
|
46 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
47 |
-
f"AI_DISABLED\n"
|
48 |
-
f"<b>Admin:</b> {mention_html(user.id, html.escape(user.first_name))}\n"
|
49 |
-
)
|
50 |
-
else:
|
51 |
-
await update.effective_message.edit_text(
|
52 |
-
f"Chatbot disable by {mention_html(user.id, user.first_name)}.",
|
53 |
-
parse_mode=ParseMode.HTML,
|
54 |
-
)
|
55 |
-
|
56 |
-
return ""
|
57 |
-
|
58 |
-
|
59 |
-
@gloggable
|
60 |
-
async def kukiadd(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
61 |
-
query: Optional[CallbackQuery] = update.callback_query
|
62 |
-
user: Optional[User] = update.effective_user
|
63 |
-
if match := re.match(r"add_chat\((.+?)\)", query.data):
|
64 |
-
user_id = match[1]
|
65 |
-
chat: Optional[Chat] = update.effective_chat
|
66 |
-
if is_kuki := sql.set_kuki(chat.id):
|
67 |
-
sql.set_kuki(user_id)
|
68 |
-
return (
|
69 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
70 |
-
f"AI_ENABLE\n"
|
71 |
-
f"<b>Admin:</b> {mention_html(user.id, html.escape(user.first_name))}\n"
|
72 |
-
)
|
73 |
-
else:
|
74 |
-
await update.effective_message.edit_text(
|
75 |
-
f"Hey Darling Chatbot enable by {mention_html(user.id, user.first_name)}.",
|
76 |
-
parse_mode=ParseMode.HTML,
|
77 |
-
)
|
78 |
-
|
79 |
-
return ""
|
80 |
-
|
81 |
-
|
82 |
-
@gloggable
|
83 |
-
async def kuki(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
84 |
-
update.effective_user
|
85 |
-
message = update.effective_message
|
86 |
-
msg = "Choose an option"
|
87 |
-
keyboard = InlineKeyboardMarkup(
|
88 |
-
[
|
89 |
-
[InlineKeyboardButton(text="Enable", callback_data="add_chat({})")],
|
90 |
-
[InlineKeyboardButton(text="Disable", callback_data="rm_chat({})")],
|
91 |
-
]
|
92 |
-
)
|
93 |
-
await message.reply_text(
|
94 |
-
msg,
|
95 |
-
reply_markup=keyboard,
|
96 |
-
parse_mode=ParseMode.HTML,
|
97 |
-
)
|
98 |
-
|
99 |
-
|
100 |
-
async def kuki_message(context: ContextTypes.DEFAULT_TYPE, message):
|
101 |
-
reply_message = message.reply_to_message
|
102 |
-
if message.text.lower() == "kuki":
|
103 |
-
return True
|
104 |
-
if reply_message:
|
105 |
-
if reply_message.from_user.id == (await context.bot.get_me()).id:
|
106 |
-
return True
|
107 |
-
else:
|
108 |
-
return False
|
109 |
-
|
110 |
-
|
111 |
-
async def chatbot(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
112 |
-
update.effective_user
|
113 |
-
message = update.effective_message
|
114 |
-
chat_id = update.effective_chat.id
|
115 |
-
bot = context.bot
|
116 |
-
is_kuki = sql.is_kuki(chat_id)
|
117 |
-
if not is_kuki:
|
118 |
-
return
|
119 |
-
|
120 |
-
if message.text and not message.document:
|
121 |
-
if not await kuki_message(context, message):
|
122 |
-
return
|
123 |
-
Message = message.text
|
124 |
-
await bot.send_chat_action(chat_id, action="typing")
|
125 |
-
kukiurl = requests.get(
|
126 |
-
f"http://api.brainshop.ai/get?bid=176809&key=lbMN8CXTGzhn1NKG&uid=[user]&msg={Message}"
|
127 |
-
)
|
128 |
-
|
129 |
-
Kuki = json.loads(kukiurl.text)
|
130 |
-
kuki = Kuki["cnt"]
|
131 |
-
|
132 |
-
await asyncio.sleep(0.3)
|
133 |
-
await message.reply_text(kuki)
|
134 |
-
|
135 |
-
|
136 |
-
async def list_all_chats(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
137 |
-
chats = sql.get_all_kuki_chats()
|
138 |
-
text = "<b>Neko Enabled Chats</b>\n"
|
139 |
-
for chat in chats:
|
140 |
-
try:
|
141 |
-
x = await context.bot.get_chat(int(*chat))
|
142 |
-
name = x.title or x.first_name
|
143 |
-
text += f"• <code>{name}</code>\n"
|
144 |
-
except (BadRequest, Forbidden):
|
145 |
-
sql.rem_kuki(*chat)
|
146 |
-
except RetryAfter as e:
|
147 |
-
await asyncio.sleep(e.retry_after)
|
148 |
-
await update.effective_message.reply_text(text, parse_mode="HTML")
|
149 |
-
|
150 |
-
|
151 |
-
# <=================================================== HELP ====================================================>
|
152 |
-
|
153 |
-
|
154 |
-
__help__ = """
|
155 |
-
➠ *Admins only command*:
|
156 |
-
|
157 |
-
» /chatbot: shows chatbot panel.
|
158 |
-
"""
|
159 |
-
|
160 |
-
__mod_name__ = "CHATBOT"
|
161 |
-
|
162 |
-
|
163 |
-
# <================================================ HANDLER =======================================================>
|
164 |
-
CHATBOTK_HANDLER = CommandHandler("chatbot", kuki, block=False)
|
165 |
-
ADD_CHAT_HANDLER = CallbackQueryHandler(kukiadd, pattern=r"add_chat", block=False)
|
166 |
-
RM_CHAT_HANDLER = CallbackQueryHandler(kukirm, pattern=r"rm_chat", block=False)
|
167 |
-
CHATBOT_HANDLER = MessageHandler(
|
168 |
-
filters.TEXT
|
169 |
-
& (~filters.Regex(r"^#[^\s]+") & ~filters.Regex(r"^!") & ~filters.Regex(r"^\/")),
|
170 |
-
chatbot,
|
171 |
-
block=False,
|
172 |
-
)
|
173 |
-
LIST_ALL_CHATS_HANDLER = CommandHandler("allchats", list_all_chats, block=False)
|
174 |
-
|
175 |
-
function(ADD_CHAT_HANDLER)
|
176 |
-
function(CHATBOTK_HANDLER)
|
177 |
-
function(RM_CHAT_HANDLER)
|
178 |
-
function(LIST_ALL_CHATS_HANDLER)
|
179 |
-
function(CHATBOT_HANDLER)
|
180 |
-
|
181 |
-
__handlers__ = [
|
182 |
-
ADD_CHAT_HANDLER,
|
183 |
-
CHATBOTK_HANDLER,
|
184 |
-
RM_CHAT_HANDLER,
|
185 |
-
LIST_ALL_CHATS_HANDLER,
|
186 |
-
CHATBOT_HANDLER,
|
187 |
-
]
|
188 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/connection.py
DELETED
@@ -1,441 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import re
|
3 |
-
import time
|
4 |
-
|
5 |
-
from telegram import Bot, InlineKeyboardButton, InlineKeyboardMarkup, Update
|
6 |
-
from telegram.constants import ParseMode
|
7 |
-
from telegram.error import BadRequest, Forbidden
|
8 |
-
from telegram.ext import CallbackQueryHandler, CommandHandler, ContextTypes
|
9 |
-
|
10 |
-
import Database.sql.connection_sql as sql
|
11 |
-
from Mikobot import DEV_USERS, DRAGONS, dispatcher, function
|
12 |
-
from Mikobot.plugins.helper_funcs import chat_status
|
13 |
-
from Mikobot.plugins.helper_funcs.alternate import send_message, typing_action
|
14 |
-
|
15 |
-
# <=======================================================================================================>
|
16 |
-
|
17 |
-
check_admin = chat_status.check_admin
|
18 |
-
|
19 |
-
|
20 |
-
# <================================================ FUNCTION =======================================================>
|
21 |
-
@check_admin(is_user=True)
|
22 |
-
@typing_action
|
23 |
-
async def allow_connections(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
24 |
-
chat = update.effective_chat
|
25 |
-
args = context.args
|
26 |
-
|
27 |
-
if chat.type != chat.PRIVATE:
|
28 |
-
if len(args) >= 1:
|
29 |
-
var = args[0]
|
30 |
-
if var == "no":
|
31 |
-
sql.set_allow_connect_to_chat(chat.id, False)
|
32 |
-
await send_message(
|
33 |
-
update.effective_message,
|
34 |
-
"Connection has been disabled for this chat.",
|
35 |
-
)
|
36 |
-
elif var == "yes":
|
37 |
-
sql.set_allow_connect_to_chat(chat.id, True)
|
38 |
-
await send_message(
|
39 |
-
update.effective_message,
|
40 |
-
"Connection has been enabled for this chat.",
|
41 |
-
)
|
42 |
-
else:
|
43 |
-
await send_message(
|
44 |
-
update.effective_message,
|
45 |
-
"Please enter 'yes' or 'no'!",
|
46 |
-
parse_mode=ParseMode.MARKDOWN,
|
47 |
-
)
|
48 |
-
else:
|
49 |
-
get_settings = sql.allow_connect_to_chat(chat.id)
|
50 |
-
if get_settings:
|
51 |
-
await send_message(
|
52 |
-
update.effective_message,
|
53 |
-
"Connections to this group are *allowed* for members!",
|
54 |
-
parse_mode=ParseMode.MARKDOWN,
|
55 |
-
)
|
56 |
-
else:
|
57 |
-
await send_message(
|
58 |
-
update.effective_message,
|
59 |
-
"Connection to this group is *not allowed* for members!",
|
60 |
-
parse_mode=ParseMode.MARKDOWN,
|
61 |
-
)
|
62 |
-
else:
|
63 |
-
await send_message(
|
64 |
-
update.effective_message,
|
65 |
-
"This command is for groups only, not in PM!",
|
66 |
-
)
|
67 |
-
|
68 |
-
|
69 |
-
@typing_action
|
70 |
-
async def connection_chat(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
71 |
-
chat = update.effective_chat
|
72 |
-
user = update.effective_user
|
73 |
-
|
74 |
-
conn = await connected(context.bot, update, chat, user.id, need_admin=True)
|
75 |
-
|
76 |
-
if conn:
|
77 |
-
chat = await dispatcher.bot.getChat(conn)
|
78 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
79 |
-
chat_name = chat_obj.title
|
80 |
-
else:
|
81 |
-
if update.effective_message.chat.type != "private":
|
82 |
-
return
|
83 |
-
chat = update.effective_chat
|
84 |
-
chat_name = update.effective_message.chat.title
|
85 |
-
|
86 |
-
if conn:
|
87 |
-
message = "You are currently connected to {}.\n".format(chat_name)
|
88 |
-
else:
|
89 |
-
message = "You are currently not connected in any group.\n"
|
90 |
-
await send_message(update.effective_message, message, parse_mode="markdown")
|
91 |
-
|
92 |
-
|
93 |
-
@typing_action
|
94 |
-
async def connect_chat(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
95 |
-
chat = update.effective_chat
|
96 |
-
user = update.effective_user
|
97 |
-
args = context.args
|
98 |
-
|
99 |
-
if update.effective_chat.type == "private":
|
100 |
-
if args and len(args) >= 1:
|
101 |
-
try:
|
102 |
-
connect_chat = int(args[0])
|
103 |
-
getstatusadmin = await context.bot.get_chat_member(
|
104 |
-
connect_chat,
|
105 |
-
update.effective_message.from_user.id,
|
106 |
-
)
|
107 |
-
except ValueError:
|
108 |
-
try:
|
109 |
-
connect_chat = str(args[0])
|
110 |
-
get_chat = await context.bot.getChat(connect_chat)
|
111 |
-
connect_chat = get_chat.id
|
112 |
-
getstatusadmin = await context.bot.get_chat_member(
|
113 |
-
connect_chat,
|
114 |
-
update.effective_message.from_user.id,
|
115 |
-
)
|
116 |
-
except BadRequest:
|
117 |
-
await send_message(update.effective_message, "Invalid Chat ID!")
|
118 |
-
return
|
119 |
-
except BadRequest:
|
120 |
-
await send_message(update.effective_message, "Invalid Chat ID!")
|
121 |
-
return
|
122 |
-
|
123 |
-
isadmin = getstatusadmin.status in ("administrator", "creator")
|
124 |
-
ismember = getstatusadmin.status in ("member")
|
125 |
-
isallow = sql.allow_connect_to_chat(connect_chat)
|
126 |
-
|
127 |
-
if (isadmin) or (isallow and ismember) or (user.id in DRAGONS):
|
128 |
-
connection_status = sql.connect(
|
129 |
-
update.effective_message.from_user.id,
|
130 |
-
connect_chat,
|
131 |
-
)
|
132 |
-
if connection_status:
|
133 |
-
conn = await connected(
|
134 |
-
context.bot, update, chat, user.id, need_admin=False
|
135 |
-
)
|
136 |
-
conn_chat = await dispatcher.bot.getChat(conn)
|
137 |
-
chat_name = conn_chat.title
|
138 |
-
await send_message(
|
139 |
-
update.effective_message,
|
140 |
-
"Successfully connected to *{}*. Use /helpconnect to check available commands.".format(
|
141 |
-
chat_name,
|
142 |
-
),
|
143 |
-
parse_mode=ParseMode.MARKDOWN,
|
144 |
-
)
|
145 |
-
sql.add_history_conn(user.id, str(conn_chat.id), chat_name)
|
146 |
-
else:
|
147 |
-
await send_message(update.effective_message, "Connection failed!")
|
148 |
-
else:
|
149 |
-
await send_message(
|
150 |
-
update.effective_message,
|
151 |
-
"Connection to this chat is not allowed!",
|
152 |
-
)
|
153 |
-
else:
|
154 |
-
gethistory = sql.get_history_conn(user.id)
|
155 |
-
if gethistory:
|
156 |
-
buttons = [
|
157 |
-
InlineKeyboardButton(
|
158 |
-
text="❎ Close Button",
|
159 |
-
callback_data="connect_close",
|
160 |
-
),
|
161 |
-
InlineKeyboardButton(
|
162 |
-
text="🧹 Clear History",
|
163 |
-
callback_data="connect_clear",
|
164 |
-
),
|
165 |
-
]
|
166 |
-
else:
|
167 |
-
buttons = []
|
168 |
-
conn = await connected(context.bot, update, chat, user.id, need_admin=False)
|
169 |
-
if conn:
|
170 |
-
connectedchat = await dispatcher.bot.getChat(conn)
|
171 |
-
text = "You are currently connected to *{}* (`{}`)".format(
|
172 |
-
connectedchat.title,
|
173 |
-
conn,
|
174 |
-
)
|
175 |
-
buttons.append(
|
176 |
-
InlineKeyboardButton(
|
177 |
-
text="🔌 Disconnect",
|
178 |
-
callback_data="connect_disconnect",
|
179 |
-
),
|
180 |
-
)
|
181 |
-
else:
|
182 |
-
text = "Write the chat ID or tag to connect!"
|
183 |
-
if gethistory:
|
184 |
-
text += "\n\n*Connection History:*\n"
|
185 |
-
text += "╒═══「 *Info* 」\n"
|
186 |
-
text += "│ Sorted: `Newest`\n"
|
187 |
-
text += "│\n"
|
188 |
-
buttons = [buttons]
|
189 |
-
for x in sorted(gethistory.keys(), reverse=True):
|
190 |
-
htime = time.strftime("%d/%m/%Y", time.localtime(x))
|
191 |
-
text += "╞═「 *{}* 」\n│ `{}`\n│ `{}`\n".format(
|
192 |
-
gethistory[x]["chat_name"],
|
193 |
-
gethistory[x]["chat_id"],
|
194 |
-
htime,
|
195 |
-
)
|
196 |
-
text += "│\n"
|
197 |
-
buttons.append(
|
198 |
-
[
|
199 |
-
InlineKeyboardButton(
|
200 |
-
text=gethistory[x]["chat_name"],
|
201 |
-
callback_data="connect({})".format(
|
202 |
-
gethistory[x]["chat_id"],
|
203 |
-
),
|
204 |
-
),
|
205 |
-
],
|
206 |
-
)
|
207 |
-
text += "╘══「 Total {} Chats 」".format(
|
208 |
-
str(len(gethistory)) + " (max)"
|
209 |
-
if len(gethistory) == 5
|
210 |
-
else str(len(gethistory)),
|
211 |
-
)
|
212 |
-
conn_hist = InlineKeyboardMarkup(buttons)
|
213 |
-
elif buttons:
|
214 |
-
conn_hist = InlineKeyboardMarkup([buttons])
|
215 |
-
else:
|
216 |
-
conn_hist = None
|
217 |
-
await send_message(
|
218 |
-
update.effective_message,
|
219 |
-
text,
|
220 |
-
parse_mode="markdown",
|
221 |
-
reply_markup=conn_hist,
|
222 |
-
)
|
223 |
-
|
224 |
-
else:
|
225 |
-
getstatusadmin = await context.bot.get_chat_member(
|
226 |
-
chat.id,
|
227 |
-
update.effective_message.from_user.id,
|
228 |
-
)
|
229 |
-
isadmin = getstatusadmin.status in ("administrator", "creator")
|
230 |
-
ismember = getstatusadmin.status in ("member")
|
231 |
-
isallow = sql.allow_connect_to_chat(chat.id)
|
232 |
-
if (isadmin) or (isallow and ismember) or (user.id in DRAGONS):
|
233 |
-
connection_status = sql.connect(
|
234 |
-
update.effective_message.from_user.id,
|
235 |
-
chat.id,
|
236 |
-
)
|
237 |
-
if connection_status:
|
238 |
-
chat_obj = await dispatcher.bot.getChat(chat.id)
|
239 |
-
chat_name = chat_obj.title
|
240 |
-
await send_message(
|
241 |
-
update.effective_message,
|
242 |
-
"Successfully connected to *{}*.".format(chat_name),
|
243 |
-
parse_mode=ParseMode.MARKDOWN,
|
244 |
-
)
|
245 |
-
try:
|
246 |
-
sql.add_history_conn(user.id, str(chat.id), chat_name)
|
247 |
-
await context.bot.send_message(
|
248 |
-
update.effective_message.from_user.id,
|
249 |
-
"You are connected to *{}*. \nUse `/helpconnect` to check available commands.".format(
|
250 |
-
chat_name,
|
251 |
-
),
|
252 |
-
parse_mode="markdown",
|
253 |
-
)
|
254 |
-
except BadRequest:
|
255 |
-
pass
|
256 |
-
except Forbidden:
|
257 |
-
pass
|
258 |
-
else:
|
259 |
-
await send_message(update.effective_message, "ᴄᴏɴɴᴇᴄᴛɪᴏɴ ғᴀɪʟᴇᴅ!")
|
260 |
-
else:
|
261 |
-
await send_message(
|
262 |
-
update.effective_message,
|
263 |
-
"Connection to this chat is not allowed!",
|
264 |
-
)
|
265 |
-
|
266 |
-
|
267 |
-
async def disconnect_chat(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
268 |
-
if update.effective_chat.type == "private":
|
269 |
-
disconnection_status = sql.disconnect(update.effective_message.from_user.id)
|
270 |
-
if disconnection_status:
|
271 |
-
sql.disconnected_chat = await send_message(
|
272 |
-
update.effective_message,
|
273 |
-
"Disconnected from chat!",
|
274 |
-
)
|
275 |
-
else:
|
276 |
-
await send_message(update.effective_message, "You're not connected!")
|
277 |
-
else:
|
278 |
-
await send_message(
|
279 |
-
update.effective_message, "This command is only available in PM."
|
280 |
-
)
|
281 |
-
|
282 |
-
|
283 |
-
async def connected(bot: Bot, update: Update, chat, user_id, need_admin=True):
|
284 |
-
user = update.effective_user
|
285 |
-
|
286 |
-
if chat.type == chat.PRIVATE and sql.get_connected_chat(user_id):
|
287 |
-
conn_id = sql.get_connected_chat(user_id).chat_id
|
288 |
-
getstatusadmin = await bot.get_chat_member(
|
289 |
-
conn_id,
|
290 |
-
update.effective_message.from_user.id,
|
291 |
-
)
|
292 |
-
isadmin = getstatusadmin.status in ("administrator", "creator")
|
293 |
-
ismember = getstatusadmin.status in ("member")
|
294 |
-
isallow = sql.allow_connect_to_chat(conn_id)
|
295 |
-
|
296 |
-
if (
|
297 |
-
(isadmin)
|
298 |
-
or (isallow and ismember)
|
299 |
-
or (user.id in DRAGONS)
|
300 |
-
or (user.id in DEV_USERS)
|
301 |
-
):
|
302 |
-
if need_admin is True:
|
303 |
-
if (
|
304 |
-
getstatusadmin.status in ("administrator", "creator")
|
305 |
-
or user_id in DRAGONS
|
306 |
-
or user.id in DEV_USERS
|
307 |
-
):
|
308 |
-
return conn_id
|
309 |
-
else:
|
310 |
-
await send_message(
|
311 |
-
update.effective_message,
|
312 |
-
"You must be an admin in the connected group!",
|
313 |
-
)
|
314 |
-
else:
|
315 |
-
return conn_id
|
316 |
-
else:
|
317 |
-
await send_message(
|
318 |
-
update.effective_message,
|
319 |
-
"The group changed the connection rights or you are no longer an admin.\nI've disconnected you.",
|
320 |
-
)
|
321 |
-
disconnect_chat(update, bot)
|
322 |
-
else:
|
323 |
-
return False
|
324 |
-
|
325 |
-
|
326 |
-
CONN_HELP = """
|
327 |
-
Actions are available with connected groups:
|
328 |
-
• View and edit Notes.
|
329 |
-
• View and edit Filters.
|
330 |
-
• Get invite link of chat.
|
331 |
-
• Set and control AntiFlood settings.
|
332 |
-
• Set and control Blacklist settings.
|
333 |
-
• Set Locks and Unlocks in chat.
|
334 |
-
• Enable and Disable commands in chat.
|
335 |
-
• Export and Imports of chat backup.
|
336 |
-
"""
|
337 |
-
|
338 |
-
|
339 |
-
async def help_connect_chat(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
340 |
-
context.args
|
341 |
-
|
342 |
-
if update.effective_message.chat.type != "private":
|
343 |
-
await send_message(
|
344 |
-
update.effective_message, "PM me with that command to get help."
|
345 |
-
)
|
346 |
-
return
|
347 |
-
else:
|
348 |
-
await send_message(update.effective_message, CONN_HELP, parse_mode="markdown")
|
349 |
-
|
350 |
-
|
351 |
-
async def connect_button(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
352 |
-
query = update.callback_query
|
353 |
-
chat = update.effective_chat
|
354 |
-
user = update.effective_user
|
355 |
-
|
356 |
-
connect_match = re.match(r"connect\((.+?)\)", query.data)
|
357 |
-
disconnect_match = query.data == "connect_disconnect"
|
358 |
-
clear_match = query.data == "connect_clear"
|
359 |
-
connect_close = query.data == "connect_close"
|
360 |
-
|
361 |
-
if connect_match:
|
362 |
-
target_chat = connect_match.group(1)
|
363 |
-
getstatusadmin = await context.bot.get_chat_member(
|
364 |
-
target_chat, query.from_user.id
|
365 |
-
)
|
366 |
-
isadmin = getstatusadmin.status in ("administrator", "creator")
|
367 |
-
ismember = getstatusadmin.status in ("member")
|
368 |
-
isallow = sql.allow_connect_to_chat(target_chat)
|
369 |
-
|
370 |
-
if (isadmin) or (isallow and ismember) or (user.id in DRAGONS):
|
371 |
-
connection_status = sql.connect(query.from_user.id, target_chat)
|
372 |
-
|
373 |
-
if connection_status:
|
374 |
-
conn = await connected(
|
375 |
-
context.bot, update, chat, user.id, need_admin=False
|
376 |
-
)
|
377 |
-
conn_chat = await dispatcher.bot.getChat(conn)
|
378 |
-
chat_name = conn_chat.title
|
379 |
-
await query.message.edit_text(
|
380 |
-
"Successfully connected to *{}*. Use `/helpconnect` to check available commands.".format(
|
381 |
-
chat_name,
|
382 |
-
),
|
383 |
-
parse_mode=ParseMode.MARKDOWN,
|
384 |
-
)
|
385 |
-
sql.add_history_conn(user.id, str(conn_chat.id), chat_name)
|
386 |
-
else:
|
387 |
-
await query.message.edit_text("Connection failed!")
|
388 |
-
else:
|
389 |
-
await context.bot.answer_callback_query(
|
390 |
-
query.id,
|
391 |
-
"Connection to this chat is not allowed!",
|
392 |
-
show_alert=True,
|
393 |
-
)
|
394 |
-
elif disconnect_match:
|
395 |
-
disconnection_status = sql.disconnect(query.from_user.id)
|
396 |
-
if disconnection_status:
|
397 |
-
sql.disconnected_chat = await query.message.edit_text(
|
398 |
-
"Disconnected from chat!"
|
399 |
-
)
|
400 |
-
else:
|
401 |
-
await context.bot.answer_callback_query(
|
402 |
-
query.id,
|
403 |
-
"You're not connected!",
|
404 |
-
show_alert=True,
|
405 |
-
)
|
406 |
-
elif clear_match:
|
407 |
-
sql.clear_history_conn(query.from_user.id)
|
408 |
-
await query.message.edit_text("History connected has been cleared!")
|
409 |
-
elif connect_close:
|
410 |
-
await query.message.edit_text("Closed. To open again, type /connect")
|
411 |
-
else:
|
412 |
-
connect_chat(update, context)
|
413 |
-
|
414 |
-
|
415 |
-
# <=================================================== HELP ====================================================>
|
416 |
-
__mod_name__ = "CONNECT"
|
417 |
-
|
418 |
-
__help__ = """
|
419 |
-
➠ *Sometimes, you just want to add some notes and filters to a group chat, but you don't want everyone to see; this is where connections come in. This allows you to connect to a chat's database and add things to it without the commands appearing in chat! For obvious reasons, you need to be an admin to add things, but any member in the group can view your data.*
|
420 |
-
|
421 |
-
» /connect: Connects to chat (can be done in a group by /connect or /connect <chat id> in PM)
|
422 |
-
|
423 |
-
» /connection: List connected chats
|
424 |
-
|
425 |
-
» /disconnect: Disconnect from a chat
|
426 |
-
|
427 |
-
» /helpconnect: List available commands that can be used remotely
|
428 |
-
|
429 |
-
➠ *Admin Only:*
|
430 |
-
|
431 |
-
» /allowconnect <yes/no>: Allow a user to connect to a chat
|
432 |
-
"""
|
433 |
-
|
434 |
-
# <================================================ HANDLER =======================================================>
|
435 |
-
function(CommandHandler("connect", connect_chat, block=False))
|
436 |
-
function(CommandHandler("connection", connection_chat, block=False))
|
437 |
-
function(CommandHandler("disconnect", disconnect_chat, block=False))
|
438 |
-
function(CommandHandler("allowconnect", allow_connections, block=False))
|
439 |
-
function(CommandHandler("helpconnect", help_connect_chat, block=False))
|
440 |
-
function(CallbackQueryHandler(connect_button, pattern=r"connect", block=False))
|
441 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/cosplay.py
DELETED
@@ -1,37 +0,0 @@
|
|
1 |
-
# SOURCE https://github.com/Team-ProjectCodeX
|
2 |
-
# CREATED BY https://t.me/O_okarma
|
3 |
-
# API BY https://www.github.com/SOME-1HING
|
4 |
-
# PROVIDED BY https://t.me/ProjectCodeX
|
5 |
-
|
6 |
-
# <============================================== IMPORTS =========================================================>
|
7 |
-
from telegram import Update
|
8 |
-
from telegram.ext import CommandHandler, ContextTypes
|
9 |
-
|
10 |
-
from Mikobot import function
|
11 |
-
from Mikobot.state import state
|
12 |
-
|
13 |
-
# <=======================================================================================================>
|
14 |
-
|
15 |
-
|
16 |
-
# <================================================ FUNCTIONS =====================================================>
|
17 |
-
async def get_cosplay_data():
|
18 |
-
cosplay_url = "https://sugoi-api.vercel.app/cosplay"
|
19 |
-
response = await state.get(cosplay_url)
|
20 |
-
return response.json()
|
21 |
-
|
22 |
-
|
23 |
-
async def cosplay(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
24 |
-
try:
|
25 |
-
data = await get_cosplay_data()
|
26 |
-
photo_url = data.get("url") # Corrected key: "url" instead of "cosplay_url"
|
27 |
-
if photo_url:
|
28 |
-
await update.message.reply_photo(photo=photo_url)
|
29 |
-
else:
|
30 |
-
await update.message.reply_text("Could not fetch photo URL.")
|
31 |
-
except state.FetchError:
|
32 |
-
await update.message.reply_text("Unable to fetch data.")
|
33 |
-
|
34 |
-
|
35 |
-
# <================================================ HANDLER =======================================================>
|
36 |
-
function(CommandHandler("cosplay", cosplay, block=False))
|
37 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/couple.py
DELETED
@@ -1,124 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import random
|
3 |
-
from datetime import datetime
|
4 |
-
|
5 |
-
from pyrogram import filters
|
6 |
-
|
7 |
-
from Database.mongodb.karma_mongo import get_couple, save_couple
|
8 |
-
from Mikobot import app
|
9 |
-
|
10 |
-
# <=======================================================================================================>
|
11 |
-
|
12 |
-
|
13 |
-
# <================================================ FUNCTION =======================================================>
|
14 |
-
def dt():
|
15 |
-
now = datetime.now()
|
16 |
-
dt_string = now.strftime("%d/%m/%Y %H:%M")
|
17 |
-
dt_list = dt_string.split(" ")
|
18 |
-
return dt_list
|
19 |
-
|
20 |
-
|
21 |
-
def dt_tom():
|
22 |
-
a = (
|
23 |
-
str(int(dt()[0].split("/")[0]) + 1)
|
24 |
-
+ "/"
|
25 |
-
+ dt()[0].split("/")[1]
|
26 |
-
+ "/"
|
27 |
-
+ dt()[0].split("/")[2]
|
28 |
-
)
|
29 |
-
return a
|
30 |
-
|
31 |
-
|
32 |
-
tomorrow = str(dt_tom())
|
33 |
-
today = str(dt()[0])
|
34 |
-
|
35 |
-
COUPLES_PIC = "https://telegra.ph/file/c6d0c884f559b9ed8a54e.jpg"
|
36 |
-
C = """
|
37 |
-
✧ 𝗖𝗢𝗨𝗣𝗟𝗘𝗦 𝗢𝗙 𝗧𝗛𝗘 𝗗𝗔𝗬 ✧
|
38 |
-
➖➖➖➖➖➖➖➖➖➖➖➖
|
39 |
-
{} + ( PGM🎀😶 (https://t.me/Chalnayaaaaaarr) + 花火 (https://t.me/zd_sr07) + ゼロツー (https://t.me/wewewe_x) ) = 💞
|
40 |
-
➖➖➖➖➖➖➖➖➖➖➖➖
|
41 |
-
𝗡𝗘𝗪 𝗖𝗢𝗨𝗣𝗟𝗘 𝗢𝗙 𝗧𝗛𝗘 𝗗𝗔𝗬 𝗖𝗔𝗡 𝗕𝗘 𝗖𝗛𝗢𝗦𝗘𝗡 𝗔𝗧 12AM {}
|
42 |
-
"""
|
43 |
-
CAP = """
|
44 |
-
✧ 𝗖𝗢𝗨𝗣𝗟𝗘𝗦 𝗢𝗙 𝗧𝗛𝗘 𝗗𝗔𝗬 ✧
|
45 |
-
➖➖➖➖➖➖➖➖➖➖➖➖
|
46 |
-
{} + {} = 💞
|
47 |
-
➖➖➖➖➖➖➖➖➖➖➖➖
|
48 |
-
𝗡𝗘𝗪 𝗖𝗢𝗨𝗣𝗟𝗘 𝗢𝗙 𝗧𝗛𝗘 𝗗𝗔𝗬 𝗖𝗔𝗡 𝗕𝗘 𝗖𝗛𝗢𝗦𝗘𝗡 𝗔𝗧 12AM {}
|
49 |
-
"""
|
50 |
-
|
51 |
-
CAP2 = """
|
52 |
-
✧ 𝗖𝗢𝗨𝗣𝗟𝗘𝗦 𝗢𝗙 𝗧𝗛𝗘 𝗗𝗔𝗬 ✧
|
53 |
-
➖➖➖➖➖➖➖➖➖➖➖➖
|
54 |
-
{} (tg://openmessage?user_id={}) + {} (tg://openmessage?user_id={}) = 💞\n
|
55 |
-
➖➖➖➖➖➖➖➖➖➖➖➖
|
56 |
-
𝗡𝗘𝗪 𝗖𝗢𝗨𝗣𝗟𝗘 𝗢𝗙 𝗧𝗛𝗘 𝗗𝗔𝗬 𝗖𝗔𝗡 𝗕𝗘 𝗖𝗛𝗢𝗦𝗘𝗡 𝗔𝗧 12AM {}
|
57 |
-
"""
|
58 |
-
|
59 |
-
|
60 |
-
@app.on_message(filters.command(["couple", "couples", "shipping"]) & ~filters.private)
|
61 |
-
async def nibba_nibbi(_, message):
|
62 |
-
if message.from_user.id == 5540249238:
|
63 |
-
my_ = await _.get_users("rfxtuv")
|
64 |
-
me = await _.get_users(5540249238)
|
65 |
-
await message.reply_photo(
|
66 |
-
photo=COUPLES_PIC, caption=C.format(me.mention, tomorrow)
|
67 |
-
)
|
68 |
-
else:
|
69 |
-
try:
|
70 |
-
chat_id = message.chat.id
|
71 |
-
is_selected = await get_couple(chat_id, today)
|
72 |
-
if not is_selected:
|
73 |
-
list_of_users = []
|
74 |
-
async for i in _.get_chat_members(message.chat.id, limit=50):
|
75 |
-
if not i.user.is_bot:
|
76 |
-
list_of_users.append(i.user.id)
|
77 |
-
if len(list_of_users) < 2:
|
78 |
-
return await message.reply_text("ɴᴏᴛ ᴇɴᴏᴜɢʜ ᴜsᴇʀs ɪɴ ᴛʜɪs ɢʀᴏᴜᴘ.")
|
79 |
-
c1_id = random.choice(list_of_users)
|
80 |
-
c2_id = random.choice(list_of_users)
|
81 |
-
while c1_id == c2_id:
|
82 |
-
c1_id = random.choice(list_of_users)
|
83 |
-
c1_mention = (await _.get_users(c1_id)).mention
|
84 |
-
c2_mention = (await _.get_users(c2_id)).mention
|
85 |
-
await _.send_photo(
|
86 |
-
message.chat.id,
|
87 |
-
photo=COUPLES_PIC,
|
88 |
-
caption=CAP.format(c1_mention, c2_mention, tomorrow),
|
89 |
-
)
|
90 |
-
|
91 |
-
couple = {"c1_id": c1_id, "c2_id": c2_id}
|
92 |
-
await save_couple(chat_id, today, couple)
|
93 |
-
|
94 |
-
elif is_selected:
|
95 |
-
c1_id = int(is_selected["c1_id"])
|
96 |
-
c2_id = int(is_selected["c2_id"])
|
97 |
-
|
98 |
-
c1_name = (await _.get_users(c1_id)).first_name
|
99 |
-
c2_name = (await _.get_users(c2_id)).first_name
|
100 |
-
print(c1_id, c2_id, c1_name, c2_name)
|
101 |
-
couple_selection_message = f"""✧ 𝗖𝗢𝗨𝗣𝗟𝗘𝗦 𝗢𝗙 𝗧𝗛𝗘 𝗗𝗔𝗬 ✧
|
102 |
-
➖➖➖➖➖➖➖➖➖➖➖➖
|
103 |
-
[{c1_name}](tg://openmessage?user_id={c1_id}) + [{c2_name}](tg://openmessage?user_id={c2_id}) = 💞
|
104 |
-
➖➖➖➖➖➖➖➖➖➖➖➖
|
105 |
-
𝗡𝗘𝗪 𝗖𝗢𝗨𝗣𝗟𝗘 𝗢𝗙 𝗧𝗛𝗘 𝗗𝗔𝗬 𝗖𝗔𝗡 𝗕𝗘 𝗖𝗛𝗢𝗦𝗘𝗡 𝗔𝗧 12AM {tomorrow}"""
|
106 |
-
await _.send_photo(
|
107 |
-
message.chat.id, photo=COUPLES_PIC, caption=couple_selection_message
|
108 |
-
)
|
109 |
-
except Exception as e:
|
110 |
-
print(e)
|
111 |
-
await message.reply_text(str(e))
|
112 |
-
|
113 |
-
|
114 |
-
# <=================================================== HELP ====================================================>
|
115 |
-
|
116 |
-
|
117 |
-
__help__ = """
|
118 |
-
💘 *Choose couples in your chat*
|
119 |
-
|
120 |
-
» /couple, /couples, /shipping *:* Choose 2 users and send their names as couples in your chat.
|
121 |
-
"""
|
122 |
-
|
123 |
-
__mod_name__ = "COUPLE"
|
124 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/cust_filters.py
DELETED
@@ -1,756 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import random
|
3 |
-
import re
|
4 |
-
from html import escape
|
5 |
-
|
6 |
-
from pyrate_limiter import BucketFullException, Duration, InMemoryBucket, Limiter, Rate
|
7 |
-
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
8 |
-
from telegram.constants import ChatMemberStatus, MessageLimit, ParseMode
|
9 |
-
from telegram.error import BadRequest
|
10 |
-
from telegram.ext import (
|
11 |
-
ApplicationHandlerStop,
|
12 |
-
CallbackQueryHandler,
|
13 |
-
CommandHandler,
|
14 |
-
ContextTypes,
|
15 |
-
MessageHandler,
|
16 |
-
)
|
17 |
-
from telegram.ext import filters as filters_module
|
18 |
-
from telegram.helpers import escape_markdown, mention_html
|
19 |
-
|
20 |
-
from Database.sql import cust_filters_sql as sql
|
21 |
-
from Mikobot import DEV_USERS, DRAGONS, LOGGER, dispatcher, function
|
22 |
-
from Mikobot.plugins.connection import connected
|
23 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
24 |
-
from Mikobot.plugins.helper_funcs.alternate import send_message, typing_action
|
25 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin
|
26 |
-
from Mikobot.plugins.helper_funcs.extraction import extract_text
|
27 |
-
from Mikobot.plugins.helper_funcs.misc import build_keyboard_parser
|
28 |
-
from Mikobot.plugins.helper_funcs.msg_types import get_filter_type
|
29 |
-
from Mikobot.plugins.helper_funcs.string_handling import (
|
30 |
-
button_markdown_parser,
|
31 |
-
escape_invalid_curly_brackets,
|
32 |
-
markdown_to_html,
|
33 |
-
split_quotes,
|
34 |
-
)
|
35 |
-
|
36 |
-
# <=======================================================================================================>
|
37 |
-
|
38 |
-
HANDLER_GROUP = 10
|
39 |
-
|
40 |
-
ENUM_FUNC_MAP = {
|
41 |
-
sql.Types.TEXT.value: dispatcher.bot.send_message,
|
42 |
-
sql.Types.BUTTON_TEXT.value: dispatcher.bot.send_message,
|
43 |
-
sql.Types.STICKER.value: dispatcher.bot.send_sticker,
|
44 |
-
sql.Types.DOCUMENT.value: dispatcher.bot.send_document,
|
45 |
-
sql.Types.PHOTO.value: dispatcher.bot.send_photo,
|
46 |
-
sql.Types.AUDIO.value: dispatcher.bot.send_audio,
|
47 |
-
sql.Types.VOICE.value: dispatcher.bot.send_voice,
|
48 |
-
sql.Types.VIDEO.value: dispatcher.bot.send_video,
|
49 |
-
}
|
50 |
-
|
51 |
-
|
52 |
-
class AntiSpam:
|
53 |
-
def __init__(self):
|
54 |
-
self.whitelist = (DEV_USERS or []) + (DRAGONS or [])
|
55 |
-
# Values are HIGHLY experimental, its recommended you pay attention to our commits as we will be adjusting the values over time with what suits best.
|
56 |
-
Duration.CUSTOM = 15 # Custom duration, 15 seconds
|
57 |
-
self.sec_limit = Rate(6, Duration.CUSTOM) # 6 / Per 15 Seconds
|
58 |
-
self.min_limit = Rate(20, Duration.MINUTE) # 20 / Per minute
|
59 |
-
self.hour_limit = Rate(100, Duration.HOUR) # 100 / Per hour
|
60 |
-
self.daily_limit = Rate(1000, Duration.DAY) # 1000 / Per day
|
61 |
-
self.limiter = Limiter(
|
62 |
-
InMemoryBucket(
|
63 |
-
[self.sec_limit, self.min_limit, self.hour_limit, self.daily_limit]
|
64 |
-
)
|
65 |
-
)
|
66 |
-
|
67 |
-
def check_user(self, user):
|
68 |
-
"""
|
69 |
-
Return True if user is to be ignored else False
|
70 |
-
"""
|
71 |
-
if user in self.whitelist:
|
72 |
-
return False
|
73 |
-
try:
|
74 |
-
self.limiter.try_acquire(user)
|
75 |
-
return False
|
76 |
-
except BucketFullException:
|
77 |
-
return True
|
78 |
-
|
79 |
-
|
80 |
-
MessageHandlerChecker = AntiSpam()
|
81 |
-
|
82 |
-
|
83 |
-
# <================================================ FUNCTION =======================================================>
|
84 |
-
@typing_action
|
85 |
-
async def list_handlers(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
86 |
-
chat = update.effective_chat
|
87 |
-
user = update.effective_user
|
88 |
-
|
89 |
-
conn = await connected(context.bot, update, chat, user.id, need_admin=False)
|
90 |
-
if not conn is False:
|
91 |
-
chat_id = conn
|
92 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
93 |
-
chat_name = chat_obj.title
|
94 |
-
filter_list = "*Filter in {}:*\n"
|
95 |
-
else:
|
96 |
-
chat_id = update.effective_chat.id
|
97 |
-
if chat.type == "private":
|
98 |
-
chat_name = "Local filters"
|
99 |
-
filter_list = "*local filters:*\n"
|
100 |
-
else:
|
101 |
-
chat_name = chat.title
|
102 |
-
filter_list = "*Filters in {}*:\n"
|
103 |
-
|
104 |
-
all_handlers = sql.get_chat_triggers(chat_id)
|
105 |
-
|
106 |
-
if not all_handlers:
|
107 |
-
await send_message(
|
108 |
-
update.effective_message,
|
109 |
-
"No filters saved in {}!".format(chat_name),
|
110 |
-
)
|
111 |
-
return
|
112 |
-
|
113 |
-
for keyword in all_handlers:
|
114 |
-
entry = " • `{}`\n".format(escape_markdown(keyword))
|
115 |
-
if len(entry) + len(filter_list) > MessageLimit.MAX_TEXT_LENGTH:
|
116 |
-
await send_message(
|
117 |
-
update.effective_message,
|
118 |
-
filter_list.format(chat_name),
|
119 |
-
parse_mode=ParseMode.MARKDOWN,
|
120 |
-
)
|
121 |
-
filter_list = entry
|
122 |
-
else:
|
123 |
-
filter_list += entry
|
124 |
-
|
125 |
-
await send_message(
|
126 |
-
update.effective_message,
|
127 |
-
filter_list.format(chat_name),
|
128 |
-
parse_mode=ParseMode.MARKDOWN,
|
129 |
-
)
|
130 |
-
|
131 |
-
|
132 |
-
@typing_action
|
133 |
-
@check_admin(is_user=True)
|
134 |
-
async def filters(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
135 |
-
chat = update.effective_chat
|
136 |
-
user = update.effective_user
|
137 |
-
msg = update.effective_message
|
138 |
-
args = msg.text.split(
|
139 |
-
None, 1
|
140 |
-
) # use python's maxsplit to separate Cmd, keyword, and reply_text
|
141 |
-
|
142 |
-
buttons = None
|
143 |
-
conn = await connected(context.bot, update, chat, user.id)
|
144 |
-
if not conn is False:
|
145 |
-
chat_id = conn
|
146 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
147 |
-
chat_name = chat_obj.title
|
148 |
-
else:
|
149 |
-
chat_id = update.effective_chat.id
|
150 |
-
if chat.type == "private":
|
151 |
-
chat_name = "local filters"
|
152 |
-
else:
|
153 |
-
chat_name = chat.title
|
154 |
-
|
155 |
-
if not msg.reply_to_message and len(args) < 2:
|
156 |
-
await send_message(
|
157 |
-
update.effective_message,
|
158 |
-
"Please provide keyboard keyword for this filter to reply with!",
|
159 |
-
)
|
160 |
-
return
|
161 |
-
|
162 |
-
if msg.reply_to_message and not msg.reply_to_message.forum_topic_created:
|
163 |
-
if len(args) < 2:
|
164 |
-
await send_message(
|
165 |
-
update.effective_message,
|
166 |
-
"Please provide keyword for this filter to reply with!",
|
167 |
-
)
|
168 |
-
return
|
169 |
-
else:
|
170 |
-
keyword = args[1]
|
171 |
-
else:
|
172 |
-
extracted = split_quotes(args[1])
|
173 |
-
if len(extracted) < 1:
|
174 |
-
return
|
175 |
-
# set trigger -> lower, so as to avoid adding duplicate filters with different cases
|
176 |
-
keyword = extracted[0].lower()
|
177 |
-
|
178 |
-
# Add the filter
|
179 |
-
# Note: perhaps handlers can be removed somehow using sql.get_chat_filters
|
180 |
-
for handler in dispatcher.handlers.get(HANDLER_GROUP, []):
|
181 |
-
if handler.filters == (keyword, chat_id):
|
182 |
-
dispatcher.remove_handler(handler, HANDLER_GROUP)
|
183 |
-
|
184 |
-
text, file_type, file_id, media_spoiler = get_filter_type(msg)
|
185 |
-
if not msg.reply_to_message and len(extracted) >= 2:
|
186 |
-
offset = len(extracted[1]) - len(
|
187 |
-
msg.text,
|
188 |
-
) # set correct offset relative to command + notename
|
189 |
-
text, buttons = button_markdown_parser(
|
190 |
-
extracted[1],
|
191 |
-
entities=msg.parse_entities(),
|
192 |
-
offset=offset,
|
193 |
-
)
|
194 |
-
text = text.strip()
|
195 |
-
if not text:
|
196 |
-
await send_message(
|
197 |
-
update.effective_message,
|
198 |
-
"There is no note message - You can't JUST have buttons, you need a message to go with it!",
|
199 |
-
)
|
200 |
-
return
|
201 |
-
|
202 |
-
if len(args) >= 2:
|
203 |
-
if msg.reply_to_message:
|
204 |
-
if msg.reply_to_message.forum_topic_created:
|
205 |
-
offset = len(extracted[1]) - len(msg.text)
|
206 |
-
|
207 |
-
text, buttons = button_markdown_parser(
|
208 |
-
extracted[1], entities=msg.parse_entities(), offset=offset
|
209 |
-
)
|
210 |
-
|
211 |
-
text = text.strip()
|
212 |
-
if not text:
|
213 |
-
await send_message(
|
214 |
-
update.effective_message,
|
215 |
-
"There is no note message - You can't JUST have buttons, you need a message to go with it!",
|
216 |
-
)
|
217 |
-
return
|
218 |
-
else:
|
219 |
-
pass
|
220 |
-
|
221 |
-
elif msg.reply_to_message and len(args) >= 1:
|
222 |
-
if msg.reply_to_message.text:
|
223 |
-
text_to_parsing = msg.reply_to_message.text
|
224 |
-
elif msg.reply_to_message.caption:
|
225 |
-
text_to_parsing = msg.reply_to_message.caption
|
226 |
-
else:
|
227 |
-
text_to_parsing = ""
|
228 |
-
offset = len(
|
229 |
-
text_to_parsing,
|
230 |
-
) # set correct offset relative to command + notename
|
231 |
-
text, buttons = button_markdown_parser(
|
232 |
-
text_to_parsing,
|
233 |
-
entities=msg.parse_entities(),
|
234 |
-
offset=offset,
|
235 |
-
)
|
236 |
-
text = text.strip()
|
237 |
-
|
238 |
-
elif not text and not file_type:
|
239 |
-
await send_message(
|
240 |
-
update.effective_message,
|
241 |
-
"Please provide keyword for this filter reply with!",
|
242 |
-
)
|
243 |
-
return
|
244 |
-
|
245 |
-
elif msg.reply_to_message:
|
246 |
-
if msg.reply_to_message.forum_topic_created:
|
247 |
-
return
|
248 |
-
|
249 |
-
if msg.reply_to_message.text:
|
250 |
-
text_to_parsing = msg.reply_to_message.text
|
251 |
-
elif msg.reply_to_message.caption:
|
252 |
-
text_to_parsing = msg.reply_to_message.caption
|
253 |
-
else:
|
254 |
-
text_to_parsing = ""
|
255 |
-
offset = len(
|
256 |
-
text_to_parsing,
|
257 |
-
) # set correct offset relative to command + notename
|
258 |
-
text, buttons = button_markdown_parser(
|
259 |
-
text_to_parsing,
|
260 |
-
entities=msg.parse_entities(),
|
261 |
-
offset=offset,
|
262 |
-
)
|
263 |
-
text = text.strip()
|
264 |
-
if (msg.reply_to_message.text or msg.reply_to_message.caption) and not text:
|
265 |
-
await send_message(
|
266 |
-
update.effective_message,
|
267 |
-
"There is no note message - You can't JUST have buttons, you need a message to go with it!",
|
268 |
-
)
|
269 |
-
return
|
270 |
-
|
271 |
-
else:
|
272 |
-
await send_message(update.effective_message, "Invalid filter!")
|
273 |
-
return
|
274 |
-
|
275 |
-
add = await addnew_filter(
|
276 |
-
update, chat_id, keyword, text, file_type, file_id, buttons, media_spoiler
|
277 |
-
)
|
278 |
-
# This is an old method
|
279 |
-
# sql.add_filter(chat_id, keyword, content, is_sticker, is_document, is_image, is_audio, is_voice, is_video, buttons)
|
280 |
-
|
281 |
-
if add is True:
|
282 |
-
await send_message(
|
283 |
-
update.effective_message,
|
284 |
-
"Saved filter '{}' in *{}*!".format(keyword, chat_name),
|
285 |
-
parse_mode=ParseMode.MARKDOWN,
|
286 |
-
)
|
287 |
-
raise ApplicationHandlerStop
|
288 |
-
|
289 |
-
|
290 |
-
@typing_action
|
291 |
-
@check_admin(is_user=True)
|
292 |
-
async def stop_filter(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
293 |
-
chat = update.effective_chat
|
294 |
-
user = update.effective_user
|
295 |
-
args = update.effective_message.text.split(None, 1)
|
296 |
-
|
297 |
-
conn = await connected(context.bot, update, chat, user.id)
|
298 |
-
if not conn is False:
|
299 |
-
chat_id = conn
|
300 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
301 |
-
chat_name = chat_obj.title
|
302 |
-
else:
|
303 |
-
chat_id = update.effective_chat.id
|
304 |
-
if chat.type == "private":
|
305 |
-
chat_name = "Local filters"
|
306 |
-
else:
|
307 |
-
chat_name = chat.title
|
308 |
-
|
309 |
-
if len(args) < 2:
|
310 |
-
await send_message(update.effective_message, "What should i stop?")
|
311 |
-
return
|
312 |
-
|
313 |
-
chat_filters = sql.get_chat_triggers(chat_id)
|
314 |
-
|
315 |
-
if not chat_filters:
|
316 |
-
await send_message(update.effective_message, "No filters active here!")
|
317 |
-
return
|
318 |
-
|
319 |
-
for keyword in chat_filters:
|
320 |
-
if keyword == args[1]:
|
321 |
-
sql.remove_filter(chat_id, args[1])
|
322 |
-
await send_message(
|
323 |
-
update.effective_message,
|
324 |
-
"Okay, I'll stop replying to that filter in *{}*.".format(chat_name),
|
325 |
-
parse_mode=ParseMode.MARKDOWN,
|
326 |
-
)
|
327 |
-
raise ApplicationHandlerStop
|
328 |
-
|
329 |
-
await send_message(
|
330 |
-
update.effective_message,
|
331 |
-
"That's not a filter - Click: /filters to get currently active filters.",
|
332 |
-
)
|
333 |
-
|
334 |
-
|
335 |
-
async def reply_filter(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
336 |
-
chat = update.effective_chat
|
337 |
-
message = update.effective_message
|
338 |
-
|
339 |
-
if not update.effective_user or update.effective_user.id == 777000:
|
340 |
-
return
|
341 |
-
to_match = await extract_text(message)
|
342 |
-
if not to_match:
|
343 |
-
return
|
344 |
-
|
345 |
-
chat_filters = sql.get_chat_triggers(chat.id)
|
346 |
-
for keyword in chat_filters:
|
347 |
-
pattern = r"( |^|[^\w])" + re.escape(keyword) + r"( |$|[^\w])"
|
348 |
-
if re.search(pattern, to_match, flags=re.IGNORECASE):
|
349 |
-
if MessageHandlerChecker.check_user(update.effective_user.id):
|
350 |
-
return
|
351 |
-
filt = sql.get_filter(chat.id, keyword)
|
352 |
-
if filt.reply == "there is should be a new reply":
|
353 |
-
buttons = sql.get_buttons(chat.id, filt.keyword)
|
354 |
-
keyb = build_keyboard_parser(context.bot, chat.id, buttons)
|
355 |
-
keyboard = InlineKeyboardMarkup(keyb)
|
356 |
-
|
357 |
-
VALID_WELCOME_FORMATTERS = [
|
358 |
-
"first",
|
359 |
-
"last",
|
360 |
-
"fullname",
|
361 |
-
"username",
|
362 |
-
"id",
|
363 |
-
"chatname",
|
364 |
-
"mention",
|
365 |
-
]
|
366 |
-
if filt.reply_text:
|
367 |
-
if "%%%" in filt.reply_text:
|
368 |
-
split = filt.reply_text.split("%%%")
|
369 |
-
if all(split):
|
370 |
-
text = random.choice(split)
|
371 |
-
else:
|
372 |
-
text = filt.reply_text
|
373 |
-
else:
|
374 |
-
text = filt.reply_text
|
375 |
-
if text.startswith("~!") and text.endswith("!~"):
|
376 |
-
sticker_id = text.replace("~!", "").replace("!~", "")
|
377 |
-
try:
|
378 |
-
await context.bot.send_sticker(
|
379 |
-
chat.id,
|
380 |
-
sticker_id,
|
381 |
-
reply_to_message_id=message.message_id,
|
382 |
-
message_thread_id=message.message_thread_id
|
383 |
-
if chat.is_forum
|
384 |
-
else None,
|
385 |
-
)
|
386 |
-
return
|
387 |
-
except BadRequest as excp:
|
388 |
-
if (
|
389 |
-
excp.message
|
390 |
-
== "Wrong remote file identifier specified: wrong padding in the string"
|
391 |
-
):
|
392 |
-
await context.bot.send_message(
|
393 |
-
chat.id,
|
394 |
-
"Message couldn't be sent, Is the sticker id valid?",
|
395 |
-
message_thread_id=message.message_thread_id
|
396 |
-
if chat.is_forum
|
397 |
-
else None,
|
398 |
-
)
|
399 |
-
return
|
400 |
-
else:
|
401 |
-
LOGGER.exception("Error in filters: " + excp.message)
|
402 |
-
return
|
403 |
-
valid_format = escape_invalid_curly_brackets(
|
404 |
-
text,
|
405 |
-
VALID_WELCOME_FORMATTERS,
|
406 |
-
)
|
407 |
-
if valid_format:
|
408 |
-
filtext = valid_format.format(
|
409 |
-
first=escape(message.from_user.first_name),
|
410 |
-
last=escape(
|
411 |
-
message.from_user.last_name
|
412 |
-
or message.from_user.first_name,
|
413 |
-
),
|
414 |
-
fullname=" ".join(
|
415 |
-
[
|
416 |
-
escape(message.from_user.first_name),
|
417 |
-
escape(message.from_user.last_name),
|
418 |
-
]
|
419 |
-
if message.from_user.last_name
|
420 |
-
else [escape(message.from_user.first_name)],
|
421 |
-
),
|
422 |
-
username="@" + escape(message.from_user.username)
|
423 |
-
if message.from_user.username
|
424 |
-
else mention_html(
|
425 |
-
message.from_user.id,
|
426 |
-
message.from_user.first_name,
|
427 |
-
),
|
428 |
-
mention=mention_html(
|
429 |
-
message.from_user.id,
|
430 |
-
message.from_user.first_name,
|
431 |
-
),
|
432 |
-
chatname=escape(message.chat.title)
|
433 |
-
if message.chat.type != "private"
|
434 |
-
else escape(message.from_user.first_name),
|
435 |
-
id=message.from_user.id,
|
436 |
-
)
|
437 |
-
else:
|
438 |
-
filtext = ""
|
439 |
-
else:
|
440 |
-
filtext = ""
|
441 |
-
|
442 |
-
if filt.file_type in (sql.Types.BUTTON_TEXT, sql.Types.TEXT):
|
443 |
-
try:
|
444 |
-
await message.reply_text(
|
445 |
-
markdown_to_html(filtext),
|
446 |
-
parse_mode=ParseMode.HTML,
|
447 |
-
disable_web_page_preview=True,
|
448 |
-
reply_markup=keyboard,
|
449 |
-
)
|
450 |
-
except BadRequest as excp:
|
451 |
-
LOGGER.exception("Error in filters: " + excp.message)
|
452 |
-
try:
|
453 |
-
await send_message(
|
454 |
-
update.effective_message,
|
455 |
-
get_exception(excp, filt, chat),
|
456 |
-
)
|
457 |
-
except BadRequest as excp:
|
458 |
-
LOGGER.exception(
|
459 |
-
"Failed to send message: " + excp.message,
|
460 |
-
)
|
461 |
-
else:
|
462 |
-
try:
|
463 |
-
if filt.file_type not in [
|
464 |
-
sql.Types.PHOTO.value,
|
465 |
-
sql.Types.VIDEO,
|
466 |
-
]:
|
467 |
-
await ENUM_FUNC_MAP[filt.file_type](
|
468 |
-
chat.id,
|
469 |
-
filt.file_id,
|
470 |
-
reply_markup=keyboard,
|
471 |
-
reply_to_message_id=message.message_id,
|
472 |
-
message_thread_id=message.message_thread_id
|
473 |
-
if chat.is_forum
|
474 |
-
else None,
|
475 |
-
)
|
476 |
-
else:
|
477 |
-
await ENUM_FUNC_MAP[filt.file_type](
|
478 |
-
chat.id,
|
479 |
-
filt.file_id,
|
480 |
-
reply_markup=keyboard,
|
481 |
-
caption=filt.reply_text,
|
482 |
-
reply_to_message_id=message.message_id,
|
483 |
-
message_thread_id=message.message_thread_id
|
484 |
-
if chat.is_forum
|
485 |
-
else None,
|
486 |
-
has_spoiler=filt.has_media_spoiler,
|
487 |
-
)
|
488 |
-
except BadRequest:
|
489 |
-
await send_message(
|
490 |
-
message,
|
491 |
-
"I don't have the permission to send the content of the filter.",
|
492 |
-
)
|
493 |
-
break
|
494 |
-
else:
|
495 |
-
if filt.is_sticker:
|
496 |
-
await message.reply_sticker(filt.reply)
|
497 |
-
elif filt.is_document:
|
498 |
-
await message.reply_document(filt.reply)
|
499 |
-
elif filt.is_image:
|
500 |
-
await message.reply_photo(
|
501 |
-
filt.reply, has_spoiler=filt.has_media_spoiler
|
502 |
-
)
|
503 |
-
elif filt.is_audio:
|
504 |
-
await message.reply_audio(filt.reply)
|
505 |
-
elif filt.is_voice:
|
506 |
-
await message.reply_voice(filt.reply)
|
507 |
-
elif filt.is_video:
|
508 |
-
await message.reply_video(
|
509 |
-
filt.reply, has_spoiler=filt.has_media_spoiler
|
510 |
-
)
|
511 |
-
elif filt.has_buttons:
|
512 |
-
buttons = sql.get_buttons(chat.id, filt.keyword)
|
513 |
-
keyb = build_keyboard_parser(context.bot, chat.id, buttons)
|
514 |
-
keyboard = InlineKeyboardMarkup(keyb)
|
515 |
-
|
516 |
-
try:
|
517 |
-
await context.bot.send_message(
|
518 |
-
chat.id,
|
519 |
-
markdown_to_html(filt.reply),
|
520 |
-
parse_mode=ParseMode.HTML,
|
521 |
-
disable_web_page_preview=True,
|
522 |
-
reply_markup=keyboard,
|
523 |
-
message_thread_id=message.message_thread_id
|
524 |
-
if chat.is_forum
|
525 |
-
else None,
|
526 |
-
)
|
527 |
-
except BadRequest as excp:
|
528 |
-
if excp.message == "Unsupported url protocol":
|
529 |
-
try:
|
530 |
-
await send_message(
|
531 |
-
update.effective_message,
|
532 |
-
"You seem to be trying to use an unsupported url protocol. "
|
533 |
-
"Telegram doesn't support buttons for some protocols, such as tg://. Please try "
|
534 |
-
"again...",
|
535 |
-
)
|
536 |
-
except BadRequest as excp:
|
537 |
-
LOGGER.exception("Error in filters: " + excp.message)
|
538 |
-
else:
|
539 |
-
try:
|
540 |
-
await send_message(
|
541 |
-
update.effective_message,
|
542 |
-
"This message couldn't be sent as it's incorrectly formatted.",
|
543 |
-
)
|
544 |
-
except BadRequest as excp:
|
545 |
-
LOGGER.exception("Error in filters: " + excp.message)
|
546 |
-
LOGGER.warning(
|
547 |
-
"Message %s could not be parsed",
|
548 |
-
str(filt.reply),
|
549 |
-
)
|
550 |
-
LOGGER.exception(
|
551 |
-
"Could not parse filter %s in chat %s",
|
552 |
-
str(filt.keyword),
|
553 |
-
str(chat.id),
|
554 |
-
)
|
555 |
-
|
556 |
-
else:
|
557 |
-
# LEGACY - all new filters will have has_markdown set to True.
|
558 |
-
try:
|
559 |
-
await context.bot.send_message(
|
560 |
-
chat.id,
|
561 |
-
filt.reply,
|
562 |
-
message_thread_id=message.message_thread_id
|
563 |
-
if chat.is_forum
|
564 |
-
else None,
|
565 |
-
)
|
566 |
-
except BadRequest as excp:
|
567 |
-
LOGGER.exception("Error in filters: " + excp.message)
|
568 |
-
break
|
569 |
-
|
570 |
-
|
571 |
-
async def rmall_filters(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
572 |
-
chat = update.effective_chat
|
573 |
-
user = update.effective_user
|
574 |
-
member = await chat.get_member(user.id)
|
575 |
-
if member.status != ChatMemberStatus.OWNER and user.id not in DRAGONS:
|
576 |
-
await update.effective_message.reply_text(
|
577 |
-
"Only the chat owner can clear all notes at once.",
|
578 |
-
)
|
579 |
-
else:
|
580 |
-
buttons = InlineKeyboardMarkup(
|
581 |
-
[
|
582 |
-
[
|
583 |
-
InlineKeyboardButton(
|
584 |
-
text="STOP ALL FILTERS",
|
585 |
-
callback_data="filters_rmall",
|
586 |
-
),
|
587 |
-
],
|
588 |
-
[InlineKeyboardButton(text="CANCEL", callback_data="filters_cancel")],
|
589 |
-
],
|
590 |
-
)
|
591 |
-
await update.effective_message.reply_text(
|
592 |
-
f"Are you sure you would like to stop ALL filters in {chat.title}? This action cannot be undone.",
|
593 |
-
reply_markup=buttons,
|
594 |
-
parse_mode=ParseMode.MARKDOWN,
|
595 |
-
)
|
596 |
-
|
597 |
-
|
598 |
-
async def rmall_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
599 |
-
query = update.callback_query
|
600 |
-
chat = update.effective_chat
|
601 |
-
msg = update.effective_message
|
602 |
-
member = await chat.get_member(query.from_user.id)
|
603 |
-
if query.data == "filters_rmall":
|
604 |
-
if member.status == "creator" or query.from_user.id in DRAGONS:
|
605 |
-
allfilters = sql.get_chat_triggers(chat.id)
|
606 |
-
if not allfilters:
|
607 |
-
await msg.edit_text("No filters in this chat, nothing to stop!")
|
608 |
-
return
|
609 |
-
|
610 |
-
count = 0
|
611 |
-
filterlist = []
|
612 |
-
for x in allfilters:
|
613 |
-
count += 1
|
614 |
-
filterlist.append(x)
|
615 |
-
|
616 |
-
for i in filterlist:
|
617 |
-
sql.remove_filter(chat.id, i)
|
618 |
-
|
619 |
-
await msg.edit_text(f"Cleaned {count} filters in {chat.title}")
|
620 |
-
|
621 |
-
if member.status == "administrator":
|
622 |
-
await query.answer("Only owner of the chat can do this.")
|
623 |
-
|
624 |
-
if member.status == "member":
|
625 |
-
await query.answer("You need to be admin to do this.")
|
626 |
-
elif query.data == "filters_cancel":
|
627 |
-
if member.status == "creator" or query.from_user.id in DRAGONS:
|
628 |
-
await msg.edit_text("Clearing of all filters has been cancelled.")
|
629 |
-
return await query.answer()
|
630 |
-
if member.status == "administrator":
|
631 |
-
await query.answer("Only owner of the chat can do this.")
|
632 |
-
if member.status == "member":
|
633 |
-
await query.answer("You need to be admin to do this.")
|
634 |
-
|
635 |
-
|
636 |
-
# NOT ASYNC NOT A HANDLER
|
637 |
-
def get_exception(excp, filt, chat):
|
638 |
-
if excp.message == "Unsupported url protocol":
|
639 |
-
return "You seem to be trying to use the URL protocol which is not supported. Telegram does not support key for multiple protocols, such as tg: //. Please try again!"
|
640 |
-
elif excp.message == "Reply message not found":
|
641 |
-
return "noreply"
|
642 |
-
else:
|
643 |
-
LOGGER.warning("Message %s could not be parsed", str(filt.reply))
|
644 |
-
LOGGER.exception(
|
645 |
-
"Could not parse filter %s in chat %s",
|
646 |
-
str(filt.keyword),
|
647 |
-
str(chat.id),
|
648 |
-
)
|
649 |
-
return "This data could not be sent because it is incorrectly formatted."
|
650 |
-
|
651 |
-
|
652 |
-
# NOT ASYNC NOT A HANDLER
|
653 |
-
async def addnew_filter(
|
654 |
-
update, chat_id, keyword, text, file_type, file_id, buttons, has_spoiler
|
655 |
-
):
|
656 |
-
msg = update.effective_message
|
657 |
-
totalfilt = sql.get_chat_triggers(chat_id)
|
658 |
-
if len(totalfilt) >= 150: # Idk why i made this like function....
|
659 |
-
await msg.reply_text("This group has reached its max filters limit of 150.")
|
660 |
-
return False
|
661 |
-
else:
|
662 |
-
sql.new_add_filter(
|
663 |
-
chat_id, keyword, text, file_type, file_id, buttons, has_spoiler
|
664 |
-
)
|
665 |
-
return True
|
666 |
-
|
667 |
-
|
668 |
-
def __stats__():
|
669 |
-
return "• {} filters, across {} chats.".format(sql.num_filters(), sql.num_chats())
|
670 |
-
|
671 |
-
|
672 |
-
async def __import_data__(chat_id, data, message):
|
673 |
-
# set chat filters
|
674 |
-
filters = data.get("filters", {})
|
675 |
-
for trigger in filters:
|
676 |
-
sql.add_to_blacklist(chat_id, trigger)
|
677 |
-
|
678 |
-
|
679 |
-
def __migrate__(old_chat_id, new_chat_id):
|
680 |
-
sql.migrate_chat(old_chat_id, new_chat_id)
|
681 |
-
|
682 |
-
|
683 |
-
def __chat_settings__(chat_id, user_id):
|
684 |
-
cust_filters = sql.get_chat_triggers(chat_id)
|
685 |
-
return "There are `{}` custom filters here.".format(len(cust_filters))
|
686 |
-
|
687 |
-
|
688 |
-
# <=================================================== HELP ====================================================>
|
689 |
-
|
690 |
-
|
691 |
-
__help__ = """
|
692 |
-
» `/filters`*:* List all active filters saved in the chat.
|
693 |
-
|
694 |
-
➠ *Admin only:*
|
695 |
-
|
696 |
-
» `/filter <keyword> <reply message>`*:* Add a filter to this chat. The bot will now reply that message whenever 'keyword'\
|
697 |
-
is mentioned. If you reply to a sticker with a keyword, the bot will reply with that sticker. NOTE: all filter \
|
698 |
-
keywords are in lowercase. If you want your keyword to be a sentence, use quotes. eg: /filter "hey there" How you \
|
699 |
-
doin?
|
700 |
-
|
701 |
-
➠ Separate diff replies by `%%%` to get random replies
|
702 |
-
➠ *Example:*
|
703 |
-
|
704 |
-
» `/filter "filtername"
|
705 |
-
Reply 1
|
706 |
-
%%%
|
707 |
-
Reply 2
|
708 |
-
%%%
|
709 |
-
Reply 3`
|
710 |
-
|
711 |
-
» `/stop <filter keyword>`*:* Stop that filter.
|
712 |
-
|
713 |
-
➠ *Chat creator only:*
|
714 |
-
» `/removeallfilters`*:* Remove all chat filters at once.
|
715 |
-
|
716 |
-
➠ *Note*: Filters also support markdown formatters like: {first}, {last} etc.. and buttons.
|
717 |
-
➠ Now Supports media spoilers too, and media caption.
|
718 |
-
"""
|
719 |
-
|
720 |
-
__mod_name__ = "FILTERS"
|
721 |
-
|
722 |
-
# <================================================ HANDLER =======================================================>
|
723 |
-
FILTER_HANDLER = CommandHandler("filter", filters, block=False)
|
724 |
-
STOP_HANDLER = CommandHandler("stop", stop_filter, block=False)
|
725 |
-
RMALLFILTER_HANDLER = CommandHandler(
|
726 |
-
"removeallfilters",
|
727 |
-
rmall_filters,
|
728 |
-
filters=filters_module.ChatType.GROUPS,
|
729 |
-
block=False,
|
730 |
-
)
|
731 |
-
RMALLFILTER_CALLBACK = CallbackQueryHandler(
|
732 |
-
rmall_callback, pattern=r"filters_.*", block=False
|
733 |
-
)
|
734 |
-
LIST_HANDLER = DisableAbleCommandHandler(
|
735 |
-
"filters", list_handlers, admin_ok=True, block=False
|
736 |
-
)
|
737 |
-
CUST_FILTER_HANDLER = MessageHandler(
|
738 |
-
filters_module.TEXT & ~filters_module.UpdateType.EDITED_MESSAGE,
|
739 |
-
reply_filter,
|
740 |
-
block=False,
|
741 |
-
)
|
742 |
-
|
743 |
-
function(FILTER_HANDLER)
|
744 |
-
function(STOP_HANDLER)
|
745 |
-
function(LIST_HANDLER)
|
746 |
-
function(CUST_FILTER_HANDLER, HANDLER_GROUP)
|
747 |
-
function(RMALLFILTER_HANDLER)
|
748 |
-
function(RMALLFILTER_CALLBACK)
|
749 |
-
|
750 |
-
__handlers__ = [
|
751 |
-
FILTER_HANDLER,
|
752 |
-
STOP_HANDLER,
|
753 |
-
LIST_HANDLER,
|
754 |
-
(CUST_FILTER_HANDLER, HANDLER_GROUP, RMALLFILTER_HANDLER),
|
755 |
-
]
|
756 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/disable.py
DELETED
@@ -1,376 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import importlib
|
3 |
-
import re
|
4 |
-
from typing import Dict, List, Optional, Tuple, Union
|
5 |
-
|
6 |
-
from future.utils import string_types
|
7 |
-
from telegram import Update
|
8 |
-
from telegram.constants import ParseMode
|
9 |
-
from telegram.ext import CommandHandler, ContextTypes, MessageHandler
|
10 |
-
from telegram.ext import filters as filters_module
|
11 |
-
from telegram.helpers import escape_markdown
|
12 |
-
|
13 |
-
from Mikobot import function
|
14 |
-
from Mikobot.plugins.helper_funcs.misc import is_module_loaded
|
15 |
-
from Mikobot.utils.cmdprefix import CMD_STARTERS
|
16 |
-
|
17 |
-
# <=======================================================================================================>
|
18 |
-
|
19 |
-
FILENAME = __name__.rsplit(".", 1)[-1]
|
20 |
-
|
21 |
-
# If module is due to be loaded, then setup all the magical handlers
|
22 |
-
if is_module_loaded(FILENAME):
|
23 |
-
from Database.sql import disable_sql as sql
|
24 |
-
from Mikobot.plugins.helper_funcs.chat_status import (
|
25 |
-
check_admin,
|
26 |
-
connection_status,
|
27 |
-
is_user_admin,
|
28 |
-
)
|
29 |
-
|
30 |
-
DISABLE_CMDS = []
|
31 |
-
DISABLE_OTHER = []
|
32 |
-
ADMIN_CMDS = []
|
33 |
-
|
34 |
-
# <================================================ CLASS =======================================================>
|
35 |
-
class DisableAbleCommandHandler(CommandHandler):
|
36 |
-
def __init__(
|
37 |
-
self,
|
38 |
-
command,
|
39 |
-
callback,
|
40 |
-
block: bool,
|
41 |
-
filters: filters_module.BaseFilter = None,
|
42 |
-
admin_ok=False,
|
43 |
-
):
|
44 |
-
super().__init__(command, callback, block=block)
|
45 |
-
self.admin_ok = admin_ok
|
46 |
-
|
47 |
-
if isinstance(command, string_types):
|
48 |
-
commands = frozenset({command.lower()})
|
49 |
-
DISABLE_CMDS.append(command)
|
50 |
-
if admin_ok:
|
51 |
-
ADMIN_CMDS.append(command)
|
52 |
-
else:
|
53 |
-
commands = frozenset(x.lower() for x in command)
|
54 |
-
DISABLE_CMDS.extend(command)
|
55 |
-
if admin_ok:
|
56 |
-
ADMIN_CMDS.extend(command)
|
57 |
-
for comm in commands:
|
58 |
-
if not re.match(r"^[\da-z_]{1,32}$", comm):
|
59 |
-
raise ValueError(f"Command `{comm}` is not a valid bot command")
|
60 |
-
|
61 |
-
self.commands = commands
|
62 |
-
self.filters = (
|
63 |
-
filters if filters is not None else filters_module.UpdateType.MESSAGES
|
64 |
-
)
|
65 |
-
|
66 |
-
def check_update(
|
67 |
-
self, update
|
68 |
-
) -> Optional[Union[bool, Tuple[List[str], Optional[Union[bool, Dict]]]]]:
|
69 |
-
if isinstance(update, Update) and update.effective_message:
|
70 |
-
message = update.effective_message
|
71 |
-
|
72 |
-
if message.text and len(message.text) > 1:
|
73 |
-
fst_word = message.text.split(None, 1)[0]
|
74 |
-
if len(fst_word) > 1 and any(
|
75 |
-
fst_word.startswith(start) for start in CMD_STARTERS
|
76 |
-
):
|
77 |
-
args = message.text.split()[1:]
|
78 |
-
command_parts = fst_word[1:].split("@")
|
79 |
-
command_parts.append(message.get_bot().username)
|
80 |
-
|
81 |
-
if not (
|
82 |
-
command_parts[0].lower() in self.commands
|
83 |
-
and command_parts[1].lower()
|
84 |
-
== message.get_bot().username.lower()
|
85 |
-
):
|
86 |
-
return None
|
87 |
-
|
88 |
-
chat = update.effective_chat
|
89 |
-
user = update.effective_user
|
90 |
-
|
91 |
-
filter_result = self.filters.check_update(update)
|
92 |
-
if filter_result:
|
93 |
-
# disabled, admincmd, user admin
|
94 |
-
if sql.is_command_disabled(
|
95 |
-
chat.id, command_parts[0].lower()
|
96 |
-
):
|
97 |
-
# check if command was disabled
|
98 |
-
is_disabled = command_parts[
|
99 |
-
0
|
100 |
-
] in ADMIN_CMDS and is_user_admin(chat, user.id)
|
101 |
-
if not is_disabled:
|
102 |
-
return None
|
103 |
-
else:
|
104 |
-
return args, filter_result
|
105 |
-
|
106 |
-
return args, filter_result
|
107 |
-
return False
|
108 |
-
return None
|
109 |
-
|
110 |
-
class DisableAbleMessageHandler(MessageHandler):
|
111 |
-
def __init__(self, filters, callback, block: bool, friendly, **kwargs):
|
112 |
-
super().__init__(filters, callback, block=block, **kwargs)
|
113 |
-
DISABLE_OTHER.append(friendly)
|
114 |
-
self.friendly = friendly
|
115 |
-
if filters:
|
116 |
-
self.filters = filters_module.UpdateType.MESSAGES & filters
|
117 |
-
else:
|
118 |
-
self.filters = filters_module.UpdateType.MESSAGES
|
119 |
-
|
120 |
-
def check_update(self, update):
|
121 |
-
chat = update.effective_chat
|
122 |
-
message = update.effective_message
|
123 |
-
filter_result = self.filters.check_update(update)
|
124 |
-
|
125 |
-
try:
|
126 |
-
args = message.text.split()[1:]
|
127 |
-
except:
|
128 |
-
args = []
|
129 |
-
|
130 |
-
if super().check_update(update):
|
131 |
-
if sql.is_command_disabled(chat.id, self.friendly):
|
132 |
-
return False
|
133 |
-
else:
|
134 |
-
return args, filter_result
|
135 |
-
|
136 |
-
# <=======================================================================================================>
|
137 |
-
|
138 |
-
# <================================================ FUNCTION =======================================================>
|
139 |
-
@connection_status
|
140 |
-
@check_admin(is_user=True)
|
141 |
-
async def disable(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
142 |
-
args = context.args
|
143 |
-
chat = update.effective_chat
|
144 |
-
if len(args) >= 1:
|
145 |
-
disable_cmd = args[0]
|
146 |
-
if disable_cmd.startswith(CMD_STARTERS):
|
147 |
-
disable_cmd = disable_cmd[1:]
|
148 |
-
|
149 |
-
if disable_cmd in set(DISABLE_CMDS + DISABLE_OTHER):
|
150 |
-
sql.disable_command(chat.id, str(disable_cmd).lower())
|
151 |
-
await update.effective_message.reply_text(
|
152 |
-
f"Disabled the use of `{disable_cmd}`",
|
153 |
-
parse_mode=ParseMode.MARKDOWN,
|
154 |
-
)
|
155 |
-
else:
|
156 |
-
await update.effective_message.reply_text(
|
157 |
-
"That command can't be disabled"
|
158 |
-
)
|
159 |
-
|
160 |
-
else:
|
161 |
-
await update.effective_message.reply_text("What should I disable?")
|
162 |
-
|
163 |
-
@connection_status
|
164 |
-
@check_admin(is_user=True)
|
165 |
-
async def disable_module(
|
166 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE
|
167 |
-
) -> None:
|
168 |
-
args = context.args
|
169 |
-
chat = update.effective_chat
|
170 |
-
if len(args) >= 1:
|
171 |
-
disable_module = "Mikobot.plugins." + args[0].rsplit(".", 1)[0]
|
172 |
-
|
173 |
-
try:
|
174 |
-
module = importlib.import_module(disable_module)
|
175 |
-
except:
|
176 |
-
await update.effective_message.reply_text(
|
177 |
-
"Does that module even exsist?"
|
178 |
-
)
|
179 |
-
return
|
180 |
-
|
181 |
-
try:
|
182 |
-
command_list = module.__command_list__
|
183 |
-
except:
|
184 |
-
await update.effective_message.reply_text(
|
185 |
-
"Module does not contain command list!",
|
186 |
-
)
|
187 |
-
return
|
188 |
-
|
189 |
-
disabled_cmds = []
|
190 |
-
failed_disabled_cmds = []
|
191 |
-
|
192 |
-
for disable_cmd in command_list:
|
193 |
-
if disable_cmd.startswith(CMD_STARTERS):
|
194 |
-
disable_cmd = disable_cmd[1:]
|
195 |
-
|
196 |
-
if disable_cmd in set(DISABLE_CMDS + DISABLE_OTHER):
|
197 |
-
sql.disable_command(chat.id, str(disable_cmd).lower())
|
198 |
-
disabled_cmds.append(disable_cmd)
|
199 |
-
else:
|
200 |
-
failed_disabled_cmds.append(disable_cmd)
|
201 |
-
|
202 |
-
if disabled_cmds:
|
203 |
-
disabled_cmds_string = ", ".join(disabled_cmds)
|
204 |
-
await update.effective_message.reply_text(
|
205 |
-
f"Disabled the use of`{disabled_cmds_string}`",
|
206 |
-
parse_mode=ParseMode.MARKDOWN,
|
207 |
-
)
|
208 |
-
|
209 |
-
if failed_disabled_cmds:
|
210 |
-
failed_disabled_cmds_string = ", ".join(failed_disabled_cmds)
|
211 |
-
await update.effective_message.reply_text(
|
212 |
-
f"Commands `{failed_disabled_cmds_string}` can't be disabled",
|
213 |
-
parse_mode=ParseMode.MARKDOWN,
|
214 |
-
)
|
215 |
-
|
216 |
-
else:
|
217 |
-
await update.effective_message.reply_text("What should I disable?")
|
218 |
-
|
219 |
-
@connection_status
|
220 |
-
@check_admin(is_user=True)
|
221 |
-
async def enable(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
222 |
-
args = context.args
|
223 |
-
chat = update.effective_chat
|
224 |
-
if len(args) >= 1:
|
225 |
-
enable_cmd = args[0]
|
226 |
-
if enable_cmd.startswith(CMD_STARTERS):
|
227 |
-
enable_cmd = enable_cmd[1:]
|
228 |
-
|
229 |
-
if sql.enable_command(chat.id, enable_cmd):
|
230 |
-
await update.effective_message.reply_text(
|
231 |
-
f"Enabled the use of`{enable_cmd}`",
|
232 |
-
parse_mode=ParseMode.MARKDOWN,
|
233 |
-
)
|
234 |
-
else:
|
235 |
-
await update.effective_message.reply_text("Is that even disabled?")
|
236 |
-
|
237 |
-
else:
|
238 |
-
await update.effective_message.reply_text("What sould I enable?")
|
239 |
-
|
240 |
-
@connection_status
|
241 |
-
@check_admin(is_user=True)
|
242 |
-
async def enable_module(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
243 |
-
args = context.args
|
244 |
-
chat = update.effective_chat
|
245 |
-
|
246 |
-
if len(args) >= 1:
|
247 |
-
enable_module = "Mikobot.plugins." + args[0].rsplit(".", 1)[0]
|
248 |
-
|
249 |
-
try:
|
250 |
-
module = importlib.import_module(enable_module)
|
251 |
-
except:
|
252 |
-
await update.effective_message.reply_text(
|
253 |
-
"Does that module even exsist?"
|
254 |
-
)
|
255 |
-
return
|
256 |
-
|
257 |
-
try:
|
258 |
-
command_list = module.__command_list__
|
259 |
-
except:
|
260 |
-
await update.effective_message.reply_text(
|
261 |
-
"Module does not contain command list!",
|
262 |
-
)
|
263 |
-
return
|
264 |
-
|
265 |
-
enabled_cmds = []
|
266 |
-
failed_enabled_cmds = []
|
267 |
-
|
268 |
-
for enable_cmd in command_list:
|
269 |
-
if enable_cmd.startswith(CMD_STARTERS):
|
270 |
-
enable_cmd = enable_cmd[1:]
|
271 |
-
|
272 |
-
if sql.enable_command(chat.id, enable_cmd):
|
273 |
-
enabled_cmds.append(enable_cmd)
|
274 |
-
else:
|
275 |
-
failed_enabled_cmds.append(enable_cmd)
|
276 |
-
|
277 |
-
if enabled_cmds:
|
278 |
-
enabled_cmds_string = ", ".join(enabled_cmds)
|
279 |
-
await update.effective_message.reply_text(
|
280 |
-
f"Enabled the use of`{enabled_cmds_string}`",
|
281 |
-
parse_mode=ParseMode.MARKDOWN,
|
282 |
-
)
|
283 |
-
|
284 |
-
if failed_enabled_cmds:
|
285 |
-
failed_enabled_cmds_string = ", ".join(failed_enabled_cmds)
|
286 |
-
await update.effective_message.reply_text(
|
287 |
-
f"Are the commands `{failed_enabled_cmds_string}` even disabled?",
|
288 |
-
parse_mode=ParseMode.MARKDOWN,
|
289 |
-
)
|
290 |
-
|
291 |
-
else:
|
292 |
-
await update.effective_message.reply_text("ᴡʜᴀᴛ sʜᴏᴜʟᴅ I ᴇɴᴀʙʟᴇ?")
|
293 |
-
|
294 |
-
@connection_status
|
295 |
-
@check_admin(is_user=True)
|
296 |
-
async def list_cmds(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
297 |
-
if DISABLE_CMDS + DISABLE_OTHER:
|
298 |
-
result = ""
|
299 |
-
for cmd in set(DISABLE_CMDS + DISABLE_OTHER):
|
300 |
-
result += f" - `{escape_markdown(cmd)}`\n"
|
301 |
-
await update.effective_message.reply_text(
|
302 |
-
f"The following commands are toggleable:\n{result}",
|
303 |
-
parse_mode=ParseMode.MARKDOWN,
|
304 |
-
)
|
305 |
-
else:
|
306 |
-
await update.effective_message.reply_text("No commands can be disabled.")
|
307 |
-
|
308 |
-
# do not async
|
309 |
-
def build_curr_disabled(chat_id: Union[str, int]) -> str:
|
310 |
-
disabled = sql.get_all_disabled(chat_id)
|
311 |
-
if not disabled:
|
312 |
-
return "No commands are disabled!"
|
313 |
-
|
314 |
-
result = ""
|
315 |
-
for cmd in disabled:
|
316 |
-
result += " - `{}`\n".format(escape_markdown(cmd))
|
317 |
-
return "The following commands are currently restricted:\n{}".format(result)
|
318 |
-
|
319 |
-
@connection_status
|
320 |
-
async def commands(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
321 |
-
chat = update.effective_chat
|
322 |
-
await update.effective_message.reply_text(
|
323 |
-
build_curr_disabled(chat.id),
|
324 |
-
parse_mode=ParseMode.MARKDOWN,
|
325 |
-
)
|
326 |
-
|
327 |
-
def __stats__():
|
328 |
-
return f"• {sql.num_disabled()} disabled items, across {sql.num_chats()} chats."
|
329 |
-
|
330 |
-
def __migrate__(old_chat_id, new_chat_id):
|
331 |
-
sql.migrate_chat(old_chat_id, new_chat_id)
|
332 |
-
|
333 |
-
def __chat_settings__(chat_id, user_id):
|
334 |
-
return build_curr_disabled(chat_id)
|
335 |
-
|
336 |
-
# <=================================================== HANDLER ====================================================>
|
337 |
-
|
338 |
-
DISABLE_HANDLER = CommandHandler("disable", disable, block=False)
|
339 |
-
DISABLE_MODULE_HANDLER = CommandHandler(
|
340 |
-
"disablemodule", disable_module, block=False
|
341 |
-
)
|
342 |
-
ENABLE_HANDLER = CommandHandler("enable", enable, block=False)
|
343 |
-
ENABLE_MODULE_HANDLER = CommandHandler("enablemodule", enable_module, block=False)
|
344 |
-
COMMANDS_HANDLER = CommandHandler(["cmds", "disabled"], commands, block=False)
|
345 |
-
TOGGLE_HANDLER = CommandHandler("listcmds", list_cmds, block=False)
|
346 |
-
|
347 |
-
function(DISABLE_HANDLER)
|
348 |
-
function(DISABLE_MODULE_HANDLER)
|
349 |
-
function(ENABLE_HANDLER)
|
350 |
-
function(ENABLE_MODULE_HANDLER)
|
351 |
-
function(COMMANDS_HANDLER)
|
352 |
-
function(TOGGLE_HANDLER)
|
353 |
-
|
354 |
-
# <=================================================== HELP ====================================================>
|
355 |
-
__help__ = """
|
356 |
-
» /cmds: Check the current status of disabled commands
|
357 |
-
|
358 |
-
➠ *Admins only*:
|
359 |
-
|
360 |
-
» /enable < cmd name >: Enable that command.
|
361 |
-
|
362 |
-
» /disable < cmd name >: Disable that command.
|
363 |
-
|
364 |
-
» /enablemodule < module name >: Enable all commands in that module.
|
365 |
-
|
366 |
-
» /disablemodule < module name >: Disable all commands in that module.
|
367 |
-
|
368 |
-
» /listcmds: List all possible toggleable commands.
|
369 |
-
"""
|
370 |
-
|
371 |
-
__mod_name__ = "DISABLE"
|
372 |
-
|
373 |
-
else:
|
374 |
-
DisableAbleCommandHandler = CommandHandler
|
375 |
-
DisableAbleMessageHandler = MessageHandler
|
376 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/extra.py
DELETED
@@ -1,137 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from time import gmtime, strftime, time
|
3 |
-
|
4 |
-
from pyrogram import filters
|
5 |
-
from pyrogram.types import Message
|
6 |
-
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
7 |
-
from telegram.ext import CallbackQueryHandler, CommandHandler, ContextTypes
|
8 |
-
|
9 |
-
from Mikobot import LOGGER, app, function
|
10 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin
|
11 |
-
|
12 |
-
# <=======================================================================================================>
|
13 |
-
|
14 |
-
UPTIME = time() # Check bot uptime
|
15 |
-
|
16 |
-
|
17 |
-
# <================================================ FUNCTION =======================================================>
|
18 |
-
async def getid(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
19 |
-
chat = update.effective_chat
|
20 |
-
your_id = update.message.from_user.id
|
21 |
-
message_id = update.message.message_id
|
22 |
-
reply = update.message.reply_to_message
|
23 |
-
|
24 |
-
text = f"[Message ID:](https://t.me/{chat.username}/{message_id}) `{message_id}`\n"
|
25 |
-
text += f"[Your ID:](tg://user?id={your_id}) `{your_id}`\n"
|
26 |
-
|
27 |
-
if context.args:
|
28 |
-
try:
|
29 |
-
user_id = context.args[0]
|
30 |
-
text += f"[User ID:](tg://user?id={user_id}) `{user_id}`\n"
|
31 |
-
except Exception:
|
32 |
-
await update.message.reply_text(
|
33 |
-
"This user doesn't exist.", parse_mode="Markdown"
|
34 |
-
)
|
35 |
-
return
|
36 |
-
|
37 |
-
text += f"[Chat ID:](https://t.me/{chat.username}) `{chat.id}`\n\n"
|
38 |
-
|
39 |
-
if reply:
|
40 |
-
text += f"[Replied Message ID:](https://t.me/{chat.username}/{reply.message_id}) `{reply.message_id}`\n"
|
41 |
-
text += f"[Replied User ID:](tg://user?id={reply.from_user.id}) `{reply.from_user.id}`\n\n"
|
42 |
-
|
43 |
-
if reply and reply.forward_from_chat:
|
44 |
-
text += f"The forwarded channel, {reply.forward_from_chat.title}, has an id of `{reply.forward_from_chat.id}`\n\n"
|
45 |
-
|
46 |
-
if reply and reply.sender_chat:
|
47 |
-
text += f"ID of the replied chat/channel, is `{reply.sender_chat.id}`"
|
48 |
-
|
49 |
-
# Sticker ID to be sent
|
50 |
-
sticker_id = (
|
51 |
-
"CAACAgIAAx0CanzPTAABASPCZQdU9NbQIol5TW1GU2zV4KfjDMEAAnccAALIWZhJPyYLf3FzPHswBA"
|
52 |
-
)
|
53 |
-
|
54 |
-
# Send the sticker
|
55 |
-
await update.message.reply_sticker(sticker=sticker_id)
|
56 |
-
|
57 |
-
# Send the text message as a caption
|
58 |
-
await update.message.reply_text(
|
59 |
-
text, parse_mode="Markdown", disable_web_page_preview=True
|
60 |
-
)
|
61 |
-
|
62 |
-
|
63 |
-
# Function to handle the "logs" command
|
64 |
-
@check_admin(only_dev=True)
|
65 |
-
async def logs(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
66 |
-
user = update.effective_user
|
67 |
-
with open("Logs.txt", "rb") as f:
|
68 |
-
caption = "Here is your log"
|
69 |
-
reply_markup = InlineKeyboardMarkup(
|
70 |
-
[[InlineKeyboardButton("Close", callback_data="close")]]
|
71 |
-
)
|
72 |
-
message = await context.bot.send_document(
|
73 |
-
document=f,
|
74 |
-
filename=f.name,
|
75 |
-
caption=caption,
|
76 |
-
reply_markup=reply_markup,
|
77 |
-
chat_id=user.id,
|
78 |
-
)
|
79 |
-
|
80 |
-
# Store the message ID for later reference
|
81 |
-
context.user_data["log_message_id"] = message.message_id
|
82 |
-
|
83 |
-
|
84 |
-
# Asynchronous callback query handler for the "close" button
|
85 |
-
@check_admin(only_dev=True)
|
86 |
-
async def close_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
87 |
-
query = update.callback_query
|
88 |
-
message_id = context.user_data.get("log_message_id")
|
89 |
-
if message_id:
|
90 |
-
await context.bot.delete_message(
|
91 |
-
chat_id=query.message.chat_id, message_id=message_id
|
92 |
-
)
|
93 |
-
|
94 |
-
|
95 |
-
@app.on_message(filters.command("pyroping"))
|
96 |
-
async def ping(_, m: Message):
|
97 |
-
LOGGER.info(f"{m.from_user.id} used ping cmd in {m.chat.id}")
|
98 |
-
start = time()
|
99 |
-
replymsg = await m.reply_text(text="Pinging...", quote=True)
|
100 |
-
delta_ping = time() - start
|
101 |
-
|
102 |
-
up = strftime("%Hh %Mm %Ss", gmtime(time() - UPTIME))
|
103 |
-
image_url = "https://telegra.ph/file/f215a1c4adf25a5bad81b.jpg"
|
104 |
-
|
105 |
-
# Send the image as a reply
|
106 |
-
await replymsg.reply_photo(
|
107 |
-
photo=image_url,
|
108 |
-
caption=f"<b>Pyro-Pong!</b>\n{delta_ping * 1000:.3f} ms\n\nUptime: <code>{up}</code>",
|
109 |
-
)
|
110 |
-
await replymsg.delete()
|
111 |
-
|
112 |
-
|
113 |
-
# <=======================================================================================================>
|
114 |
-
|
115 |
-
|
116 |
-
# <================================================ HANDLER =======================================================>
|
117 |
-
function(CommandHandler("logs", logs, block=False))
|
118 |
-
function(CommandHandler("id", getid, block=False))
|
119 |
-
function(CallbackQueryHandler(close_callback, pattern="^close$", block=False))
|
120 |
-
|
121 |
-
# <================================================= HELP ======================================================>
|
122 |
-
__help__ = """
|
123 |
-
➠ *Commands*:
|
124 |
-
|
125 |
-
» /instadl, /insta <link>: Get instagram contents like reel video or images.
|
126 |
-
|
127 |
-
» /pyroping: see pyroping.
|
128 |
-
|
129 |
-
» /hyperlink <text> <link> : Creates a markdown hyperlink with the provided text and link.
|
130 |
-
|
131 |
-
» /pickwinner <participant1> <participant2> ... : Picks a random winner from the provided list of participants.
|
132 |
-
|
133 |
-
» /id: reply to get user id.
|
134 |
-
"""
|
135 |
-
|
136 |
-
__mod_name__ = "EXTRA"
|
137 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/feds.py
DELETED
@@ -1,2505 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import ast
|
3 |
-
import csv
|
4 |
-
import json
|
5 |
-
import os
|
6 |
-
import re
|
7 |
-
import time
|
8 |
-
import uuid
|
9 |
-
from io import BytesIO
|
10 |
-
|
11 |
-
from telegram import (
|
12 |
-
ChatMember,
|
13 |
-
InlineKeyboardButton,
|
14 |
-
InlineKeyboardMarkup,
|
15 |
-
MessageEntity,
|
16 |
-
Update,
|
17 |
-
)
|
18 |
-
from telegram.constants import ParseMode
|
19 |
-
from telegram.error import BadRequest, Forbidden, TelegramError
|
20 |
-
from telegram.ext import CallbackQueryHandler, CommandHandler, ContextTypes
|
21 |
-
from telegram.helpers import mention_html, mention_markdown
|
22 |
-
|
23 |
-
import Database.sql.feds_sql as sql
|
24 |
-
from Mikobot import (
|
25 |
-
DRAGONS,
|
26 |
-
EVENT_LOGS,
|
27 |
-
LOGGER,
|
28 |
-
OWNER_ID,
|
29 |
-
SUPPORT_CHAT,
|
30 |
-
dispatcher,
|
31 |
-
function,
|
32 |
-
)
|
33 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
34 |
-
from Mikobot.plugins.helper_funcs.alternate import send_message
|
35 |
-
from Mikobot.plugins.helper_funcs.chat_status import is_user_admin
|
36 |
-
from Mikobot.plugins.helper_funcs.extraction import (
|
37 |
-
extract_unt_fedban,
|
38 |
-
extract_user,
|
39 |
-
extract_user_fban,
|
40 |
-
)
|
41 |
-
from Mikobot.plugins.helper_funcs.string_handling import markdown_parser
|
42 |
-
|
43 |
-
# <=======================================================================================================>
|
44 |
-
|
45 |
-
FBAN_ERRORS = {
|
46 |
-
"User is an administrator of the chat",
|
47 |
-
"Chat not found",
|
48 |
-
"Not enough rights to restrict/unrestrict chat member",
|
49 |
-
"User_not_participant",
|
50 |
-
"Peer_id_invalid",
|
51 |
-
"Group chat was deactivated",
|
52 |
-
"Need to be inviter of a user to kick it from a basic group",
|
53 |
-
"Chat_admin_required",
|
54 |
-
"Only the creator of a basic group can kick group administrators",
|
55 |
-
"Channel_private",
|
56 |
-
"Not in the chat",
|
57 |
-
"Have no rights to send a message",
|
58 |
-
}
|
59 |
-
|
60 |
-
UNFBAN_ERRORS = {
|
61 |
-
"User is an administrator of the chat",
|
62 |
-
"Chat not found",
|
63 |
-
"Not enough rights to restrict/unrestrict chat member",
|
64 |
-
"User_not_participant",
|
65 |
-
"Method is available for supergroup and channel chats only",
|
66 |
-
"Not in the chat",
|
67 |
-
"Channel_private",
|
68 |
-
"Chat_admin_required",
|
69 |
-
"Have no rights to send a message",
|
70 |
-
}
|
71 |
-
|
72 |
-
|
73 |
-
# <================================================ FUNCTION =======================================================>
|
74 |
-
async def new_fed(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
75 |
-
chat = update.effective_chat
|
76 |
-
user = update.effective_user
|
77 |
-
message = update.effective_message
|
78 |
-
bot = context.bot
|
79 |
-
if chat.type != "private":
|
80 |
-
await update.effective_message.reply_text(
|
81 |
-
"Federations can only be created by privately messaging me.",
|
82 |
-
)
|
83 |
-
return
|
84 |
-
if len(message.text) == 1:
|
85 |
-
await send_message(
|
86 |
-
update.effective_message,
|
87 |
-
"Please write the name of the federation!",
|
88 |
-
)
|
89 |
-
return
|
90 |
-
fednam = message.text.split(None, 1)[1]
|
91 |
-
if not fednam == "":
|
92 |
-
fed_id = str(uuid.uuid4())
|
93 |
-
fed_name = fednam
|
94 |
-
LOGGER.info(fed_id)
|
95 |
-
|
96 |
-
x = sql.new_fed(user.id, fed_name, fed_id)
|
97 |
-
if not x:
|
98 |
-
await update.effective_message.reply_text(
|
99 |
-
f"Can't federate! Please contact @{SUPPORT_CHAT} if the problem persist.",
|
100 |
-
)
|
101 |
-
return
|
102 |
-
|
103 |
-
await update.effective_message.reply_text(
|
104 |
-
"*You have succeeded in creating a new federation!*"
|
105 |
-
"\nName: `{}`"
|
106 |
-
"\nID: `{}`"
|
107 |
-
"\n\nUse the command below to join the federation:"
|
108 |
-
"\n`/joinfed {}`".format(fed_name, fed_id, fed_id),
|
109 |
-
parse_mode=ParseMode.MARKDOWN,
|
110 |
-
)
|
111 |
-
try:
|
112 |
-
await bot.send_message(
|
113 |
-
EVENT_LOGS,
|
114 |
-
"New Federation: <b>{}</b>\nID: <pre>{}</pre>".format(fed_name, fed_id),
|
115 |
-
parse_mode=ParseMode.HTML,
|
116 |
-
)
|
117 |
-
except:
|
118 |
-
LOGGER.warning("Cannot send a message to EVENT_LOGS")
|
119 |
-
else:
|
120 |
-
await update.effective_message.reply_text(
|
121 |
-
"Please write down the name of the federation",
|
122 |
-
)
|
123 |
-
|
124 |
-
|
125 |
-
async def del_fed(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
126 |
-
bot, args = context.bot, context.args
|
127 |
-
chat = update.effective_chat
|
128 |
-
user = update.effective_user
|
129 |
-
if chat.type != "private":
|
130 |
-
await update.effective_message.reply_text(
|
131 |
-
"Federations can only be deleted by privately messaging me.",
|
132 |
-
)
|
133 |
-
return
|
134 |
-
if args:
|
135 |
-
is_fed_id = args[0]
|
136 |
-
getinfo = sql.get_fed_info(is_fed_id)
|
137 |
-
if getinfo is False:
|
138 |
-
await update.effective_message.reply_text("This federation does not exist.")
|
139 |
-
return
|
140 |
-
if int(getinfo["owner"]) == int(user.id) or int(user.id) == OWNER_ID:
|
141 |
-
fed_id = is_fed_id
|
142 |
-
else:
|
143 |
-
await update.effective_message.reply_text(
|
144 |
-
"Only federation owners can do this!"
|
145 |
-
)
|
146 |
-
return
|
147 |
-
else:
|
148 |
-
await update.effective_message.reply_text("What should I delete?")
|
149 |
-
return
|
150 |
-
|
151 |
-
if is_user_fed_owner(fed_id, user.id) is False:
|
152 |
-
await update.effective_message.reply_text("Only federation owners can do this!")
|
153 |
-
return
|
154 |
-
|
155 |
-
await update.effective_message.reply_text(
|
156 |
-
"You sure you want to delete your federation? This cannot be reverted, you will lose your entire ban list, and '{}' will be permanently lost.".format(
|
157 |
-
getinfo["fname"],
|
158 |
-
),
|
159 |
-
reply_markup=InlineKeyboardMarkup(
|
160 |
-
[
|
161 |
-
[
|
162 |
-
InlineKeyboardButton(
|
163 |
-
text="⚠️ Delete Federation ⚠️",
|
164 |
-
callback_data="rmfed_{}".format(fed_id),
|
165 |
-
),
|
166 |
-
],
|
167 |
-
[InlineKeyboardButton(text="Cancel", callback_data="rmfed_cancel")],
|
168 |
-
],
|
169 |
-
),
|
170 |
-
)
|
171 |
-
|
172 |
-
|
173 |
-
async def rename_fed(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
174 |
-
user = update.effective_user
|
175 |
-
msg = update.effective_message
|
176 |
-
args = msg.text.split(None, 2)
|
177 |
-
|
178 |
-
if len(args) < 3:
|
179 |
-
return await msg.reply_text("usage: /renamefed <fed_id> <newname>")
|
180 |
-
|
181 |
-
fed_id, newname = args[1], args[2]
|
182 |
-
verify_fed = sql.get_fed_info(fed_id)
|
183 |
-
|
184 |
-
if not verify_fed:
|
185 |
-
return await msg.reply_text("This fed not exist in my database!")
|
186 |
-
|
187 |
-
if is_user_fed_owner(fed_id, user.id):
|
188 |
-
sql.rename_fed(fed_id, user.id, newname)
|
189 |
-
await msg.reply_text(f"Successfully renamed your fed name to {newname}!")
|
190 |
-
else:
|
191 |
-
await msg.reply_text("Only federation owner can do this!")
|
192 |
-
|
193 |
-
|
194 |
-
async def fed_chat(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
195 |
-
bot, args = context.bot, context.args
|
196 |
-
chat = update.effective_chat
|
197 |
-
user = update.effective_user
|
198 |
-
fed_id = sql.get_fed_id(chat.id)
|
199 |
-
|
200 |
-
user_id = update.effective_message.from_user.id
|
201 |
-
if not await is_user_admin(update.effective_chat, user_id):
|
202 |
-
await update.effective_message.reply_text(
|
203 |
-
"You must be an admin to execute this command",
|
204 |
-
)
|
205 |
-
return
|
206 |
-
|
207 |
-
if not fed_id:
|
208 |
-
await update.effective_message.reply_text(
|
209 |
-
"This group is not in any federation!"
|
210 |
-
)
|
211 |
-
return
|
212 |
-
|
213 |
-
user = update.effective_user
|
214 |
-
chat = update.effective_chat
|
215 |
-
info = sql.get_fed_info(fed_id)
|
216 |
-
|
217 |
-
text = "This group is part of the following federation:"
|
218 |
-
text += "\n{} (ID: <code>{}</code>)".format(info["fname"], fed_id)
|
219 |
-
|
220 |
-
await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML)
|
221 |
-
|
222 |
-
|
223 |
-
async def join_fed(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
224 |
-
bot, args = context.bot, context.args
|
225 |
-
chat = update.effective_chat
|
226 |
-
user = update.effective_user
|
227 |
-
|
228 |
-
if chat.type == "private":
|
229 |
-
await send_message(
|
230 |
-
update.effective_message,
|
231 |
-
"This command is specific to the group, not to our pm!",
|
232 |
-
)
|
233 |
-
return
|
234 |
-
|
235 |
-
message = update.effective_message
|
236 |
-
administrators = await chat.get_administrators()
|
237 |
-
fed_id = sql.get_fed_id(chat.id)
|
238 |
-
|
239 |
-
if user.id in DRAGONS:
|
240 |
-
pass
|
241 |
-
else:
|
242 |
-
for admin in administrators:
|
243 |
-
status = admin.status
|
244 |
-
if status == "creator":
|
245 |
-
if str(admin.user.id) == str(user.id):
|
246 |
-
pass
|
247 |
-
else:
|
248 |
-
await update.effective_message.reply_text(
|
249 |
-
"Only group creators can use this command!",
|
250 |
-
)
|
251 |
-
return
|
252 |
-
if fed_id:
|
253 |
-
await message.reply_text("You cannot join two federations from one chat")
|
254 |
-
return
|
255 |
-
|
256 |
-
if len(args) >= 1:
|
257 |
-
getfed = sql.search_fed_by_id(args[0])
|
258 |
-
if getfed is False:
|
259 |
-
await message.reply_text("Please enter a valid federation ID")
|
260 |
-
return
|
261 |
-
|
262 |
-
x = sql.chat_join_fed(args[0], chat.title, chat.id)
|
263 |
-
if not x:
|
264 |
-
await message.reply_text(
|
265 |
-
f"Failed to join federation! Please contact @{SUPPORT_CHAT} should this problem persist!",
|
266 |
-
)
|
267 |
-
return
|
268 |
-
|
269 |
-
get_fedlog = await sql.get_fed_log(args[0])
|
270 |
-
if get_fedlog:
|
271 |
-
if ast.literal_eval(get_fedlog):
|
272 |
-
await bot.send_message(
|
273 |
-
get_fedlog,
|
274 |
-
"Chat *{}* has joined the federation *{}*".format(
|
275 |
-
chat.title,
|
276 |
-
getfed["fname"],
|
277 |
-
),
|
278 |
-
parse_mode="markdown",
|
279 |
-
message_thread_id=message.message_thread_id
|
280 |
-
if chat.is_forum
|
281 |
-
else None,
|
282 |
-
)
|
283 |
-
|
284 |
-
await message.reply_text(
|
285 |
-
"This group has joined the federation: {}!".format(getfed["fname"]),
|
286 |
-
)
|
287 |
-
|
288 |
-
|
289 |
-
async def leave_fed(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
290 |
-
bot, args = context.bot, context.args
|
291 |
-
chat = update.effective_chat
|
292 |
-
user = update.effective_user
|
293 |
-
|
294 |
-
if chat.type == "private":
|
295 |
-
await send_message(
|
296 |
-
update.effective_message,
|
297 |
-
"This command is specific to the group, not to our PM!",
|
298 |
-
)
|
299 |
-
return
|
300 |
-
|
301 |
-
fed_id = sql.get_fed_id(chat.id)
|
302 |
-
fed_info = sql.get_fed_info(fed_id)
|
303 |
-
|
304 |
-
# administrators = await chat.get_administrators().status
|
305 |
-
getuser = await bot.get_chat_member(chat.id, user.id).status
|
306 |
-
if getuser in "creator" or user.id in DRAGONS:
|
307 |
-
if sql.chat_leave_fed(chat.id) is True:
|
308 |
-
get_fedlog = await sql.get_fed_log(fed_id)
|
309 |
-
if get_fedlog:
|
310 |
-
if ast.literal_eval(get_fedlog):
|
311 |
-
await bot.send_message(
|
312 |
-
get_fedlog,
|
313 |
-
"Chat *{}* has left the federation *{}*".format(
|
314 |
-
chat.title,
|
315 |
-
fed_info["fname"],
|
316 |
-
),
|
317 |
-
parse_mode="markdown",
|
318 |
-
message_thread_id=update.effective_message.message_thread_id
|
319 |
-
if chat.is_forum
|
320 |
-
else None,
|
321 |
-
)
|
322 |
-
await send_message(
|
323 |
-
update.effective_message,
|
324 |
-
"This group has left the federation {}!".format(fed_info["fname"]),
|
325 |
-
)
|
326 |
-
else:
|
327 |
-
await update.effective_message.reply_text(
|
328 |
-
"How can you leave a federation that you never joined?!",
|
329 |
-
)
|
330 |
-
else:
|
331 |
-
await update.effective_message.reply_text(
|
332 |
-
"Only group creators can use this command!"
|
333 |
-
)
|
334 |
-
|
335 |
-
|
336 |
-
async def user_join_fed(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
337 |
-
bot, args = context.bot, context.args
|
338 |
-
chat = update.effective_chat
|
339 |
-
user = update.effective_user
|
340 |
-
msg = update.effective_message
|
341 |
-
|
342 |
-
if chat.type == "private":
|
343 |
-
await send_message(
|
344 |
-
update.effective_message,
|
345 |
-
"This command is specific to the group, not to our pm!",
|
346 |
-
)
|
347 |
-
return
|
348 |
-
|
349 |
-
fed_id = sql.get_fed_id(chat.id)
|
350 |
-
|
351 |
-
if is_user_fed_owner(fed_id, user.id) or user.id in DRAGONS:
|
352 |
-
user_id = await extract_user(msg, context, args)
|
353 |
-
if user_id:
|
354 |
-
user = await bot.get_chat(user_id)
|
355 |
-
elif not msg.reply_to_message and not args:
|
356 |
-
user = msg.from_user
|
357 |
-
elif not msg.reply_to_message and (
|
358 |
-
not args
|
359 |
-
or (
|
360 |
-
len(args) >= 1
|
361 |
-
and not args[0].startswith("@")
|
362 |
-
and not args[0].isdigit()
|
363 |
-
and not msg.parse_entities([MessageEntity.TEXT_MENTION])
|
364 |
-
)
|
365 |
-
):
|
366 |
-
await msg.reply_text("I cannot extract user from this message")
|
367 |
-
return
|
368 |
-
else:
|
369 |
-
LOGGER.warning("error")
|
370 |
-
getuser = sql.search_user_in_fed(fed_id, user_id)
|
371 |
-
fed_id = sql.get_fed_id(chat.id)
|
372 |
-
info = sql.get_fed_info(fed_id)
|
373 |
-
get_owner = ast.literal_eval(info["fusers"])["owner"]
|
374 |
-
get_owner = await bot.get_chat(get_owner)
|
375 |
-
if isinstance(get_owner, ChatMember):
|
376 |
-
if user_id == get_owner.id:
|
377 |
-
await update.effective_message.reply_text(
|
378 |
-
"You do know that the user is the federation owner, right? RIGHT?",
|
379 |
-
)
|
380 |
-
return
|
381 |
-
if getuser:
|
382 |
-
await update.effective_message.reply_text(
|
383 |
-
"I cannot promote users who are already federation admins! Can remove them if you want!",
|
384 |
-
)
|
385 |
-
return
|
386 |
-
if user_id == bot.id:
|
387 |
-
await update.effective_message.reply_text(
|
388 |
-
"I already am a federation admin in all federations!",
|
389 |
-
)
|
390 |
-
return
|
391 |
-
res = sql.user_join_fed(fed_id, user_id)
|
392 |
-
if res:
|
393 |
-
await update.effective_message.reply_text("Successfully Promoted!")
|
394 |
-
else:
|
395 |
-
await update.effective_message.reply_text("Failed to promote!")
|
396 |
-
else:
|
397 |
-
await update.effective_message.reply_text("Only federation owners can do this!")
|
398 |
-
|
399 |
-
|
400 |
-
async def user_demote_fed(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
401 |
-
bot, args = context.bot, context.args
|
402 |
-
chat = update.effective_chat
|
403 |
-
user = update.effective_user
|
404 |
-
|
405 |
-
if chat.type == "private":
|
406 |
-
await send_message(
|
407 |
-
update.effective_message,
|
408 |
-
"This command is specific to the group, not to our pm!",
|
409 |
-
)
|
410 |
-
return
|
411 |
-
|
412 |
-
fed_id = sql.get_fed_id(chat.id)
|
413 |
-
|
414 |
-
if is_user_fed_owner(fed_id, user.id):
|
415 |
-
msg = update.effective_message
|
416 |
-
user_id = await extract_user(msg, context, args)
|
417 |
-
if user_id:
|
418 |
-
user = await bot.get_chat(user_id)
|
419 |
-
|
420 |
-
elif not msg.reply_to_message and not args:
|
421 |
-
user = msg.from_user
|
422 |
-
|
423 |
-
elif not msg.reply_to_message and (
|
424 |
-
not args
|
425 |
-
or (
|
426 |
-
len(args) >= 1
|
427 |
-
and not args[0].startswith("@")
|
428 |
-
and not args[0].isdigit()
|
429 |
-
and not msg.parse_entities([MessageEntity.TEXT_MENTION])
|
430 |
-
)
|
431 |
-
):
|
432 |
-
await msg.reply_text("I cannot extract user from this message")
|
433 |
-
return
|
434 |
-
else:
|
435 |
-
LOGGER.warning("error")
|
436 |
-
|
437 |
-
if user_id == bot.id:
|
438 |
-
await update.effective_message.reply_text(
|
439 |
-
"The thing you are trying to demote me from will fail to work without me! Just saying.",
|
440 |
-
)
|
441 |
-
return
|
442 |
-
|
443 |
-
if sql.search_user_in_fed(fed_id, user_id) is False:
|
444 |
-
await update.effective_message.reply_text(
|
445 |
-
"I cannot demote people who are not federation admins!",
|
446 |
-
)
|
447 |
-
return
|
448 |
-
|
449 |
-
res = sql.user_demote_fed(fed_id, user_id)
|
450 |
-
if res is True:
|
451 |
-
await update.effective_message.reply_text("Demoted from a Fed Admin!")
|
452 |
-
else:
|
453 |
-
await update.effective_message.reply_text("Demotion failed!")
|
454 |
-
else:
|
455 |
-
await update.effective_message.reply_text("Only federation owners can do this!")
|
456 |
-
return
|
457 |
-
|
458 |
-
|
459 |
-
async def fed_info(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
460 |
-
bot, args = context.bot, context.args
|
461 |
-
chat = update.effective_chat
|
462 |
-
user = update.effective_user
|
463 |
-
if args:
|
464 |
-
fed_id = args[0]
|
465 |
-
info = sql.get_fed_info(fed_id)
|
466 |
-
else:
|
467 |
-
if chat.type == "private":
|
468 |
-
await send_message(
|
469 |
-
update.effective_message,
|
470 |
-
"You need to provide me a fedid to check fedinfo in my pm.",
|
471 |
-
)
|
472 |
-
return
|
473 |
-
fed_id = sql.get_fed_id(chat.id)
|
474 |
-
if not fed_id:
|
475 |
-
await send_message(
|
476 |
-
update.effective_message,
|
477 |
-
"This group is not in any federation!",
|
478 |
-
)
|
479 |
-
return
|
480 |
-
info = sql.get_fed_info(fed_id)
|
481 |
-
|
482 |
-
if is_user_fed_admin(fed_id, user.id) is False:
|
483 |
-
await update.effective_message.reply_text(
|
484 |
-
"Only a federation admin can do this!"
|
485 |
-
)
|
486 |
-
return
|
487 |
-
|
488 |
-
owner = await bot.get_chat(info["owner"])
|
489 |
-
try:
|
490 |
-
owner_name = owner.first_name + " " + owner.last_name
|
491 |
-
except:
|
492 |
-
owner_name = owner.first_name
|
493 |
-
FEDADMIN = sql.all_fed_users(fed_id)
|
494 |
-
TotalAdminFed = len(FEDADMIN)
|
495 |
-
|
496 |
-
user = update.effective_user
|
497 |
-
chat = update.effective_chat
|
498 |
-
info = sql.get_fed_info(fed_id)
|
499 |
-
|
500 |
-
text = "<b>ℹ️ Federation Information:</b>"
|
501 |
-
text += "\nFedID: <code>{}</code>".format(fed_id)
|
502 |
-
text += "\nName: {}".format(info["fname"])
|
503 |
-
text += "\nCreator: {}".format(mention_html(owner.id, owner_name))
|
504 |
-
text += "\nAll Admins: <code>{}</code>".format(TotalAdminFed)
|
505 |
-
getfban = sql.get_all_fban_users(fed_id)
|
506 |
-
text += "\nTotal banned users: <code>{}</code>".format(len(getfban))
|
507 |
-
getfchat = sql.all_fed_chats(fed_id)
|
508 |
-
text += "\nNumber of groups in this federation: <code>{}</code>".format(
|
509 |
-
len(getfchat),
|
510 |
-
)
|
511 |
-
|
512 |
-
await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML)
|
513 |
-
|
514 |
-
|
515 |
-
async def fed_admin(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
516 |
-
bot, args = context.bot, context.args
|
517 |
-
chat = update.effective_chat
|
518 |
-
user = update.effective_user
|
519 |
-
|
520 |
-
if chat.type == "private":
|
521 |
-
await send_message(
|
522 |
-
update.effective_message,
|
523 |
-
"This command is specific to the group, not to our pm!",
|
524 |
-
)
|
525 |
-
return
|
526 |
-
|
527 |
-
fed_id = sql.get_fed_id(chat.id)
|
528 |
-
|
529 |
-
if not fed_id:
|
530 |
-
await update.effective_message.reply_text(
|
531 |
-
"This group is not in any federation!"
|
532 |
-
)
|
533 |
-
return
|
534 |
-
|
535 |
-
if is_user_fed_admin(fed_id, user.id) is False:
|
536 |
-
await update.effective_message.reply_text("Only federation admins can do this!")
|
537 |
-
return
|
538 |
-
|
539 |
-
user = update.effective_user
|
540 |
-
chat = update.effective_chat
|
541 |
-
info = sql.get_fed_info(fed_id)
|
542 |
-
|
543 |
-
text = "<b>Federation Admin {}:</b>\n\n".format(info["fname"])
|
544 |
-
text += "👑 Owner:\n"
|
545 |
-
owner = await bot.get_chat(info["owner"])
|
546 |
-
try:
|
547 |
-
owner_name = owner.first_name + " " + owner.last_name
|
548 |
-
except:
|
549 |
-
owner_name = owner.first_name
|
550 |
-
text += " • {}\n".format(mention_html(owner.id, owner_name))
|
551 |
-
|
552 |
-
members = sql.all_fed_members(fed_id)
|
553 |
-
if len(members) == 0:
|
554 |
-
text += "\n🔱 There are no admins in this federation"
|
555 |
-
else:
|
556 |
-
text += "\n🔱 Admin:\n"
|
557 |
-
for x in members:
|
558 |
-
user = await bot.get_chat(x)
|
559 |
-
text += " • {}\n".format(mention_html(user.id, user.first_name))
|
560 |
-
|
561 |
-
await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML)
|
562 |
-
|
563 |
-
|
564 |
-
async def fed_ban(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
565 |
-
bot, args = context.bot, context.args
|
566 |
-
chat = update.effective_chat
|
567 |
-
user = update.effective_user
|
568 |
-
|
569 |
-
if chat.type == "private":
|
570 |
-
await send_message(
|
571 |
-
update.effective_message,
|
572 |
-
"This command is specific to the group, not to our pm!",
|
573 |
-
)
|
574 |
-
return
|
575 |
-
|
576 |
-
fed_id = sql.get_fed_id(chat.id)
|
577 |
-
|
578 |
-
if not fed_id:
|
579 |
-
await update.effective_message.reply_text(
|
580 |
-
"This group is not a part of any federation!",
|
581 |
-
)
|
582 |
-
return
|
583 |
-
|
584 |
-
info = sql.get_fed_info(fed_id)
|
585 |
-
getfednotif = sql.user_feds_report(info["owner"])
|
586 |
-
|
587 |
-
if is_user_fed_admin(fed_id, user.id) is False:
|
588 |
-
await update.effective_message.reply_text("Only federation admins can do this!")
|
589 |
-
return
|
590 |
-
|
591 |
-
message = update.effective_message
|
592 |
-
|
593 |
-
user_id, reason = extract_unt_fedban(message, context, args)
|
594 |
-
|
595 |
-
fban, fbanreason, fbantime = sql.get_fban_user(fed_id, user_id)
|
596 |
-
|
597 |
-
if not user_id:
|
598 |
-
await message.reply_text("You don't seem to be referring to a user")
|
599 |
-
return
|
600 |
-
|
601 |
-
if user_id == bot.id:
|
602 |
-
await message.reply_text(
|
603 |
-
"What is funnier than kicking the group creator? Self sacrifice.",
|
604 |
-
)
|
605 |
-
return
|
606 |
-
|
607 |
-
if is_user_fed_owner(fed_id, user_id) is True:
|
608 |
-
await message.reply_text("Why did you try the federation fban?")
|
609 |
-
return
|
610 |
-
|
611 |
-
if is_user_fed_admin(fed_id, user_id) is True:
|
612 |
-
await message.reply_text("He is a federation admin, I can't fban him.")
|
613 |
-
return
|
614 |
-
|
615 |
-
if user_id == OWNER_ID:
|
616 |
-
await message.reply_text("Disaster level God cannot be fed banned!")
|
617 |
-
return
|
618 |
-
|
619 |
-
if int(user_id) in DRAGONS:
|
620 |
-
await message.reply_text("Dragons cannot be fed banned!")
|
621 |
-
return
|
622 |
-
|
623 |
-
if user_id in [777000, 1087968824]:
|
624 |
-
await message.reply_text("Fool! You can't attack Telegram's native tech!")
|
625 |
-
return
|
626 |
-
|
627 |
-
try:
|
628 |
-
user_chat = await bot.get_chat(user_id)
|
629 |
-
isvalid = True
|
630 |
-
fban_user_id = user_chat.id
|
631 |
-
fban_user_name = user_chat.first_name
|
632 |
-
fban_user_lname = user_chat.last_name
|
633 |
-
fban_user_uname = user_chat.username
|
634 |
-
except BadRequest as excp:
|
635 |
-
if not str(user_id).isdigit():
|
636 |
-
await send_message(update.effective_message, excp.message)
|
637 |
-
return
|
638 |
-
elif len(str(user_id)) != 9:
|
639 |
-
await send_message(update.effective_message, "That's so not a user!")
|
640 |
-
return
|
641 |
-
isvalid = False
|
642 |
-
fban_user_id = int(user_id)
|
643 |
-
fban_user_name = "user({})".format(user_id)
|
644 |
-
fban_user_lname = None
|
645 |
-
fban_user_uname = None
|
646 |
-
|
647 |
-
if isvalid and user_chat.type != "private":
|
648 |
-
await send_message(update.effective_message, "That's so not a user!")
|
649 |
-
return
|
650 |
-
|
651 |
-
if isvalid:
|
652 |
-
user_target = mention_html(fban_user_id, fban_user_name)
|
653 |
-
else:
|
654 |
-
user_target = fban_user_name
|
655 |
-
|
656 |
-
if fban:
|
657 |
-
fed_name = info["fname"]
|
658 |
-
# https://t.me/OnePunchSupport/41606 // https://t.me/OnePunchSupport/41619
|
659 |
-
# starting = "The reason fban is replaced for {} in the Federation <b>{}</b>.".format(user_target, fed_name)
|
660 |
-
# await send_message(update.effective_message, starting, parse_mode=ParseMode.HTML)
|
661 |
-
|
662 |
-
# if reason == "":
|
663 |
-
# reason = "No reason given."
|
664 |
-
|
665 |
-
temp = sql.un_fban_user(fed_id, fban_user_id)
|
666 |
-
if not temp:
|
667 |
-
await message.reply_text("Failed to update the reason for fedban!")
|
668 |
-
return
|
669 |
-
x = sql.fban_user(
|
670 |
-
fed_id,
|
671 |
-
fban_user_id,
|
672 |
-
fban_user_name,
|
673 |
-
fban_user_lname,
|
674 |
-
fban_user_uname,
|
675 |
-
reason,
|
676 |
-
int(time.time()),
|
677 |
-
)
|
678 |
-
if not x:
|
679 |
-
await message.reply_text(
|
680 |
-
f"Failed to ban from the federation! If this problem continues, contact @{SUPPORT_CHAT}.",
|
681 |
-
)
|
682 |
-
return
|
683 |
-
|
684 |
-
fed_chats = sql.all_fed_chats(fed_id)
|
685 |
-
# Will send to current chat
|
686 |
-
await bot.send_message(
|
687 |
-
chat.id,
|
688 |
-
"<b>FedBan reason updated</b>"
|
689 |
-
"\n<b>Federation:</b> {}"
|
690 |
-
"\n<b>Federation Admin:</b> {}"
|
691 |
-
"\n<b>User:</b> {}"
|
692 |
-
"\n<b>User ID:</b> <code>{}</code>"
|
693 |
-
"\n<b>Reason:</b> {}".format(
|
694 |
-
fed_name,
|
695 |
-
mention_html(user.id, user.first_name),
|
696 |
-
user_target,
|
697 |
-
fban_user_id,
|
698 |
-
reason,
|
699 |
-
),
|
700 |
-
parse_mode="HTML",
|
701 |
-
)
|
702 |
-
# Send message to owner if fednotif is enabled
|
703 |
-
if getfednotif:
|
704 |
-
await bot.send_message(
|
705 |
-
info["owner"],
|
706 |
-
"<b>FedBan reason updated</b>"
|
707 |
-
"\n<b>Federation:</b> {}"
|
708 |
-
"\n<b>Federation Admin:</b> {}"
|
709 |
-
"\n<b>User:</b> {}"
|
710 |
-
"\n<b>User ID:</b> <code>{}</code>"
|
711 |
-
"\n<b>Reason:</b> {}".format(
|
712 |
-
fed_name,
|
713 |
-
mention_html(user.id, user.first_name),
|
714 |
-
user_target,
|
715 |
-
fban_user_id,
|
716 |
-
reason,
|
717 |
-
),
|
718 |
-
parse_mode="HTML",
|
719 |
-
)
|
720 |
-
# If fedlog is set, then send message, except fedlog is current chat
|
721 |
-
get_fedlog = await sql.get_fed_log(fed_id)
|
722 |
-
if get_fedlog:
|
723 |
-
if int(get_fedlog) != int(chat.id):
|
724 |
-
await bot.send_message(
|
725 |
-
get_fedlog,
|
726 |
-
"<b>FedBan reason updated</b>"
|
727 |
-
"\n<b>Federation:</b> {}"
|
728 |
-
"\n<b>Federation Admin:</b> {}"
|
729 |
-
"\n<b>User:</b> {}"
|
730 |
-
"\n<b>User ID:</b> <code>{}</code>"
|
731 |
-
"\n<b>Reason:</b> {}".format(
|
732 |
-
fed_name,
|
733 |
-
mention_html(user.id, user.first_name),
|
734 |
-
user_target,
|
735 |
-
fban_user_id,
|
736 |
-
reason,
|
737 |
-
),
|
738 |
-
parse_mode="HTML",
|
739 |
-
)
|
740 |
-
for fedschat in fed_chats:
|
741 |
-
try:
|
742 |
-
# Do not spam all fed chats
|
743 |
-
"""
|
744 |
-
bot.send_message(chat, "<b>FedBan reason updated</b>" \
|
745 |
-
"\n<b>Federation:</b> {}" \
|
746 |
-
"\n<b>Federation Admin:</b> {}" \
|
747 |
-
"\n<b>User:</b> {}" \
|
748 |
-
"\n<b>User ID:</b> <code>{}</code>" \
|
749 |
-
"\n<b>Reason:</b> {}".format(fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason), parse_mode="HTML")
|
750 |
-
"""
|
751 |
-
await bot.ban_chat_member(fedschat, fban_user_id)
|
752 |
-
except BadRequest as excp:
|
753 |
-
if excp.message in FBAN_ERRORS:
|
754 |
-
try:
|
755 |
-
await dispatcher.bot.getChat(fedschat)
|
756 |
-
except Forbidden:
|
757 |
-
sql.chat_leave_fed(fedschat)
|
758 |
-
LOGGER.info(
|
759 |
-
"Chat {} has leave fed {} because I was kicked".format(
|
760 |
-
fedschat,
|
761 |
-
info["fname"],
|
762 |
-
),
|
763 |
-
)
|
764 |
-
continue
|
765 |
-
elif excp.message == "User_id_invalid":
|
766 |
-
break
|
767 |
-
else:
|
768 |
-
LOGGER.warning(
|
769 |
-
"Could not fban on {} because: {}".format(chat, excp.message),
|
770 |
-
)
|
771 |
-
except TelegramError:
|
772 |
-
pass
|
773 |
-
# Also do not spam all fed admins
|
774 |
-
"""
|
775 |
-
send_to_list(bot, FEDADMIN,
|
776 |
-
"<b>FedBan reason updated</b>" \
|
777 |
-
"\n<b>Federation:</b> {}" \
|
778 |
-
"\n<b>Federation Admin:</b> {}" \
|
779 |
-
"\n<b>User:</b> {}" \
|
780 |
-
"\n<b>User ID:</b> <code>{}</code>" \
|
781 |
-
"\n<b>Reason:</b> {}".format(fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason),
|
782 |
-
html=True)
|
783 |
-
"""
|
784 |
-
|
785 |
-
# Fban for fed subscriber
|
786 |
-
subscriber = list(sql.get_subscriber(fed_id))
|
787 |
-
if len(subscriber) != 0:
|
788 |
-
for fedsid in subscriber:
|
789 |
-
all_fedschat = sql.all_fed_chats(fedsid)
|
790 |
-
for fedschat in all_fedschat:
|
791 |
-
try:
|
792 |
-
await bot.ban_chat_member(fedschat, fban_user_id)
|
793 |
-
except BadRequest as excp:
|
794 |
-
if excp.message in FBAN_ERRORS:
|
795 |
-
try:
|
796 |
-
await dispatcher.bot.getChat(fedschat)
|
797 |
-
except Forbidden:
|
798 |
-
targetfed_id = sql.get_fed_id(fedschat)
|
799 |
-
sql.unsubs_fed(fed_id, targetfed_id)
|
800 |
-
LOGGER.info(
|
801 |
-
"Chat {} has unsub fed {} because I was kicked".format(
|
802 |
-
fedschat,
|
803 |
-
info["fname"],
|
804 |
-
),
|
805 |
-
)
|
806 |
-
continue
|
807 |
-
elif excp.message == "User_id_invalid":
|
808 |
-
break
|
809 |
-
else:
|
810 |
-
LOGGER.warning(
|
811 |
-
"Unable to fban on {} because: {}".format(
|
812 |
-
fedschat,
|
813 |
-
excp.message,
|
814 |
-
),
|
815 |
-
)
|
816 |
-
except TelegramError:
|
817 |
-
pass
|
818 |
-
# await send_message(update.effective_message, "Fedban Reason has been updated.")
|
819 |
-
return
|
820 |
-
|
821 |
-
fed_name = info["fname"]
|
822 |
-
|
823 |
-
# starting = "Starting a federation ban for {} in the Federation <b>{}</b>.".format(
|
824 |
-
# user_target, fed_name)
|
825 |
-
# await update.effective_message.reply_text(starting, parse_mode=ParseMode.HTML)
|
826 |
-
|
827 |
-
# if reason == "":
|
828 |
-
# reason = "No reason given."
|
829 |
-
|
830 |
-
x = sql.fban_user(
|
831 |
-
fed_id,
|
832 |
-
fban_user_id,
|
833 |
-
fban_user_name,
|
834 |
-
fban_user_lname,
|
835 |
-
fban_user_uname,
|
836 |
-
reason,
|
837 |
-
int(time.time()),
|
838 |
-
)
|
839 |
-
if not x:
|
840 |
-
await message.reply_text(
|
841 |
-
f"Failed to ban from the federation! If this problem continues, contact @{SUPPORT_CHAT}.",
|
842 |
-
)
|
843 |
-
return
|
844 |
-
|
845 |
-
fed_chats = sql.all_fed_chats(fed_id)
|
846 |
-
# Will send to current chat
|
847 |
-
await bot.send_message(
|
848 |
-
chat.id,
|
849 |
-
"<b>New FedBan</b>"
|
850 |
-
"\n<b>Federation:</b> {}"
|
851 |
-
"\n<b>Federation Admin:</b> {}"
|
852 |
-
"\n<b>User:</b> {}"
|
853 |
-
"\n<b>User ID:</b> <code>{}</code>"
|
854 |
-
"\n<b>Reason:</b> {}".format(
|
855 |
-
fed_name,
|
856 |
-
mention_html(user.id, user.first_name),
|
857 |
-
user_target,
|
858 |
-
fban_user_id,
|
859 |
-
reason,
|
860 |
-
),
|
861 |
-
parse_mode="HTML",
|
862 |
-
)
|
863 |
-
# Send message to owner if fednotif is enabled
|
864 |
-
if getfednotif:
|
865 |
-
await bot.send_message(
|
866 |
-
info["owner"],
|
867 |
-
"<b>New FedBan</b>"
|
868 |
-
"\n<b>Federation:</b> {}"
|
869 |
-
"\n<b>Federation Admin:</b> {}"
|
870 |
-
"\n<b>User:</b> {}"
|
871 |
-
"\n<b>User ID:</b> <code>{}</code>"
|
872 |
-
"\n<b>Reason:</b> {}".format(
|
873 |
-
fed_name,
|
874 |
-
mention_html(user.id, user.first_name),
|
875 |
-
user_target,
|
876 |
-
fban_user_id,
|
877 |
-
reason,
|
878 |
-
),
|
879 |
-
parse_mode="HTML",
|
880 |
-
)
|
881 |
-
# If fedlog is set, then send message, except fedlog is current chat
|
882 |
-
get_fedlog = await sql.get_fed_log(fed_id)
|
883 |
-
if get_fedlog:
|
884 |
-
if int(get_fedlog) != int(chat.id):
|
885 |
-
await bot.send_message(
|
886 |
-
get_fedlog,
|
887 |
-
"<b>New FedBan</b>"
|
888 |
-
"\n<b>Federation:</b> {}"
|
889 |
-
"\n<b>Federation Admin:</b> {}"
|
890 |
-
"\n<b>User:</b> {}"
|
891 |
-
"\n<b>User ID:</b> <code>{}</code>"
|
892 |
-
"\n<b>Reason:</b> {}".format(
|
893 |
-
fed_name,
|
894 |
-
mention_html(user.id, user.first_name),
|
895 |
-
user_target,
|
896 |
-
fban_user_id,
|
897 |
-
reason,
|
898 |
-
),
|
899 |
-
parse_mode="HTML",
|
900 |
-
)
|
901 |
-
chats_in_fed = 0
|
902 |
-
for fedschat in fed_chats:
|
903 |
-
chats_in_fed += 1
|
904 |
-
try:
|
905 |
-
# Do not spamming all fed chats
|
906 |
-
"""
|
907 |
-
bot.send_message(chat, "<b>FedBan reason updated</b>" \
|
908 |
-
"\n<b>Federation:</b> {}" \
|
909 |
-
"\n<b>Federation Admin:</b> {}" \
|
910 |
-
"\n<b>User:</b> {}" \
|
911 |
-
"\n<b>User ID:</b> <code>{}</code>" \
|
912 |
-
"\n<b>Reason:</b> {}".format(fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason), parse_mode="HTML")
|
913 |
-
"""
|
914 |
-
await bot.ban_chat_member(fedschat, fban_user_id)
|
915 |
-
except BadRequest as excp:
|
916 |
-
if excp.message in FBAN_ERRORS:
|
917 |
-
pass
|
918 |
-
elif excp.message == "User_id_invalid":
|
919 |
-
break
|
920 |
-
else:
|
921 |
-
LOGGER.warning(
|
922 |
-
"Could not fban on {} because: {}".format(chat, excp.message),
|
923 |
-
)
|
924 |
-
except TelegramError:
|
925 |
-
pass
|
926 |
-
|
927 |
-
# Also do not spamming all fed admins
|
928 |
-
"""
|
929 |
-
send_to_list(bot, FEDADMIN,
|
930 |
-
"<b>FedBan reason updated</b>" \
|
931 |
-
"\n<b>Federation:</b> {}" \
|
932 |
-
"\n<b>Federation Admin:</b> {}" \
|
933 |
-
"\n<b>User:</b> {}" \
|
934 |
-
"\n<b>User ID:</b> <code>{}</code>" \
|
935 |
-
"\n<b>Reason:</b> {}".format(fed_name, mention_html(user.id, user.first_name), user_target, fban_user_id, reason),
|
936 |
-
html=True)
|
937 |
-
"""
|
938 |
-
|
939 |
-
# Fban for fed subscriber
|
940 |
-
subscriber = list(sql.get_subscriber(fed_id))
|
941 |
-
if len(subscriber) != 0:
|
942 |
-
for fedsid in subscriber:
|
943 |
-
all_fedschat = sql.all_fed_chats(fedsid)
|
944 |
-
for fedschat in all_fedschat:
|
945 |
-
try:
|
946 |
-
await bot.ban_chat_member(fedschat, fban_user_id)
|
947 |
-
except BadRequest as excp:
|
948 |
-
if excp.message in FBAN_ERRORS:
|
949 |
-
try:
|
950 |
-
await dispatcher.bot.getChat(fedschat)
|
951 |
-
except Forbidden:
|
952 |
-
targetfed_id = sql.get_fed_id(fedschat)
|
953 |
-
sql.unsubs_fed(fed_id, targetfed_id)
|
954 |
-
LOGGER.info(
|
955 |
-
"Chat {} has unsub fed {} because I was kicked".format(
|
956 |
-
fedschat,
|
957 |
-
info["fname"],
|
958 |
-
),
|
959 |
-
)
|
960 |
-
continue
|
961 |
-
elif excp.message == "User_id_invalid":
|
962 |
-
break
|
963 |
-
else:
|
964 |
-
LOGGER.warning(
|
965 |
-
"Unable to fban on {} because: {}".format(
|
966 |
-
fedschat,
|
967 |
-
excp.message,
|
968 |
-
),
|
969 |
-
)
|
970 |
-
except TelegramError:
|
971 |
-
pass
|
972 |
-
|
973 |
-
|
974 |
-
async def unfban(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
975 |
-
bot, args = context.bot, context.args
|
976 |
-
chat = update.effective_chat
|
977 |
-
user = update.effective_user
|
978 |
-
message = update.effective_message
|
979 |
-
|
980 |
-
if chat.type == "private":
|
981 |
-
await send_message(
|
982 |
-
update.effective_message,
|
983 |
-
"This command is specific to the group, not to our pm!",
|
984 |
-
)
|
985 |
-
return
|
986 |
-
|
987 |
-
fed_id = sql.get_fed_id(chat.id)
|
988 |
-
|
989 |
-
if not fed_id:
|
990 |
-
await update.effective_message.reply_text(
|
991 |
-
"This group is not a part of any federation!",
|
992 |
-
)
|
993 |
-
return
|
994 |
-
|
995 |
-
info = sql.get_fed_info(fed_id)
|
996 |
-
getfednotif = sql.user_feds_report(info["owner"])
|
997 |
-
|
998 |
-
if is_user_fed_admin(fed_id, user.id) is False:
|
999 |
-
await update.effective_message.reply_text("Only federation admins can do this!")
|
1000 |
-
return
|
1001 |
-
|
1002 |
-
user_id = extract_user_fban(message, context, args)
|
1003 |
-
if not user_id:
|
1004 |
-
await message.reply_text("You do not seem to be referring to a user.")
|
1005 |
-
return
|
1006 |
-
|
1007 |
-
try:
|
1008 |
-
user_chat = await bot.get_chat(user_id)
|
1009 |
-
isvalid = True
|
1010 |
-
fban_user_id = user_chat.id
|
1011 |
-
fban_user_name = user_chat.first_name
|
1012 |
-
fban_user_lname = user_chat.last_name
|
1013 |
-
fban_user_uname = user_chat.username
|
1014 |
-
except BadRequest as excp:
|
1015 |
-
if not str(user_id).isdigit():
|
1016 |
-
await send_message(update.effective_message, excp.message)
|
1017 |
-
return
|
1018 |
-
elif len(str(user_id)) != 9:
|
1019 |
-
await send_message(update.effective_message, "That's so not a user!")
|
1020 |
-
return
|
1021 |
-
isvalid = False
|
1022 |
-
fban_user_id = int(user_id)
|
1023 |
-
fban_user_name = "user({})".format(user_id)
|
1024 |
-
fban_user_lname = None
|
1025 |
-
fban_user_uname = None
|
1026 |
-
|
1027 |
-
if isvalid and user_chat.type != "private":
|
1028 |
-
await message.reply_text("That's so not a user!")
|
1029 |
-
return
|
1030 |
-
|
1031 |
-
if isvalid:
|
1032 |
-
user_target = mention_html(fban_user_id, fban_user_name)
|
1033 |
-
else:
|
1034 |
-
user_target = fban_user_name
|
1035 |
-
|
1036 |
-
fban, fbanreason, fbantime = sql.get_fban_user(fed_id, fban_user_id)
|
1037 |
-
if fban is False:
|
1038 |
-
await message.reply_text("This user is not fbanned!")
|
1039 |
-
return
|
1040 |
-
|
1041 |
-
banner = update.effective_user
|
1042 |
-
|
1043 |
-
chat_list = sql.all_fed_chats(fed_id)
|
1044 |
-
# Will send to current chat
|
1045 |
-
await bot.send_message(
|
1046 |
-
chat.id,
|
1047 |
-
"<b>Un-FedBan</b>"
|
1048 |
-
"\n<b>Federation:</b> {}"
|
1049 |
-
"\n<b>Federation Admin:</b> {}"
|
1050 |
-
"\n<b>User:</b> {}"
|
1051 |
-
"\n<b>User ID:</b> <code>{}</code>".format(
|
1052 |
-
info["fname"],
|
1053 |
-
mention_html(user.id, user.first_name),
|
1054 |
-
user_target,
|
1055 |
-
fban_user_id,
|
1056 |
-
),
|
1057 |
-
parse_mode="HTML",
|
1058 |
-
)
|
1059 |
-
# Send message to owner if fednotif is enabled
|
1060 |
-
if getfednotif:
|
1061 |
-
await bot.send_message(
|
1062 |
-
info["owner"],
|
1063 |
-
"<b>Un-FedBan</b>"
|
1064 |
-
"\n<b>Federation:</b> {}"
|
1065 |
-
"\n<b>Federation Admin:</b> {}"
|
1066 |
-
"\n<b>User:</b> {}"
|
1067 |
-
"\n<b>User ID:</b> <code>{}</code>".format(
|
1068 |
-
info["fname"],
|
1069 |
-
mention_html(user.id, user.first_name),
|
1070 |
-
user_target,
|
1071 |
-
fban_user_id,
|
1072 |
-
),
|
1073 |
-
parse_mode="HTML",
|
1074 |
-
)
|
1075 |
-
# If fedlog is set, then send message, except fedlog is current chat
|
1076 |
-
get_fedlog = await sql.get_fed_log(fed_id)
|
1077 |
-
if get_fedlog:
|
1078 |
-
if int(get_fedlog) != int(chat.id):
|
1079 |
-
await bot.send_message(
|
1080 |
-
get_fedlog,
|
1081 |
-
"<b>Un-FedBan</b>"
|
1082 |
-
"\n<b>Federation:</b> {}"
|
1083 |
-
"\n<b>Federation Admin:</b> {}"
|
1084 |
-
"\n<b>User:</b> {}"
|
1085 |
-
"\n<b>User ID:</b> <code>{}</code>".format(
|
1086 |
-
info["fname"],
|
1087 |
-
mention_html(user.id, user.first_name),
|
1088 |
-
user_target,
|
1089 |
-
fban_user_id,
|
1090 |
-
),
|
1091 |
-
parse_mode="HTML",
|
1092 |
-
)
|
1093 |
-
unfbanned_in_chats = 0
|
1094 |
-
for fedchats in chat_list:
|
1095 |
-
unfbanned_in_chats += 1
|
1096 |
-
try:
|
1097 |
-
member = await bot.get_chat_member(fedchats, user_id)
|
1098 |
-
if member.status == "kicked":
|
1099 |
-
await bot.unban_chat_member(fedchats, user_id)
|
1100 |
-
# Do not spamming all fed chats
|
1101 |
-
"""
|
1102 |
-
bot.send_message(chat, "<b>Un-FedBan</b>" \
|
1103 |
-
"\n<b>Federation:</b> {}" \
|
1104 |
-
"\n<b>Federation Admin:</b> {}" \
|
1105 |
-
"\n<b>User:</b> {}" \
|
1106 |
-
"\n<b>User ID:</b> <code>{}</code>".format(info['fname'], mention_html(user.id, user.first_name), user_target, fban_user_id), parse_mode="HTML")
|
1107 |
-
"""
|
1108 |
-
except BadRequest as excp:
|
1109 |
-
if excp.message in UNFBAN_ERRORS:
|
1110 |
-
pass
|
1111 |
-
elif excp.message == "User_id_invalid":
|
1112 |
-
break
|
1113 |
-
else:
|
1114 |
-
LOGGER.warning(
|
1115 |
-
"Could not fban on {} because: {}".format(chat, excp.message),
|
1116 |
-
)
|
1117 |
-
except TelegramError:
|
1118 |
-
pass
|
1119 |
-
|
1120 |
-
try:
|
1121 |
-
x = sql.un_fban_user(fed_id, user_id)
|
1122 |
-
if not x:
|
1123 |
-
await send_message(
|
1124 |
-
update.effective_message,
|
1125 |
-
"Un-fban failed, this user may already be un-fedbanned!",
|
1126 |
-
)
|
1127 |
-
return
|
1128 |
-
except:
|
1129 |
-
pass
|
1130 |
-
|
1131 |
-
# UnFban for fed subscriber
|
1132 |
-
subscriber = list(sql.get_subscriber(fed_id))
|
1133 |
-
if len(subscriber) != 0:
|
1134 |
-
for fedsid in subscriber:
|
1135 |
-
all_fedschat = sql.all_fed_chats(fedsid)
|
1136 |
-
for fedschat in all_fedschat:
|
1137 |
-
try:
|
1138 |
-
await bot.unban_chat_member(fedchats, user_id)
|
1139 |
-
except BadRequest as excp:
|
1140 |
-
if excp.message in FBAN_ERRORS:
|
1141 |
-
try:
|
1142 |
-
await dispatcher.bot.getChat(fedschat)
|
1143 |
-
except Forbidden:
|
1144 |
-
targetfed_id = sql.get_fed_id(fedschat)
|
1145 |
-
sql.unsubs_fed(fed_id, targetfed_id)
|
1146 |
-
LOGGER.info(
|
1147 |
-
"Chat {} has unsub fed {} because I was kicked".format(
|
1148 |
-
fedschat,
|
1149 |
-
info["fname"],
|
1150 |
-
),
|
1151 |
-
)
|
1152 |
-
continue
|
1153 |
-
elif excp.message == "User_id_invalid":
|
1154 |
-
break
|
1155 |
-
else:
|
1156 |
-
LOGGER.warning(
|
1157 |
-
"Unable to fban on {} because: {}".format(
|
1158 |
-
fedschat,
|
1159 |
-
excp.message,
|
1160 |
-
),
|
1161 |
-
)
|
1162 |
-
except TelegramError:
|
1163 |
-
pass
|
1164 |
-
|
1165 |
-
if unfbanned_in_chats == 0:
|
1166 |
-
await send_message(
|
1167 |
-
update.effective_message,
|
1168 |
-
"This person has been un-fbanned in 0 chats.",
|
1169 |
-
)
|
1170 |
-
if unfbanned_in_chats > 0:
|
1171 |
-
await send_message(
|
1172 |
-
update.effective_message,
|
1173 |
-
"This person has been un-fbanned in {} chats.".format(unfbanned_in_chats),
|
1174 |
-
)
|
1175 |
-
# Also do not spamming all fed admins
|
1176 |
-
"""
|
1177 |
-
FEDADMIN = sql.all_fed_users(fed_id)
|
1178 |
-
for x in FEDADMIN:
|
1179 |
-
getreport = sql.user_feds_report(x)
|
1180 |
-
if getreport is False:
|
1181 |
-
FEDADMIN.remove(x)
|
1182 |
-
send_to_list(bot, FEDADMIN,
|
1183 |
-
"<b>Un-FedBan</b>" \
|
1184 |
-
"\n<b>Federation:</b> {}" \
|
1185 |
-
"\n<b>Federation Admin:</b> {}" \
|
1186 |
-
"\n<b>User:</b> {}" \
|
1187 |
-
"\n<b>User ID:</b> <code>{}</code>".format(info['fname'], mention_html(user.id, user.first_name),
|
1188 |
-
mention_html(user_chat.id, user_chat.first_name),
|
1189 |
-
user_chat.id),
|
1190 |
-
html=True)
|
1191 |
-
"""
|
1192 |
-
|
1193 |
-
|
1194 |
-
async def set_frules(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
1195 |
-
bot, args = context.bot, context.args
|
1196 |
-
chat = update.effective_chat
|
1197 |
-
user = update.effective_user
|
1198 |
-
|
1199 |
-
if chat.type == "private":
|
1200 |
-
await send_message(
|
1201 |
-
update.effective_message,
|
1202 |
-
"This command is specific to the group, not to our pm!",
|
1203 |
-
)
|
1204 |
-
return
|
1205 |
-
|
1206 |
-
fed_id = sql.get_fed_id(chat.id)
|
1207 |
-
|
1208 |
-
if not fed_id:
|
1209 |
-
await update.effective_message.reply_text(
|
1210 |
-
"This group is not in any federation!"
|
1211 |
-
)
|
1212 |
-
return
|
1213 |
-
|
1214 |
-
if is_user_fed_admin(fed_id, user.id) is False:
|
1215 |
-
await update.effective_message.reply_text("Only fed admins can do this!")
|
1216 |
-
return
|
1217 |
-
|
1218 |
-
if len(args) >= 1:
|
1219 |
-
msg = update.effective_message
|
1220 |
-
raw_text = msg.text
|
1221 |
-
args = raw_text.split(None, 1) # use python's maxsplit to separate cmd and args
|
1222 |
-
if len(args) == 2:
|
1223 |
-
txt = args[1]
|
1224 |
-
offset = len(txt) - len(raw_text) # set correct offset relative to command
|
1225 |
-
markdown_rules = markdown_parser(
|
1226 |
-
txt,
|
1227 |
-
entities=msg.parse_entities(),
|
1228 |
-
offset=offset,
|
1229 |
-
)
|
1230 |
-
x = sql.set_frules(fed_id, markdown_rules)
|
1231 |
-
if not x:
|
1232 |
-
await update.effective_message.reply_text(
|
1233 |
-
f"Whoa! There was an error while setting federation rules! If you wondered why please ask it in @{SUPPORT_CHAT}!",
|
1234 |
-
)
|
1235 |
-
return
|
1236 |
-
|
1237 |
-
rules = sql.get_fed_info(fed_id)["frules"]
|
1238 |
-
getfed = sql.get_fed_info(fed_id)
|
1239 |
-
get_fedlog = await sql.get_fed_log(fed_id)
|
1240 |
-
if get_fedlog:
|
1241 |
-
if ast.literal_eval(get_fedlog):
|
1242 |
-
await bot.send_message(
|
1243 |
-
get_fedlog,
|
1244 |
-
"*{}* has updated federation rules for fed *{}*".format(
|
1245 |
-
user.first_name,
|
1246 |
-
getfed["fname"],
|
1247 |
-
),
|
1248 |
-
parse_mode="markdown",
|
1249 |
-
message_thread_id=update.effective_message.message_thread_id
|
1250 |
-
if chat.is_forum
|
1251 |
-
else None,
|
1252 |
-
)
|
1253 |
-
await update.effective_message.reply_text(
|
1254 |
-
f"Rules have been changed to :\n{rules}!"
|
1255 |
-
)
|
1256 |
-
else:
|
1257 |
-
await update.effective_message.reply_text("Please write rules to set this up!")
|
1258 |
-
|
1259 |
-
|
1260 |
-
async def get_frules(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
1261 |
-
bot, args = context.bot, context.args
|
1262 |
-
chat = update.effective_chat
|
1263 |
-
|
1264 |
-
if chat.type == "private":
|
1265 |
-
await send_message(
|
1266 |
-
update.effective_message,
|
1267 |
-
"This command is specific to the group, not to our pm!",
|
1268 |
-
)
|
1269 |
-
return
|
1270 |
-
|
1271 |
-
fed_id = sql.get_fed_id(chat.id)
|
1272 |
-
if not fed_id:
|
1273 |
-
await update.effective_message.reply_text(
|
1274 |
-
"This group is not in any federation!"
|
1275 |
-
)
|
1276 |
-
return
|
1277 |
-
|
1278 |
-
rules = sql.get_frules(fed_id)
|
1279 |
-
text = "*Rules in this fed:*\n"
|
1280 |
-
text += rules
|
1281 |
-
await update.effective_message.reply_text(text, parse_mode=ParseMode.MARKDOWN)
|
1282 |
-
|
1283 |
-
|
1284 |
-
async def fed_broadcast(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
1285 |
-
bot, args = context.bot, context.args
|
1286 |
-
msg = update.effective_message
|
1287 |
-
user = update.effective_user
|
1288 |
-
chat = update.effective_chat
|
1289 |
-
|
1290 |
-
if chat.type == "private":
|
1291 |
-
await send_message(
|
1292 |
-
update.effective_message,
|
1293 |
-
"This command is specific to the group, not to our pm!",
|
1294 |
-
)
|
1295 |
-
return
|
1296 |
-
|
1297 |
-
if args:
|
1298 |
-
chat = update.effective_chat
|
1299 |
-
fed_id = sql.get_fed_id(chat.id)
|
1300 |
-
fedinfo = sql.get_fed_info(fed_id)
|
1301 |
-
if is_user_fed_owner(fed_id, user.id) is False:
|
1302 |
-
await update.effective_message.reply_text(
|
1303 |
-
"Only federation owners can do this!"
|
1304 |
-
)
|
1305 |
-
return
|
1306 |
-
# Parsing md
|
1307 |
-
raw_text = msg.text
|
1308 |
-
args = raw_text.split(None, 1) # use python's maxsplit to separate cmd and args
|
1309 |
-
txt = args[1]
|
1310 |
-
offset = len(txt) - len(raw_text) # set correct offset relative to command
|
1311 |
-
text_parser = markdown_parser(txt, entities=msg.parse_entities(), offset=offset)
|
1312 |
-
text = text_parser
|
1313 |
-
try:
|
1314 |
-
broadcaster = user.first_name
|
1315 |
-
except:
|
1316 |
-
broadcaster = user.first_name + " " + user.last_name
|
1317 |
-
text += "\n\n- {}".format(mention_markdown(user.id, broadcaster))
|
1318 |
-
chat_list = sql.all_fed_chats(fed_id)
|
1319 |
-
failed = 0
|
1320 |
-
for chat in chat_list:
|
1321 |
-
title = "*New broadcast from Fed {}*\n".format(fedinfo["fname"])
|
1322 |
-
try:
|
1323 |
-
await bot.sendMessage(
|
1324 |
-
chat,
|
1325 |
-
title + text,
|
1326 |
-
parse_mode="markdown",
|
1327 |
-
message_thread_id=msg.message_thread_id if chat.is_forum else None,
|
1328 |
-
)
|
1329 |
-
except TelegramError:
|
1330 |
-
try:
|
1331 |
-
await dispatcher.bot.getChat(chat)
|
1332 |
-
except Forbidden:
|
1333 |
-
failed += 1
|
1334 |
-
sql.chat_leave_fed(chat)
|
1335 |
-
LOGGER.info(
|
1336 |
-
"Chat {} has left fed {} because I was kicked".format(
|
1337 |
-
chat,
|
1338 |
-
fedinfo["fname"],
|
1339 |
-
),
|
1340 |
-
)
|
1341 |
-
continue
|
1342 |
-
failed += 1
|
1343 |
-
LOGGER.warning("Couldn't send broadcast to {}".format(str(chat)))
|
1344 |
-
|
1345 |
-
send_text = "The federation broadcast is complete"
|
1346 |
-
if failed >= 1:
|
1347 |
-
send_text += "{} the group failed to receive the message, probably because it left the Federation.".format(
|
1348 |
-
failed,
|
1349 |
-
)
|
1350 |
-
await update.effective_message.reply_text(send_text)
|
1351 |
-
|
1352 |
-
|
1353 |
-
async def fed_ban_list(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
1354 |
-
bot, args, chat_data = context.bot, context.args, context.chat_data
|
1355 |
-
chat = update.effective_chat
|
1356 |
-
user = update.effective_user
|
1357 |
-
|
1358 |
-
if chat.type == "private":
|
1359 |
-
await send_message(
|
1360 |
-
update.effective_message,
|
1361 |
-
"This command is specific to the group, not to our pm!",
|
1362 |
-
)
|
1363 |
-
return
|
1364 |
-
|
1365 |
-
fed_id = sql.get_fed_id(chat.id)
|
1366 |
-
info = sql.get_fed_info(fed_id)
|
1367 |
-
|
1368 |
-
if not fed_id:
|
1369 |
-
await update.effective_message.reply_text(
|
1370 |
-
"This group is not a part of any federation!",
|
1371 |
-
)
|
1372 |
-
return
|
1373 |
-
|
1374 |
-
if is_user_fed_owner(fed_id, user.id) is False:
|
1375 |
-
await update.effective_message.reply_text("Only Federation owners can do this!")
|
1376 |
-
return
|
1377 |
-
|
1378 |
-
user = update.effective_user
|
1379 |
-
chat = update.effective_chat
|
1380 |
-
getfban = sql.get_all_fban_users(fed_id)
|
1381 |
-
if len(getfban) == 0:
|
1382 |
-
await update.effective_message.reply_text(
|
1383 |
-
"The federation ban list of {} is empty".format(info["fname"]),
|
1384 |
-
parse_mode=ParseMode.HTML,
|
1385 |
-
)
|
1386 |
-
return
|
1387 |
-
|
1388 |
-
if args:
|
1389 |
-
if args[0] == "json":
|
1390 |
-
jam = time.time()
|
1391 |
-
new_jam = jam + 1800
|
1392 |
-
cek = get_chat(chat.id, chat_data)
|
1393 |
-
if cek.get("status"):
|
1394 |
-
if jam <= int(cek.get("value")):
|
1395 |
-
waktu = time.strftime(
|
1396 |
-
"%H:%M:%S %d/%m/%Y",
|
1397 |
-
time.localtime(cek.get("value")),
|
1398 |
-
)
|
1399 |
-
await update.effective_message.reply_text(
|
1400 |
-
"You can backup your data once every 30 minutes!\nYou can back up data again at `{}`".format(
|
1401 |
-
waktu,
|
1402 |
-
),
|
1403 |
-
parse_mode=ParseMode.MARKDOWN,
|
1404 |
-
)
|
1405 |
-
return
|
1406 |
-
else:
|
1407 |
-
if user.id not in DRAGONS:
|
1408 |
-
put_chat(chat.id, new_jam, chat_data)
|
1409 |
-
else:
|
1410 |
-
if user.id not in DRAGONS:
|
1411 |
-
put_chat(chat.id, new_jam, chat_data)
|
1412 |
-
backups = ""
|
1413 |
-
for users in getfban:
|
1414 |
-
getuserinfo = sql.get_all_fban_users_target(fed_id, users)
|
1415 |
-
json_parser = {
|
1416 |
-
"user_id": users,
|
1417 |
-
"first_name": getuserinfo["first_name"],
|
1418 |
-
"last_name": getuserinfo["last_name"],
|
1419 |
-
"user_name": getuserinfo["user_name"],
|
1420 |
-
"reason": getuserinfo["reason"],
|
1421 |
-
}
|
1422 |
-
backups += json.dumps(json_parser)
|
1423 |
-
backups += "\n"
|
1424 |
-
with BytesIO(str.encode(backups)) as output:
|
1425 |
-
output.name = "mikobot_fbanned_users.json"
|
1426 |
-
await update.effective_message.reply_document(
|
1427 |
-
document=output,
|
1428 |
-
filename="mikobot_fbanned_users.json",
|
1429 |
-
caption="Total {} User are blocked by the Federation {}.".format(
|
1430 |
-
len(getfban),
|
1431 |
-
info["fname"],
|
1432 |
-
),
|
1433 |
-
)
|
1434 |
-
return
|
1435 |
-
elif args[0] == "csv":
|
1436 |
-
jam = time.time()
|
1437 |
-
new_jam = jam + 1800
|
1438 |
-
cek = get_chat(chat.id, chat_data)
|
1439 |
-
if cek.get("status"):
|
1440 |
-
if jam <= int(cek.get("value")):
|
1441 |
-
waktu = time.strftime(
|
1442 |
-
"%H:%M:%S %d/%m/%Y",
|
1443 |
-
time.localtime(cek.get("value")),
|
1444 |
-
)
|
1445 |
-
await update.effective_message.reply_text(
|
1446 |
-
"You can back up data once every 30 minutes!\nYou can back up data again at `{}`".format(
|
1447 |
-
waktu,
|
1448 |
-
),
|
1449 |
-
parse_mode=ParseMode.MARKDOWN,
|
1450 |
-
)
|
1451 |
-
return
|
1452 |
-
else:
|
1453 |
-
if user.id not in DRAGONS:
|
1454 |
-
put_chat(chat.id, new_jam, chat_data)
|
1455 |
-
else:
|
1456 |
-
if user.id not in DRAGONS:
|
1457 |
-
put_chat(chat.id, new_jam, chat_data)
|
1458 |
-
backups = "id,firstname,lastname,username,reason\n"
|
1459 |
-
for users in getfban:
|
1460 |
-
getuserinfo = sql.get_all_fban_users_target(fed_id, users)
|
1461 |
-
backups += (
|
1462 |
-
"{user_id},{first_name},{last_name},{user_name},{reason}".format(
|
1463 |
-
user_id=users,
|
1464 |
-
first_name=getuserinfo["first_name"],
|
1465 |
-
last_name=getuserinfo["last_name"],
|
1466 |
-
user_name=getuserinfo["user_name"],
|
1467 |
-
reason=getuserinfo["reason"],
|
1468 |
-
)
|
1469 |
-
)
|
1470 |
-
backups += "\n"
|
1471 |
-
with BytesIO(str.encode(backups)) as output:
|
1472 |
-
output.name = "mikobot_fbanned_users.csv"
|
1473 |
-
await update.effective_message.reply_document(
|
1474 |
-
document=output,
|
1475 |
-
filename="mikobot_fbanned_users.csv",
|
1476 |
-
caption="Total {} User are blocked by Federation {}.".format(
|
1477 |
-
len(getfban),
|
1478 |
-
info["fname"],
|
1479 |
-
),
|
1480 |
-
)
|
1481 |
-
return
|
1482 |
-
|
1483 |
-
text = "<b>{} users have been banned from the federation {}:</b>\n".format(
|
1484 |
-
len(getfban),
|
1485 |
-
info["fname"],
|
1486 |
-
)
|
1487 |
-
for users in getfban:
|
1488 |
-
getuserinfo = sql.get_all_fban_users_target(fed_id, users)
|
1489 |
-
if getuserinfo is False:
|
1490 |
-
text = "There are no users banned from the federation {}".format(
|
1491 |
-
info["fname"],
|
1492 |
-
)
|
1493 |
-
break
|
1494 |
-
user_name = getuserinfo["first_name"]
|
1495 |
-
if getuserinfo["last_name"]:
|
1496 |
-
user_name += " " + getuserinfo["last_name"]
|
1497 |
-
text += " • {} (<code>{}</code>)\n".format(
|
1498 |
-
mention_html(users, user_name),
|
1499 |
-
users,
|
1500 |
-
)
|
1501 |
-
|
1502 |
-
try:
|
1503 |
-
await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML)
|
1504 |
-
except:
|
1505 |
-
jam = time.time()
|
1506 |
-
new_jam = jam + 1800
|
1507 |
-
cek = get_chat(chat.id, chat_data)
|
1508 |
-
if cek.get("status"):
|
1509 |
-
if jam <= int(cek.get("value")):
|
1510 |
-
waktu = time.strftime(
|
1511 |
-
"%H:%M:%S %d/%m/%Y",
|
1512 |
-
time.localtime(cek.get("value")),
|
1513 |
-
)
|
1514 |
-
await update.effective_message.reply_text(
|
1515 |
-
"You can back up data once every 30 minutes!\nYou can back up data again at `{}`".format(
|
1516 |
-
waktu,
|
1517 |
-
),
|
1518 |
-
parse_mode=ParseMode.MARKDOWN,
|
1519 |
-
)
|
1520 |
-
return
|
1521 |
-
else:
|
1522 |
-
if user.id not in DRAGONS:
|
1523 |
-
put_chat(chat.id, new_jam, chat_data)
|
1524 |
-
else:
|
1525 |
-
if user.id not in DRAGONS:
|
1526 |
-
put_chat(chat.id, new_jam, chat_data)
|
1527 |
-
cleanr = re.compile("<.*?>")
|
1528 |
-
cleantext = re.sub(cleanr, "", text)
|
1529 |
-
with BytesIO(str.encode(cleantext)) as output:
|
1530 |
-
output.name = "fbanlist.txt"
|
1531 |
-
await update.effective_message.reply_document(
|
1532 |
-
document=output,
|
1533 |
-
filename="fbanlist.txt",
|
1534 |
-
caption="The following is a list of users who are currently fbanned in the Federation {}.".format(
|
1535 |
-
info["fname"],
|
1536 |
-
),
|
1537 |
-
)
|
1538 |
-
|
1539 |
-
|
1540 |
-
async def fed_notif(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
1541 |
-
bot, args = context.bot, context.args
|
1542 |
-
chat = update.effective_chat
|
1543 |
-
user = update.effective_user
|
1544 |
-
msg = update.effective_message
|
1545 |
-
fed_id = sql.get_fed_id(chat.id)
|
1546 |
-
|
1547 |
-
if not fed_id:
|
1548 |
-
await update.effective_message.reply_text(
|
1549 |
-
"This group is not a part of any federation!",
|
1550 |
-
)
|
1551 |
-
return
|
1552 |
-
|
1553 |
-
if args:
|
1554 |
-
if args[0] in ("yes", "on"):
|
1555 |
-
sql.set_feds_setting(user.id, True)
|
1556 |
-
await msg.reply_text(
|
1557 |
-
"Reporting Federation back up! Every user who is fban / unfban you will be notified via PM.",
|
1558 |
-
)
|
1559 |
-
elif args[0] in ("no", "off"):
|
1560 |
-
sql.set_feds_setting(user.id, False)
|
1561 |
-
await msg.reply_text(
|
1562 |
-
"Reporting Federation has stopped! Every user who is fban / unfban you will not be notified via PM.",
|
1563 |
-
)
|
1564 |
-
else:
|
1565 |
-
await msg.reply_text("Please enter `on`/`off`", parse_mode="markdown")
|
1566 |
-
else:
|
1567 |
-
getreport = sql.user_feds_report(user.id)
|
1568 |
-
await msg.reply_text(
|
1569 |
-
"Your current Federation report preferences: `{}`".format(getreport),
|
1570 |
-
parse_mode="markdown",
|
1571 |
-
)
|
1572 |
-
|
1573 |
-
|
1574 |
-
async def fed_chats(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
1575 |
-
bot, args = context.bot, context.args
|
1576 |
-
chat = update.effective_chat
|
1577 |
-
user = update.effective_user
|
1578 |
-
|
1579 |
-
if chat.type == "private":
|
1580 |
-
await send_message(
|
1581 |
-
update.effective_message,
|
1582 |
-
"This command is specific to the group, not to our pm!",
|
1583 |
-
)
|
1584 |
-
return
|
1585 |
-
|
1586 |
-
fed_id = sql.get_fed_id(chat.id)
|
1587 |
-
info = sql.get_fed_info(fed_id)
|
1588 |
-
|
1589 |
-
if not fed_id:
|
1590 |
-
await update.effective_message.reply_text(
|
1591 |
-
"This group is not a part of any federation!",
|
1592 |
-
)
|
1593 |
-
return
|
1594 |
-
|
1595 |
-
if is_user_fed_admin(fed_id, user.id) is False:
|
1596 |
-
await update.effective_message.reply_text("Only federation admins can do this!")
|
1597 |
-
return
|
1598 |
-
|
1599 |
-
getlist = sql.all_fed_chats(fed_id)
|
1600 |
-
if len(getlist) == 0:
|
1601 |
-
await update.effective_message.reply_text(
|
1602 |
-
"No users are fbanned from the federation {}".format(info["fname"]),
|
1603 |
-
parse_mode=ParseMode.HTML,
|
1604 |
-
)
|
1605 |
-
return
|
1606 |
-
|
1607 |
-
text = "<b>New chat joined the federation {}:</b>\n".format(info["fname"])
|
1608 |
-
for chats in getlist:
|
1609 |
-
try:
|
1610 |
-
chat_obj = await dispatcher.bot.getChat(chats)
|
1611 |
-
chat_name = chat_obj.title
|
1612 |
-
except Forbidden:
|
1613 |
-
sql.chat_leave_fed(chats)
|
1614 |
-
LOGGER.info(
|
1615 |
-
"Chat {} has leave fed {} because I was kicked".format(
|
1616 |
-
chats,
|
1617 |
-
info["fname"],
|
1618 |
-
),
|
1619 |
-
)
|
1620 |
-
continue
|
1621 |
-
text += " • {} (<code>{}</code>)\n".format(chat_name, chats)
|
1622 |
-
|
1623 |
-
try:
|
1624 |
-
await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML)
|
1625 |
-
except:
|
1626 |
-
cleanr = re.compile("<.*?>")
|
1627 |
-
cleantext = re.sub(cleanr, "", text)
|
1628 |
-
with BytesIO(str.encode(cleantext)) as output:
|
1629 |
-
output.name = "fedchats.txt"
|
1630 |
-
await update.effective_message.reply_document(
|
1631 |
-
document=output,
|
1632 |
-
filename="fedchats.txt",
|
1633 |
-
caption="Here is a list of all the chats that joined the federation {}.".format(
|
1634 |
-
info["fname"],
|
1635 |
-
),
|
1636 |
-
)
|
1637 |
-
|
1638 |
-
|
1639 |
-
async def fed_import_bans(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
1640 |
-
bot, chat_data = context.bot, context.chat_data
|
1641 |
-
chat = update.effective_chat
|
1642 |
-
user = update.effective_user
|
1643 |
-
msg = update.effective_message
|
1644 |
-
|
1645 |
-
if chat.type == "private":
|
1646 |
-
await send_message(
|
1647 |
-
update.effective_message,
|
1648 |
-
"This command is specific to the group, not to our pm!",
|
1649 |
-
)
|
1650 |
-
return
|
1651 |
-
|
1652 |
-
fed_id = sql.get_fed_id(chat.id)
|
1653 |
-
info = sql.get_fed_info(fed_id)
|
1654 |
-
getfed = sql.get_fed_info(fed_id)
|
1655 |
-
|
1656 |
-
if not fed_id:
|
1657 |
-
await update.effective_message.reply_text(
|
1658 |
-
"This group is not a part of any federation!",
|
1659 |
-
)
|
1660 |
-
return
|
1661 |
-
|
1662 |
-
if is_user_fed_owner(fed_id, user.id) is False:
|
1663 |
-
await update.effective_message.reply_text("Only Federation owners can do this!")
|
1664 |
-
return
|
1665 |
-
|
1666 |
-
if msg.reply_to_message and msg.reply_to_message.document:
|
1667 |
-
jam = time.time()
|
1668 |
-
new_jam = jam + 1800
|
1669 |
-
cek = get_chat(chat.id, chat_data)
|
1670 |
-
if cek.get("status"):
|
1671 |
-
if jam <= int(cek.get("value")):
|
1672 |
-
waktu = time.strftime(
|
1673 |
-
"%H:%M:%S %d/%m/%Y",
|
1674 |
-
time.localtime(cek.get("value")),
|
1675 |
-
)
|
1676 |
-
await update.effective_message.reply_text(
|
1677 |
-
"You can get your data once every 30 minutes!\nYou can get data again at `{}`".format(
|
1678 |
-
waktu,
|
1679 |
-
),
|
1680 |
-
parse_mode=ParseMode.MARKDOWN,
|
1681 |
-
)
|
1682 |
-
return
|
1683 |
-
else:
|
1684 |
-
if user.id not in DRAGONS:
|
1685 |
-
put_chat(chat.id, new_jam, chat_data)
|
1686 |
-
else:
|
1687 |
-
if user.id not in DRAGONS:
|
1688 |
-
put_chat(chat.id, new_jam, chat_data)
|
1689 |
-
# if int(int(msg.reply_to_message.document.file_size)/1024) >= 200:
|
1690 |
-
# msg.reply_text("This file is too big!")
|
1691 |
-
# return
|
1692 |
-
success = 0
|
1693 |
-
failed = 0
|
1694 |
-
try:
|
1695 |
-
file_info = await bot.get_file(msg.reply_to_message.document.file_id)
|
1696 |
-
except BadRequest:
|
1697 |
-
await msg.reply_text(
|
1698 |
-
"Try downloading and re-uploading the file, this one seems broken!",
|
1699 |
-
)
|
1700 |
-
return
|
1701 |
-
fileformat = msg.reply_to_message.document.file_name.split(".")[-1]
|
1702 |
-
if fileformat == "json":
|
1703 |
-
multi_fed_id = []
|
1704 |
-
multi_import_userid = []
|
1705 |
-
multi_import_firstname = []
|
1706 |
-
multi_import_lastname = []
|
1707 |
-
multi_import_username = []
|
1708 |
-
multi_import_reason = []
|
1709 |
-
with BytesIO() as file:
|
1710 |
-
file_info.download_to_object(out=file)
|
1711 |
-
file.seek(0)
|
1712 |
-
reading = file.read().decode("UTF-8")
|
1713 |
-
splitting = reading.split("\n")
|
1714 |
-
for x in splitting:
|
1715 |
-
if x == "":
|
1716 |
-
continue
|
1717 |
-
try:
|
1718 |
-
data = json.loads(x)
|
1719 |
-
except json.decoder.JSONDecodeError as err:
|
1720 |
-
failed += 1
|
1721 |
-
continue
|
1722 |
-
try:
|
1723 |
-
import_userid = int(data["user_id"]) # Make sure it int
|
1724 |
-
import_firstname = str(data["first_name"])
|
1725 |
-
import_lastname = str(data["last_name"])
|
1726 |
-
import_username = str(data["user_name"])
|
1727 |
-
import_reason = str(data["reason"])
|
1728 |
-
except ValueError:
|
1729 |
-
failed += 1
|
1730 |
-
continue
|
1731 |
-
# Checking user
|
1732 |
-
if int(import_userid) == bot.id:
|
1733 |
-
failed += 1
|
1734 |
-
continue
|
1735 |
-
if is_user_fed_owner(fed_id, import_userid) is True:
|
1736 |
-
failed += 1
|
1737 |
-
continue
|
1738 |
-
if is_user_fed_admin(fed_id, import_userid) is True:
|
1739 |
-
failed += 1
|
1740 |
-
continue
|
1741 |
-
if str(import_userid) == str(OWNER_ID):
|
1742 |
-
failed += 1
|
1743 |
-
continue
|
1744 |
-
if int(import_userid) in DRAGONS:
|
1745 |
-
failed += 1
|
1746 |
-
continue
|
1747 |
-
multi_fed_id.append(fed_id)
|
1748 |
-
multi_import_userid.append(str(import_userid))
|
1749 |
-
multi_import_firstname.append(import_firstname)
|
1750 |
-
multi_import_lastname.append(import_lastname)
|
1751 |
-
multi_import_username.append(import_username)
|
1752 |
-
multi_import_reason.append(import_reason)
|
1753 |
-
success += 1
|
1754 |
-
sql.multi_fban_user(
|
1755 |
-
multi_fed_id,
|
1756 |
-
multi_import_userid,
|
1757 |
-
multi_import_firstname,
|
1758 |
-
multi_import_lastname,
|
1759 |
-
multi_import_username,
|
1760 |
-
multi_import_reason,
|
1761 |
-
)
|
1762 |
-
text = "Blocks were successfully imported. {} people are blocked.".format(
|
1763 |
-
success,
|
1764 |
-
)
|
1765 |
-
if failed >= 1:
|
1766 |
-
text += " {} Failed to import.".format(failed)
|
1767 |
-
get_fedlog = await sql.get_fed_log(fed_id)
|
1768 |
-
if get_fedlog:
|
1769 |
-
if ast.literal_eval(get_fedlog):
|
1770 |
-
teks = "Fed *{}* has successfully imported data. {} banned.".format(
|
1771 |
-
getfed["fname"],
|
1772 |
-
success,
|
1773 |
-
)
|
1774 |
-
if failed >= 1:
|
1775 |
-
teks += " {} Failed to import.".format(failed)
|
1776 |
-
await bot.send_message(
|
1777 |
-
get_fedlog,
|
1778 |
-
teks,
|
1779 |
-
parse_mode="markdown",
|
1780 |
-
message_thread_id=update.effective_message.message_thread_id
|
1781 |
-
if chat.is_forum
|
1782 |
-
else None,
|
1783 |
-
)
|
1784 |
-
elif fileformat == "csv":
|
1785 |
-
multi_fed_id = []
|
1786 |
-
multi_import_userid = []
|
1787 |
-
multi_import_firstname = []
|
1788 |
-
multi_import_lastname = []
|
1789 |
-
multi_import_username = []
|
1790 |
-
multi_import_reason = []
|
1791 |
-
file_info.download_to_drive(
|
1792 |
-
"fban_{}.csv".format(msg.reply_to_message.document.file_id),
|
1793 |
-
)
|
1794 |
-
with open(
|
1795 |
-
"fban_{}.csv".format(msg.reply_to_message.document.file_id),
|
1796 |
-
"r",
|
1797 |
-
encoding="utf8",
|
1798 |
-
) as csvFile:
|
1799 |
-
reader = csv.reader(csvFile)
|
1800 |
-
for data in reader:
|
1801 |
-
try:
|
1802 |
-
import_userid = int(data[0]) # Make sure it int
|
1803 |
-
import_firstname = str(data[1])
|
1804 |
-
import_lastname = str(data[2])
|
1805 |
-
import_username = str(data[3])
|
1806 |
-
import_reason = str(data[4])
|
1807 |
-
except ValueError:
|
1808 |
-
failed += 1
|
1809 |
-
continue
|
1810 |
-
# Checking user
|
1811 |
-
if int(import_userid) == bot.id:
|
1812 |
-
failed += 1
|
1813 |
-
continue
|
1814 |
-
if is_user_fed_owner(fed_id, import_userid) is True:
|
1815 |
-
failed += 1
|
1816 |
-
continue
|
1817 |
-
if is_user_fed_admin(fed_id, import_userid) is True:
|
1818 |
-
failed += 1
|
1819 |
-
continue
|
1820 |
-
if str(import_userid) == str(OWNER_ID):
|
1821 |
-
failed += 1
|
1822 |
-
continue
|
1823 |
-
if int(import_userid) in DRAGONS:
|
1824 |
-
failed += 1
|
1825 |
-
continue
|
1826 |
-
|
1827 |
-
multi_fed_id.append(fed_id)
|
1828 |
-
multi_import_userid.append(str(import_userid))
|
1829 |
-
multi_import_firstname.append(import_firstname)
|
1830 |
-
multi_import_lastname.append(import_lastname)
|
1831 |
-
multi_import_username.append(import_username)
|
1832 |
-
multi_import_reason.append(import_reason)
|
1833 |
-
success += 1
|
1834 |
-
# t = ThreadWithReturnValue(target=sql.fban_user, args=(fed_id, str(import_userid), import_firstname, import_lastname, import_username, import_reason,))
|
1835 |
-
# t.start()
|
1836 |
-
sql.multi_fban_user(
|
1837 |
-
multi_fed_id,
|
1838 |
-
multi_import_userid,
|
1839 |
-
multi_import_firstname,
|
1840 |
-
multi_import_lastname,
|
1841 |
-
multi_import_username,
|
1842 |
-
multi_import_reason,
|
1843 |
-
)
|
1844 |
-
csvFile.close()
|
1845 |
-
os.remove("fban_{}.csv".format(msg.reply_to_message.document.file_id))
|
1846 |
-
text = "Files were imported successfully. {} people banned.".format(success)
|
1847 |
-
if failed >= 1:
|
1848 |
-
text += " {} Failed to import.".format(failed)
|
1849 |
-
get_fedlog = await sql.get_fed_log(fed_id)
|
1850 |
-
if get_fedlog:
|
1851 |
-
if ast.literal_eval(get_fedlog):
|
1852 |
-
teks = "Fed *{}* has successfully imported data. {} banned.".format(
|
1853 |
-
getfed["fname"],
|
1854 |
-
success,
|
1855 |
-
)
|
1856 |
-
if failed >= 1:
|
1857 |
-
teks += " {} Failed to import.".format(failed)
|
1858 |
-
await bot.send_message(
|
1859 |
-
get_fedlog,
|
1860 |
-
teks,
|
1861 |
-
parse_mode="markdown",
|
1862 |
-
message_thread_id=update.effective_message.message_thread_id
|
1863 |
-
if chat.is_forum
|
1864 |
-
else None,
|
1865 |
-
)
|
1866 |
-
else:
|
1867 |
-
await send_message(update.effective_message, "This file is not supported.")
|
1868 |
-
return
|
1869 |
-
await send_message(update.effective_message, text)
|
1870 |
-
|
1871 |
-
|
1872 |
-
async def del_fed_button(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
1873 |
-
query = update.callback_query
|
1874 |
-
userid = query.message.chat.id
|
1875 |
-
fed_id = query.data.split("_")[1]
|
1876 |
-
|
1877 |
-
if fed_id == "cancel":
|
1878 |
-
await query.message.edit_text("Federation deletion cancelled")
|
1879 |
-
return
|
1880 |
-
|
1881 |
-
getfed = sql.get_fed_info(fed_id)
|
1882 |
-
if getfed:
|
1883 |
-
delete = sql.del_fed(fed_id)
|
1884 |
-
if delete:
|
1885 |
-
await query.message.edit_text(
|
1886 |
-
"You have removed your Federation! Now all the Groups that are connected with `{}` do not have a Federation.".format(
|
1887 |
-
getfed["fname"],
|
1888 |
-
),
|
1889 |
-
parse_mode="markdown",
|
1890 |
-
)
|
1891 |
-
|
1892 |
-
|
1893 |
-
async def fed_stat_user(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
1894 |
-
bot, args = context.bot, context.args
|
1895 |
-
chat = update.effective_chat
|
1896 |
-
user = update.effective_user
|
1897 |
-
msg = update.effective_message
|
1898 |
-
|
1899 |
-
if args:
|
1900 |
-
if args[0].isdigit():
|
1901 |
-
user_id = args[0]
|
1902 |
-
else:
|
1903 |
-
user_id = await extract_user(msg, context, args)
|
1904 |
-
else:
|
1905 |
-
user_id = await extract_user(msg, context, args)
|
1906 |
-
|
1907 |
-
if user_id:
|
1908 |
-
if len(args) == 2 and args[0].isdigit():
|
1909 |
-
fed_id = args[1]
|
1910 |
-
user_name, reason, fbantime = sql.get_user_fban(fed_id, str(user_id))
|
1911 |
-
if fbantime:
|
1912 |
-
fbantime = time.strftime("%d/%m/%Y", time.localtime(fbantime))
|
1913 |
-
else:
|
1914 |
-
fbantime = "Unavaiable"
|
1915 |
-
if user_name is False:
|
1916 |
-
await send_message(
|
1917 |
-
update.effective_message,
|
1918 |
-
"Fed {} not found!".format(fed_id),
|
1919 |
-
parse_mode="markdown",
|
1920 |
-
)
|
1921 |
-
return
|
1922 |
-
if user_name == "" or user_name is None:
|
1923 |
-
user_name = "He/she"
|
1924 |
-
if not reason:
|
1925 |
-
await send_message(
|
1926 |
-
update.effective_message,
|
1927 |
-
"{} is not banned in this federation!".format(user_name),
|
1928 |
-
)
|
1929 |
-
else:
|
1930 |
-
teks = "{} banned in this federation because:\n`{}`\n*Banned at:* `{}`".format(
|
1931 |
-
user_name,
|
1932 |
-
reason,
|
1933 |
-
fbantime,
|
1934 |
-
)
|
1935 |
-
await send_message(
|
1936 |
-
update.effective_message, teks, parse_mode="markdown"
|
1937 |
-
)
|
1938 |
-
return
|
1939 |
-
user_name, fbanlist = sql.get_user_fbanlist(str(user_id))
|
1940 |
-
if user_name == "":
|
1941 |
-
try:
|
1942 |
-
user_first = await bot.get_chat(user_id)
|
1943 |
-
if isinstance(user_first, ChatMember):
|
1944 |
-
user_name = user_id.first_name
|
1945 |
-
except BadRequest:
|
1946 |
-
user_name = "He/she"
|
1947 |
-
if user_name == "" or user_name is None:
|
1948 |
-
user_name = "He/she"
|
1949 |
-
if len(fbanlist) == 0:
|
1950 |
-
await send_message(
|
1951 |
-
update.effective_message,
|
1952 |
-
"{} is not banned in any federation!".format(user_name),
|
1953 |
-
)
|
1954 |
-
return
|
1955 |
-
else:
|
1956 |
-
teks = "{} has been banned in this federation:\n".format(user_name)
|
1957 |
-
for x in fbanlist:
|
1958 |
-
teks += "- `{}`: {}\n".format(x[0], x[1][:20])
|
1959 |
-
teks += "\nIf you want to find out more about the reasons for Fedban specifically, use /fbanstat <FedID>"
|
1960 |
-
await send_message(update.effective_message, teks, parse_mode="markdown")
|
1961 |
-
|
1962 |
-
elif not msg.reply_to_message and not args:
|
1963 |
-
user_id = msg.from_user.id
|
1964 |
-
user_name, fbanlist = sql.get_user_fbanlist(user_id)
|
1965 |
-
if user_name == "":
|
1966 |
-
user_name = msg.from_user.first_name
|
1967 |
-
if len(fbanlist) == 0:
|
1968 |
-
await send_message(
|
1969 |
-
update.effective_message,
|
1970 |
-
"{} is not banned in any federation!".format(user_name),
|
1971 |
-
)
|
1972 |
-
else:
|
1973 |
-
teks = "{} has been banned in this federation:\n".format(user_name)
|
1974 |
-
for x in fbanlist:
|
1975 |
-
teks += "- `{}`: {}\n".format(x[0], x[1][:20])
|
1976 |
-
teks += "\nIf you want to find out more about the reasons for Fedban specifically, use /fbanstat <FedID>"
|
1977 |
-
await send_message(update.effective_message, teks, parse_mode="markdown")
|
1978 |
-
|
1979 |
-
else:
|
1980 |
-
fed_id = args[0]
|
1981 |
-
fedinfo = sql.get_fed_info(fed_id)
|
1982 |
-
if not fedinfo:
|
1983 |
-
await send_message(
|
1984 |
-
update.effective_message, "Fed {} not found!".format(fed_id)
|
1985 |
-
)
|
1986 |
-
return
|
1987 |
-
name, reason, fbantime = sql.get_user_fban(fed_id, msg.from_user.id)
|
1988 |
-
if fbantime:
|
1989 |
-
fbantime = time.strftime("%d/%m/%Y", time.localtime(fbantime))
|
1990 |
-
else:
|
1991 |
-
fbantime = "Unavaiable"
|
1992 |
-
if not name:
|
1993 |
-
name = msg.from_user.first_name
|
1994 |
-
if not reason:
|
1995 |
-
await send_message(
|
1996 |
-
update.effective_message,
|
1997 |
-
"{} is not banned in this federation".format(name),
|
1998 |
-
)
|
1999 |
-
return
|
2000 |
-
await send_message(
|
2001 |
-
update.effective_message,
|
2002 |
-
"{} banned in this federation because:\n`{}`\n*Banned at:* `{}`".format(
|
2003 |
-
name,
|
2004 |
-
reason,
|
2005 |
-
fbantime,
|
2006 |
-
),
|
2007 |
-
parse_mode="markdown",
|
2008 |
-
)
|
2009 |
-
|
2010 |
-
|
2011 |
-
async def set_fed_log(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2012 |
-
args = context.args
|
2013 |
-
chat = update.effective_chat
|
2014 |
-
user = update.effective_user
|
2015 |
-
msg = update.effective_message
|
2016 |
-
|
2017 |
-
if chat.type == "private":
|
2018 |
-
await send_message(
|
2019 |
-
update.effective_message,
|
2020 |
-
"This command is specific to the group, not to our pm!",
|
2021 |
-
)
|
2022 |
-
return
|
2023 |
-
|
2024 |
-
if args:
|
2025 |
-
fedinfo = sql.get_fed_info(args[0])
|
2026 |
-
if not fedinfo:
|
2027 |
-
await send_message(
|
2028 |
-
update.effective_message, "This Federation does not exist!"
|
2029 |
-
)
|
2030 |
-
return
|
2031 |
-
isowner = is_user_fed_owner(args[0], user.id)
|
2032 |
-
if not isowner:
|
2033 |
-
await send_message(
|
2034 |
-
update.effective_message,
|
2035 |
-
"Only federation creator can set federation logs.",
|
2036 |
-
)
|
2037 |
-
return
|
2038 |
-
setlog = sql.set_fed_log(args[0], chat.id)
|
2039 |
-
if setlog:
|
2040 |
-
await send_message(
|
2041 |
-
update.effective_message,
|
2042 |
-
"Federation log `{}` has been set to {}".format(
|
2043 |
-
fedinfo["fname"],
|
2044 |
-
chat.title,
|
2045 |
-
),
|
2046 |
-
parse_mode="markdown",
|
2047 |
-
)
|
2048 |
-
else:
|
2049 |
-
await send_message(
|
2050 |
-
update.effective_message,
|
2051 |
-
"You have not provided your federated ID!",
|
2052 |
-
)
|
2053 |
-
|
2054 |
-
|
2055 |
-
async def unset_fed_log(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2056 |
-
args = context.args
|
2057 |
-
chat = update.effective_chat
|
2058 |
-
user = update.effective_user
|
2059 |
-
msg = update.effective_message
|
2060 |
-
|
2061 |
-
if chat.type == "private":
|
2062 |
-
await send_message(
|
2063 |
-
update.effective_message,
|
2064 |
-
"This command is specific to the group, not to our pm!",
|
2065 |
-
)
|
2066 |
-
return
|
2067 |
-
|
2068 |
-
if args:
|
2069 |
-
fedinfo = sql.get_fed_info(args[0])
|
2070 |
-
if not fedinfo:
|
2071 |
-
await send_message(
|
2072 |
-
update.effective_message, "This Federation does not exist!"
|
2073 |
-
)
|
2074 |
-
return
|
2075 |
-
isowner = is_user_fed_owner(args[0], user.id)
|
2076 |
-
if not isowner:
|
2077 |
-
await send_message(
|
2078 |
-
update.effective_message,
|
2079 |
-
"Only federation creator can set federation logs.",
|
2080 |
-
)
|
2081 |
-
return
|
2082 |
-
setlog = sql.set_fed_log(args[0], None)
|
2083 |
-
if setlog:
|
2084 |
-
await send_message(
|
2085 |
-
update.effective_message,
|
2086 |
-
"Federation log `{}` has been revoked on {}".format(
|
2087 |
-
fedinfo["fname"],
|
2088 |
-
chat.title,
|
2089 |
-
),
|
2090 |
-
parse_mode="markdown",
|
2091 |
-
)
|
2092 |
-
else:
|
2093 |
-
await send_message(
|
2094 |
-
update.effective_message,
|
2095 |
-
"You have not provided your federated ID!",
|
2096 |
-
)
|
2097 |
-
|
2098 |
-
|
2099 |
-
async def subs_feds(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2100 |
-
bot, args = context.bot, context.args
|
2101 |
-
chat = update.effective_chat
|
2102 |
-
user = update.effective_user
|
2103 |
-
msg = update.effective_message
|
2104 |
-
|
2105 |
-
if chat.type == "private":
|
2106 |
-
await send_message(
|
2107 |
-
update.effective_message,
|
2108 |
-
"This command is specific to the group, not to our pm!",
|
2109 |
-
)
|
2110 |
-
return
|
2111 |
-
|
2112 |
-
fed_id = sql.get_fed_id(chat.id)
|
2113 |
-
fedinfo = sql.get_fed_info(fed_id)
|
2114 |
-
|
2115 |
-
if not fed_id:
|
2116 |
-
await send_message(
|
2117 |
-
update.effective_message, "This group is not in any federation!"
|
2118 |
-
)
|
2119 |
-
return
|
2120 |
-
|
2121 |
-
if is_user_fed_owner(fed_id, user.id) is False:
|
2122 |
-
await send_message(update.effective_message, "Only fed owner can do this!")
|
2123 |
-
return
|
2124 |
-
|
2125 |
-
if args:
|
2126 |
-
getfed = sql.search_fed_by_id(args[0])
|
2127 |
-
if getfed is False:
|
2128 |
-
await send_message(
|
2129 |
-
update.effective_message,
|
2130 |
-
"Please enter a valid federation id.",
|
2131 |
-
)
|
2132 |
-
return
|
2133 |
-
subfed = sql.subs_fed(args[0], fed_id)
|
2134 |
-
if subfed:
|
2135 |
-
await send_message(
|
2136 |
-
update.effective_message,
|
2137 |
-
"Federation `{}` has subscribe the federation `{}`. Every time there is a Fedban from that federation, this federation will also banned that user.".format(
|
2138 |
-
fedinfo["fname"],
|
2139 |
-
getfed["fname"],
|
2140 |
-
),
|
2141 |
-
parse_mode="markdown",
|
2142 |
-
)
|
2143 |
-
get_fedlog = await sql.get_fed_log(args[0])
|
2144 |
-
if get_fedlog:
|
2145 |
-
if int(get_fedlog) != int(chat.id):
|
2146 |
-
await bot.send_message(
|
2147 |
-
get_fedlog,
|
2148 |
-
"Federation `{}` has subscribe the federation `{}`".format(
|
2149 |
-
fedinfo["fname"],
|
2150 |
-
getfed["fname"],
|
2151 |
-
),
|
2152 |
-
parse_mode="markdown",
|
2153 |
-
message_thread_id=update.effective_message.message_thread_id
|
2154 |
-
if chat.is_forum
|
2155 |
-
else None,
|
2156 |
-
)
|
2157 |
-
else:
|
2158 |
-
await send_message(
|
2159 |
-
update.effective_message,
|
2160 |
-
"Federation `{}` already subscribe the federation `{}`.".format(
|
2161 |
-
fedinfo["fname"],
|
2162 |
-
getfed["fname"],
|
2163 |
-
),
|
2164 |
-
parse_mode="markdown",
|
2165 |
-
)
|
2166 |
-
else:
|
2167 |
-
await send_message(
|
2168 |
-
update.effective_message,
|
2169 |
-
"You have not provided your federated ID!",
|
2170 |
-
)
|
2171 |
-
|
2172 |
-
|
2173 |
-
async def unsubs_feds(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2174 |
-
bot, args = context.bot, context.args
|
2175 |
-
chat = update.effective_chat
|
2176 |
-
user = update.effective_user
|
2177 |
-
msg = update.effective_message
|
2178 |
-
|
2179 |
-
if chat.type == "private":
|
2180 |
-
await send_message(
|
2181 |
-
update.effective_message,
|
2182 |
-
"This command is specific to the group, not to our pm!",
|
2183 |
-
)
|
2184 |
-
return
|
2185 |
-
|
2186 |
-
fed_id = sql.get_fed_id(chat.id)
|
2187 |
-
fedinfo = sql.get_fed_info(fed_id)
|
2188 |
-
|
2189 |
-
if not fed_id:
|
2190 |
-
await send_message(
|
2191 |
-
update.effective_message, "This group is not in any federation!"
|
2192 |
-
)
|
2193 |
-
return
|
2194 |
-
|
2195 |
-
if is_user_fed_owner(fed_id, user.id) is False:
|
2196 |
-
await send_message(update.effective_message, "Only fed owner can do this!")
|
2197 |
-
return
|
2198 |
-
|
2199 |
-
if args:
|
2200 |
-
getfed = sql.search_fed_by_id(args[0])
|
2201 |
-
if getfed is False:
|
2202 |
-
await send_message(
|
2203 |
-
update.effective_message,
|
2204 |
-
"Please enter a valid federation id.",
|
2205 |
-
)
|
2206 |
-
return
|
2207 |
-
subfed = sql.unsubs_fed(args[0], fed_id)
|
2208 |
-
if subfed:
|
2209 |
-
await send_message(
|
2210 |
-
update.effective_message,
|
2211 |
-
"Federation `{}` now unsubscribe fed `{}`.".format(
|
2212 |
-
fedinfo["fname"],
|
2213 |
-
getfed["fname"],
|
2214 |
-
),
|
2215 |
-
parse_mode="markdown",
|
2216 |
-
)
|
2217 |
-
get_fedlog = await sql.get_fed_log(args[0])
|
2218 |
-
if get_fedlog:
|
2219 |
-
if int(get_fedlog) != int(chat.id):
|
2220 |
-
await bot.send_message(
|
2221 |
-
get_fedlog,
|
2222 |
-
"Federation `{}` has unsubscribe fed `{}`.".format(
|
2223 |
-
fedinfo["fname"],
|
2224 |
-
getfed["fname"],
|
2225 |
-
),
|
2226 |
-
parse_mode="markdown",
|
2227 |
-
message_thread_id=update.effective_message.message_thread_id
|
2228 |
-
if chat.is_forum
|
2229 |
-
else None,
|
2230 |
-
)
|
2231 |
-
else:
|
2232 |
-
await send_message(
|
2233 |
-
update.effective_message,
|
2234 |
-
"Federation `{}` is not subscribing `{}`.".format(
|
2235 |
-
fedinfo["fname"],
|
2236 |
-
getfed["fname"],
|
2237 |
-
),
|
2238 |
-
parse_mode="markdown",
|
2239 |
-
)
|
2240 |
-
else:
|
2241 |
-
await send_message(
|
2242 |
-
update.effective_message,
|
2243 |
-
"You have not provided your federated ID!",
|
2244 |
-
)
|
2245 |
-
|
2246 |
-
|
2247 |
-
async def get_myfedsubs(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2248 |
-
args = context.args
|
2249 |
-
chat = update.effective_chat
|
2250 |
-
user = update.effective_user
|
2251 |
-
msg = update.effective_message
|
2252 |
-
|
2253 |
-
if chat.type == "private":
|
2254 |
-
await send_message(
|
2255 |
-
update.effective_message,
|
2256 |
-
"This command is specific to the group, not to our pm!",
|
2257 |
-
)
|
2258 |
-
return
|
2259 |
-
|
2260 |
-
fed_id = sql.get_fed_id(chat.id)
|
2261 |
-
fedinfo = sql.get_fed_info(fed_id)
|
2262 |
-
|
2263 |
-
if not fed_id:
|
2264 |
-
await send_message(
|
2265 |
-
update.effective_message, "This group is not in any federation!"
|
2266 |
-
)
|
2267 |
-
return
|
2268 |
-
|
2269 |
-
if is_user_fed_owner(fed_id, user.id) is False:
|
2270 |
-
await send_message(update.effective_message, "Only fed owner can do this!")
|
2271 |
-
return
|
2272 |
-
|
2273 |
-
try:
|
2274 |
-
getmy = sql.get_mysubs(fed_id)
|
2275 |
-
except:
|
2276 |
-
getmy = []
|
2277 |
-
|
2278 |
-
if len(getmy) == 0:
|
2279 |
-
await send_message(
|
2280 |
-
update.effective_message,
|
2281 |
-
"Federation `{}` is not subscribing any federation.".format(
|
2282 |
-
fedinfo["fname"],
|
2283 |
-
),
|
2284 |
-
parse_mode="markdown",
|
2285 |
-
)
|
2286 |
-
return
|
2287 |
-
else:
|
2288 |
-
listfed = "Federation `{}` is subscribing federation:\n".format(
|
2289 |
-
fedinfo["fname"],
|
2290 |
-
)
|
2291 |
-
for x in getmy:
|
2292 |
-
listfed += "- `{}`\n".format(x)
|
2293 |
-
listfed += (
|
2294 |
-
"\nTo get fed info `/fedinfo <fedid>`. To unsubscribe `/unsubfed <fedid>`."
|
2295 |
-
)
|
2296 |
-
await send_message(update.effective_message, listfed, parse_mode="markdown")
|
2297 |
-
|
2298 |
-
|
2299 |
-
async def get_myfeds_list(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2300 |
-
chat = update.effective_chat
|
2301 |
-
user = update.effective_user
|
2302 |
-
msg = update.effective_message
|
2303 |
-
|
2304 |
-
fedowner = sql.get_user_owner_fed_full(user.id)
|
2305 |
-
if fedowner:
|
2306 |
-
text = "*You are owner of feds:\n*"
|
2307 |
-
for f in fedowner:
|
2308 |
-
text += "- `{}`: *{}*\n".format(f["fed_id"], f["fed"]["fname"])
|
2309 |
-
else:
|
2310 |
-
text = "*You are not have any feds!*"
|
2311 |
-
await send_message(update.effective_message, text, parse_mode="markdown")
|
2312 |
-
|
2313 |
-
|
2314 |
-
def is_user_fed_admin(fed_id, user_id):
|
2315 |
-
fed_admins = sql.all_fed_users(fed_id)
|
2316 |
-
if fed_admins is False:
|
2317 |
-
return False
|
2318 |
-
if int(user_id) in fed_admins or int(user_id) == OWNER_ID:
|
2319 |
-
return True
|
2320 |
-
else:
|
2321 |
-
return False
|
2322 |
-
|
2323 |
-
|
2324 |
-
def is_user_fed_owner(fed_id, user_id):
|
2325 |
-
getsql = sql.get_fed_info(fed_id)
|
2326 |
-
if getsql is False:
|
2327 |
-
return False
|
2328 |
-
getfedowner = ast.literal_eval(getsql["fusers"])
|
2329 |
-
if getfedowner is None or getfedowner is False:
|
2330 |
-
return False
|
2331 |
-
getfedowner = getfedowner["owner"]
|
2332 |
-
if str(user_id) == getfedowner or int(user_id) == OWNER_ID:
|
2333 |
-
return True
|
2334 |
-
else:
|
2335 |
-
return False
|
2336 |
-
|
2337 |
-
|
2338 |
-
# There's no handler for this yet, but updating for v12 in case its used
|
2339 |
-
|
2340 |
-
|
2341 |
-
async def welcome_fed(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2342 |
-
bot, args = context.bot, context.args
|
2343 |
-
chat = update.effective_chat
|
2344 |
-
user = update.effective_user
|
2345 |
-
fed_id = sql.get_fed_id(chat.id)
|
2346 |
-
fban, fbanreason, fbantime = sql.get_fban_user(fed_id, user.id)
|
2347 |
-
if fban:
|
2348 |
-
await update.effective_message.reply_text(
|
2349 |
-
"This user is banned in current federation! I will remove him.",
|
2350 |
-
)
|
2351 |
-
await bot.ban_chat_member(chat.id, user.id)
|
2352 |
-
return True
|
2353 |
-
else:
|
2354 |
-
return False
|
2355 |
-
|
2356 |
-
|
2357 |
-
def __stats__():
|
2358 |
-
all_fbanned = sql.get_all_fban_users_global()
|
2359 |
-
all_feds = sql.get_all_feds_users_global()
|
2360 |
-
return "• {} banned users across {} Federations".format(
|
2361 |
-
len(all_fbanned),
|
2362 |
-
len(all_feds),
|
2363 |
-
)
|
2364 |
-
|
2365 |
-
|
2366 |
-
def __user_info__(user_id, chat_id):
|
2367 |
-
fed_id = sql.get_fed_id(chat_id)
|
2368 |
-
if fed_id:
|
2369 |
-
fban, fbanreason, fbantime = sql.get_fban_user(fed_id, user_id)
|
2370 |
-
info = sql.get_fed_info(fed_id)
|
2371 |
-
infoname = info["fname"]
|
2372 |
-
|
2373 |
-
if int(info["owner"]) == user_id:
|
2374 |
-
text = "Federation owner of: <b>{}</b>.".format(infoname)
|
2375 |
-
elif is_user_fed_admin(fed_id, user_id):
|
2376 |
-
text = "Federation admin of: <b>{}</b>.".format(infoname)
|
2377 |
-
|
2378 |
-
elif fban:
|
2379 |
-
text = "Federation banned: <b>Yes</b>"
|
2380 |
-
text += "\n<b>Reason:</b> {}".format(fbanreason)
|
2381 |
-
else:
|
2382 |
-
text = "Federation banned: <b>No</b>"
|
2383 |
-
else:
|
2384 |
-
text = ""
|
2385 |
-
return text
|
2386 |
-
|
2387 |
-
|
2388 |
-
# Temporary data
|
2389 |
-
def put_chat(chat_id, value, chat_data):
|
2390 |
-
# print(chat_data)
|
2391 |
-
if value is False:
|
2392 |
-
status = False
|
2393 |
-
else:
|
2394 |
-
status = True
|
2395 |
-
chat_data[chat_id] = {"federation": {"status": status, "value": value}}
|
2396 |
-
|
2397 |
-
|
2398 |
-
def get_chat(chat_id, chat_data):
|
2399 |
-
# print(chat_data)
|
2400 |
-
try:
|
2401 |
-
value = chat_data[chat_id]["federation"]
|
2402 |
-
return value
|
2403 |
-
except KeyError:
|
2404 |
-
return {"status": False, "value": False}
|
2405 |
-
|
2406 |
-
|
2407 |
-
async def fed_owner_help(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2408 |
-
await update.effective_message.reply_text(
|
2409 |
-
"""*👑 Fed Owner Only:*
|
2410 |
-
» `/newfed <fed_name>`*:* Creates a Federation, One allowed per user
|
2411 |
-
» `/renamefed <fed_id> <new_fed_name>`*:* Renames the fed id to a new name
|
2412 |
-
» `/delfed <fed_id>`*:* Delete a Federation, and any information related to it. Will not cancel blocked users
|
2413 |
-
» `/fpromote <user>`*:* Assigns the user as a federation admin. Enables all commands for the user under `Fed Admins`
|
2414 |
-
» `/fdemote <user>`*:* Drops the User from the admin Federation to a normal User
|
2415 |
-
» `/subfed <fed_id>`*:* Subscribes to a given fed ID, bans from that subscribed fed will also happen in your fed
|
2416 |
-
» `/unsubfed <fed_id>`*:* Unsubscribes to a given fed ID
|
2417 |
-
» `/setfedlog <fed_id>`*:* Sets the group as a fed log report base for the federation
|
2418 |
-
» `/unsetfedlog <fed_id>`*:* Removed the group as a fed log report base for the federation
|
2419 |
-
» `/fbroadcast <message>`*:* Broadcasts a messages to all groups that have joined your fed
|
2420 |
-
» `/fedsubs`*:* Shows the feds your group is subscribed to `(broken rn)`""",
|
2421 |
-
parse_mode=ParseMode.MARKDOWN,
|
2422 |
-
)
|
2423 |
-
|
2424 |
-
|
2425 |
-
async def fed_admin_help(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2426 |
-
await update.effective_message.reply_text(
|
2427 |
-
"""*🔱 Fed Admins:*
|
2428 |
-
» `/fban <user> <reason>`*:* Fed bans a user
|
2429 |
-
» `/unfban <user> <reason>`*:* Removes a user from a fed ban
|
2430 |
-
» `/fedinfo <fed_id>`*:* Information about the specified Federation
|
2431 |
-
» `/joinfed <fed_id>`*:* Join the current chat to the Federation. Only chat owners can do this. Every chat can only be in one Federation
|
2432 |
-
» `/leavefed <fed_id>`*:* Leave the Federation given. Only chat owners can do this
|
2433 |
-
» `/setfrules <rules>`*:* Arrange Federation rules
|
2434 |
-
» `/fedadmins`*:* Show Federation admin
|
2435 |
-
» `/fbanlist`*:* Displays all users who are victimized at the Federation at this time
|
2436 |
-
» `/fedchats`*:* Get all the chats that are connected in the Federation
|
2437 |
-
» `/chatfed `*:* See the Federation in the current chat\n""",
|
2438 |
-
parse_mode=ParseMode.MARKDOWN,
|
2439 |
-
)
|
2440 |
-
|
2441 |
-
|
2442 |
-
async def fed_user_help(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
2443 |
-
await update.effective_message.reply_text(
|
2444 |
-
"""*🎩 Any user:*
|
2445 |
-
» `/fbanstat`*:* Shows if you/or the user you are replying to or their username is fbanned somewhere or not
|
2446 |
-
» `/fednotif <on/off>`*:* Federation settings not in PM when there are users who are fbaned/unfbanned
|
2447 |
-
» `/frules`*:* See Federation regulations\n""",
|
2448 |
-
parse_mode=ParseMode.MARKDOWN,
|
2449 |
-
)
|
2450 |
-
|
2451 |
-
|
2452 |
-
# <=================================================== HELP ====================================================>
|
2453 |
-
|
2454 |
-
|
2455 |
-
__mod_name__ = "FEDS"
|
2456 |
-
|
2457 |
-
__help__ = """
|
2458 |
-
➠ *Everything is fun, until a spammer starts entering your group, and you have to block it. Then you need to start banning more, and more, and it hurts*.
|
2459 |
-
*But then you have many groups, and you don't want this spammer to be in one of your groups - how can you deal? Do you have to manually block it, in all your groups*?\n
|
2460 |
-
*No longer!* *With Federation, you can make a ban in one chat overlap with all other chats*.\n
|
2461 |
-
*You can even designate federation admins, so your trusted admin can ban all the spammers from chats you want to protect*.\n
|
2462 |
-
|
2463 |
-
➠ *Commands:*
|
2464 |
-
➠ Feds are now divided into 3 sections for your ease.
|
2465 |
-
|
2466 |
-
» /fedownerhelp: Provides help for fed creation and owner only commands.
|
2467 |
-
|
2468 |
-
» /fedadminhelp: Provides help for fed administration commands.
|
2469 |
-
|
2470 |
-
» /feduserhelp: Provides help for commands anyone can use.
|
2471 |
-
|
2472 |
-
"""
|
2473 |
-
|
2474 |
-
# <================================================ HANDLER =======================================================>
|
2475 |
-
function(CommandHandler("newfed", new_fed, block=False))
|
2476 |
-
function(CommandHandler("delfed", del_fed, block=False))
|
2477 |
-
function(CommandHandler("renamefed", rename_fed, block=False))
|
2478 |
-
function(CommandHandler("joinfed", join_fed, block=False))
|
2479 |
-
function(CommandHandler("leavefed", leave_fed, block=False))
|
2480 |
-
function(CommandHandler("fpromote", user_join_fed, block=False))
|
2481 |
-
function(CommandHandler("fdemote", user_demote_fed, block=False))
|
2482 |
-
function(CommandHandler("fedinfo", fed_info, block=False))
|
2483 |
-
function(DisableAbleCommandHandler("fban", fed_ban, block=False))
|
2484 |
-
function(CommandHandler("unfban", unfban, block=False))
|
2485 |
-
function(CommandHandler("fbroadcast", fed_broadcast, block=False))
|
2486 |
-
function(CommandHandler("setfrules", set_frules, block=False))
|
2487 |
-
function(CommandHandler("frules", get_frules, block=False))
|
2488 |
-
function(CommandHandler("chatfed", fed_chat, block=False))
|
2489 |
-
function(CommandHandler("fedadmins", fed_admin, block=False))
|
2490 |
-
function(CommandHandler("fbanlist", fed_ban_list, block=False))
|
2491 |
-
function(CommandHandler("fednotif", fed_notif, block=False))
|
2492 |
-
function(CommandHandler("fedchats", fed_chats, block=False))
|
2493 |
-
function(CommandHandler("importfbans", fed_import_bans, block=False))
|
2494 |
-
function(DisableAbleCommandHandler(["fedstat", "fbanstat"], fed_stat_user, block=False))
|
2495 |
-
function(CommandHandler("setfedlog", set_fed_log, block=False))
|
2496 |
-
function(CommandHandler("unsetfedlog", unset_fed_log, block=False))
|
2497 |
-
function(CommandHandler("subfed", subs_feds, block=False))
|
2498 |
-
function(CommandHandler("unsubfed", unsubs_feds, block=False))
|
2499 |
-
function(CommandHandler("fedsubs", get_myfedsubs, block=False))
|
2500 |
-
function(CommandHandler("myfeds", get_myfeds_list, block=False))
|
2501 |
-
function(CallbackQueryHandler(del_fed_button, pattern=r"rmfed_", block=False))
|
2502 |
-
function(CommandHandler("fedownerhelp", fed_owner_help, block=False))
|
2503 |
-
function(CommandHandler("fedadminhelp", fed_admin_help, block=False))
|
2504 |
-
function(CommandHandler("feduserhelp", fed_user_help, block=False))
|
2505 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/flood.py
DELETED
@@ -1,457 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import html
|
3 |
-
import re
|
4 |
-
|
5 |
-
from telegram import ChatPermissions, Update
|
6 |
-
from telegram.error import BadRequest
|
7 |
-
from telegram.ext import (
|
8 |
-
CallbackQueryHandler,
|
9 |
-
CommandHandler,
|
10 |
-
ContextTypes,
|
11 |
-
MessageHandler,
|
12 |
-
filters,
|
13 |
-
)
|
14 |
-
from telegram.helpers import mention_html
|
15 |
-
|
16 |
-
from Database.sql import antiflood_sql as sql
|
17 |
-
from Database.sql.approve_sql import is_approved
|
18 |
-
from Mikobot import dispatcher, function
|
19 |
-
from Mikobot.plugins.connection import connected
|
20 |
-
from Mikobot.plugins.helper_funcs.alternate import send_message
|
21 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin, is_user_admin
|
22 |
-
from Mikobot.plugins.helper_funcs.string_handling import extract_time
|
23 |
-
from Mikobot.plugins.log_channel import loggable
|
24 |
-
|
25 |
-
# <=======================================================================================================>
|
26 |
-
|
27 |
-
FLOOD_GROUP = 3
|
28 |
-
|
29 |
-
|
30 |
-
# <================================================ FUNCTION =======================================================>
|
31 |
-
@loggable
|
32 |
-
async def check_flood(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
33 |
-
user = update.effective_user
|
34 |
-
chat = update.effective_chat
|
35 |
-
msg = update.effective_message
|
36 |
-
if not user:
|
37 |
-
return ""
|
38 |
-
|
39 |
-
if await is_user_admin(chat, user.id):
|
40 |
-
sql.update_flood(chat.id, None)
|
41 |
-
return ""
|
42 |
-
|
43 |
-
if is_approved(chat.id, user.id):
|
44 |
-
sql.update_flood(chat.id, None)
|
45 |
-
return
|
46 |
-
|
47 |
-
should_ban = sql.update_flood(chat.id, user.id)
|
48 |
-
if not should_ban:
|
49 |
-
return ""
|
50 |
-
|
51 |
-
try:
|
52 |
-
getmode, getvalue = sql.get_flood_setting(chat.id)
|
53 |
-
if getmode == 1:
|
54 |
-
await chat.ban_member(user.id)
|
55 |
-
execstrings = "BANNED"
|
56 |
-
tag = "BANNED"
|
57 |
-
elif getmode == 2:
|
58 |
-
await chat.ban_member(user.id)
|
59 |
-
await chat.unban_member(user.id)
|
60 |
-
execstrings = "KICKED"
|
61 |
-
tag = "KICKED"
|
62 |
-
elif getmode == 3:
|
63 |
-
await context.bot.restrict_chat_member(
|
64 |
-
chat.id,
|
65 |
-
user.id,
|
66 |
-
permissions=ChatPermissions(can_send_messages=False),
|
67 |
-
)
|
68 |
-
execstrings = "MUTED"
|
69 |
-
tag = "MUTED"
|
70 |
-
elif getmode == 4:
|
71 |
-
bantime = await extract_time(msg, getvalue)
|
72 |
-
await chat.ban_member(user.id, until_date=bantime)
|
73 |
-
execstrings = "BANNED for {}".format(getvalue)
|
74 |
-
tag = "TBAN"
|
75 |
-
elif getmode == 5:
|
76 |
-
mutetime = await extract_time(msg, getvalue)
|
77 |
-
await context.bot.restrict_chat_member(
|
78 |
-
chat.id,
|
79 |
-
user.id,
|
80 |
-
until_date=mutetime,
|
81 |
-
permissions=ChatPermissions(can_send_messages=False),
|
82 |
-
)
|
83 |
-
execstrings = "MUTED for {}".format(getvalue)
|
84 |
-
tag = "TMUTE"
|
85 |
-
await send_message(
|
86 |
-
update.effective_message,
|
87 |
-
"Beep boop! Boop beep!\n{}!".format(execstrings),
|
88 |
-
)
|
89 |
-
|
90 |
-
return (
|
91 |
-
"<b>{}:</b>"
|
92 |
-
"\n#{}"
|
93 |
-
"\n<b>user:</b> {}"
|
94 |
-
"\nFlooded the group.".format(
|
95 |
-
tag,
|
96 |
-
html.escape(chat.title),
|
97 |
-
mention_html(user.id, html.escape(user.first_name)),
|
98 |
-
)
|
99 |
-
)
|
100 |
-
|
101 |
-
except BadRequest:
|
102 |
-
await msg.reply_text(
|
103 |
-
"I can't restrict people here, give me permissions first! Until then, I'll disable anti-flood.",
|
104 |
-
)
|
105 |
-
sql.set_flood(chat.id, 0)
|
106 |
-
return (
|
107 |
-
"<b>{}:</b>"
|
108 |
-
"\n#INFO"
|
109 |
-
"\nDon't have enough permission to restrict users so automatically disabled anti-flood.".format(
|
110 |
-
chat.title,
|
111 |
-
)
|
112 |
-
)
|
113 |
-
|
114 |
-
|
115 |
-
@check_admin(permission="can_restrict_members", is_both=True, no_reply=True)
|
116 |
-
async def flood_button(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
117 |
-
bot = context.bot
|
118 |
-
query = update.callback_query
|
119 |
-
user = update.effective_user
|
120 |
-
match = re.match(r"unmute_flooder\((.+?)\)", query.data)
|
121 |
-
if match:
|
122 |
-
user_id = match.group(1)
|
123 |
-
chat = update.effective_chat.id
|
124 |
-
try:
|
125 |
-
await bot.restrict_chat_member(
|
126 |
-
chat,
|
127 |
-
int(user_id),
|
128 |
-
permissions=ChatPermissions(
|
129 |
-
can_send_messages=True,
|
130 |
-
can_send_media_messages=True,
|
131 |
-
can_send_other_messages=True,
|
132 |
-
can_add_web_page_previews=True,
|
133 |
-
),
|
134 |
-
)
|
135 |
-
await update.effective_message.edit_text(
|
136 |
-
f"Unmuted by {mention_html(user.id, html.escape(user.first_name))}.",
|
137 |
-
parse_mode="HTML",
|
138 |
-
)
|
139 |
-
except:
|
140 |
-
pass
|
141 |
-
|
142 |
-
|
143 |
-
@loggable
|
144 |
-
@check_admin(is_user=True)
|
145 |
-
async def set_flood(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
146 |
-
chat = update.effective_chat
|
147 |
-
user = update.effective_user
|
148 |
-
message = update.effective_message
|
149 |
-
args = context.args
|
150 |
-
|
151 |
-
conn = await connected(context.bot, update, chat, user.id, need_admin=True)
|
152 |
-
if conn:
|
153 |
-
chat_id = conn
|
154 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
155 |
-
chat_name = chat_obj.title
|
156 |
-
else:
|
157 |
-
if update.effective_message.chat.type == "private":
|
158 |
-
await send_message(
|
159 |
-
update.effective_message,
|
160 |
-
"This command is meant to use in a group, not in PM.",
|
161 |
-
)
|
162 |
-
return ""
|
163 |
-
chat_id = update.effective_chat.id
|
164 |
-
chat_name = update.effective_message.chat.title
|
165 |
-
|
166 |
-
if len(args) >= 1:
|
167 |
-
val = args[0].lower()
|
168 |
-
if val in ["off", "no", "0"]:
|
169 |
-
sql.set_flood(chat_id, 0)
|
170 |
-
if conn:
|
171 |
-
text = await message.reply_text(
|
172 |
-
"Antiflood has been disabled in {}.".format(chat_name),
|
173 |
-
)
|
174 |
-
else:
|
175 |
-
text = await message.reply_text("Antiflood has been disabled.")
|
176 |
-
|
177 |
-
elif val.isdigit():
|
178 |
-
amount = int(val)
|
179 |
-
if amount <= 0:
|
180 |
-
sql.set_flood(chat_id, 0)
|
181 |
-
if conn:
|
182 |
-
text = await message.reply_text(
|
183 |
-
"Antiflood has been disabled in {}.".format(chat_name),
|
184 |
-
)
|
185 |
-
else:
|
186 |
-
text = await message.reply_text("Antiflood has been disabled.")
|
187 |
-
return (
|
188 |
-
"<b>{}:</b>"
|
189 |
-
"\n#SETFLOOD"
|
190 |
-
"\n<b>Admin:</b> {}"
|
191 |
-
"\nDisable Antiflood.".format(
|
192 |
-
html.escape(chat_name),
|
193 |
-
mention_html(user.id, html.escape(user.first_name)),
|
194 |
-
)
|
195 |
-
)
|
196 |
-
|
197 |
-
elif amount <= 3:
|
198 |
-
await send_message(
|
199 |
-
update.effective_message,
|
200 |
-
"Antiflood must be either 0 (disabled) or a number greater than 3!",
|
201 |
-
)
|
202 |
-
return ""
|
203 |
-
|
204 |
-
else:
|
205 |
-
sql.set_flood(chat_id, amount)
|
206 |
-
if conn:
|
207 |
-
text = await message.reply_text(
|
208 |
-
"Antiflood limit has been set to {} in chat: {}".format(
|
209 |
-
amount,
|
210 |
-
chat_name,
|
211 |
-
),
|
212 |
-
)
|
213 |
-
else:
|
214 |
-
text = await message.reply_text(
|
215 |
-
"Successfully updated antiflood limit to {}!".format(amount),
|
216 |
-
)
|
217 |
-
return (
|
218 |
-
"<b>{}:</b>"
|
219 |
-
"\n#SETFLOOD"
|
220 |
-
"\n<b>Admin:</b> {}"
|
221 |
-
"\nSet Antiflood to <code>{}</code>.".format(
|
222 |
-
html.escape(chat_name),
|
223 |
-
mention_html(user.id, html.escape(user.first_name)),
|
224 |
-
amount,
|
225 |
-
)
|
226 |
-
)
|
227 |
-
|
228 |
-
else:
|
229 |
-
await message.reply_text(
|
230 |
-
"Invalid argument, please use a number, 'off', or 'no'."
|
231 |
-
)
|
232 |
-
else:
|
233 |
-
await message.reply_text(
|
234 |
-
(
|
235 |
-
"Use `/setflood number` to enable antiflood.\n"
|
236 |
-
"Or use `/setflood off` to disable antiflood."
|
237 |
-
),
|
238 |
-
parse_mode="markdown",
|
239 |
-
)
|
240 |
-
return ""
|
241 |
-
|
242 |
-
|
243 |
-
async def flood(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
244 |
-
chat = update.effective_chat
|
245 |
-
user = update.effective_user
|
246 |
-
msg = update.effective_message
|
247 |
-
|
248 |
-
conn = await connected(context.bot, update, chat, user.id, need_admin=False)
|
249 |
-
if conn:
|
250 |
-
chat_id = conn
|
251 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
252 |
-
chat_name = chat_obj.title
|
253 |
-
else:
|
254 |
-
if update.effective_message.chat.type == "private":
|
255 |
-
await send_message(
|
256 |
-
update.effective_message,
|
257 |
-
"This command is meant to use in a group, not in PM.",
|
258 |
-
)
|
259 |
-
return
|
260 |
-
chat_id = update.effective_chat.id
|
261 |
-
chat_name = update.effective_message.chat.title
|
262 |
-
|
263 |
-
limit = sql.get_flood_limit(chat_id)
|
264 |
-
if limit == 0:
|
265 |
-
if conn:
|
266 |
-
text = await msg.reply_text(
|
267 |
-
"I'm not enforcing any flood control in {}!".format(chat_name),
|
268 |
-
)
|
269 |
-
else:
|
270 |
-
text = await msg.reply_text("I'm not enforcing any flood control here!")
|
271 |
-
else:
|
272 |
-
if conn:
|
273 |
-
text = await msg.reply_text(
|
274 |
-
"I'm currently restricting members after {} consecutive messages in {}.".format(
|
275 |
-
limit,
|
276 |
-
chat_name,
|
277 |
-
),
|
278 |
-
)
|
279 |
-
else:
|
280 |
-
text = await msg.reply_text(
|
281 |
-
"I'm currently restricting members after {} consecutive messages.".format(
|
282 |
-
limit,
|
283 |
-
),
|
284 |
-
)
|
285 |
-
|
286 |
-
|
287 |
-
@check_admin(is_user=True)
|
288 |
-
async def set_flood_mode(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
289 |
-
chat = update.effective_chat
|
290 |
-
user = update.effective_user
|
291 |
-
msg = update.effective_message
|
292 |
-
args = context.args
|
293 |
-
|
294 |
-
conn = await connected(context.bot, update, chat, user.id, need_admin=True)
|
295 |
-
if conn:
|
296 |
-
chat = await dispatcher.bot.getChat(conn)
|
297 |
-
chat_id = conn
|
298 |
-
chat_obj = await dispatcher.bot.getChat(conn)
|
299 |
-
chat_name = chat_obj.title
|
300 |
-
else:
|
301 |
-
if update.effective_message.chat.type == "private":
|
302 |
-
await send_message(
|
303 |
-
update.effective_message,
|
304 |
-
"This command is meant to use in a group, not in PM.",
|
305 |
-
)
|
306 |
-
return ""
|
307 |
-
chat = update.effective_chat
|
308 |
-
chat_id = update.effective_chat.id
|
309 |
-
chat_name = update.effective_message.chat.title
|
310 |
-
|
311 |
-
if args:
|
312 |
-
if args[0].lower() == "ban":
|
313 |
-
settypeflood = "ban"
|
314 |
-
sql.set_flood_strength(chat_id, 1, "0")
|
315 |
-
elif args[0].lower() == "kick":
|
316 |
-
settypeflood = "kick"
|
317 |
-
sql.set_flood_strength(chat_id, 2, "0")
|
318 |
-
elif args[0].lower() == "mute":
|
319 |
-
settypeflood = "mute"
|
320 |
-
sql.set_flood_strength(chat_id, 3, "0")
|
321 |
-
elif args[0].lower() == "tban":
|
322 |
-
if len(args) == 1:
|
323 |
-
teks = """It looks like you tried to set time value for antiflood but you didn't specified time; Try, `/setfloodmode tban <timevalue>`.
|
324 |
-
Examples of time value: 4m = 4 minutes, 3h = 3 hours, 6d = 6 days, 5w = 5 weeks."""
|
325 |
-
await send_message(
|
326 |
-
update.effective_message, teks, parse_mode="markdown"
|
327 |
-
)
|
328 |
-
return
|
329 |
-
settypeflood = "tban for {}".format(args[1])
|
330 |
-
sql.set_flood_strength(chat_id, 4, str(args[1]))
|
331 |
-
elif args[0].lower() == "tmute":
|
332 |
-
if len(args) == 1:
|
333 |
-
teks = """It looks like you tried to set time value for antiflood but you didn't specified time; Try, `/setfloodmode tmute <timevalue>`.
|
334 |
-
Examples of time value: 4m = 4 minutes, 3h = 3 hours, 6d = 6 days, 5w = 5 weeks."""
|
335 |
-
await send_message(
|
336 |
-
update.effective_message, teks, parse_mode="markdown"
|
337 |
-
)
|
338 |
-
return
|
339 |
-
settypeflood = "tmute for {}".format(args[1])
|
340 |
-
sql.set_flood_strength(chat_id, 5, str(args[1]))
|
341 |
-
else:
|
342 |
-
await send_message(
|
343 |
-
update.effective_message,
|
344 |
-
"I only understand ban/kick/mute/tban/tmute!",
|
345 |
-
)
|
346 |
-
return
|
347 |
-
if conn:
|
348 |
-
text = await msg.reply_text(
|
349 |
-
"Exceeding consecutive flood limit will result in {} in {}!".format(
|
350 |
-
settypeflood,
|
351 |
-
chat_name,
|
352 |
-
),
|
353 |
-
)
|
354 |
-
else:
|
355 |
-
text = await msg.reply_text(
|
356 |
-
"Exceeding consecutive flood limit will result in {}!".format(
|
357 |
-
settypeflood,
|
358 |
-
),
|
359 |
-
)
|
360 |
-
return (
|
361 |
-
"<b>{}:</b>\n"
|
362 |
-
"<b>Admin:</b> {}\n"
|
363 |
-
"Has changed antiflood mode. User will {}.".format(
|
364 |
-
settypeflood,
|
365 |
-
html.escape(chat.title),
|
366 |
-
mention_html(user.id, html.escape(user.first_name)),
|
367 |
-
)
|
368 |
-
)
|
369 |
-
else:
|
370 |
-
getmode, getvalue = sql.get_flood_setting(chat.id)
|
371 |
-
if getmode == 1:
|
372 |
-
settypeflood = "ban"
|
373 |
-
elif getmode == 2:
|
374 |
-
settypeflood = "kick"
|
375 |
-
elif getmode == 3:
|
376 |
-
settypeflood = "mute"
|
377 |
-
elif getmode == 4:
|
378 |
-
settypeflood = "tban for {}".format(getvalue)
|
379 |
-
elif getmode == 5:
|
380 |
-
settypeflood = "tmute for {}".format(getvalue)
|
381 |
-
if conn:
|
382 |
-
text = await msg.reply_text(
|
383 |
-
"Sending more messages than flood limit will result in {} in {}.".format(
|
384 |
-
settypeflood,
|
385 |
-
chat_name,
|
386 |
-
),
|
387 |
-
)
|
388 |
-
else:
|
389 |
-
text = await msg.reply_text(
|
390 |
-
"Sending more messages than flood limit will result in {}.".format(
|
391 |
-
settypeflood,
|
392 |
-
),
|
393 |
-
)
|
394 |
-
return ""
|
395 |
-
|
396 |
-
|
397 |
-
def __migrate__(old_chat_id, new_chat_id):
|
398 |
-
sql.migrate_chat(old_chat_id, new_chat_id)
|
399 |
-
|
400 |
-
|
401 |
-
def __chat_settings__(chat_id, user_id):
|
402 |
-
limit = sql.get_flood_limit(chat_id)
|
403 |
-
if limit == 0:
|
404 |
-
return "Not enforcing flood control."
|
405 |
-
else:
|
406 |
-
return "Antiflood has been set to `{}`.".format(limit)
|
407 |
-
|
408 |
-
|
409 |
-
# <=================================================== HELP ====================================================>
|
410 |
-
|
411 |
-
|
412 |
-
__help__ = """
|
413 |
-
➠ *Antiflood allows you to take action on users that send more than x messages in a row. Exceeding the set flood will result in restricting that user.*
|
414 |
-
|
415 |
-
➠ *Admin Only*
|
416 |
-
|
417 |
-
» /flood: Get the current antiflood settings.
|
418 |
-
|
419 |
-
» /setflood <number/off/no>: Set the number of messages after which to take action on a user. Set to '0', 'off', or 'no' to disable.
|
420 |
-
|
421 |
-
» /setfloodmode <action type>: Choose which action to take on a user who has been flooding. Options: ban/kick/mute/tban/tmute.
|
422 |
-
"""
|
423 |
-
|
424 |
-
__mod_name__ = "ANTI-FLOOD"
|
425 |
-
|
426 |
-
# <================================================ HANDLER =======================================================>
|
427 |
-
FLOOD_BAN_HANDLER = MessageHandler(
|
428 |
-
filters.ALL & ~filters.StatusUpdate.ALL & filters.ChatType.GROUPS,
|
429 |
-
check_flood,
|
430 |
-
block=False,
|
431 |
-
)
|
432 |
-
SET_FLOOD_HANDLER = CommandHandler(
|
433 |
-
"setflood", set_flood, filters=filters.ChatType.GROUPS, block=False
|
434 |
-
)
|
435 |
-
SET_FLOOD_MODE_HANDLER = CommandHandler(
|
436 |
-
"setfloodmode", set_flood_mode, block=False
|
437 |
-
) # , filters=filters.ChatType.GROUPS)
|
438 |
-
FLOOD_QUERY_HANDLER = CallbackQueryHandler(
|
439 |
-
flood_button, pattern=r"unmute_flooder", block=False
|
440 |
-
)
|
441 |
-
FLOOD_HANDLER = CommandHandler(
|
442 |
-
"flood", flood, filters=filters.ChatType.GROUPS, block=False
|
443 |
-
)
|
444 |
-
|
445 |
-
function(FLOOD_BAN_HANDLER, FLOOD_GROUP)
|
446 |
-
function(FLOOD_QUERY_HANDLER)
|
447 |
-
function(SET_FLOOD_HANDLER)
|
448 |
-
function(SET_FLOOD_MODE_HANDLER)
|
449 |
-
function(FLOOD_HANDLER)
|
450 |
-
|
451 |
-
__handlers__ = [
|
452 |
-
(FLOOD_BAN_HANDLER, FLOOD_GROUP),
|
453 |
-
SET_FLOOD_HANDLER,
|
454 |
-
FLOOD_HANDLER,
|
455 |
-
SET_FLOOD_MODE_HANDLER,
|
456 |
-
]
|
457 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/fsub.py
DELETED
@@ -1,189 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from telethon import Button, events, types
|
3 |
-
from telethon.errors import ChatAdminRequiredError, UserNotParticipantError
|
4 |
-
from telethon.tl.functions.channels import GetParticipantRequest
|
5 |
-
|
6 |
-
from Database.mongodb import fsub_db as db
|
7 |
-
from Mikobot import BOT_ID
|
8 |
-
from Mikobot import DRAGONS as DEVS
|
9 |
-
from Mikobot import OWNER_ID, tbot
|
10 |
-
from Mikobot.events import register
|
11 |
-
|
12 |
-
# <=======================================================================================================>
|
13 |
-
|
14 |
-
# Constants
|
15 |
-
F_SUBSCRIBE_COMMAND = "/(fsub|Fsub|forcesubscribe|Forcesub|forcesub|Forcesubscribe)"
|
16 |
-
FORCESUBSCRIBE_ON = ["on", "yes", "y"]
|
17 |
-
FORCESUBSCRIBE_OFF = ["off", "no", "n"]
|
18 |
-
|
19 |
-
|
20 |
-
# <================================================ FUNCTION =======================================================>
|
21 |
-
def fsk_ck(**args):
|
22 |
-
def decorator(func):
|
23 |
-
tbot.add_event_handler(func, events.CallbackQuery(**args))
|
24 |
-
return func
|
25 |
-
|
26 |
-
return decorator
|
27 |
-
|
28 |
-
|
29 |
-
# Helper functions
|
30 |
-
async def is_admin(chat_id, user_id):
|
31 |
-
try:
|
32 |
-
p = await tbot(GetParticipantRequest(chat_id, user_id))
|
33 |
-
except UserNotParticipantError:
|
34 |
-
return False
|
35 |
-
return isinstance(
|
36 |
-
p.participant, (types.ChannelParticipantAdmin, types.ChannelParticipantCreator)
|
37 |
-
)
|
38 |
-
|
39 |
-
|
40 |
-
async def participant_check(channel, user_id):
|
41 |
-
try:
|
42 |
-
await tbot(GetParticipantRequest(channel, int(user_id)))
|
43 |
-
return True
|
44 |
-
except UserNotParticipantError:
|
45 |
-
return False
|
46 |
-
except Exception:
|
47 |
-
return False
|
48 |
-
|
49 |
-
|
50 |
-
# Main command function
|
51 |
-
@register(pattern=f"^{F_SUBSCRIBE_COMMAND} ?(.*)")
|
52 |
-
async def force_subscribe(event):
|
53 |
-
"""Handle the force subscribe command."""
|
54 |
-
if event.is_private:
|
55 |
-
return
|
56 |
-
|
57 |
-
if event.is_group:
|
58 |
-
perm = await event.client.get_permissions(event.chat_id, event.sender_id)
|
59 |
-
if not perm.is_admin:
|
60 |
-
return await event.reply("You need to be an admin to do this.")
|
61 |
-
|
62 |
-
if not perm.is_creator:
|
63 |
-
return await event.reply(
|
64 |
-
"❗ Group creator required\nYou have to be the group creator to do that."
|
65 |
-
)
|
66 |
-
|
67 |
-
try:
|
68 |
-
channel = event.text.split(None, 1)[1]
|
69 |
-
except IndexError:
|
70 |
-
channel = None
|
71 |
-
|
72 |
-
if not channel:
|
73 |
-
chat_db = db.fs_settings(event.chat_id)
|
74 |
-
if not chat_db:
|
75 |
-
await event.reply("Force subscribe is disabled in this chat.")
|
76 |
-
else:
|
77 |
-
await event.reply(
|
78 |
-
f"Force subscribe is currently enabled. Users are forced to join @{chat_db.channel} to speak here."
|
79 |
-
)
|
80 |
-
elif channel.lower() in FORCESUBSCRIBE_ON:
|
81 |
-
await event.reply("Please specify the channel username.")
|
82 |
-
elif channel.lower() in FORCESUBSCRIBE_OFF:
|
83 |
-
await event.reply("**Force subscribe is disabled successfully.**")
|
84 |
-
db.disapprove(event.chat_id)
|
85 |
-
else:
|
86 |
-
try:
|
87 |
-
channel_entity = await event.client.get_entity(channel)
|
88 |
-
except:
|
89 |
-
return await event.reply("Invalid channel username provided.")
|
90 |
-
|
91 |
-
channel = channel_entity.username
|
92 |
-
try:
|
93 |
-
if not channel_entity.broadcast:
|
94 |
-
return await event.reply("That's not a valid channel.")
|
95 |
-
except:
|
96 |
-
return await event.reply("That's not a valid channel.")
|
97 |
-
|
98 |
-
if not await participant_check(channel, BOT_ID):
|
99 |
-
return await event.reply(
|
100 |
-
f"**Not an admin in the channel**\nI am not an admin in the [channel](https://t.me/{channel}). Add me as an admin to enable force subscribe.",
|
101 |
-
link_preview=False,
|
102 |
-
)
|
103 |
-
|
104 |
-
db.add_channel(event.chat_id, str(channel))
|
105 |
-
await event.reply(f"Force subscribe is enabled to @{channel}.")
|
106 |
-
|
107 |
-
|
108 |
-
# Event handler for new messages
|
109 |
-
@tbot.on(events.NewMessage())
|
110 |
-
async def force_subscribe_new_message(e):
|
111 |
-
"""Handle new messages for force subscribe."""
|
112 |
-
if not db.fs_settings(e.chat_id):
|
113 |
-
return
|
114 |
-
|
115 |
-
if e.is_private or not e.from_id or e.sender_id in DEVS or e.sender_id == OWNER_ID:
|
116 |
-
return
|
117 |
-
|
118 |
-
if not e.chat.admin_rights or not e.chat.admin_rights.ban_users:
|
119 |
-
return
|
120 |
-
|
121 |
-
try:
|
122 |
-
channel = db.fs_settings(e.chat_id)["channel"]
|
123 |
-
check = await participant_check(channel, e.sender_id)
|
124 |
-
except (ChatAdminRequiredError, UserNotParticipantError):
|
125 |
-
return
|
126 |
-
|
127 |
-
if not check:
|
128 |
-
buttons = [
|
129 |
-
Button.url("Join Channel", f"t.me/{channel}"),
|
130 |
-
Button.inline("Unmute Me", data=f"fs_{e.sender_id}"),
|
131 |
-
]
|
132 |
-
|
133 |
-
txt = f'<b><a href="tg://user?id={e.sender_id}">{e.sender.first_name}</a></b>, you have <b>not subscribed</b> to our <b><a href="t.me/{channel}">channel</a></b> yet. Please <b><a href="t.me/{channel}">join</a></b> and press the button below to unmute yourself.'
|
134 |
-
await e.reply(txt, buttons=buttons, parse_mode="html", link_preview=False)
|
135 |
-
await e.client.edit_permissions(e.chat_id, e.sender_id, send_messages=False)
|
136 |
-
|
137 |
-
|
138 |
-
# Inline query handler
|
139 |
-
@fsk_ck(pattern=r"fs(\_(.*))")
|
140 |
-
async def unmute_force_subscribe(event):
|
141 |
-
"""Handle inline query for unmuting force subscribe."""
|
142 |
-
user_id = int(((event.pattern_match.group(1)).decode()).split("_", 1)[1])
|
143 |
-
|
144 |
-
if not event.sender_id == user_id:
|
145 |
-
return await event.answer("This is not meant for you.", alert=True)
|
146 |
-
|
147 |
-
channel = db.fs_settings(event.chat_id)["channel"]
|
148 |
-
try:
|
149 |
-
check = await participant_check(channel, user_id)
|
150 |
-
except ChatAdminRequiredError:
|
151 |
-
check = False
|
152 |
-
return
|
153 |
-
|
154 |
-
if not check:
|
155 |
-
return await event.answer(
|
156 |
-
"You have to join the channel first, to get unmuted!", alert=True
|
157 |
-
)
|
158 |
-
|
159 |
-
try:
|
160 |
-
await event.client.edit_permissions(event.chat_id, user_id, send_messages=True)
|
161 |
-
except ChatAdminRequiredError:
|
162 |
-
pass
|
163 |
-
|
164 |
-
await event.delete()
|
165 |
-
|
166 |
-
|
167 |
-
# <=================================================== HELP ====================================================>
|
168 |
-
|
169 |
-
|
170 |
-
__help__ = """
|
171 |
-
➠ *Dazai has the capability to hush members who haven't yet subscribed to your channel until they decide to hit that subscribe button.*
|
172 |
-
➠ *When activated, I'll silence those who are not subscribed and provide them with an option to unmute. Once they click the button, I'll lift the mute.*
|
173 |
-
|
174 |
-
➠ Configuration Process
|
175 |
-
➠ Exclusively for Creators
|
176 |
-
➠ Grant me admin privileges in your group
|
177 |
-
➠ Designate me as an admin in your channel
|
178 |
-
|
179 |
-
➠ *Commands*
|
180 |
-
» /fsub channel\_username - to initiate and customize settings for the channel.
|
181 |
-
|
182 |
-
➠ *Kick things off with...*
|
183 |
-
» /fsub - to review the current settings.
|
184 |
-
» /fsub off - to deactivate the force subscription feature.
|
185 |
-
|
186 |
-
➠ *If you disable fsub, you'll need to set it up again for it to take effect. Utilize /fsub channel\_username.*
|
187 |
-
"""
|
188 |
-
__mod_name__ = "F-SUB"
|
189 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/fun.py
DELETED
@@ -1,257 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import random
|
3 |
-
|
4 |
-
from pyjokes import get_joke
|
5 |
-
from telegram import Update
|
6 |
-
from telegram.constants import ParseMode
|
7 |
-
from telegram.ext import ContextTypes
|
8 |
-
|
9 |
-
import Mikobot.utils.fun_strings as fun_strings
|
10 |
-
from Mikobot import function
|
11 |
-
from Mikobot.events import register
|
12 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
13 |
-
from Mikobot.state import state
|
14 |
-
|
15 |
-
# <=======================================================================================================>
|
16 |
-
|
17 |
-
|
18 |
-
# <================================================ FUNCTION =======================================================>
|
19 |
-
async def make_request(url: str) -> str:
|
20 |
-
response = await state.get(url)
|
21 |
-
response.raise_for_status()
|
22 |
-
return response.json()["question"]
|
23 |
-
|
24 |
-
|
25 |
-
async def truth(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
26 |
-
truth_question = await make_request("https://api.truthordarebot.xyz/v1/truth")
|
27 |
-
await update.effective_message.reply_text(truth_question)
|
28 |
-
|
29 |
-
|
30 |
-
async def dare(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
31 |
-
dare_question = await make_request("https://api.truthordarebot.xyz/v1/dare")
|
32 |
-
await update.effective_message.reply_text(dare_question)
|
33 |
-
|
34 |
-
|
35 |
-
@register(pattern="^/joke ?(.*)")
|
36 |
-
async def joke(event):
|
37 |
-
await event.reply(get_joke())
|
38 |
-
|
39 |
-
|
40 |
-
async def roll(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
41 |
-
await update.message.reply_text(random.choice(range(1, 7)))
|
42 |
-
|
43 |
-
|
44 |
-
async def flirt(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
45 |
-
args = context.args
|
46 |
-
await update.effective_message.reply_text(random.choice(fun_strings.FLIRT))
|
47 |
-
|
48 |
-
|
49 |
-
async def toss(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
50 |
-
await update.message.reply_text(random.choice(fun_strings.TOSS))
|
51 |
-
|
52 |
-
|
53 |
-
async def shrug(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
54 |
-
msg = update.effective_message
|
55 |
-
reply_text = (
|
56 |
-
msg.reply_to_message.reply_text if msg.reply_to_message else msg.reply_text
|
57 |
-
)
|
58 |
-
await reply_text(r"¯\_(ツ)_/¯")
|
59 |
-
|
60 |
-
|
61 |
-
async def bluetext(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
62 |
-
msg = update.effective_message
|
63 |
-
reply_text = (
|
64 |
-
msg.reply_to_message.reply_text if msg.reply_to_message else msg.reply_text
|
65 |
-
)
|
66 |
-
await reply_text(
|
67 |
-
"/BLUE /TEXT\n/MUST /CLICK\n/I /AM /A /STUPID /ANIMAL /THAT /IS /ATTRACTED /TO /COLORS"
|
68 |
-
)
|
69 |
-
|
70 |
-
|
71 |
-
async def rlg(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
72 |
-
eyes = random.choice(fun_strings.EYES)
|
73 |
-
mouth = random.choice(fun_strings.MOUTHS)
|
74 |
-
ears = random.choice(fun_strings.EARS)
|
75 |
-
|
76 |
-
if len(eyes) == 2:
|
77 |
-
repl = ears[0] + eyes[0] + mouth[0] + eyes[1] + ears[1]
|
78 |
-
else:
|
79 |
-
repl = ears[0] + eyes[0] + mouth[0] + eyes[0] + ears[1]
|
80 |
-
await update.message.reply_text(repl)
|
81 |
-
|
82 |
-
|
83 |
-
async def decide(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
84 |
-
reply_text = (
|
85 |
-
update.effective_message.reply_to_message.reply_text
|
86 |
-
if update.effective_message.reply_to_message
|
87 |
-
else update.effective_message.reply_text
|
88 |
-
)
|
89 |
-
await reply_text(random.choice(fun_strings.DECIDE))
|
90 |
-
|
91 |
-
|
92 |
-
normiefont = [
|
93 |
-
"a",
|
94 |
-
"b",
|
95 |
-
"c",
|
96 |
-
"d",
|
97 |
-
"e",
|
98 |
-
"f",
|
99 |
-
"g",
|
100 |
-
"h",
|
101 |
-
"i",
|
102 |
-
"j",
|
103 |
-
"k",
|
104 |
-
"l",
|
105 |
-
"m",
|
106 |
-
"n",
|
107 |
-
"o",
|
108 |
-
"p",
|
109 |
-
"q",
|
110 |
-
"r",
|
111 |
-
"s",
|
112 |
-
"t",
|
113 |
-
"u",
|
114 |
-
"v",
|
115 |
-
"w",
|
116 |
-
"x",
|
117 |
-
"y",
|
118 |
-
"z",
|
119 |
-
]
|
120 |
-
|
121 |
-
weebyfont = [
|
122 |
-
"卂",
|
123 |
-
"乃",
|
124 |
-
"匚",
|
125 |
-
"刀",
|
126 |
-
"乇",
|
127 |
-
"下",
|
128 |
-
"厶",
|
129 |
-
"卄",
|
130 |
-
"工",
|
131 |
-
"丁",
|
132 |
-
"长",
|
133 |
-
"乚",
|
134 |
-
"从",
|
135 |
-
"𠘨",
|
136 |
-
"口",
|
137 |
-
"尸",
|
138 |
-
"㔿",
|
139 |
-
"尺",
|
140 |
-
"丂",
|
141 |
-
"丅",
|
142 |
-
"凵",
|
143 |
-
"リ",
|
144 |
-
"山",
|
145 |
-
"乂",
|
146 |
-
"丫",
|
147 |
-
"乙",
|
148 |
-
]
|
149 |
-
|
150 |
-
|
151 |
-
async def webify(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
152 |
-
args = context.args
|
153 |
-
message = update.effective_message
|
154 |
-
string = ""
|
155 |
-
|
156 |
-
if message.reply_to_message:
|
157 |
-
string = message.reply_to_message.text.lower().replace(" ", " ")
|
158 |
-
|
159 |
-
if args:
|
160 |
-
string = " ".join(args).lower()
|
161 |
-
|
162 |
-
if not string:
|
163 |
-
await message.reply_text(
|
164 |
-
"Usage is `/weebify <text>`", parse_mode=ParseMode.MARKDOWN
|
165 |
-
)
|
166 |
-
return
|
167 |
-
|
168 |
-
for normiecharacter in string:
|
169 |
-
if normiecharacter in normiefont:
|
170 |
-
weebycharacter = weebyfont[normiefont.index(normiecharacter)]
|
171 |
-
string = string.replace(normiecharacter, weebycharacter)
|
172 |
-
|
173 |
-
if message.reply_to_message:
|
174 |
-
await message.reply_to_message.reply_text(string)
|
175 |
-
else:
|
176 |
-
await message.reply_text(string)
|
177 |
-
|
178 |
-
|
179 |
-
# <=================================================== HELP ====================================================>
|
180 |
-
|
181 |
-
|
182 |
-
__help__ = """
|
183 |
-
» /cosplay: sends cosplay images.
|
184 |
-
|
185 |
-
» /decide: randomly answers yes/no/maybe.
|
186 |
-
|
187 |
-
» /truth: sends a random truth string.
|
188 |
-
|
189 |
-
» /dare: sends a random dare string.
|
190 |
-
|
191 |
-
» /toss: tosses a coin.
|
192 |
-
|
193 |
-
» /shrug: get shrug xd.
|
194 |
-
|
195 |
-
» /bluetext: check yourself :V.
|
196 |
-
|
197 |
-
�� /roll: roll a dice.
|
198 |
-
|
199 |
-
» /rlg: join ears, nose, mouth and create an emo ;-;
|
200 |
-
|
201 |
-
» /weebify <text>: returns a weebified text.
|
202 |
-
|
203 |
-
» /flirt <text>: returns a flirt text.
|
204 |
-
|
205 |
-
» /joke <text>: tells a random joke.
|
206 |
-
"""
|
207 |
-
|
208 |
-
# <================================================ HANDLER =======================================================>
|
209 |
-
ROLL_HANDLER = DisableAbleCommandHandler("roll", roll, block=False)
|
210 |
-
TOSS_HANDLER = DisableAbleCommandHandler("toss", toss, block=False)
|
211 |
-
SHRUG_HANDLER = DisableAbleCommandHandler("shrug", shrug, block=False)
|
212 |
-
BLUETEXT_HANDLER = DisableAbleCommandHandler("bluetext", bluetext, block=False)
|
213 |
-
RLG_HANDLER = DisableAbleCommandHandler("rlg", rlg, block=False)
|
214 |
-
DECIDE_HANDLER = DisableAbleCommandHandler("decide", decide, block=False)
|
215 |
-
WEEBIFY_HANDLER = DisableAbleCommandHandler("weebify", webify, block=False)
|
216 |
-
FLIRT_HANDLER = DisableAbleCommandHandler("flirt", flirt, block=False)
|
217 |
-
TRUTH_HANDLER = DisableAbleCommandHandler("truth", truth, block=False)
|
218 |
-
DARE_HANDLER = DisableAbleCommandHandler("dare", dare, block=False)
|
219 |
-
|
220 |
-
function(WEEBIFY_HANDLER)
|
221 |
-
function(ROLL_HANDLER)
|
222 |
-
function(TOSS_HANDLER)
|
223 |
-
function(SHRUG_HANDLER)
|
224 |
-
function(BLUETEXT_HANDLER)
|
225 |
-
function(RLG_HANDLER)
|
226 |
-
function(DECIDE_HANDLER)
|
227 |
-
function(FLIRT_HANDLER)
|
228 |
-
function(TRUTH_HANDLER)
|
229 |
-
function(DARE_HANDLER)
|
230 |
-
|
231 |
-
__mod_name__ = "FUN"
|
232 |
-
__command_list__ = [
|
233 |
-
"roll",
|
234 |
-
"toss",
|
235 |
-
"shrug",
|
236 |
-
"bluetext",
|
237 |
-
"rlg",
|
238 |
-
"decide",
|
239 |
-
"cosplay",
|
240 |
-
"weebify",
|
241 |
-
"flirt",
|
242 |
-
"truth",
|
243 |
-
"dare",
|
244 |
-
]
|
245 |
-
__handlers__ = [
|
246 |
-
ROLL_HANDLER,
|
247 |
-
TOSS_HANDLER,
|
248 |
-
SHRUG_HANDLER,
|
249 |
-
BLUETEXT_HANDLER,
|
250 |
-
RLG_HANDLER,
|
251 |
-
DECIDE_HANDLER,
|
252 |
-
WEEBIFY_HANDLER,
|
253 |
-
FLIRT_HANDLER,
|
254 |
-
TRUTH_HANDLER,
|
255 |
-
DARE_HANDLER,
|
256 |
-
]
|
257 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/gban.py
DELETED
@@ -1,544 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import html
|
3 |
-
import time
|
4 |
-
from datetime import datetime
|
5 |
-
from io import BytesIO
|
6 |
-
|
7 |
-
from telegram import ChatMemberAdministrator, Update
|
8 |
-
from telegram.constants import ParseMode
|
9 |
-
from telegram.error import BadRequest, Forbidden, TelegramError
|
10 |
-
from telegram.ext import CommandHandler, ContextTypes, MessageHandler, filters
|
11 |
-
from telegram.helpers import mention_html
|
12 |
-
|
13 |
-
import Database.sql.global_bans_sql as sql
|
14 |
-
from Database.sql.users_sql import get_user_com_chats
|
15 |
-
from Mikobot import (
|
16 |
-
DEV_USERS,
|
17 |
-
DRAGONS,
|
18 |
-
EVENT_LOGS,
|
19 |
-
OWNER_ID,
|
20 |
-
STRICT_GBAN,
|
21 |
-
SUPPORT_CHAT,
|
22 |
-
dispatcher,
|
23 |
-
function,
|
24 |
-
)
|
25 |
-
from Mikobot.plugins.helper_funcs.chat_status import (
|
26 |
-
check_admin,
|
27 |
-
is_user_admin,
|
28 |
-
support_plus,
|
29 |
-
)
|
30 |
-
from Mikobot.plugins.helper_funcs.extraction import extract_user, extract_user_and_text
|
31 |
-
from Mikobot.plugins.helper_funcs.misc import send_to_list
|
32 |
-
|
33 |
-
# <=======================================================================================================>
|
34 |
-
|
35 |
-
GBAN_ENFORCE_GROUP = 6
|
36 |
-
|
37 |
-
GBAN_ERRORS = {
|
38 |
-
"User is an administrator of the chat",
|
39 |
-
"Chat not found",
|
40 |
-
"Not enough rights to restrict/unrestrict chat member",
|
41 |
-
"User_not_participant",
|
42 |
-
"Peer_id_invalid",
|
43 |
-
"Group chat was deactivated",
|
44 |
-
"Need to be inviter of a user to kick it from a basic group",
|
45 |
-
"Chat_admin_required",
|
46 |
-
"Only the creator of a basic group can kick group administrators",
|
47 |
-
"Channel_private",
|
48 |
-
"Not in the chat",
|
49 |
-
"Can't remove chat owner",
|
50 |
-
}
|
51 |
-
|
52 |
-
UNGBAN_ERRORS = {
|
53 |
-
"User is an administrator of the chat",
|
54 |
-
"Chat not found",
|
55 |
-
"Not enough rights to restrict/unrestrict chat member",
|
56 |
-
"User_not_participant",
|
57 |
-
"Method is available for supergroup and channel chats only",
|
58 |
-
"Not in the chat",
|
59 |
-
"Channel_private",
|
60 |
-
"Chat_admin_required",
|
61 |
-
"Peer_id_invalid",
|
62 |
-
"User not found",
|
63 |
-
}
|
64 |
-
|
65 |
-
|
66 |
-
# <================================================ FUNCTION =======================================================>
|
67 |
-
@support_plus
|
68 |
-
async def gban(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
69 |
-
bot, args = context.bot, context.args
|
70 |
-
message = update.effective_message
|
71 |
-
user = update.effective_user
|
72 |
-
chat = update.effective_chat
|
73 |
-
log_message = ""
|
74 |
-
|
75 |
-
user_id, reason = await extract_user_and_text(message, context, args)
|
76 |
-
|
77 |
-
if not user_id:
|
78 |
-
await message.reply_text(
|
79 |
-
"You don't seem to be referring to a user or the ID specified is incorrect..",
|
80 |
-
)
|
81 |
-
return
|
82 |
-
|
83 |
-
if int(user_id) in DEV_USERS:
|
84 |
-
await message.reply_text(
|
85 |
-
"That user is part of the Association\nI can't act against our own.",
|
86 |
-
)
|
87 |
-
return
|
88 |
-
|
89 |
-
if int(user_id) in DRAGONS:
|
90 |
-
await message.reply_text(
|
91 |
-
"I spy, with my little eye... a disaster! Why are you guys turning on each other?",
|
92 |
-
)
|
93 |
-
return
|
94 |
-
|
95 |
-
if user_id == bot.id:
|
96 |
-
await message.reply_text("You uhh...want me to kick myself?")
|
97 |
-
return
|
98 |
-
|
99 |
-
if user_id in [777000, 1087968824]:
|
100 |
-
await message.reply_text("Fool! You can't attack Telegram's native tech!")
|
101 |
-
return
|
102 |
-
|
103 |
-
try:
|
104 |
-
user_chat = await bot.get_chat(user_id)
|
105 |
-
except BadRequest as excp:
|
106 |
-
if excp.message == "User not found":
|
107 |
-
await message.reply_text("I can't seem to find this user.")
|
108 |
-
return ""
|
109 |
-
else:
|
110 |
-
return
|
111 |
-
|
112 |
-
if user_chat.type != "private":
|
113 |
-
await message.reply_text("That's not a user!")
|
114 |
-
return
|
115 |
-
|
116 |
-
if sql.is_user_gbanned(user_id):
|
117 |
-
if not reason:
|
118 |
-
await message.reply_text(
|
119 |
-
"This user is already gbanned; I'd change the reason, but you haven't given me one...",
|
120 |
-
)
|
121 |
-
return
|
122 |
-
|
123 |
-
old_reason = sql.update_gban_reason(
|
124 |
-
user_id,
|
125 |
-
user_chat.username or user_chat.first_name,
|
126 |
-
reason,
|
127 |
-
)
|
128 |
-
if old_reason:
|
129 |
-
await message.reply_text(
|
130 |
-
"This user is already gbanned, for the following reason:\n"
|
131 |
-
"<code>{}</code>\n"
|
132 |
-
"I've gone and updated it with your new reason!".format(
|
133 |
-
html.escape(old_reason),
|
134 |
-
),
|
135 |
-
parse_mode=ParseMode.HTML,
|
136 |
-
)
|
137 |
-
|
138 |
-
else:
|
139 |
-
await message.reply_text(
|
140 |
-
"This user is already gbanned, but had no reason set; I've gone and updated it!",
|
141 |
-
)
|
142 |
-
|
143 |
-
return
|
144 |
-
|
145 |
-
await message.reply_text("On it!")
|
146 |
-
|
147 |
-
start_time = time.time()
|
148 |
-
datetime_fmt = "%Y-%m-%dT%H:%M"
|
149 |
-
current_time = datetime.utcnow().strftime(datetime_fmt)
|
150 |
-
|
151 |
-
if chat.type != "private":
|
152 |
-
chat_origin = "<b>{} ({})</b>\n".format(html.escape(chat.title), chat.id)
|
153 |
-
else:
|
154 |
-
chat_origin = "<b>{}</b>\n".format(chat.id)
|
155 |
-
|
156 |
-
log_message = (
|
157 |
-
f"#GBANNED\n"
|
158 |
-
f"<b>Originated from:</b> <code>{chat_origin}</code>\n"
|
159 |
-
f"<b>Admin:</b> {mention_html(user.id, user.first_name)}\n"
|
160 |
-
f"<b>Banned User:</b> {mention_html(user_chat.id, user_chat.first_name)}\n"
|
161 |
-
f"<b>Banned User ID:</b> <code>{user_chat.id}</code>\n"
|
162 |
-
f"<b>Event Stamp:</b> <code>{current_time}</code>"
|
163 |
-
)
|
164 |
-
|
165 |
-
if reason:
|
166 |
-
if chat.type == chat.SUPERGROUP and chat.username:
|
167 |
-
log_message += f'\n<b>Reason:</b> <a href="https://telegram.me/{chat.username}/{message.message_id}">{reason}</a>'
|
168 |
-
else:
|
169 |
-
log_message += f"\n<b>Reason:</b> <code>{reason}</code>"
|
170 |
-
|
171 |
-
if EVENT_LOGS:
|
172 |
-
try:
|
173 |
-
log = await bot.send_message(
|
174 |
-
EVENT_LOGS, log_message, parse_mode=ParseMode.HTML
|
175 |
-
)
|
176 |
-
except BadRequest as excp:
|
177 |
-
log = await bot.send_message(
|
178 |
-
EVENT_LOGS,
|
179 |
-
log_message
|
180 |
-
+ "\n\nFormatting has been disabled due to an unexpected error.",
|
181 |
-
)
|
182 |
-
|
183 |
-
else:
|
184 |
-
send_to_list(bot, DRAGONS, log_message, html=True)
|
185 |
-
|
186 |
-
sql.gban_user(user_id, user_chat.username or user_chat.first_name, reason)
|
187 |
-
|
188 |
-
chats = get_user_com_chats(user_id)
|
189 |
-
gbanned_chats = 0
|
190 |
-
|
191 |
-
for chat in chats:
|
192 |
-
chat_id = int(chat)
|
193 |
-
|
194 |
-
# Check if this group has disabled gbans
|
195 |
-
if not sql.does_chat_gban(chat_id):
|
196 |
-
continue
|
197 |
-
|
198 |
-
try:
|
199 |
-
await bot.ban_chat_member(chat_id, user_id)
|
200 |
-
gbanned_chats += 1
|
201 |
-
|
202 |
-
except BadRequest as excp:
|
203 |
-
if excp.message in GBAN_ERRORS:
|
204 |
-
pass
|
205 |
-
else:
|
206 |
-
await message.reply_text(f"Could not gban due to: {excp.message}")
|
207 |
-
if EVENT_LOGS:
|
208 |
-
await bot.send_message(
|
209 |
-
EVENT_LOGS,
|
210 |
-
f"Could not gban due to {excp.message}",
|
211 |
-
parse_mode=ParseMode.HTML,
|
212 |
-
)
|
213 |
-
else:
|
214 |
-
send_to_list(
|
215 |
-
bot,
|
216 |
-
DRAGONS,
|
217 |
-
f"Could not gban due to: {excp.message}",
|
218 |
-
)
|
219 |
-
sql.ungban_user(user_id)
|
220 |
-
return
|
221 |
-
except TelegramError:
|
222 |
-
pass
|
223 |
-
|
224 |
-
if EVENT_LOGS:
|
225 |
-
await log.edit_text(
|
226 |
-
log_message + f"\n<b>Chats affected:</b> <code>{gbanned_chats}</code>",
|
227 |
-
parse_mode=ParseMode.HTML,
|
228 |
-
)
|
229 |
-
else:
|
230 |
-
send_to_list(
|
231 |
-
bot,
|
232 |
-
DRAGONS,
|
233 |
-
f"Gban complete! (User banned in <code>{gbanned_chats}</code> chats)",
|
234 |
-
html=True,
|
235 |
-
)
|
236 |
-
|
237 |
-
end_time = time.time()
|
238 |
-
gban_time = round((end_time - start_time), 2)
|
239 |
-
|
240 |
-
if gban_time > 60:
|
241 |
-
gban_time = round((gban_time / 60), 2)
|
242 |
-
await message.reply_text("Done! Gbanned.", parse_mode=ParseMode.HTML)
|
243 |
-
else:
|
244 |
-
await message.reply_text("Done! Gbanned.", parse_mode=ParseMode.HTML)
|
245 |
-
|
246 |
-
try:
|
247 |
-
await bot.send_message(
|
248 |
-
user_id,
|
249 |
-
"#EVENT"
|
250 |
-
"You have been marked as Malicious and as such have been banned from any future groups we manage."
|
251 |
-
f"\n<b>Reason:</b> <code>{html.escape(user.reason)}</code>"
|
252 |
-
f"</b>Appeal Chat:</b> @{SUPPORT_CHAT}",
|
253 |
-
parse_mode=ParseMode.HTML,
|
254 |
-
)
|
255 |
-
except:
|
256 |
-
pass # bot probably blocked by user
|
257 |
-
|
258 |
-
|
259 |
-
@support_plus
|
260 |
-
async def ungban(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
261 |
-
bot, args = context.bot, context.args
|
262 |
-
message = update.effective_message
|
263 |
-
user = update.effective_user
|
264 |
-
chat = update.effective_chat
|
265 |
-
log_message = ""
|
266 |
-
|
267 |
-
user_id = await extract_user(message, context, args)
|
268 |
-
|
269 |
-
if not user_id:
|
270 |
-
await message.reply_text(
|
271 |
-
"You don't seem to be referring to a user or the ID specified is incorrect..",
|
272 |
-
)
|
273 |
-
return
|
274 |
-
|
275 |
-
user_chat = await bot.get_chat(user_id)
|
276 |
-
if user_chat.type != "private":
|
277 |
-
await message.reply_text("That's not a user!")
|
278 |
-
return
|
279 |
-
|
280 |
-
if not sql.is_user_gbanned(user_id):
|
281 |
-
await message.reply_text("This user is not gbanned!")
|
282 |
-
return
|
283 |
-
|
284 |
-
await message.reply_text(
|
285 |
-
f"I'll give {user_chat.first_name} a second chance, globally."
|
286 |
-
)
|
287 |
-
|
288 |
-
start_time = time.time()
|
289 |
-
datetime_fmt = "%Y-%m-%dT%H:%M"
|
290 |
-
current_time = datetime.utcnow().strftime(datetime_fmt)
|
291 |
-
|
292 |
-
if chat.type != "private":
|
293 |
-
chat_origin = f"<b>{html.escape(chat.title)} ({chat.id})</b>\n"
|
294 |
-
else:
|
295 |
-
chat_origin = f"<b>{chat.id}</b>\n"
|
296 |
-
|
297 |
-
log_message = (
|
298 |
-
f"#UNGBANNED\n"
|
299 |
-
f"<b>Originated from:</b> <code>{chat_origin}</code>\n"
|
300 |
-
f"<b>Admin:</b> {mention_html(user.id, user.first_name)}\n"
|
301 |
-
f"<b>Unbanned User:</b> {mention_html(user_chat.id, user_chat.first_name)}\n"
|
302 |
-
f"<b>Unbanned User ID:</b> <code>{user_chat.id}</code>\n"
|
303 |
-
f"<b>Event Stamp:</b> <code>{current_time}</code>"
|
304 |
-
)
|
305 |
-
|
306 |
-
if EVENT_LOGS:
|
307 |
-
try:
|
308 |
-
log = await bot.send_message(
|
309 |
-
EVENT_LOGS, log_message, parse_mode=ParseMode.HTML
|
310 |
-
)
|
311 |
-
except BadRequest as excp:
|
312 |
-
log = await bot.send_message(
|
313 |
-
EVENT_LOGS,
|
314 |
-
log_message
|
315 |
-
+ "\n\nFormatting has been disabled due to an unexpected error.",
|
316 |
-
)
|
317 |
-
else:
|
318 |
-
send_to_list(bot, DRAGONS, log_message, html=True)
|
319 |
-
|
320 |
-
chats = get_user_com_chats(user_id)
|
321 |
-
ungbanned_chats = 0
|
322 |
-
|
323 |
-
for chat in chats:
|
324 |
-
chat_id = int(chat)
|
325 |
-
|
326 |
-
# Check if this group has disabled gbans
|
327 |
-
if not sql.does_chat_gban(chat_id):
|
328 |
-
continue
|
329 |
-
|
330 |
-
try:
|
331 |
-
member = await bot.get_chat_member(chat_id, user_id)
|
332 |
-
if member.status == "kicked":
|
333 |
-
await bot.unban_chat_member(chat_id, user_id)
|
334 |
-
ungbanned_chats += 1
|
335 |
-
|
336 |
-
except BadRequest as excp:
|
337 |
-
if excp.message in UNGBAN_ERRORS:
|
338 |
-
pass
|
339 |
-
else:
|
340 |
-
await message.reply_text(f"Could not un-gban due to: {excp.message}")
|
341 |
-
if EVENT_LOGS:
|
342 |
-
await bot.send_message(
|
343 |
-
EVENT_LOGS,
|
344 |
-
f"Could not un-gban due to: {excp.message}",
|
345 |
-
parse_mode=ParseMode.HTML,
|
346 |
-
)
|
347 |
-
else:
|
348 |
-
await bot.send_message(
|
349 |
-
OWNER_ID,
|
350 |
-
f"Could not un-gban due to: {excp.message}",
|
351 |
-
)
|
352 |
-
return
|
353 |
-
except TelegramError:
|
354 |
-
pass
|
355 |
-
|
356 |
-
sql.ungban_user(user_id)
|
357 |
-
|
358 |
-
if EVENT_LOGS:
|
359 |
-
await log.edit_text(
|
360 |
-
log_message + f"\n<b>Chats affected:</b> {ungbanned_chats}",
|
361 |
-
parse_mode=ParseMode.HTML,
|
362 |
-
)
|
363 |
-
else:
|
364 |
-
send_to_list(bot, DRAGONS, "un-gban complete!")
|
365 |
-
|
366 |
-
end_time = time.time()
|
367 |
-
ungban_time = round((end_time - start_time), 2)
|
368 |
-
|
369 |
-
if ungban_time > 60:
|
370 |
-
ungban_time = round((ungban_time / 60), 2)
|
371 |
-
await message.reply_text(f"Person has been un-gbanned. Took {ungban_time} min")
|
372 |
-
else:
|
373 |
-
await message.reply_text(f"Person has been un-gbanned. Took {ungban_time} sec")
|
374 |
-
|
375 |
-
|
376 |
-
@support_plus
|
377 |
-
async def gbanlist(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
378 |
-
banned_users = sql.get_gban_list()
|
379 |
-
|
380 |
-
if not banned_users:
|
381 |
-
await update.effective_message.reply_text(
|
382 |
-
"There aren't any gbanned users! You're kinder than I expected...",
|
383 |
-
)
|
384 |
-
return
|
385 |
-
|
386 |
-
banfile = "Screw these guys.\n"
|
387 |
-
for user in banned_users:
|
388 |
-
banfile += f"[x] {user['name']} - {user['user_id']}\n"
|
389 |
-
if user["reason"]:
|
390 |
-
banfile += f"Reason: {user['reason']}\n"
|
391 |
-
|
392 |
-
with BytesIO(str.encode(banfile)) as output:
|
393 |
-
output.name = "gbanlist.txt"
|
394 |
-
await update.effective_message.reply_document(
|
395 |
-
document=output,
|
396 |
-
filename="gbanlist.txt",
|
397 |
-
caption="Here is the list of currently gbanned users.",
|
398 |
-
)
|
399 |
-
|
400 |
-
|
401 |
-
async def check_and_ban(update, user_id, should_message=True):
|
402 |
-
if sql.is_user_gbanned(user_id):
|
403 |
-
await update.effective_chat.ban_member(user_id)
|
404 |
-
if should_message:
|
405 |
-
text = (
|
406 |
-
f"<b>Alert</b>: this user is globally banned.\n"
|
407 |
-
f"<code>*bans them from here*</code>.\n"
|
408 |
-
f"<b>Appeal chat</b>: @{SUPPORT_CHAT}\n"
|
409 |
-
f"<b>User ID</b>: <code>{user_id}</code>"
|
410 |
-
)
|
411 |
-
user = sql.get_gbanned_user(user_id)
|
412 |
-
if user.reason:
|
413 |
-
text += f"\n<b>Ban Reason:</b> <code>{html.escape(user.reason)}</code>"
|
414 |
-
await update.effective_message.reply_text(text, parse_mode=ParseMode.HTML)
|
415 |
-
|
416 |
-
|
417 |
-
async def enforce_gban(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
418 |
-
# Not using @restrict handler to avoid spamming - just ignore if cant gban.
|
419 |
-
bot = context.bot
|
420 |
-
try:
|
421 |
-
get_member = await update.effective_chat.get_member(
|
422 |
-
bot.id,
|
423 |
-
)
|
424 |
-
if isinstance(get_member, ChatMemberAdministrator):
|
425 |
-
restrict_permission = get_member.can_restrict_members
|
426 |
-
else:
|
427 |
-
return
|
428 |
-
except Forbidden:
|
429 |
-
return
|
430 |
-
if sql.does_chat_gban(update.effective_chat.id) and restrict_permission:
|
431 |
-
user = update.effective_user
|
432 |
-
chat = update.effective_chat
|
433 |
-
msg = update.effective_message
|
434 |
-
|
435 |
-
if user and not await is_user_admin(chat, user.id):
|
436 |
-
await check_and_ban(update, user.id)
|
437 |
-
return
|
438 |
-
|
439 |
-
if msg.new_chat_members:
|
440 |
-
new_members = update.effective_message.new_chat_members
|
441 |
-
for mem in new_members:
|
442 |
-
await check_and_ban(update, mem.id)
|
443 |
-
|
444 |
-
if msg.reply_to_message:
|
445 |
-
user = msg.reply_to_message.from_user
|
446 |
-
if user and not await is_user_admin(chat, user.id):
|
447 |
-
await check_and_ban(update, user.id, should_message=False)
|
448 |
-
|
449 |
-
|
450 |
-
@check_admin(is_user=True)
|
451 |
-
async def gbanstat(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
452 |
-
args = context.args
|
453 |
-
if len(args) > 0:
|
454 |
-
if args[0].lower() in ["on", "yes"]:
|
455 |
-
sql.enable_gbans(update.effective_chat.id)
|
456 |
-
await update.effective_message.reply_text(
|
457 |
-
"Antispam is now enabled ✅ "
|
458 |
-
"I am now protecting your group from potential remote threats!",
|
459 |
-
)
|
460 |
-
elif args[0].lower() in ["off", "no"]:
|
461 |
-
sql.disable_gbans(update.effective_chat.id)
|
462 |
-
await update.effective_message.reply_text(
|
463 |
-
"I am not now protecting your group from potential remote threats!",
|
464 |
-
)
|
465 |
-
else:
|
466 |
-
await update.effective_message.reply_text(
|
467 |
-
"Give me some arguments to choose a setting! on/off, yes/no!\n\n"
|
468 |
-
"Your current setting is: {}\n"
|
469 |
-
"When True, any gbans that happen will also happen in your group. "
|
470 |
-
"When False, they won't, leaving you at the possible mercy of "
|
471 |
-
"spammers.".format(sql.does_chat_gban(update.effective_chat.id)),
|
472 |
-
)
|
473 |
-
|
474 |
-
|
475 |
-
def __stats__():
|
476 |
-
return f"• {sql.num_gbanned_users()} gbanned users."
|
477 |
-
|
478 |
-
|
479 |
-
def __user_info__(user_id):
|
480 |
-
is_gbanned = sql.is_user_gbanned(user_id)
|
481 |
-
text = "Malicious: <b>{}</b>"
|
482 |
-
if user_id in [777000, 1087968824]:
|
483 |
-
return ""
|
484 |
-
if user_id == dispatcher.bot.id:
|
485 |
-
return ""
|
486 |
-
if int(user_id) in DRAGONS:
|
487 |
-
return ""
|
488 |
-
if is_gbanned:
|
489 |
-
text = text.format("Yes")
|
490 |
-
user = sql.get_gbanned_user(user_id)
|
491 |
-
if user.reason:
|
492 |
-
text += f"\n<b>Reason:</b> <code>{html.escape(user.reason)}</code>"
|
493 |
-
text += f"\n<b>Appeal Chat:</b> @{SUPPORT_CHAT}"
|
494 |
-
else:
|
495 |
-
text = text.format("???")
|
496 |
-
return text
|
497 |
-
|
498 |
-
|
499 |
-
def __migrate__(old_chat_id, new_chat_id):
|
500 |
-
sql.migrate_chat(old_chat_id, new_chat_id)
|
501 |
-
|
502 |
-
|
503 |
-
def __chat_settings__(chat_id, user_id):
|
504 |
-
return f"This chat is enforcing *gbans*: `{sql.does_chat_gban(chat_id)}`."
|
505 |
-
|
506 |
-
|
507 |
-
# <=================================================== HELP ====================================================>
|
508 |
-
|
509 |
-
|
510 |
-
__help__ = f"""
|
511 |
-
➠ *Admins only:*
|
512 |
-
|
513 |
-
» /antispam <on/off/yes/no>: Will toggle our antispam tech or return your current settings.
|
514 |
-
|
515 |
-
➠ Anti-Spam, used by bot devs to ban spammers across all groups. This helps protect \
|
516 |
-
you and your groups by removing spam flooders as quickly as possible.
|
517 |
-
➠ *Note:* Users can appeal gbans or report spammers at @hydraX2support
|
518 |
-
"""
|
519 |
-
|
520 |
-
# <================================================ HANDLER =======================================================>
|
521 |
-
GBAN_HANDLER = CommandHandler("gban", gban, block=False)
|
522 |
-
UNGBAN_HANDLER = CommandHandler("ungban", ungban, block=False)
|
523 |
-
GBAN_LIST = CommandHandler("gbanlist", gbanlist, block=False)
|
524 |
-
|
525 |
-
GBAN_STATUS = CommandHandler(
|
526 |
-
"antispam", gbanstat, filters=filters.ChatType.GROUPS, block=False
|
527 |
-
)
|
528 |
-
|
529 |
-
GBAN_ENFORCER = MessageHandler(
|
530 |
-
filters.ALL & filters.ChatType.GROUPS, enforce_gban, block=False
|
531 |
-
)
|
532 |
-
|
533 |
-
function(GBAN_HANDLER)
|
534 |
-
function(UNGBAN_HANDLER)
|
535 |
-
function(GBAN_LIST)
|
536 |
-
function(GBAN_STATUS)
|
537 |
-
|
538 |
-
__mod_name__ = "ANTI-SPAM"
|
539 |
-
__handlers__ = [GBAN_HANDLER, UNGBAN_HANDLER, GBAN_LIST, GBAN_STATUS]
|
540 |
-
|
541 |
-
if STRICT_GBAN: # enforce GBANS if this is set
|
542 |
-
function(GBAN_ENFORCER, GBAN_ENFORCE_GROUP)
|
543 |
-
__handlers__.append((GBAN_ENFORCER, GBAN_ENFORCE_GROUP))
|
544 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/helper_funcs/alternate.py
DELETED
@@ -1,85 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from functools import wraps
|
3 |
-
|
4 |
-
from telegram import Message, Update
|
5 |
-
from telegram.constants import ChatAction
|
6 |
-
from telegram.error import BadRequest
|
7 |
-
from telegram.ext import ContextTypes
|
8 |
-
|
9 |
-
# <=======================================================================================================>
|
10 |
-
|
11 |
-
|
12 |
-
# <================================================ FUNCTION =======================================================>
|
13 |
-
async def send_message(message: Message, text, *args, **kwargs):
|
14 |
-
try:
|
15 |
-
return await message.reply_text(text, *args, **kwargs)
|
16 |
-
except BadRequest as err:
|
17 |
-
if str(err) == "Reply message not found":
|
18 |
-
return await message.reply_text(text, quote=False, *args, **kwargs)
|
19 |
-
|
20 |
-
|
21 |
-
def typing_action(func):
|
22 |
-
"""Sends typing action while processing func command."""
|
23 |
-
|
24 |
-
@wraps(func)
|
25 |
-
async def command_func(
|
26 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
27 |
-
):
|
28 |
-
await context.bot.send_chat_action(
|
29 |
-
chat_id=update.effective_chat.id,
|
30 |
-
action=ChatAction.TYPING,
|
31 |
-
)
|
32 |
-
return await func(update, context, *args, **kwargs)
|
33 |
-
|
34 |
-
return command_func
|
35 |
-
|
36 |
-
|
37 |
-
def sticker_action(func):
|
38 |
-
"""Sends typing action while processing func command."""
|
39 |
-
|
40 |
-
@wraps(func)
|
41 |
-
async def command_func(
|
42 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
43 |
-
):
|
44 |
-
await context.bot.send_chat_action(
|
45 |
-
chat_id=update.effective_chat.id,
|
46 |
-
action=ChatAction.CHOOSE_STICKER,
|
47 |
-
)
|
48 |
-
return await func(update, context, *args, **kwargs)
|
49 |
-
|
50 |
-
return command_func
|
51 |
-
|
52 |
-
|
53 |
-
def document_action(func):
|
54 |
-
"""Sends typing action while processing func command."""
|
55 |
-
|
56 |
-
@wraps(func)
|
57 |
-
async def command_func(
|
58 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
59 |
-
):
|
60 |
-
await context.bot.send_chat_action(
|
61 |
-
chat_id=update.effective_chat.id,
|
62 |
-
action=ChatAction.UPLOAD_DOCUMENT,
|
63 |
-
)
|
64 |
-
return await func(update, context, *args, **kwargs)
|
65 |
-
|
66 |
-
return command_func
|
67 |
-
|
68 |
-
|
69 |
-
def photo_action(func):
|
70 |
-
"""Sends typing action while processing func command."""
|
71 |
-
|
72 |
-
@wraps(func)
|
73 |
-
async def command_func(
|
74 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
75 |
-
):
|
76 |
-
await context.bot.send_chat_action(
|
77 |
-
chat_id=update.effective_chat.id,
|
78 |
-
action=ChatAction.UPLOAD_PHOTO,
|
79 |
-
)
|
80 |
-
return await func(update, context, *args, **kwargs)
|
81 |
-
|
82 |
-
return command_func
|
83 |
-
|
84 |
-
|
85 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/helper_funcs/chat_status.py
DELETED
@@ -1,415 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from functools import wraps
|
3 |
-
from threading import RLock
|
4 |
-
from time import perf_counter
|
5 |
-
|
6 |
-
from cachetools import TTLCache
|
7 |
-
from telegram import Chat, ChatMember, ChatMemberAdministrator, ChatMemberOwner, Update
|
8 |
-
from telegram.constants import ChatMemberStatus, ChatType
|
9 |
-
from telegram.error import Forbidden
|
10 |
-
from telegram.ext import ContextTypes
|
11 |
-
|
12 |
-
from Mikobot import DEL_CMDS, DEV_USERS, DRAGONS, SUPPORT_CHAT, dispatcher
|
13 |
-
|
14 |
-
# <=======================================================================================================>
|
15 |
-
|
16 |
-
# stores admemes in memory for 10 min.
|
17 |
-
ADMIN_CACHE = TTLCache(maxsize=512, ttl=60 * 10, timer=perf_counter)
|
18 |
-
THREAD_LOCK = RLock()
|
19 |
-
|
20 |
-
|
21 |
-
# <================================================ FUNCTION =======================================================>
|
22 |
-
def check_admin(
|
23 |
-
permission: str = None,
|
24 |
-
is_bot: bool = False,
|
25 |
-
is_user: bool = False,
|
26 |
-
is_both: bool = False,
|
27 |
-
only_owner: bool = False,
|
28 |
-
only_sudo: bool = False,
|
29 |
-
only_dev: bool = False,
|
30 |
-
no_reply: object = False,
|
31 |
-
) -> object:
|
32 |
-
"""Check for permission level to perform some operations
|
33 |
-
|
34 |
-
Args:
|
35 |
-
permission (str, optional): permission type to check. Defaults to None.
|
36 |
-
is_bot (bool, optional): if bot can perform the action. Defaults to False.
|
37 |
-
is_user (bool, optional): if user can perform the action. Defaults to False.
|
38 |
-
is_both (bool, optional): if both user and bot can perform the action. Defaults to False.
|
39 |
-
only_owner (bool, optional): if only owner can perform the action. Defaults to False.
|
40 |
-
only_sudo (bool, optional): if only sudo users can perform the operation. Defaults to False.
|
41 |
-
only_dev (bool, optional): if only dev users can perform the operation. Defaults to False.
|
42 |
-
no_reply (boot, optional): if should not reply. Defaults to False.
|
43 |
-
"""
|
44 |
-
|
45 |
-
def wrapper(func):
|
46 |
-
@wraps(func)
|
47 |
-
async def wrapped(
|
48 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
49 |
-
):
|
50 |
-
nonlocal permission
|
51 |
-
chat = update.effective_chat
|
52 |
-
user = update.effective_user
|
53 |
-
message = update.effective_message
|
54 |
-
|
55 |
-
if chat.type == ChatType.PRIVATE and not (
|
56 |
-
only_dev or only_sudo or only_owner
|
57 |
-
):
|
58 |
-
return await func(update, context, *args, **kwargs)
|
59 |
-
|
60 |
-
bot_member = (
|
61 |
-
await chat.get_member(context.bot.id) if is_bot or is_both else None
|
62 |
-
)
|
63 |
-
user_member = await chat.get_member(user.id) if is_user or is_both else None
|
64 |
-
|
65 |
-
if only_owner:
|
66 |
-
if isinstance(user_member, ChatMemberOwner) or user.id in DEV_USERS:
|
67 |
-
return await func(update, context, *args, **kwargs)
|
68 |
-
else:
|
69 |
-
return await message.reply_text(
|
70 |
-
"Only chat owner can perform this action."
|
71 |
-
)
|
72 |
-
if only_dev:
|
73 |
-
if user.id in DEV_USERS:
|
74 |
-
return await func(update, context, *args, **kwargs)
|
75 |
-
else:
|
76 |
-
return await update.effective_message.reply_text(
|
77 |
-
"Hey little kid"
|
78 |
-
"\nWho the hell are you to say me what to execute on my server?",
|
79 |
-
)
|
80 |
-
|
81 |
-
if only_sudo:
|
82 |
-
if user.id in DRAGONS:
|
83 |
-
return await func(update, context, *args, **kwargs)
|
84 |
-
else:
|
85 |
-
return await update.effective_message.reply_text(
|
86 |
-
"Who the hell are you to say me what to do?",
|
87 |
-
)
|
88 |
-
|
89 |
-
if message.from_user.id == 1087968824:
|
90 |
-
return await func(update, context, *args, **kwargs)
|
91 |
-
|
92 |
-
if permission:
|
93 |
-
no_permission = permission.replace("_", " ").replace("can", "")
|
94 |
-
if is_bot:
|
95 |
-
if (
|
96 |
-
getattr(bot_member, permission)
|
97 |
-
if isinstance(bot_member, ChatMemberAdministrator)
|
98 |
-
else False
|
99 |
-
):
|
100 |
-
return await func(update, context, *args, **kwargs)
|
101 |
-
elif no_reply:
|
102 |
-
return
|
103 |
-
else:
|
104 |
-
return await message.reply_text(
|
105 |
-
f"I don't have permission to {no_permission}."
|
106 |
-
)
|
107 |
-
if is_user:
|
108 |
-
if isinstance(user_member, ChatMemberOwner):
|
109 |
-
return await func(update, context, *args, **kwargs)
|
110 |
-
elif (
|
111 |
-
getattr(user_member, permission)
|
112 |
-
if isinstance(user_member, ChatMemberAdministrator)
|
113 |
-
else False or user.id in DRAGONS
|
114 |
-
):
|
115 |
-
return await func(update, context, *args, **kwargs)
|
116 |
-
elif no_reply:
|
117 |
-
return
|
118 |
-
else:
|
119 |
-
return await message.reply_text(
|
120 |
-
f"You don't have permission to {no_permission}."
|
121 |
-
)
|
122 |
-
if is_both:
|
123 |
-
if (
|
124 |
-
getattr(bot_member, permission)
|
125 |
-
if isinstance(bot_member, ChatMemberAdministrator)
|
126 |
-
else False
|
127 |
-
):
|
128 |
-
pass
|
129 |
-
elif no_reply:
|
130 |
-
return
|
131 |
-
else:
|
132 |
-
return await message.reply_text(
|
133 |
-
f"I don't have permission to {no_permission}."
|
134 |
-
)
|
135 |
-
|
136 |
-
if isinstance(user_member, ChatMemberOwner) or user.id in DEV_USERS:
|
137 |
-
pass
|
138 |
-
elif (
|
139 |
-
getattr(user_member, permission)
|
140 |
-
if isinstance(user_member, ChatMemberAdministrator)
|
141 |
-
else False or user.id in DRAGONS
|
142 |
-
):
|
143 |
-
pass
|
144 |
-
elif no_reply:
|
145 |
-
return
|
146 |
-
else:
|
147 |
-
return await message.reply_text(
|
148 |
-
f"You don't have permission to {no_permission}."
|
149 |
-
)
|
150 |
-
return await func(update, context, *args, **kwargs)
|
151 |
-
else:
|
152 |
-
if is_bot:
|
153 |
-
if bot_member.status == ChatMemberStatus.ADMINISTRATOR:
|
154 |
-
return await func(update, context, *args, **kwargs)
|
155 |
-
else:
|
156 |
-
return await message.reply_text("I'm not admin here.")
|
157 |
-
elif is_user:
|
158 |
-
if user_member.status in [
|
159 |
-
ChatMemberStatus.ADMINISTRATOR,
|
160 |
-
ChatMemberStatus.OWNER,
|
161 |
-
]:
|
162 |
-
return await func(update, context, *args, **kwargs)
|
163 |
-
elif user.id in DRAGONS:
|
164 |
-
return await func(update, context, *args, **kwargs)
|
165 |
-
else:
|
166 |
-
return await message.reply_text("You are not admin here.")
|
167 |
-
elif is_both:
|
168 |
-
if bot_member.status == ChatMemberStatus.ADMINISTRATOR:
|
169 |
-
pass
|
170 |
-
else:
|
171 |
-
return await message.reply_text("I'm not admin here.")
|
172 |
-
|
173 |
-
if user_member.status in [
|
174 |
-
ChatMemberStatus.ADMINISTRATOR,
|
175 |
-
ChatMemberStatus.OWNER,
|
176 |
-
]:
|
177 |
-
pass
|
178 |
-
elif user.id in DRAGONS:
|
179 |
-
pass
|
180 |
-
else:
|
181 |
-
return await message.reply_text("You are not admin here.")
|
182 |
-
return await func(update, context, *args, **kwargs)
|
183 |
-
|
184 |
-
return wrapped
|
185 |
-
|
186 |
-
return wrapper
|
187 |
-
|
188 |
-
|
189 |
-
def is_whitelist_plus(chat: Chat, user_id: int, member: ChatMember = None) -> bool:
|
190 |
-
return any(user_id in user for user in [DRAGONS, DEV_USERS])
|
191 |
-
|
192 |
-
|
193 |
-
def is_support_plus(chat: Chat, user_id: int, member: ChatMember = None) -> bool:
|
194 |
-
return user_id in DRAGONS or user_id in DEV_USERS
|
195 |
-
|
196 |
-
|
197 |
-
def is_sudo_plus(chat: Chat, user_id: int, member: ChatMember = None) -> bool:
|
198 |
-
return user_id in DRAGONS or user_id in DEV_USERS
|
199 |
-
|
200 |
-
|
201 |
-
async def is_user_admin(chat: Chat, user_id: int, member: ChatMember = None) -> bool:
|
202 |
-
if (
|
203 |
-
chat.type == "private"
|
204 |
-
or user_id in DRAGONS
|
205 |
-
or user_id in DEV_USERS
|
206 |
-
or user_id in [777000, 1087968824]
|
207 |
-
): # Count telegram and Group Anonymous as admin
|
208 |
-
return True
|
209 |
-
if not member:
|
210 |
-
with THREAD_LOCK:
|
211 |
-
# try to fetch from cache first.
|
212 |
-
try:
|
213 |
-
return user_id in ADMIN_CACHE[chat.id]
|
214 |
-
except KeyError:
|
215 |
-
# keyerror happend means cache is deleted,
|
216 |
-
# so query bot api again and return user status
|
217 |
-
# while saving it in cache for future usage...
|
218 |
-
try:
|
219 |
-
chat_admins = await dispatcher.bot.getChatAdministrators(chat.id)
|
220 |
-
except Forbidden:
|
221 |
-
return False
|
222 |
-
admin_list = [x.user.id for x in chat_admins]
|
223 |
-
ADMIN_CACHE[chat.id] = admin_list
|
224 |
-
|
225 |
-
return user_id in admin_list
|
226 |
-
else:
|
227 |
-
return member.status in (ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER)
|
228 |
-
|
229 |
-
|
230 |
-
async def is_bot_admin(chat: Chat, bot_id: int, bot_member: ChatMember = None) -> bool:
|
231 |
-
if chat.type == "private":
|
232 |
-
return True
|
233 |
-
|
234 |
-
if not bot_member:
|
235 |
-
bot_member = await chat.get_member(bot_id)
|
236 |
-
|
237 |
-
return bot_member.status in (ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER)
|
238 |
-
|
239 |
-
|
240 |
-
async def can_delete(chat: Chat, bot_id: int) -> bool:
|
241 |
-
chat_member = await chat.get_member(bot_id)
|
242 |
-
if isinstance(chat_member, ChatMemberAdministrator):
|
243 |
-
return chat_member.can_delete_messages
|
244 |
-
|
245 |
-
|
246 |
-
async def is_user_ban_protected(
|
247 |
-
chat: Chat, user_id: int, member: ChatMember = None
|
248 |
-
) -> bool:
|
249 |
-
if (
|
250 |
-
chat.type == "private"
|
251 |
-
or user_id in DRAGONS
|
252 |
-
or user_id in DEV_USERS
|
253 |
-
or user_id in [777000, 1087968824]
|
254 |
-
): # Count telegram and Group Anonymous as admin
|
255 |
-
return True
|
256 |
-
|
257 |
-
if not member:
|
258 |
-
member = await chat.get_member(user_id)
|
259 |
-
|
260 |
-
return member.status in (ChatMemberStatus.ADMINISTRATOR, ChatMemberStatus.OWNER)
|
261 |
-
|
262 |
-
|
263 |
-
async def is_user_in_chat(chat: Chat, user_id: int) -> bool:
|
264 |
-
member = await chat.get_member(user_id)
|
265 |
-
return member.status in (ChatMemberStatus.LEFT, ChatMemberStatus.RESTRICTED)
|
266 |
-
|
267 |
-
|
268 |
-
def dev_plus(func):
|
269 |
-
@wraps(func)
|
270 |
-
def is_dev_plus_func(
|
271 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
272 |
-
):
|
273 |
-
context.bot
|
274 |
-
user = update.effective_user
|
275 |
-
|
276 |
-
if user.id in DEV_USERS:
|
277 |
-
return func(update, context, *args, **kwargs)
|
278 |
-
elif not user:
|
279 |
-
pass
|
280 |
-
elif DEL_CMDS and " " not in update.effective_message.text:
|
281 |
-
try:
|
282 |
-
update.effective_message.delete()
|
283 |
-
except:
|
284 |
-
pass
|
285 |
-
else:
|
286 |
-
update.effective_message.reply_text(
|
287 |
-
"This is a developer restricted command."
|
288 |
-
" You do not have permissions to run this."
|
289 |
-
)
|
290 |
-
|
291 |
-
return is_dev_plus_func
|
292 |
-
|
293 |
-
|
294 |
-
def sudo_plus(func):
|
295 |
-
@wraps(func)
|
296 |
-
def is_sudo_plus_func(
|
297 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
298 |
-
):
|
299 |
-
context.bot
|
300 |
-
user = update.effective_user
|
301 |
-
chat = update.effective_chat
|
302 |
-
|
303 |
-
if user and is_sudo_plus(chat, user.id):
|
304 |
-
return func(update, context, *args, **kwargs)
|
305 |
-
elif not user:
|
306 |
-
pass
|
307 |
-
elif DEL_CMDS and " " not in update.effective_message.text:
|
308 |
-
try:
|
309 |
-
update.effective_message.delete()
|
310 |
-
except:
|
311 |
-
pass
|
312 |
-
else:
|
313 |
-
update.effective_message.reply_text(
|
314 |
-
"Who dis non-admin telling me what to do? You want a punch?"
|
315 |
-
)
|
316 |
-
|
317 |
-
return is_sudo_plus_func
|
318 |
-
|
319 |
-
|
320 |
-
def support_plus(func):
|
321 |
-
@wraps(func)
|
322 |
-
async def is_support_plus_func(
|
323 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
324 |
-
):
|
325 |
-
bot = context.bot
|
326 |
-
user = update.effective_user
|
327 |
-
chat = update.effective_chat
|
328 |
-
|
329 |
-
if user and is_support_plus(chat, user.id):
|
330 |
-
return await func(update, context, *args, **kwargs)
|
331 |
-
elif DEL_CMDS and " " not in update.effective_message.text:
|
332 |
-
try:
|
333 |
-
await update.effective_message.delete()
|
334 |
-
except:
|
335 |
-
pass
|
336 |
-
|
337 |
-
return is_support_plus_func
|
338 |
-
|
339 |
-
|
340 |
-
def whitelist_plus(func):
|
341 |
-
@wraps(func)
|
342 |
-
async def is_whitelist_plus_func(
|
343 |
-
update: Update,
|
344 |
-
context: ContextTypes.DEFAULT_TYPE,
|
345 |
-
*args,
|
346 |
-
**kwargs,
|
347 |
-
):
|
348 |
-
bot = context.bot
|
349 |
-
user = update.effective_user
|
350 |
-
chat = update.effective_chat
|
351 |
-
|
352 |
-
if user and is_whitelist_plus(chat, user.id):
|
353 |
-
return await func(update, context, *args, **kwargs)
|
354 |
-
else:
|
355 |
-
await update.effective_message.reply_text(
|
356 |
-
f"You don't have access to use this.\nVisit @{SUPPORT_CHAT}",
|
357 |
-
)
|
358 |
-
|
359 |
-
return is_whitelist_plus_func
|
360 |
-
|
361 |
-
|
362 |
-
def user_not_admin(func):
|
363 |
-
@wraps(func)
|
364 |
-
async def is_not_admin(
|
365 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
366 |
-
):
|
367 |
-
bot = context.bot
|
368 |
-
user = update.effective_user
|
369 |
-
chat = update.effective_chat
|
370 |
-
|
371 |
-
if user and not await is_user_admin(chat, user.id):
|
372 |
-
return await func(update, context, *args, **kwargs)
|
373 |
-
elif not user:
|
374 |
-
pass
|
375 |
-
|
376 |
-
return is_not_admin
|
377 |
-
|
378 |
-
|
379 |
-
def connection_status(func):
|
380 |
-
@wraps(func)
|
381 |
-
async def connected_status(
|
382 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
383 |
-
):
|
384 |
-
conn = await connected(
|
385 |
-
context.bot,
|
386 |
-
update,
|
387 |
-
update.effective_chat,
|
388 |
-
update.effective_user.id,
|
389 |
-
need_admin=False,
|
390 |
-
)
|
391 |
-
|
392 |
-
if conn:
|
393 |
-
chat = await dispatcher.bot.getChat(conn)
|
394 |
-
update.__setattr__("_effective_chat", chat)
|
395 |
-
return await func(update, context, *args, **kwargs)
|
396 |
-
else:
|
397 |
-
if update.effective_message.chat.type == "private":
|
398 |
-
await update.effective_message.reply_text(
|
399 |
-
"Send /connect in a group that you and I have in common first.",
|
400 |
-
)
|
401 |
-
return connected_status
|
402 |
-
|
403 |
-
return await func(update, context, *args, **kwargs)
|
404 |
-
|
405 |
-
return connected_status
|
406 |
-
|
407 |
-
|
408 |
-
# <=======================================================================================================>
|
409 |
-
|
410 |
-
# <=======================================================================================================>
|
411 |
-
# Workaround for circular import with connection.py
|
412 |
-
from Mikobot.plugins import connection
|
413 |
-
|
414 |
-
connected = connection.connected
|
415 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/helper_funcs/extraction.py
DELETED
@@ -1,190 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from typing import List, Optional, Union
|
3 |
-
|
4 |
-
from telegram import Message, MessageEntity
|
5 |
-
from telegram.error import BadRequest
|
6 |
-
from telegram.ext import ContextTypes
|
7 |
-
|
8 |
-
from Mikobot import LOGGER
|
9 |
-
from Mikobot.plugins.users import get_user_id
|
10 |
-
|
11 |
-
# <=======================================================================================================>
|
12 |
-
|
13 |
-
|
14 |
-
# <================================================ FUNCTION =======================================================>
|
15 |
-
async def id_from_reply(message: Message):
|
16 |
-
prev_message = message.reply_to_message
|
17 |
-
if not prev_message or prev_message.forum_topic_created:
|
18 |
-
return None, None
|
19 |
-
user_id = prev_message.from_user.id
|
20 |
-
# if user id is from channel bot, then fetch channel id from sender_chat
|
21 |
-
if user_id == 136817688:
|
22 |
-
user_id = message.reply_to_message.sender_chat.id
|
23 |
-
res = message.text.split(None, 1)
|
24 |
-
if len(res) < 2:
|
25 |
-
return user_id, ""
|
26 |
-
return user_id, res[1]
|
27 |
-
|
28 |
-
|
29 |
-
async def extract_user(
|
30 |
-
message: Message,
|
31 |
-
context: ContextTypes.DEFAULT_TYPE,
|
32 |
-
args: List[str],
|
33 |
-
) -> Optional[int]:
|
34 |
-
return (await extract_user_and_text(message, context, args))[0]
|
35 |
-
|
36 |
-
|
37 |
-
async def extract_user_and_text(
|
38 |
-
message: Message,
|
39 |
-
context: ContextTypes.DEFAULT_TYPE,
|
40 |
-
args: List[str],
|
41 |
-
) -> Union[(Optional[int], Optional[str])]:
|
42 |
-
prev_message = message.reply_to_message
|
43 |
-
split_text = message.text.split(None, 1)
|
44 |
-
|
45 |
-
if len(split_text) < 2:
|
46 |
-
return await id_from_reply(message) # only option possible
|
47 |
-
|
48 |
-
text_to_parse = split_text[1]
|
49 |
-
|
50 |
-
text = ""
|
51 |
-
|
52 |
-
entities = list(message.parse_entities([MessageEntity.TEXT_MENTION]))
|
53 |
-
ent = entities[0] if entities else None
|
54 |
-
# if entity offset matches (command end/text start) then all good
|
55 |
-
if entities and ent and ent.offset == len(message.text) - len(text_to_parse):
|
56 |
-
ent = entities[0]
|
57 |
-
user_id = ent.user.id
|
58 |
-
text = message.text[ent.offset + ent.length :]
|
59 |
-
|
60 |
-
elif len(args) >= 1 and args[0][0] == "@":
|
61 |
-
user = args[0]
|
62 |
-
user_id = await get_user_id(user)
|
63 |
-
if not user_id:
|
64 |
-
await message.reply_text(
|
65 |
-
"No idea who this user is. You'll be able to interact with them if "
|
66 |
-
"you reply to that person's message instead, or forward one of that user's messages.",
|
67 |
-
)
|
68 |
-
return None, None
|
69 |
-
|
70 |
-
else:
|
71 |
-
user_id = user_id
|
72 |
-
res = message.text.split(None, 2)
|
73 |
-
if len(res) >= 3:
|
74 |
-
text = res[2]
|
75 |
-
|
76 |
-
elif len(args) >= 1 and args[0].isdigit():
|
77 |
-
user_id = int(args[0])
|
78 |
-
res = message.text.split(None, 2)
|
79 |
-
if len(res) >= 3:
|
80 |
-
text = res[2]
|
81 |
-
|
82 |
-
elif prev_message:
|
83 |
-
user_id, text = await id_from_reply(message)
|
84 |
-
|
85 |
-
else:
|
86 |
-
return None, None
|
87 |
-
|
88 |
-
try:
|
89 |
-
await context.bot.get_chat(user_id)
|
90 |
-
except BadRequest as excp:
|
91 |
-
if excp.message in ("User_id_invalid", "Chat not found"):
|
92 |
-
await message.reply_text(
|
93 |
-
"I don't seem to have interacted with this user before - please forward a message from "
|
94 |
-
"them to give me control! (like a voodoo doll, I need a piece of them to be able "
|
95 |
-
"to execute certain commands...)",
|
96 |
-
)
|
97 |
-
else:
|
98 |
-
LOGGER.exception("Exception %s on user %s", excp.message, user_id)
|
99 |
-
|
100 |
-
return None, None
|
101 |
-
|
102 |
-
return user_id, text
|
103 |
-
|
104 |
-
|
105 |
-
async def extract_text(message) -> str:
|
106 |
-
return (
|
107 |
-
message.text
|
108 |
-
or message.caption
|
109 |
-
or (message.sticker.emoji if message.sticker else None)
|
110 |
-
)
|
111 |
-
|
112 |
-
|
113 |
-
async def extract_unt_fedban(
|
114 |
-
message: Message, context: ContextTypes.DEFAULT_TYPE, args: List[str]
|
115 |
-
) -> Union[(Optional[int], Optional[str])]:
|
116 |
-
prev_message = message.reply_to_message
|
117 |
-
split_text = message.text.split(None, 1)
|
118 |
-
|
119 |
-
if len(split_text) < 2:
|
120 |
-
return await id_from_reply(message) # only option possible
|
121 |
-
|
122 |
-
text_to_parse = split_text[1]
|
123 |
-
|
124 |
-
text = ""
|
125 |
-
|
126 |
-
entities = list(message.parse_entities([MessageEntity.TEXT_MENTION]))
|
127 |
-
ent = entities[0] if entities else None
|
128 |
-
# if entity offset matches (command end/text start) then all good
|
129 |
-
if entities and ent and ent.offset == len(message.text) - len(text_to_parse):
|
130 |
-
ent = entities[0]
|
131 |
-
user_id = ent.user.id
|
132 |
-
text = message.text[ent.offset + ent.length :]
|
133 |
-
|
134 |
-
elif len(args) >= 1 and args[0][0] == "@":
|
135 |
-
user = args[0]
|
136 |
-
user_id = await get_user_id(user)
|
137 |
-
if not user_id and not isinstance(user_id, int):
|
138 |
-
await message.reply_text(
|
139 |
-
"I don't have that user in my db. "
|
140 |
-
"You'll be able to interact with them if you reply to that person's message instead, or forward one of that user's messages.",
|
141 |
-
)
|
142 |
-
return None, None
|
143 |
-
|
144 |
-
else:
|
145 |
-
user_id = user_id
|
146 |
-
res = message.text.split(None, 2)
|
147 |
-
if len(res) >= 3:
|
148 |
-
text = res[2]
|
149 |
-
|
150 |
-
elif len(args) >= 1 and args[0].isdigit():
|
151 |
-
user_id = int(args[0])
|
152 |
-
res = message.text.split(None, 2)
|
153 |
-
if len(res) >= 3:
|
154 |
-
text = res[2]
|
155 |
-
|
156 |
-
elif prev_message:
|
157 |
-
user_id, text = await id_from_reply(message)
|
158 |
-
|
159 |
-
else:
|
160 |
-
return None, None
|
161 |
-
|
162 |
-
try:
|
163 |
-
await context.bot.get_chat(user_id)
|
164 |
-
except BadRequest as excp:
|
165 |
-
if excp.message in ("User_id_invalid", "Chat not found") and not isinstance(
|
166 |
-
user_id,
|
167 |
-
int,
|
168 |
-
):
|
169 |
-
await message.reply_text(
|
170 |
-
"I don't seem to have interacted with this user before "
|
171 |
-
"please forward a message from them to give me control! "
|
172 |
-
"(like a voodoo doll, I need a piece of them to be able to execute certain commands...)",
|
173 |
-
)
|
174 |
-
return None, None
|
175 |
-
elif excp.message != "Chat not found":
|
176 |
-
LOGGER.exception("Exception %s on user %s", excp.message, user_id)
|
177 |
-
return None, None
|
178 |
-
elif not isinstance(user_id, int):
|
179 |
-
return None, None
|
180 |
-
|
181 |
-
return user_id, text
|
182 |
-
|
183 |
-
|
184 |
-
async def extract_user_fban(
|
185 |
-
message: Message, context: ContextTypes.DEFAULT_TYPE, args: List[str]
|
186 |
-
) -> Optional[int]:
|
187 |
-
return (await extract_unt_fedban(message, context, args))[0]
|
188 |
-
|
189 |
-
|
190 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/helper_funcs/misc.py
DELETED
@@ -1,263 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from math import ceil
|
3 |
-
from typing import Dict, List
|
4 |
-
from uuid import uuid4
|
5 |
-
|
6 |
-
import cv2
|
7 |
-
import ffmpeg
|
8 |
-
from telegram import (
|
9 |
-
Bot,
|
10 |
-
InlineKeyboardButton,
|
11 |
-
InlineKeyboardMarkup,
|
12 |
-
InlineQueryResultArticle,
|
13 |
-
InputTextMessageContent,
|
14 |
-
)
|
15 |
-
from telegram.constants import MessageLimit, ParseMode
|
16 |
-
from telegram.error import TelegramError
|
17 |
-
|
18 |
-
from Mikobot import NO_LOAD
|
19 |
-
|
20 |
-
# <=======================================================================================================>
|
21 |
-
|
22 |
-
|
23 |
-
# <================================================ FUNCTION =======================================================>
|
24 |
-
class EqInlineKeyboardButton(InlineKeyboardButton):
|
25 |
-
def __eq__(self, other):
|
26 |
-
return self.text == other.text
|
27 |
-
|
28 |
-
def __lt__(self, other):
|
29 |
-
return self.text < other.text
|
30 |
-
|
31 |
-
def __gt__(self, other):
|
32 |
-
return self.text > other.text
|
33 |
-
|
34 |
-
|
35 |
-
def split_message(msg: str) -> List[str]:
|
36 |
-
if len(msg) < MessageLimit.MAX_TEXT_LENGTH:
|
37 |
-
return [msg]
|
38 |
-
|
39 |
-
lines = msg.splitlines(True)
|
40 |
-
small_msg = ""
|
41 |
-
result = []
|
42 |
-
for line in lines:
|
43 |
-
if len(small_msg) + len(line) < MessageLimit.MAX_TEXT_LENGTH:
|
44 |
-
small_msg += line
|
45 |
-
else:
|
46 |
-
result.append(small_msg)
|
47 |
-
small_msg = line
|
48 |
-
else:
|
49 |
-
# Else statement at the end of the for loop, so append the leftover string.
|
50 |
-
result.append(small_msg)
|
51 |
-
|
52 |
-
return result
|
53 |
-
|
54 |
-
|
55 |
-
def paginate_modules(page_n: int, module_dict: Dict, prefix, chat=None) -> List:
|
56 |
-
if not chat:
|
57 |
-
modules = sorted(
|
58 |
-
[
|
59 |
-
EqInlineKeyboardButton(
|
60 |
-
x.__mod_name__,
|
61 |
-
callback_data="{}_module({})".format(
|
62 |
-
prefix, x.__mod_name__.lower()
|
63 |
-
),
|
64 |
-
)
|
65 |
-
for x in module_dict.values()
|
66 |
-
]
|
67 |
-
)
|
68 |
-
else:
|
69 |
-
modules = sorted(
|
70 |
-
[
|
71 |
-
EqInlineKeyboardButton(
|
72 |
-
x.__mod_name__,
|
73 |
-
callback_data="{}_module({},{})".format(
|
74 |
-
prefix, chat, x.__mod_name__.lower()
|
75 |
-
),
|
76 |
-
)
|
77 |
-
for x in module_dict.values()
|
78 |
-
]
|
79 |
-
)
|
80 |
-
|
81 |
-
pairs = [modules[i * 3 : (i + 1) * 3] for i in range((len(modules) + 3 - 1) // 3)]
|
82 |
-
|
83 |
-
round_num = len(modules) / 3
|
84 |
-
calc = len(modules) - round(round_num)
|
85 |
-
if calc in [1, 2]:
|
86 |
-
pairs.append((modules[-1],))
|
87 |
-
|
88 |
-
max_num_pages = ceil(len(pairs) / 6)
|
89 |
-
modulo_page = page_n % max_num_pages
|
90 |
-
|
91 |
-
# can only have a certain amount of buttons side by side
|
92 |
-
if len(pairs) > 3:
|
93 |
-
pairs = pairs[modulo_page * 6 : 6 * (modulo_page + 1)] + [
|
94 |
-
(
|
95 |
-
EqInlineKeyboardButton(
|
96 |
-
"◁", callback_data="{}_prev({})".format(prefix, modulo_page)
|
97 |
-
),
|
98 |
-
EqInlineKeyboardButton("» 𝙃𝙊𝙈𝙀 «", callback_data="Miko_back"),
|
99 |
-
EqInlineKeyboardButton(
|
100 |
-
"▷", callback_data="{}_next({})".format(prefix, modulo_page)
|
101 |
-
),
|
102 |
-
)
|
103 |
-
]
|
104 |
-
|
105 |
-
else:
|
106 |
-
pairs += [[EqInlineKeyboardButton("⇦ 𝘽𝘼𝘾𝙆", callback_data="Miko_back")]]
|
107 |
-
|
108 |
-
return pairs
|
109 |
-
|
110 |
-
|
111 |
-
def article(
|
112 |
-
title: str = "",
|
113 |
-
description: str = "",
|
114 |
-
message_text: str = "",
|
115 |
-
thumb_url: str = None,
|
116 |
-
reply_markup: InlineKeyboardMarkup = None,
|
117 |
-
disable_web_page_preview: bool = False,
|
118 |
-
) -> InlineQueryResultArticle:
|
119 |
-
return InlineQueryResultArticle(
|
120 |
-
id=uuid4(),
|
121 |
-
title=title,
|
122 |
-
description=description,
|
123 |
-
thumb_url=thumb_url,
|
124 |
-
input_message_content=InputTextMessageContent(
|
125 |
-
message_text=message_text,
|
126 |
-
disable_web_page_preview=disable_web_page_preview,
|
127 |
-
),
|
128 |
-
reply_markup=reply_markup,
|
129 |
-
)
|
130 |
-
|
131 |
-
|
132 |
-
def send_to_list(
|
133 |
-
bot: Bot, send_to: list, message: str, markdown=False, html=False
|
134 |
-
) -> None:
|
135 |
-
if html and markdown:
|
136 |
-
raise Exception("Can only send with either markdown or HTML!")
|
137 |
-
for user_id in set(send_to):
|
138 |
-
try:
|
139 |
-
if markdown:
|
140 |
-
bot.send_message(user_id, message, parse_mode=ParseMode.MARKDOWN)
|
141 |
-
elif html:
|
142 |
-
bot.send_message(user_id, message, parse_mode=ParseMode.HTML)
|
143 |
-
else:
|
144 |
-
bot.send_message(user_id, message)
|
145 |
-
except TelegramError:
|
146 |
-
pass # ignore users who fail
|
147 |
-
|
148 |
-
|
149 |
-
def build_keyboard(buttons):
|
150 |
-
keyb = []
|
151 |
-
for btn in buttons:
|
152 |
-
if btn.same_line and keyb:
|
153 |
-
keyb[-1].append(InlineKeyboardButton(btn.name, url=btn.url))
|
154 |
-
else:
|
155 |
-
keyb.append([InlineKeyboardButton(btn.name, url=btn.url)])
|
156 |
-
|
157 |
-
return keyb
|
158 |
-
|
159 |
-
|
160 |
-
def revert_buttons(buttons):
|
161 |
-
res = ""
|
162 |
-
for btn in buttons:
|
163 |
-
if btn.same_line:
|
164 |
-
res += "\n[{}](buttonurl://{}:same)".format(btn.name, btn.url)
|
165 |
-
else:
|
166 |
-
res += "\n[{}](buttonurl://{})".format(btn.name, btn.url)
|
167 |
-
|
168 |
-
return res
|
169 |
-
|
170 |
-
|
171 |
-
def build_keyboard_parser(bot, chat_id, buttons):
|
172 |
-
keyb = []
|
173 |
-
for btn in buttons:
|
174 |
-
if btn.url == "{rules}":
|
175 |
-
btn.url = "http://t.me/{}?start={}".format(bot.username, chat_id)
|
176 |
-
if btn.same_line and keyb:
|
177 |
-
keyb[-1].append(InlineKeyboardButton(btn.name, url=btn.url))
|
178 |
-
else:
|
179 |
-
keyb.append([InlineKeyboardButton(btn.name, url=btn.url)])
|
180 |
-
|
181 |
-
return keyb
|
182 |
-
|
183 |
-
|
184 |
-
def user_bot_owner(func):
|
185 |
-
@wraps(func)
|
186 |
-
def is_user_bot_owner(bot: Bot, update: Update, *args, **kwargs):
|
187 |
-
user = update.effective_user
|
188 |
-
if user and user.id == OWNER_ID:
|
189 |
-
return func(bot, update, *args, **kwargs)
|
190 |
-
else:
|
191 |
-
pass
|
192 |
-
|
193 |
-
return is_user_bot_owner
|
194 |
-
|
195 |
-
|
196 |
-
def build_keyboard_alternate(buttons):
|
197 |
-
keyb = []
|
198 |
-
for btn in buttons:
|
199 |
-
if btn[2] and keyb:
|
200 |
-
keyb[-1].append(InlineKeyboardButton(btn[0], url=btn[1]))
|
201 |
-
else:
|
202 |
-
keyb.append([InlineKeyboardButton(btn[0], url=btn[1])])
|
203 |
-
|
204 |
-
return keyb
|
205 |
-
|
206 |
-
|
207 |
-
def is_module_loaded(name):
|
208 |
-
return name not in NO_LOAD
|
209 |
-
|
210 |
-
|
211 |
-
def convert_gif(input):
|
212 |
-
"""Function to convert mp4 to webm(vp9)"""
|
213 |
-
|
214 |
-
vid = cv2.VideoCapture(input)
|
215 |
-
height = vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
|
216 |
-
width = vid.get(cv2.CAP_PROP_FRAME_WIDTH)
|
217 |
-
|
218 |
-
# check height and width to scale
|
219 |
-
if width > height:
|
220 |
-
width = 512
|
221 |
-
height = -1
|
222 |
-
elif height > width:
|
223 |
-
height = 512
|
224 |
-
width = -1
|
225 |
-
elif width == height:
|
226 |
-
width = 512
|
227 |
-
height = 512
|
228 |
-
|
229 |
-
converted_name = "kangsticker.webm"
|
230 |
-
|
231 |
-
(
|
232 |
-
ffmpeg.input(input)
|
233 |
-
.filter("fps", fps=30, round="up")
|
234 |
-
.filter("scale", width=width, height=height)
|
235 |
-
.trim(start="00:00:00", end="00:00:03", duration="3")
|
236 |
-
.output(
|
237 |
-
converted_name,
|
238 |
-
vcodec="libvpx-vp9",
|
239 |
-
**{
|
240 |
-
#'vf': 'scale=512:-1',
|
241 |
-
"crf": "30"
|
242 |
-
},
|
243 |
-
)
|
244 |
-
.overwrite_output()
|
245 |
-
.run()
|
246 |
-
)
|
247 |
-
|
248 |
-
return converted_name
|
249 |
-
|
250 |
-
|
251 |
-
def mention_username(username: str, name: str) -> str:
|
252 |
-
"""
|
253 |
-
Args:
|
254 |
-
username (:obj:`str`): The username of chat which you want to mention.
|
255 |
-
name (:obj:`str`): The name the mention is showing.
|
256 |
-
|
257 |
-
Returns:
|
258 |
-
:obj:`str`: The inline mention for the user as HTML.
|
259 |
-
"""
|
260 |
-
return f'<a href="t.me/{username}">{escape(name)}</a>'
|
261 |
-
|
262 |
-
|
263 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/helper_funcs/msg_types.py
DELETED
@@ -1,251 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from enum import IntEnum, unique
|
3 |
-
|
4 |
-
from telegram import Message
|
5 |
-
|
6 |
-
from Mikobot.plugins.helper_funcs.string_handling import button_markdown_parser
|
7 |
-
|
8 |
-
# <=======================================================================================================>
|
9 |
-
|
10 |
-
|
11 |
-
# <================================================ CLASS =======================================================>
|
12 |
-
@unique
|
13 |
-
class Types(IntEnum):
|
14 |
-
TEXT = 0
|
15 |
-
BUTTON_TEXT = 1
|
16 |
-
STICKER = 2
|
17 |
-
DOCUMENT = 3
|
18 |
-
PHOTO = 4
|
19 |
-
AUDIO = 5
|
20 |
-
VOICE = 6
|
21 |
-
VIDEO = 7
|
22 |
-
|
23 |
-
|
24 |
-
# <================================================ FUNCTION =======================================================>
|
25 |
-
def get_note_type(msg: Message):
|
26 |
-
data_type = None
|
27 |
-
content = None
|
28 |
-
text = ""
|
29 |
-
raw_text = msg.text or msg.caption
|
30 |
-
args = raw_text.split(None, 2) # use python's maxsplit to separate cmd and args
|
31 |
-
note_name = args[1]
|
32 |
-
|
33 |
-
buttons = []
|
34 |
-
# determine what the contents of the filter are - text, image, sticker, etc
|
35 |
-
if len(args) >= 3:
|
36 |
-
offset = len(args[2]) - len(
|
37 |
-
raw_text,
|
38 |
-
) # set correct offset relative to command + notename
|
39 |
-
text, buttons = button_markdown_parser(
|
40 |
-
args[2],
|
41 |
-
entities=msg.parse_entities() or msg.parse_caption_entities(),
|
42 |
-
offset=offset,
|
43 |
-
)
|
44 |
-
if buttons:
|
45 |
-
data_type = Types.BUTTON_TEXT
|
46 |
-
else:
|
47 |
-
data_type = Types.TEXT
|
48 |
-
|
49 |
-
elif msg.reply_to_message and not msg.reply_to_message.forum_topic_created:
|
50 |
-
entities = msg.reply_to_message.parse_entities()
|
51 |
-
msgtext = msg.reply_to_message.text or msg.reply_to_message.caption
|
52 |
-
if len(args) >= 2 and msg.reply_to_message.text: # not caption, text
|
53 |
-
text, buttons = button_markdown_parser(msgtext, entities=entities)
|
54 |
-
if buttons:
|
55 |
-
data_type = Types.BUTTON_TEXT
|
56 |
-
else:
|
57 |
-
data_type = Types.TEXT
|
58 |
-
|
59 |
-
elif msg.reply_to_message.sticker:
|
60 |
-
content = msg.reply_to_message.sticker.file_id
|
61 |
-
data_type = Types.STICKER
|
62 |
-
|
63 |
-
elif msg.reply_to_message.document:
|
64 |
-
content = msg.reply_to_message.document.file_id
|
65 |
-
text, buttons = button_markdown_parser(msgtext, entities=entities)
|
66 |
-
data_type = Types.DOCUMENT
|
67 |
-
|
68 |
-
elif msg.reply_to_message.photo:
|
69 |
-
content = msg.reply_to_message.photo[-1].file_id # last elem = best quality
|
70 |
-
text, buttons = button_markdown_parser(msgtext, entities=entities)
|
71 |
-
data_type = Types.PHOTO
|
72 |
-
|
73 |
-
elif msg.reply_to_message.audio:
|
74 |
-
content = msg.reply_to_message.audio.file_id
|
75 |
-
text, buttons = button_markdown_parser(msgtext, entities=entities)
|
76 |
-
data_type = Types.AUDIO
|
77 |
-
|
78 |
-
elif msg.reply_to_message.voice:
|
79 |
-
content = msg.reply_to_message.voice.file_id
|
80 |
-
text, buttons = button_markdown_parser(msgtext, entities=entities)
|
81 |
-
data_type = Types.VOICE
|
82 |
-
|
83 |
-
elif msg.reply_to_message.video:
|
84 |
-
content = msg.reply_to_message.video.file_id
|
85 |
-
text, buttons = button_markdown_parser(msgtext, entities=entities)
|
86 |
-
data_type = Types.VIDEO
|
87 |
-
|
88 |
-
return note_name, text, data_type, content, buttons
|
89 |
-
|
90 |
-
|
91 |
-
# note: add own args?
|
92 |
-
def get_welcome_type(msg: Message):
|
93 |
-
data_type = None
|
94 |
-
content = None
|
95 |
-
text = ""
|
96 |
-
|
97 |
-
try:
|
98 |
-
if msg.reply_to_message and not msg.reply_to_message.forum_topic_created:
|
99 |
-
if msg.reply_to_message.text:
|
100 |
-
args = msg.reply_to_message.text
|
101 |
-
else:
|
102 |
-
args = msg.reply_to_message.caption
|
103 |
-
else:
|
104 |
-
args = msg.text.split(
|
105 |
-
None,
|
106 |
-
1,
|
107 |
-
) # use python's maxsplit to separate cmd and args
|
108 |
-
except AttributeError:
|
109 |
-
args = False
|
110 |
-
|
111 |
-
if msg.reply_to_message and not msg.reply_to_message.forum_topic_created:
|
112 |
-
if msg.reply_to_message.sticker:
|
113 |
-
content = msg.reply_to_message.sticker.file_id
|
114 |
-
text = None
|
115 |
-
data_type = Types.STICKER
|
116 |
-
|
117 |
-
elif msg.reply_to_message.document:
|
118 |
-
content = msg.reply_to_message.document.file_id
|
119 |
-
text = msg.reply_to_message.caption
|
120 |
-
data_type = Types.DOCUMENT
|
121 |
-
|
122 |
-
elif msg.reply_to_message.photo:
|
123 |
-
content = msg.reply_to_message.photo[-1].file_id # last elem = best quality
|
124 |
-
text = msg.reply_to_message.caption
|
125 |
-
data_type = Types.PHOTO
|
126 |
-
|
127 |
-
elif msg.reply_to_message.audio:
|
128 |
-
content = msg.reply_to_message.audio.file_id
|
129 |
-
text = msg.reply_to_message.caption
|
130 |
-
data_type = Types.AUDIO
|
131 |
-
|
132 |
-
elif msg.reply_to_message.voice:
|
133 |
-
content = msg.reply_to_message.voice.file_id
|
134 |
-
text = msg.reply_to_message.caption
|
135 |
-
data_type = Types.VOICE
|
136 |
-
|
137 |
-
elif msg.reply_to_message.video:
|
138 |
-
content = msg.reply_to_message.video.file_id
|
139 |
-
text = msg.reply_to_message.caption
|
140 |
-
data_type = Types.VIDEO
|
141 |
-
|
142 |
-
elif msg.reply_to_message and msg.reply_to_message.video_note:
|
143 |
-
content = msg.reply_to_message.video_note.file_id
|
144 |
-
text = None
|
145 |
-
data_type = Types.VIDEO_NOTE
|
146 |
-
|
147 |
-
buttons = []
|
148 |
-
# determine what the contents of the filter are - text, image, sticker, etc
|
149 |
-
if args:
|
150 |
-
if msg.reply_to_message and not msg.reply_to_message.forum_topic_created:
|
151 |
-
argumen = (
|
152 |
-
msg.reply_to_message.caption if msg.reply_to_message.caption else ""
|
153 |
-
)
|
154 |
-
offset = 0 # offset is no need since target was in reply
|
155 |
-
entities = msg.reply_to_message.parse_entities()
|
156 |
-
else:
|
157 |
-
argumen = args[1]
|
158 |
-
offset = len(argumen) - len(
|
159 |
-
msg.text,
|
160 |
-
) # set correct offset relative to command + notename
|
161 |
-
entities = msg.parse_entities()
|
162 |
-
text, buttons = button_markdown_parser(
|
163 |
-
argumen,
|
164 |
-
entities=entities,
|
165 |
-
offset=offset,
|
166 |
-
)
|
167 |
-
|
168 |
-
if not data_type:
|
169 |
-
if text and buttons:
|
170 |
-
data_type = Types.BUTTON_TEXT
|
171 |
-
elif text:
|
172 |
-
data_type = Types.TEXT
|
173 |
-
|
174 |
-
return text, data_type, content, buttons
|
175 |
-
|
176 |
-
|
177 |
-
def get_filter_type(msg: Message):
|
178 |
-
if not msg.reply_to_message and msg.text and len(msg.text.split()) >= 3:
|
179 |
-
content = None
|
180 |
-
text = msg.text.split(None, 2)[2]
|
181 |
-
data_type = Types.TEXT
|
182 |
-
media_spoiler = None
|
183 |
-
elif msg.reply_to_message and msg.reply_to_message.forum_topic_created:
|
184 |
-
content = None
|
185 |
-
text = msg.text.split(None, 2)[2]
|
186 |
-
data_type = Types.TEXT
|
187 |
-
media_spoiler = None
|
188 |
-
elif msg.reply_to_message and not msg.reply_to_message.forum_topic_created:
|
189 |
-
if msg.reply_to_message.text and len(msg.text.split()) >= 2:
|
190 |
-
content = None
|
191 |
-
text = msg.reply_to_message.text
|
192 |
-
data_type = Types.TEXT
|
193 |
-
media_spoiler = None
|
194 |
-
|
195 |
-
elif msg.reply_to_message.sticker:
|
196 |
-
content = msg.reply_to_message.sticker.file_id
|
197 |
-
text = None
|
198 |
-
data_type = Types.STICKER
|
199 |
-
media_spoiler = None
|
200 |
-
|
201 |
-
elif msg.reply_to_message.document:
|
202 |
-
content = msg.reply_to_message.document.file_id
|
203 |
-
text = msg.reply_to_message.caption
|
204 |
-
data_type = Types.DOCUMENT
|
205 |
-
media_spoiler = None
|
206 |
-
|
207 |
-
elif msg.reply_to_message.photo:
|
208 |
-
content = msg.reply_to_message.photo[-1].file_id # last elem = best quality
|
209 |
-
text = msg.reply_to_message.caption
|
210 |
-
data_type = Types.PHOTO
|
211 |
-
media_spoiler = msg.reply_to_message.has_media_spoiler
|
212 |
-
|
213 |
-
elif msg.reply_to_message.audio:
|
214 |
-
content = msg.reply_to_message.audio.file_id
|
215 |
-
text = msg.reply_to_message.caption
|
216 |
-
data_type = Types.AUDIO
|
217 |
-
media_spoiler = None
|
218 |
-
|
219 |
-
elif msg.reply_to_message.voice:
|
220 |
-
content = msg.reply_to_message.voice.file_id
|
221 |
-
text = msg.reply_to_message.caption
|
222 |
-
data_type = Types.VOICE
|
223 |
-
media_spoiler = None
|
224 |
-
|
225 |
-
elif msg.reply_to_message.video:
|
226 |
-
content = msg.reply_to_message.video.file_id
|
227 |
-
text = msg.reply_to_message.caption
|
228 |
-
data_type = Types.VIDEO
|
229 |
-
media_spoiler = msg.reply_to_message.has_media_spoiler
|
230 |
-
|
231 |
-
elif msg.reply_to_message.video_note:
|
232 |
-
content = msg.reply_to_message.video_note.file_id
|
233 |
-
text = None
|
234 |
-
data_type = Types.VIDEO_NOTE
|
235 |
-
media_spoiler = None
|
236 |
-
|
237 |
-
else:
|
238 |
-
text = None
|
239 |
-
data_type = None
|
240 |
-
content = None
|
241 |
-
media_spoiler = None
|
242 |
-
else:
|
243 |
-
text = None
|
244 |
-
data_type = None
|
245 |
-
content = None
|
246 |
-
media_spoiler = None
|
247 |
-
|
248 |
-
return text, data_type, content, media_spoiler
|
249 |
-
|
250 |
-
|
251 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/helper_funcs/string_handling.py
DELETED
@@ -1,311 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import re
|
3 |
-
import time
|
4 |
-
from typing import Dict, List
|
5 |
-
|
6 |
-
import bleach
|
7 |
-
import markdown2
|
8 |
-
from emoji import unicode_codes
|
9 |
-
from telegram import MessageEntity
|
10 |
-
from telegram.helpers import escape_markdown
|
11 |
-
|
12 |
-
# <=======================================================================================================>
|
13 |
-
|
14 |
-
MATCH_MD = re.compile(
|
15 |
-
r"\*(.*?)\*|"
|
16 |
-
r"_(.*?)_|"
|
17 |
-
r"`(.*?)`|"
|
18 |
-
r"(?<!\\)(\[.*?\])(\(.*?\))|"
|
19 |
-
r"(?P<esc>[*_`\[])",
|
20 |
-
)
|
21 |
-
|
22 |
-
LINK_REGEX = re.compile(r"(?<!\\)\[.+?\]\((.*?)\)")
|
23 |
-
BTN_URL_REGEX = re.compile(r"(\[([^\[]+?)\]\(buttonurl:(?:/{0,2})(.+?)(:same)?\))")
|
24 |
-
_EMOJI_REGEXP = None
|
25 |
-
|
26 |
-
|
27 |
-
# <================================================ FUNCTION =======================================================>
|
28 |
-
def get_emoji_regexp():
|
29 |
-
global _EMOJI_REGEXP
|
30 |
-
if _EMOJI_REGEXP is None:
|
31 |
-
emojis = sorted(unicode_codes.EMOJI_DATA, key=len, reverse=True)
|
32 |
-
pattern = "(" + "|".join(re.escape(u) for u in emojis) + ")"
|
33 |
-
return re.compile(pattern)
|
34 |
-
|
35 |
-
|
36 |
-
def _selective_escape(to_parse: str) -> str:
|
37 |
-
"""
|
38 |
-
Escape all invalid markdown
|
39 |
-
|
40 |
-
:param to_parse: text to escape
|
41 |
-
:return: valid markdown string
|
42 |
-
"""
|
43 |
-
offset = 0 # offset to be used as adding a \ character causes the string to shift
|
44 |
-
for match in MATCH_MD.finditer(to_parse):
|
45 |
-
if match.group("esc"):
|
46 |
-
ent_start = match.start()
|
47 |
-
to_parse = (
|
48 |
-
to_parse[: ent_start + offset] + "\\" + to_parse[ent_start + offset :]
|
49 |
-
)
|
50 |
-
offset += 1
|
51 |
-
return to_parse
|
52 |
-
|
53 |
-
|
54 |
-
# This is a fun one.
|
55 |
-
def _calc_emoji_offset(to_calc) -> int:
|
56 |
-
# Get all emoji in text.
|
57 |
-
emoticons = get_emoji_regexp().finditer(to_calc)
|
58 |
-
# Check the utf16 length of the emoji to determine the offset it caused.
|
59 |
-
# Normal, 1 character emoji don't affect; hence sub 1.
|
60 |
-
# special, eg with two emoji characters (eg face, and skin col) will have length 2, so by subbing one we
|
61 |
-
# know we'll get one extra offset,
|
62 |
-
return sum(len(e.group(0).encode("utf-16-le")) // 2 - 1 for e in emoticons)
|
63 |
-
|
64 |
-
|
65 |
-
def markdown_parser(
|
66 |
-
txt: str,
|
67 |
-
entities: Dict[MessageEntity, str] = None,
|
68 |
-
offset: int = 0,
|
69 |
-
) -> str:
|
70 |
-
"""
|
71 |
-
Parse a string, escaping all invalid markdown entities.
|
72 |
-
|
73 |
-
Escapes URL's so as to avoid URL mangling.
|
74 |
-
Re-adds any telegram code entities obtained from the entities object.
|
75 |
-
|
76 |
-
:param txt: text to parse
|
77 |
-
:param entities: dict of message entities in text
|
78 |
-
:param offset: message offset - command and notename length
|
79 |
-
:return: valid markdown string
|
80 |
-
"""
|
81 |
-
if not entities:
|
82 |
-
entities = {}
|
83 |
-
if not txt:
|
84 |
-
return ""
|
85 |
-
|
86 |
-
prev = 0
|
87 |
-
res = ""
|
88 |
-
# Loop over all message entities, and:
|
89 |
-
# reinsert code
|
90 |
-
# escape free-standing urls
|
91 |
-
for ent, ent_text in entities.items():
|
92 |
-
if ent.offset < -offset:
|
93 |
-
continue
|
94 |
-
|
95 |
-
start = ent.offset + offset # start of entity
|
96 |
-
end = ent.offset + offset + ent.length - 1 # end of entity
|
97 |
-
|
98 |
-
# we only care about code, url, text links
|
99 |
-
if ent.type in ("code", "url", "text_link", "spoiler"):
|
100 |
-
# count emoji to switch counter
|
101 |
-
count = _calc_emoji_offset(txt[:start])
|
102 |
-
start -= count
|
103 |
-
end -= count
|
104 |
-
|
105 |
-
# URL handling -> do not escape if in [](), escape otherwise.
|
106 |
-
if ent.type == "url":
|
107 |
-
if any(
|
108 |
-
match.start(1) <= start and end <= match.end(1)
|
109 |
-
for match in LINK_REGEX.finditer(txt)
|
110 |
-
):
|
111 |
-
continue
|
112 |
-
# else, check the escapes between the prev and last and forcefully escape the url to avoid mangling
|
113 |
-
else:
|
114 |
-
# TODO: investigate possible offset bug when lots of emoji are present
|
115 |
-
res += _selective_escape(txt[prev:start] or "") + escape_markdown(
|
116 |
-
ent_text, 2
|
117 |
-
)
|
118 |
-
|
119 |
-
# code handling
|
120 |
-
elif ent.type == "code":
|
121 |
-
res += _selective_escape(txt[prev:start]) + "`" + ent_text + "`"
|
122 |
-
|
123 |
-
# handle markdown/html links
|
124 |
-
elif ent.type == "text_link":
|
125 |
-
res += _selective_escape(txt[prev:start]) + "[{}]({})".format(
|
126 |
-
ent_text,
|
127 |
-
ent.url,
|
128 |
-
)
|
129 |
-
# handle spoiler
|
130 |
-
elif ent.type == "spoiler":
|
131 |
-
res += _selective_escape(txt[prev:start]) + "||" + ent_text + "||"
|
132 |
-
|
133 |
-
end += 1
|
134 |
-
|
135 |
-
# anything else
|
136 |
-
else:
|
137 |
-
continue
|
138 |
-
|
139 |
-
prev = end
|
140 |
-
|
141 |
-
res += _selective_escape(txt[prev:]) # add the rest of the text
|
142 |
-
return res
|
143 |
-
|
144 |
-
|
145 |
-
def button_markdown_parser(
|
146 |
-
txt: str,
|
147 |
-
entities: Dict[MessageEntity, str] = None,
|
148 |
-
offset: int = 0,
|
149 |
-
) -> (str, List):
|
150 |
-
markdown_note = markdown_parser(txt, entities, offset)
|
151 |
-
prev = 0
|
152 |
-
note_data = ""
|
153 |
-
buttons = []
|
154 |
-
for match in BTN_URL_REGEX.finditer(markdown_note):
|
155 |
-
# Check if btnurl is escaped
|
156 |
-
n_escapes = 0
|
157 |
-
to_check = match.start(1) - 1
|
158 |
-
while to_check > 0 and markdown_note[to_check] == "\\":
|
159 |
-
n_escapes += 1
|
160 |
-
to_check -= 1
|
161 |
-
|
162 |
-
# if even, not escaped -> create button
|
163 |
-
if n_escapes % 2 == 0:
|
164 |
-
# create a thruple with button label, url, and newline status
|
165 |
-
buttons.append((match.group(2), match.group(3), bool(match.group(4))))
|
166 |
-
note_data += markdown_note[prev : match.start(1)]
|
167 |
-
prev = match.end(1)
|
168 |
-
# if odd, escaped -> move along
|
169 |
-
else:
|
170 |
-
note_data += markdown_note[prev:to_check]
|
171 |
-
prev = match.start(1) - 1
|
172 |
-
else:
|
173 |
-
note_data += markdown_note[prev:]
|
174 |
-
|
175 |
-
return note_data, buttons
|
176 |
-
|
177 |
-
|
178 |
-
def escape_invalid_curly_brackets(text: str, valids: List[str]) -> str:
|
179 |
-
new_text = ""
|
180 |
-
idx = 0
|
181 |
-
while idx < len(text):
|
182 |
-
if text[idx] == "{":
|
183 |
-
if idx + 1 < len(text) and text[idx + 1] == "{":
|
184 |
-
idx += 2
|
185 |
-
new_text += "{{{{"
|
186 |
-
continue
|
187 |
-
else:
|
188 |
-
success = False
|
189 |
-
for v in valids:
|
190 |
-
if text[idx:].startswith("{" + v + "}"):
|
191 |
-
success = True
|
192 |
-
break
|
193 |
-
if success:
|
194 |
-
new_text += text[idx : idx + len(v) + 2]
|
195 |
-
idx += len(v) + 2
|
196 |
-
continue
|
197 |
-
else:
|
198 |
-
new_text += "{{"
|
199 |
-
|
200 |
-
elif text[idx] == "}":
|
201 |
-
if idx + 1 < len(text) and text[idx + 1] == "}":
|
202 |
-
idx += 2
|
203 |
-
new_text += "}}}}"
|
204 |
-
continue
|
205 |
-
else:
|
206 |
-
new_text += "}}"
|
207 |
-
|
208 |
-
else:
|
209 |
-
new_text += text[idx]
|
210 |
-
idx += 1
|
211 |
-
|
212 |
-
return new_text
|
213 |
-
|
214 |
-
|
215 |
-
SMART_OPEN = "“"
|
216 |
-
SMART_CLOSE = "”"
|
217 |
-
START_CHAR = ("'", '"', SMART_OPEN)
|
218 |
-
|
219 |
-
|
220 |
-
def split_quotes(text: str) -> List:
|
221 |
-
if not any(text.startswith(char) for char in START_CHAR):
|
222 |
-
return text.split(None, 1)
|
223 |
-
counter = 1 # ignore first char -> is some kind of quote
|
224 |
-
while counter < len(text):
|
225 |
-
if text[counter] == "\\":
|
226 |
-
counter += 1
|
227 |
-
elif text[counter] == text[0] or (
|
228 |
-
text[0] == SMART_OPEN and text[counter] == SMART_CLOSE
|
229 |
-
):
|
230 |
-
break
|
231 |
-
counter += 1
|
232 |
-
else:
|
233 |
-
return text.split(None, 1)
|
234 |
-
|
235 |
-
# 1 to avoid starting quote, and counter is exclusive so avoids ending
|
236 |
-
key = remove_escapes(text[1:counter].strip())
|
237 |
-
# index will be in range, or `else` would have been executed and returned
|
238 |
-
rest = text[counter + 1 :].strip()
|
239 |
-
if not key:
|
240 |
-
key = text[0] + text[0]
|
241 |
-
return list(filter(None, [key, rest]))
|
242 |
-
|
243 |
-
|
244 |
-
def remove_escapes(text: str) -> str:
|
245 |
-
res = ""
|
246 |
-
is_escaped = False
|
247 |
-
for counter in range(len(text)):
|
248 |
-
if is_escaped:
|
249 |
-
res += text[counter]
|
250 |
-
is_escaped = False
|
251 |
-
elif text[counter] == "\\":
|
252 |
-
is_escaped = True
|
253 |
-
else:
|
254 |
-
res += text[counter]
|
255 |
-
return res
|
256 |
-
|
257 |
-
|
258 |
-
def escape_chars(text: str, to_escape: List[str]) -> str:
|
259 |
-
to_escape.append("\\")
|
260 |
-
new_text = ""
|
261 |
-
for x in text:
|
262 |
-
if x in to_escape:
|
263 |
-
new_text += "\\"
|
264 |
-
new_text += x
|
265 |
-
return new_text
|
266 |
-
|
267 |
-
|
268 |
-
async def extract_time(message, time_val):
|
269 |
-
if any(time_val.endswith(unit) for unit in ("m", "h", "d")):
|
270 |
-
unit = time_val[-1]
|
271 |
-
time_num = time_val[:-1] # type: str
|
272 |
-
if not time_num.isdigit():
|
273 |
-
await message.reply_text("Invalid time amount specified.")
|
274 |
-
return ""
|
275 |
-
|
276 |
-
if unit == "m":
|
277 |
-
bantime = int(time.time() + int(time_num) * 60)
|
278 |
-
elif unit == "h":
|
279 |
-
bantime = int(time.time() + int(time_num) * 60 * 60)
|
280 |
-
elif unit == "d":
|
281 |
-
bantime = int(time.time() + int(time_num) * 24 * 60 * 60)
|
282 |
-
else:
|
283 |
-
# how even...?
|
284 |
-
return ""
|
285 |
-
return bantime
|
286 |
-
else:
|
287 |
-
await message.reply_text(
|
288 |
-
"Invalid time type specified. Expected m,h, or d, got: {}".format(
|
289 |
-
time_val[-1],
|
290 |
-
),
|
291 |
-
)
|
292 |
-
return ""
|
293 |
-
|
294 |
-
|
295 |
-
def markdown_to_html(text: str):
|
296 |
-
text = text.replace("*", "**")
|
297 |
-
text = text.replace("`", "```")
|
298 |
-
text = text.replace("~", "~~")
|
299 |
-
|
300 |
-
spoiler_pattern = re.compile(r"\|\|(?=\S)(.+?)(?<=\S)\|\|", re.S)
|
301 |
-
text = spoiler_pattern.sub(r"<tg-spoiler>\1</tg-spoiler>", text)
|
302 |
-
|
303 |
-
_html = markdown2.markdown(text, extras=["strike", "underline"])
|
304 |
-
return bleach.clean(
|
305 |
-
_html,
|
306 |
-
tags=["strong", "em", "a", "code", "pre", "strike", "u", "tg-spoiler"],
|
307 |
-
strip=True,
|
308 |
-
)[:-1]
|
309 |
-
|
310 |
-
|
311 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/hyperlink.py
DELETED
@@ -1,63 +0,0 @@
|
|
1 |
-
# SOURCE https://github.com/Team-ProjectCodeX
|
2 |
-
# CREATED BY https://t.me/O_okarma
|
3 |
-
# PROVIDED BY https://t.me/ProjectCodeX
|
4 |
-
|
5 |
-
# <============================================== IMPORTS =========================================================>
|
6 |
-
import random
|
7 |
-
import re
|
8 |
-
|
9 |
-
from telegram import Update
|
10 |
-
from telegram.constants import ParseMode
|
11 |
-
from telegram.ext import CommandHandler, ContextTypes
|
12 |
-
|
13 |
-
from Mikobot import function
|
14 |
-
|
15 |
-
# <=======================================================================================================>
|
16 |
-
|
17 |
-
|
18 |
-
# <================================================ FUNCTION =======================================================>
|
19 |
-
# Define the command handler for the "/pickwinner" command
|
20 |
-
async def pick_winner(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
21 |
-
# Get the list of participants
|
22 |
-
participants = context.args
|
23 |
-
|
24 |
-
if participants:
|
25 |
-
# Select a random winner
|
26 |
-
winner = random.choice(participants)
|
27 |
-
|
28 |
-
# Send the winner as a reply
|
29 |
-
await update.message.reply_text(f"🎉 The winner is: {winner}")
|
30 |
-
else:
|
31 |
-
# If no participants are provided
|
32 |
-
await update.message.reply_text("Please provide a list of participants.")
|
33 |
-
|
34 |
-
|
35 |
-
# Define the command handler for the "/hyperlink" command
|
36 |
-
async def hyperlink_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
37 |
-
args = context.args
|
38 |
-
if len(args) >= 2:
|
39 |
-
text = " ".join(args[:-1])
|
40 |
-
link = args[-1]
|
41 |
-
hyperlink = f"[{text}]({link})"
|
42 |
-
await update.message.reply_text(
|
43 |
-
text=hyperlink, parse_mode="Markdown", disable_web_page_preview=True
|
44 |
-
)
|
45 |
-
else:
|
46 |
-
match = re.search(r"/hyperlink ([^\s]+) (.+)", update.message.text)
|
47 |
-
if match:
|
48 |
-
text = match.group(1)
|
49 |
-
link = match.group(2)
|
50 |
-
hyperlink = f"[{text}]({link})"
|
51 |
-
await update.message.reply_text(
|
52 |
-
text=hyperlink, parse_mode=ParseMode.HTML, disable_web_page_preview=True
|
53 |
-
)
|
54 |
-
else:
|
55 |
-
await update.message.reply_text(
|
56 |
-
"❌ Invalid format! Please use the format: /hyperlink <text> <link>."
|
57 |
-
)
|
58 |
-
|
59 |
-
|
60 |
-
# <================================================ HANDLER =======================================================>
|
61 |
-
function(CommandHandler("pickwinner", pick_winner, block=False))
|
62 |
-
function(CommandHandler("hyperlink", hyperlink_command, block=False))
|
63 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/imagegen.py
DELETED
@@ -1,132 +0,0 @@
|
|
1 |
-
# CREATED BY: https://t.me/O_oKarma
|
2 |
-
# API CREDITS: @Qewertyy
|
3 |
-
# PROVIDED BY: https://github.com/Team-ProjectCodeX
|
4 |
-
|
5 |
-
# <============================================== IMPORTS =========================================================>
|
6 |
-
import asyncio
|
7 |
-
|
8 |
-
import aiohttp
|
9 |
-
from telethon import events
|
10 |
-
|
11 |
-
from Mikobot import tbot as client
|
12 |
-
|
13 |
-
# <=======================================================================================================>
|
14 |
-
|
15 |
-
BASE_URL = "https://lexica.qewertyy.me"
|
16 |
-
SESSION_HEADERS = {"Host": "lexica.qewertyy.me"}
|
17 |
-
|
18 |
-
|
19 |
-
# <=============================================== CLASS + FUNCTION ========================================================>
|
20 |
-
class AsyncClient:
|
21 |
-
def __init__(self):
|
22 |
-
self.url = BASE_URL
|
23 |
-
self.session = aiohttp.ClientSession()
|
24 |
-
|
25 |
-
async def generate(self, model_id, prompt, negative_prompt):
|
26 |
-
data = {
|
27 |
-
"model_id": model_id,
|
28 |
-
"prompt": prompt,
|
29 |
-
"negative_prompt": negative_prompt if negative_prompt else "",
|
30 |
-
"num_images": 1,
|
31 |
-
}
|
32 |
-
try:
|
33 |
-
async with self.session.post(
|
34 |
-
f"{self.url}/models/inference", data=data, headers=SESSION_HEADERS
|
35 |
-
) as resp:
|
36 |
-
return await resp.json()
|
37 |
-
except Exception as e:
|
38 |
-
print(f"Request failed: {str(e)}")
|
39 |
-
|
40 |
-
async def get_images(self, task_id, request_id):
|
41 |
-
data = {"task_id": task_id, "request_id": request_id}
|
42 |
-
try:
|
43 |
-
async with self.session.post(
|
44 |
-
f"{self.url}/models/inference/task", data=data, headers=SESSION_HEADERS
|
45 |
-
) as resp:
|
46 |
-
return await resp.json()
|
47 |
-
except Exception as e:
|
48 |
-
print(f"Request failed: {str(e)}")
|
49 |
-
|
50 |
-
|
51 |
-
async def generate_image_handler(event, model_id):
|
52 |
-
command_parts = event.text.split(" ", 1)
|
53 |
-
if len(command_parts) < 2:
|
54 |
-
await event.reply("Please provide a prompt.")
|
55 |
-
return
|
56 |
-
|
57 |
-
prompt = command_parts[1]
|
58 |
-
negative_prompt = ""
|
59 |
-
|
60 |
-
# Send the initial "Generating your image, wait sometime" message
|
61 |
-
reply_message = await event.reply("Generating your image, please wait...")
|
62 |
-
|
63 |
-
client = AsyncClient()
|
64 |
-
response = await client.generate(model_id, prompt, negative_prompt)
|
65 |
-
task_id = response["task_id"]
|
66 |
-
request_id = response["request_id"]
|
67 |
-
|
68 |
-
while True:
|
69 |
-
generated_images = await client.get_images(task_id, request_id)
|
70 |
-
|
71 |
-
if "img_urls" in generated_images:
|
72 |
-
for img_url in generated_images["img_urls"]:
|
73 |
-
# Delete the initial reply message
|
74 |
-
await reply_message.delete()
|
75 |
-
|
76 |
-
# Send the generated image
|
77 |
-
await event.reply(file=img_url)
|
78 |
-
break # Exit the loop when images are available
|
79 |
-
else:
|
80 |
-
# Wait for a few seconds before checking again
|
81 |
-
await asyncio.sleep(5)
|
82 |
-
|
83 |
-
# Optionally, you can add a timeout to avoid an infinite loop
|
84 |
-
timeout_seconds = 600 # 10 minutes (adjust as needed)
|
85 |
-
if timeout_seconds <= 0:
|
86 |
-
await reply_message.edit("Image generation timed out.")
|
87 |
-
break
|
88 |
-
|
89 |
-
timeout_seconds -= 5 # Decrement timeout by 5 seconds
|
90 |
-
|
91 |
-
|
92 |
-
@client.on(events.NewMessage(pattern=r"/meinamix"))
|
93 |
-
async def meinamix_handler(event):
|
94 |
-
await generate_image_handler(event, model_id=2)
|
95 |
-
|
96 |
-
|
97 |
-
@client.on(events.NewMessage(pattern=r"/sushi"))
|
98 |
-
async def darksushi_handler(event):
|
99 |
-
await generate_image_handler(event, model_id=7)
|
100 |
-
|
101 |
-
|
102 |
-
@client.on(events.NewMessage(pattern=r"/meinahentai"))
|
103 |
-
async def meinahentai_handler(event):
|
104 |
-
await generate_image_handler(event, model_id=8)
|
105 |
-
|
106 |
-
|
107 |
-
@client.on(events.NewMessage(pattern=r"/darksushimix"))
|
108 |
-
async def darksushimix_handler(event):
|
109 |
-
await generate_image_handler(event, model_id=9)
|
110 |
-
|
111 |
-
|
112 |
-
@client.on(events.NewMessage(pattern=r"/anylora"))
|
113 |
-
async def anylora_handler(event):
|
114 |
-
await generate_image_handler(event, model_id=3)
|
115 |
-
|
116 |
-
|
117 |
-
@client.on(events.NewMessage(pattern=r"/cetusmix"))
|
118 |
-
async def cetusmix_handler(event):
|
119 |
-
await generate_image_handler(event, model_id=10)
|
120 |
-
|
121 |
-
|
122 |
-
@client.on(events.NewMessage(pattern=r"/darkv2"))
|
123 |
-
async def darkv_handler(event):
|
124 |
-
await generate_image_handler(event, model_id=14)
|
125 |
-
|
126 |
-
|
127 |
-
@client.on(events.NewMessage(pattern=r"/creative"))
|
128 |
-
async def creative_handler(event):
|
129 |
-
await generate_image_handler(event, model_id=12)
|
130 |
-
|
131 |
-
|
132 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/info.py
DELETED
@@ -1,221 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import os
|
3 |
-
import re
|
4 |
-
from html import escape
|
5 |
-
from random import choice
|
6 |
-
|
7 |
-
from telegram import ChatMemberAdministrator, Update
|
8 |
-
from telegram.constants import ChatID, ChatType, ParseMode
|
9 |
-
from telegram.error import BadRequest
|
10 |
-
from telegram.ext import CommandHandler, ContextTypes
|
11 |
-
from telegram.helpers import mention_html
|
12 |
-
|
13 |
-
from Database.sql.approve_sql import is_approved
|
14 |
-
from Infamous.karma import START_IMG
|
15 |
-
from Mikobot import DEV_USERS, DRAGONS, INFOPIC, OWNER_ID, function
|
16 |
-
from Mikobot.__main__ import STATS, USER_INFO
|
17 |
-
from Mikobot.plugins.helper_funcs.chat_status import support_plus, dev_plus
|
18 |
-
from Mikobot.plugins.users import get_user_id
|
19 |
-
|
20 |
-
# <=======================================================================================================>
|
21 |
-
|
22 |
-
|
23 |
-
# <================================================ FUNCTION =======================================================>
|
24 |
-
async def info(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
25 |
-
chat = update.effective_chat
|
26 |
-
message = update.effective_message
|
27 |
-
args = context.args
|
28 |
-
bot = context.bot
|
29 |
-
|
30 |
-
def reply_with_text(text):
|
31 |
-
return message.reply_text(text, parse_mode=ParseMode.HTML)
|
32 |
-
|
33 |
-
head = ""
|
34 |
-
premium = False
|
35 |
-
|
36 |
-
reply = await reply_with_text("<code>Getting information...</code>")
|
37 |
-
|
38 |
-
user_id = None
|
39 |
-
user_name = None
|
40 |
-
|
41 |
-
if len(args) >= 1:
|
42 |
-
if args[0][0] == "@":
|
43 |
-
user_name = args[0]
|
44 |
-
user_id = await get_user_id(user_name)
|
45 |
-
|
46 |
-
if not user_id:
|
47 |
-
try:
|
48 |
-
chat_obj = await bot.get_chat(user_name)
|
49 |
-
userid = chat_obj.id
|
50 |
-
except BadRequest:
|
51 |
-
await reply_with_text(
|
52 |
-
"I can't get information about this user/channel/group."
|
53 |
-
)
|
54 |
-
return
|
55 |
-
else:
|
56 |
-
userid = user_id
|
57 |
-
elif len(args) >= 1 and args[0].lstrip("-").isdigit():
|
58 |
-
userid = int(args[0])
|
59 |
-
elif message.reply_to_message and not message.reply_to_message.forum_topic_created:
|
60 |
-
if message.reply_to_message.sender_chat:
|
61 |
-
userid = message.reply_to_message.sender_chat.id
|
62 |
-
elif message.reply_to_message.from_user:
|
63 |
-
if message.reply_to_message.from_user.id == ChatID.FAKE_CHANNEL:
|
64 |
-
userid = message.reply_to_message.chat.id
|
65 |
-
else:
|
66 |
-
userid = message.reply_to_message.from_user.id
|
67 |
-
premium = message.reply_to_message.from_user.is_premium
|
68 |
-
elif not message.reply_to_message and not args:
|
69 |
-
if message.from_user.id == ChatID.FAKE_CHANNEL:
|
70 |
-
userid = message.sender_chat.id
|
71 |
-
else:
|
72 |
-
userid = message.from_user.id
|
73 |
-
premium = message.from_user.is_premium
|
74 |
-
|
75 |
-
try:
|
76 |
-
chat_obj = await bot.get_chat(userid)
|
77 |
-
except (BadRequest, UnboundLocalError):
|
78 |
-
await reply_with_text("I can't get information about this user/channel/group.")
|
79 |
-
return
|
80 |
-
|
81 |
-
if chat_obj.type == ChatType.PRIVATE:
|
82 |
-
if chat_obj.username:
|
83 |
-
head = f"⇨【 <b>USER INFORMATION</b> 】⇦\n\n"
|
84 |
-
if chat_obj.username.endswith("bot"):
|
85 |
-
head = f"⇨【 <b>BOT INFORMATION</b> 】⇦\n\n"
|
86 |
-
|
87 |
-
head += f"➲ <b>ID:</b> <code>{chat_obj.id}</code>"
|
88 |
-
head += f"\n➲ <b>First Name:</b> {chat_obj.first_name}"
|
89 |
-
if chat_obj.last_name:
|
90 |
-
head += f"\n➲ <b>Last Name:</b> {chat_obj.last_name}"
|
91 |
-
if chat_obj.username:
|
92 |
-
head += f"\n➲ <b>Username:</b> @{chat_obj.username}"
|
93 |
-
head += f"\n➲ <b>Permalink:</b> {mention_html(chat_obj.id, 'link')}"
|
94 |
-
|
95 |
-
if chat_obj.username and not chat_obj.username.endswith("bot"):
|
96 |
-
head += f"\n\n💎 <b>Premium User:</b> {premium}"
|
97 |
-
|
98 |
-
if chat_obj.bio:
|
99 |
-
head += f"\n\n<b>➲ Bio:</b> {chat_obj.bio}"
|
100 |
-
|
101 |
-
chat_member = await chat.get_member(chat_obj.id)
|
102 |
-
if isinstance(chat_member, ChatMemberAdministrator):
|
103 |
-
head += f"\n➲ <b>Presence:</b> {chat_member.status}"
|
104 |
-
if chat_member.custom_title:
|
105 |
-
head += f"\n➲ <b>Admin Title:</b> {chat_member.custom_title}"
|
106 |
-
else:
|
107 |
-
head += f"\n➲ <b>Presence:</b> {chat_member.status}"
|
108 |
-
|
109 |
-
if is_approved(chat.id, chat_obj.id):
|
110 |
-
head += f"\n➲ <b>Approved:</b> This user is approved in this chat."
|
111 |
-
|
112 |
-
disaster_level_present = False
|
113 |
-
|
114 |
-
if chat_obj.id == OWNER_ID:
|
115 |
-
head += "\n\n👑 <b>The disaster level of this person is My Owner.</b>"
|
116 |
-
disaster_level_present = True
|
117 |
-
elif chat_obj.id in DEV_USERS:
|
118 |
-
head += "\n\n🐉 <b>This user is a member of Infamous Hydra.</b>"
|
119 |
-
disaster_level_present = True
|
120 |
-
elif chat_obj.id in DRAGONS:
|
121 |
-
head += "\n\n🐲 <b>The disaster level of this person is Dragon.</b>"
|
122 |
-
disaster_level_present = True
|
123 |
-
if disaster_level_present:
|
124 |
-
head += " [?]"
|
125 |
-
|
126 |
-
for mod in USER_INFO:
|
127 |
-
try:
|
128 |
-
mod_info = mod.__user_info__(chat_obj.id).strip()
|
129 |
-
except TypeError:
|
130 |
-
mod_info = mod.__user_info__(chat_obj.id, chat.id).strip()
|
131 |
-
|
132 |
-
head += "\n\n" + mod_info if mod_info else ""
|
133 |
-
|
134 |
-
if chat_obj.type == ChatType.SENDER:
|
135 |
-
head = f"📨 Sender Chat Information:\n"
|
136 |
-
await reply_with_text("Found sender chat, getting information...")
|
137 |
-
head += f"<b>ID:</b> <code>{chat_obj.id}</code>"
|
138 |
-
if chat_obj.title:
|
139 |
-
head += f"\n🏷️ <b>Title:</b> {chat_obj.title}"
|
140 |
-
if chat_obj.username:
|
141 |
-
head += f"\n📧 <b>Username:</b> @{chat_obj.username}"
|
142 |
-
head += f"\n🔗 Permalink: {mention_html(chat_obj.id, 'link')}"
|
143 |
-
if chat_obj.description:
|
144 |
-
head += f"\n📝 <b>Description:</b> {chat_obj.description}"
|
145 |
-
|
146 |
-
elif chat_obj.type == ChatType.CHANNEL:
|
147 |
-
head = f"Channel Information:\n"
|
148 |
-
await reply_with_text("Found channel, getting information...")
|
149 |
-
head += f"<b>ID:</b> <code>{chat_obj.id}</code>"
|
150 |
-
if chat_obj.title:
|
151 |
-
head += f"\n<b>Title:</b> {chat_obj.title}"
|
152 |
-
if chat_obj.username:
|
153 |
-
head += f"\n<b>Username:</b> @{chat_obj.username}"
|
154 |
-
head += f"\nPermalink: {mention_html(chat_obj.id, 'link')}"
|
155 |
-
if chat_obj.description:
|
156 |
-
head += f"\n<b>Description:</b> {chat_obj.description}"
|
157 |
-
if chat_obj.linked_chat_id:
|
158 |
-
head += f"\n<b>Linked Chat ID:</b> <code>{chat_obj.linked_chat_id}</code>"
|
159 |
-
|
160 |
-
elif chat_obj.type in [ChatType.GROUP, ChatType.SUPERGROUP]:
|
161 |
-
head = f"Group Information:\n"
|
162 |
-
await reply_with_text("Found group, getting information...")
|
163 |
-
head += f"<b>ID:</b> <code>{chat_obj.id}</code>"
|
164 |
-
if chat_obj.title:
|
165 |
-
head += f"\n<b>Title:</b> {chat_obj.title}"
|
166 |
-
if chat_obj.username:
|
167 |
-
head += f"\n<b>Username:</b> @{chat_obj.username}"
|
168 |
-
head += f"\nPermalink: {mention_html(chat_obj.id, 'link')}"
|
169 |
-
if chat_obj.description:
|
170 |
-
head += f"\n<b>Description:</b> {chat_obj.description}"
|
171 |
-
|
172 |
-
if INFOPIC:
|
173 |
-
try:
|
174 |
-
if chat_obj.photo:
|
175 |
-
_file = await chat_obj.photo.get_big_file()
|
176 |
-
await _file.download_to_drive(f"{chat_obj.id}.png")
|
177 |
-
await message.reply_photo(
|
178 |
-
photo=open(f"{chat_obj.id}.png", "rb"),
|
179 |
-
caption=(head),
|
180 |
-
parse_mode=ParseMode.HTML,
|
181 |
-
)
|
182 |
-
await reply.delete()
|
183 |
-
os.remove(f"{chat_obj.id}.png")
|
184 |
-
else:
|
185 |
-
await reply_with_text(escape(head))
|
186 |
-
except:
|
187 |
-
await reply_with_text(escape(head))
|
188 |
-
|
189 |
-
|
190 |
-
@dev_plus
|
191 |
-
async def stats(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
192 |
-
stats = "📊 <b>Miko-Bot's Statistics:</b>\n\n" + "\n".join(
|
193 |
-
[mod.__stats__() for mod in STATS]
|
194 |
-
)
|
195 |
-
result = re.sub(r"(\d+)", r"<code>\1</code>", stats)
|
196 |
-
|
197 |
-
await update.effective_message.reply_photo(
|
198 |
-
photo=str(choice(START_IMG)), caption=result, parse_mode=ParseMode.HTML
|
199 |
-
)
|
200 |
-
|
201 |
-
|
202 |
-
# <=================================================== HELP ====================================================>
|
203 |
-
|
204 |
-
|
205 |
-
__help__ = """
|
206 |
-
*Overall information about user:*
|
207 |
-
|
208 |
-
» /info : Fetch information.
|
209 |
-
"""
|
210 |
-
|
211 |
-
# <================================================ HANDLER =======================================================>
|
212 |
-
STATS_HANDLER = CommandHandler(["stats", "gstats"], stats, block=False)
|
213 |
-
INFO_HANDLER = CommandHandler(("info", "book"), info, block=False)
|
214 |
-
|
215 |
-
function(STATS_HANDLER)
|
216 |
-
function(INFO_HANDLER)
|
217 |
-
|
218 |
-
__mod_name__ = "INFO"
|
219 |
-
__command_list__ = ["info"]
|
220 |
-
__handlers__ = [INFO_HANDLER, STATS_HANDLER]
|
221 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/instadl.py
DELETED
@@ -1,66 +0,0 @@
|
|
1 |
-
# SOURCE https://github.com/Team-ProjectCodeX
|
2 |
-
# CREATED BY https://t.me/O_okarma
|
3 |
-
# PROVIDED BY https://t.me/ProjectCodeX
|
4 |
-
|
5 |
-
# <============================================== IMPORTS =========================================================>
|
6 |
-
from telegram import Update
|
7 |
-
from telegram.ext import CommandHandler, ContextTypes
|
8 |
-
|
9 |
-
from Mikobot import function
|
10 |
-
from Mikobot.state import state
|
11 |
-
|
12 |
-
# <=======================================================================================================>
|
13 |
-
|
14 |
-
DOWNLOADING_STICKER_ID = (
|
15 |
-
"CAACAgIAAxkBAAEDv_xlJWmh2-fKRwvLywJaFeGy9wmBKgACVQADr8ZRGmTn_PAl6RC_MAQ"
|
16 |
-
)
|
17 |
-
API_URL = "https://karma-api2.vercel.app/instadl" # Replace with your actual API URL
|
18 |
-
|
19 |
-
|
20 |
-
# <================================================ FUNCTION =======================================================>
|
21 |
-
async def instadl_command_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
22 |
-
if len(context.args) < 1:
|
23 |
-
await update.message.reply_text("Usage: /instadl [Instagram URL]")
|
24 |
-
return
|
25 |
-
|
26 |
-
link = context.args[0]
|
27 |
-
try:
|
28 |
-
downloading_sticker = await update.message.reply_sticker(DOWNLOADING_STICKER_ID)
|
29 |
-
|
30 |
-
# Make an asynchronous GET request to the API using httpx
|
31 |
-
response = await state.get(API_URL, params={"url": link})
|
32 |
-
data = response.json()
|
33 |
-
|
34 |
-
# Check if the API request was successful
|
35 |
-
if "content_url" in data:
|
36 |
-
content_url = data["content_url"]
|
37 |
-
|
38 |
-
# Determine content type from the URL
|
39 |
-
content_type = "video" if "video" in content_url else "photo"
|
40 |
-
|
41 |
-
# Reply with either photo or video
|
42 |
-
if content_type == "photo":
|
43 |
-
await update.message.reply_photo(content_url)
|
44 |
-
elif content_type == "video":
|
45 |
-
await update.message.reply_video(content_url)
|
46 |
-
else:
|
47 |
-
await update.message.reply_text("Unsupported content type.")
|
48 |
-
else:
|
49 |
-
await update.message.reply_text(
|
50 |
-
"Unable to fetch content. Please check the Instagram URL or try with another Instagram link."
|
51 |
-
)
|
52 |
-
|
53 |
-
except Exception as e:
|
54 |
-
print(e)
|
55 |
-
await update.message.reply_text(
|
56 |
-
"An error occurred while processing the request."
|
57 |
-
)
|
58 |
-
|
59 |
-
finally:
|
60 |
-
await downloading_sticker.delete()
|
61 |
-
|
62 |
-
|
63 |
-
function(
|
64 |
-
CommandHandler(["ig", "instagram", "insta", "instadl"], instadl_command_handler)
|
65 |
-
)
|
66 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/karma.py
DELETED
@@ -1,182 +0,0 @@
|
|
1 |
-
# https://github.com/Team-ProjectCodeX
|
2 |
-
# UPDATED BY https://t.me/O_okarma
|
3 |
-
# https://t.me/ProjectCodeX
|
4 |
-
|
5 |
-
# <============================================== IMPORTS =========================================================>
|
6 |
-
import asyncio
|
7 |
-
|
8 |
-
from pyrogram import filters
|
9 |
-
|
10 |
-
from Database.mongodb.karma_mongo import *
|
11 |
-
from Mikobot import OWNER_ID, app
|
12 |
-
from Mikobot.utils.can_restrict import can_restrict
|
13 |
-
from Mikobot.utils.errors import capture_err
|
14 |
-
|
15 |
-
# <=======================================================================================================>
|
16 |
-
|
17 |
-
karma_positive_group = 3
|
18 |
-
karma_negative_group = 4
|
19 |
-
|
20 |
-
|
21 |
-
# <================================================ FUNCTION =======================================================>
|
22 |
-
@app.on_message(
|
23 |
-
filters.text
|
24 |
-
& filters.group
|
25 |
-
& filters.incoming
|
26 |
-
& filters.reply
|
27 |
-
& filters.regex(
|
28 |
-
r"^(\+|\+\+|\+1|thx|tnx|ty|tq|thank you|thanx|thanks|pro|cool|good|agree|makasih|👍|\+\+ .+)$"
|
29 |
-
)
|
30 |
-
& ~filters.via_bot
|
31 |
-
& ~filters.bot,
|
32 |
-
group=karma_positive_group,
|
33 |
-
)
|
34 |
-
@capture_err
|
35 |
-
async def upvote(_, message):
|
36 |
-
if not await is_karma_on(message.chat.id):
|
37 |
-
return
|
38 |
-
reply_user = message.reply_to_message.from_user
|
39 |
-
current_user = message.from_user
|
40 |
-
if not (reply_user and current_user):
|
41 |
-
return
|
42 |
-
if reply_user.id == OWNER_ID:
|
43 |
-
await message.reply_text("How so pro?")
|
44 |
-
return
|
45 |
-
if reply_user.id == current_user.id:
|
46 |
-
return
|
47 |
-
|
48 |
-
chat_id = message.chat.id
|
49 |
-
user_id = reply_user.id
|
50 |
-
user_mention = reply_user.mention
|
51 |
-
current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
|
52 |
-
karma = current_karma["karma"] + 1 if current_karma else 1
|
53 |
-
new_karma = {"karma": karma}
|
54 |
-
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
|
55 |
-
await message.reply_text(
|
56 |
-
f"𝗜𝗻𝗰𝗿𝗲𝗺𝗲𝗻𝘁𝗲𝗱 𝗸𝗮𝗿𝗺𝗮 𝗼𝗳 {user_mention} 𝗯𝘆 1.\n**⭐️ 𝗧𝗢𝗧𝗔𝗟 𝗣𝗢𝗜𝗡𝗧𝗦:** {karma}"
|
57 |
-
)
|
58 |
-
|
59 |
-
|
60 |
-
@app.on_message(
|
61 |
-
filters.text
|
62 |
-
& filters.group
|
63 |
-
& filters.incoming
|
64 |
-
& filters.reply
|
65 |
-
& filters.regex(r"^(-|--|-1|not cool|disagree|worst|bad|👎|-- .+)$")
|
66 |
-
& ~filters.via_bot
|
67 |
-
& ~filters.bot,
|
68 |
-
group=karma_negative_group,
|
69 |
-
)
|
70 |
-
@capture_err
|
71 |
-
async def downvote(_, message):
|
72 |
-
if not await is_karma_on(message.chat.id):
|
73 |
-
return
|
74 |
-
reply_user = message.reply_to_message.from_user
|
75 |
-
current_user = message.from_user
|
76 |
-
if not (reply_user and current_user):
|
77 |
-
return
|
78 |
-
if reply_user.id == OWNER_ID:
|
79 |
-
await message.reply_text("I know him, so I'm not gonna do that, baby.")
|
80 |
-
return
|
81 |
-
if reply_user.id == current_user.id:
|
82 |
-
return
|
83 |
-
|
84 |
-
user_id = reply_user.id
|
85 |
-
user_mention = reply_user.mention
|
86 |
-
current_karma = await get_karma(message.chat.id, await int_to_alpha(user_id))
|
87 |
-
karma = current_karma["karma"] - 1 if current_karma else 0
|
88 |
-
new_karma = {"karma": karma}
|
89 |
-
await update_karma(message.chat.id, await int_to_alpha(user_id), new_karma)
|
90 |
-
await message.reply_text(
|
91 |
-
f"𝗗𝗲𝗰𝗿𝗲𝗺𝗲𝗻𝘁𝗲𝗱 𝗸𝗮𝗿𝗺𝗮 𝗼𝗳 {user_mention} 𝗯𝘆 1.\n**⭐️ 𝗧𝗢𝗧𝗔𝗟 𝗣𝗢𝗜𝗡𝗧𝗦:** {karma}"
|
92 |
-
)
|
93 |
-
|
94 |
-
|
95 |
-
@app.on_message(filters.command("karmastat") & filters.group)
|
96 |
-
@capture_err
|
97 |
-
async def karma(_, message):
|
98 |
-
if not message.reply_to_message:
|
99 |
-
m = await message.reply_text("Analyzing karma... This may take a while.")
|
100 |
-
karma = await get_karmas(message.chat.id)
|
101 |
-
if not karma:
|
102 |
-
await m.edit_text("No karma in the database for this chat.")
|
103 |
-
return
|
104 |
-
msg = f"**🎖 𝗞𝗔𝗥𝗠𝗔 𝗟𝗜𝗦𝗧 𝗢𝗙 {message.chat.title} :**\n"
|
105 |
-
limit = 0
|
106 |
-
karma_dicc = {}
|
107 |
-
for i in karma:
|
108 |
-
user_id = await alpha_to_int(i)
|
109 |
-
user_karma = karma[i]["karma"]
|
110 |
-
karma_dicc[str(user_id)] = user_karma
|
111 |
-
karma_arranged = dict(
|
112 |
-
sorted(karma_dicc.items(), key=lambda item: item[1], reverse=True)
|
113 |
-
)
|
114 |
-
if not karma_dicc:
|
115 |
-
await m.edit_text("No karma in the database for this chat.")
|
116 |
-
return
|
117 |
-
for user_idd, karma_count in karma_arranged.items():
|
118 |
-
if limit > 9:
|
119 |
-
break
|
120 |
-
try:
|
121 |
-
user = await _.get_users(int(user_idd))
|
122 |
-
await asyncio.sleep(0.8)
|
123 |
-
except Exception:
|
124 |
-
continue
|
125 |
-
first_name = user.first_name
|
126 |
-
if not first_name:
|
127 |
-
continue
|
128 |
-
msg += f"`{karma_count}` {(first_name[0:12] + '...') if len(first_name) > 12 else first_name}\n"
|
129 |
-
limit += 1
|
130 |
-
await m.edit_text(msg)
|
131 |
-
else:
|
132 |
-
user_id = message.reply_to_message.from_user.id
|
133 |
-
karma = await get_karma(message.chat.id, await int_to_alpha(user_id))
|
134 |
-
karma = karma["karma"] if karma else 0
|
135 |
-
await message.reply_text(f"**⭐️ 𝗧𝗢𝗧𝗔𝗟 𝗣𝗢𝗜𝗡𝗧𝗦:** {karma}")
|
136 |
-
|
137 |
-
|
138 |
-
@app.on_message(filters.command("karma"))
|
139 |
-
@can_restrict
|
140 |
-
async def karma_toggle_xd(_, message):
|
141 |
-
usage = "**Usage:**\n/karma [ON|OFF]"
|
142 |
-
if len(message.command) != 2:
|
143 |
-
return await message.reply_text(usage)
|
144 |
-
chat_id = message.chat.id
|
145 |
-
state = message.text.split(None, 1)[1].strip().lower()
|
146 |
-
|
147 |
-
if state == "on":
|
148 |
-
disabled = karmadb.find_one({"chat_id_toggle": chat_id})
|
149 |
-
if disabled:
|
150 |
-
karmadb.delete_one({"chat_id_toggle": chat_id})
|
151 |
-
await message.reply_text("Enabled the karma system.")
|
152 |
-
else:
|
153 |
-
await message.reply_text("Karma system is already enabled.")
|
154 |
-
elif state == "off":
|
155 |
-
disabled = karmadb.find_one({"chat_id_toggle": chat_id})
|
156 |
-
if disabled:
|
157 |
-
await message.reply_text("Karma system is already disabled.")
|
158 |
-
else:
|
159 |
-
karmadb.insert_one({"chat_id_toggle": chat_id})
|
160 |
-
await message.reply_text("Disabled the karma system.")
|
161 |
-
else:
|
162 |
-
await message.reply_text(usage)
|
163 |
-
|
164 |
-
|
165 |
-
# <=================================================== HELP ====================================================>
|
166 |
-
|
167 |
-
|
168 |
-
__mod_name__ = "KARMA"
|
169 |
-
__help__ = """
|
170 |
-
|
171 |
-
➠ *UPVOTE* - Use upvote keywords like "+", "+1", "thanks", etc. to upvote a message.
|
172 |
-
➠ *DOWNVOTE* - Use downvote keywords like "-", "-1", etc. to downvote a message.
|
173 |
-
|
174 |
-
➠ *Commands*
|
175 |
-
|
176 |
-
» /karmastat:- `Reply to a user to check that user's karma points`
|
177 |
-
|
178 |
-
» /karmastat:- `Send without replying to any message to check karma point list of top 10`
|
179 |
-
|
180 |
-
» /karma [OFF|ON] - `Enable or disable karma system in your chat.`
|
181 |
-
"""
|
182 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/log_channel.py
DELETED
@@ -1,257 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from datetime import datetime
|
3 |
-
from functools import wraps
|
4 |
-
|
5 |
-
from telegram.constants import ChatType
|
6 |
-
from telegram.ext import ContextTypes
|
7 |
-
|
8 |
-
from Mikobot import function
|
9 |
-
from Mikobot.plugins.helper_funcs.misc import is_module_loaded
|
10 |
-
|
11 |
-
FILENAME = __name__.rsplit(".", 1)[-1]
|
12 |
-
|
13 |
-
if is_module_loaded(FILENAME):
|
14 |
-
from telegram import Update
|
15 |
-
from telegram.constants import ParseMode
|
16 |
-
from telegram.error import BadRequest, Forbidden
|
17 |
-
from telegram.ext import CommandHandler, JobQueue
|
18 |
-
from telegram.helpers import escape_markdown
|
19 |
-
|
20 |
-
from Database.sql import log_channel_sql as sql
|
21 |
-
from Mikobot import EVENT_LOGS, LOGGER, dispatcher
|
22 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin
|
23 |
-
|
24 |
-
# <=======================================================================================================>
|
25 |
-
# <================================================ FUNCTION =======================================================>
|
26 |
-
def loggable(func):
|
27 |
-
@wraps(func)
|
28 |
-
async def log_action(
|
29 |
-
update: Update,
|
30 |
-
context: ContextTypes.DEFAULT_TYPE,
|
31 |
-
job_queue: JobQueue = None,
|
32 |
-
*args,
|
33 |
-
**kwargs,
|
34 |
-
):
|
35 |
-
if not job_queue:
|
36 |
-
result = await func(update, context, *args, **kwargs)
|
37 |
-
else:
|
38 |
-
result = await func(update, context, job_queue, *args, **kwargs)
|
39 |
-
|
40 |
-
chat = update.effective_chat
|
41 |
-
message = update.effective_message
|
42 |
-
|
43 |
-
if result and isinstance(result, str):
|
44 |
-
datetime_fmt = "%H:%M - %d-%m-%Y"
|
45 |
-
result += f"\nEvent stamp: {datetime.utcnow().strftime(datetime_fmt)}"
|
46 |
-
|
47 |
-
if chat.is_forum and chat.username:
|
48 |
-
result += f"\nLink: https://t.me/{chat.username}/{message.message_thread_id}/{message.message_id}"
|
49 |
-
|
50 |
-
if message.chat.type == chat.SUPERGROUP and message.chat.username:
|
51 |
-
result += (
|
52 |
-
f"\nLink: https://t.me/{chat.username}/{message.message_id}"
|
53 |
-
)
|
54 |
-
log_chat = sql.get_chat_log_channel(chat.id)
|
55 |
-
if log_chat:
|
56 |
-
await send_log(context, log_chat, chat.id, result)
|
57 |
-
|
58 |
-
return result
|
59 |
-
|
60 |
-
return log_action
|
61 |
-
|
62 |
-
def gloggable(func):
|
63 |
-
@wraps(func)
|
64 |
-
async def glog_action(
|
65 |
-
update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs
|
66 |
-
):
|
67 |
-
result = await func(update, context, *args, **kwargs)
|
68 |
-
chat = update.effective_chat
|
69 |
-
message = update.effective_message
|
70 |
-
|
71 |
-
if result:
|
72 |
-
datetime_fmt = "%H:%M - %d-%m-%Y"
|
73 |
-
result += f"\nEvent stamp: {datetime.utcnow().strftime(datetime_fmt)}"
|
74 |
-
if chat.is_forum and chat.username:
|
75 |
-
result += f"\nLink: https://t.me/{chat.username}/{message.message_thread_id}/{message.message_id}"
|
76 |
-
elif message.chat.type == chat.SUPERGROUP and message.chat.username:
|
77 |
-
result += (
|
78 |
-
f"\nLink: https://t.me/{chat.username}/{message.message_id}"
|
79 |
-
)
|
80 |
-
log_chat = str(EVENT_LOGS)
|
81 |
-
if log_chat:
|
82 |
-
await send_log(context, log_chat, chat.id, result)
|
83 |
-
|
84 |
-
return result
|
85 |
-
|
86 |
-
return glog_action
|
87 |
-
|
88 |
-
async def send_log(
|
89 |
-
context: ContextTypes.DEFAULT_TYPE,
|
90 |
-
log_chat_id: str,
|
91 |
-
orig_chat_id: str,
|
92 |
-
result: str,
|
93 |
-
):
|
94 |
-
bot = context.bot
|
95 |
-
try:
|
96 |
-
await bot.send_message(
|
97 |
-
log_chat_id,
|
98 |
-
result,
|
99 |
-
parse_mode=ParseMode.HTML,
|
100 |
-
disable_web_page_preview=True,
|
101 |
-
)
|
102 |
-
except BadRequest as excp:
|
103 |
-
if excp.message == "Chat not found":
|
104 |
-
try:
|
105 |
-
await bot.send_message(
|
106 |
-
orig_chat_id,
|
107 |
-
"This log channel has been deleted - unsetting.",
|
108 |
-
message_thread_id=1,
|
109 |
-
)
|
110 |
-
except:
|
111 |
-
await bot.send_message(
|
112 |
-
orig_chat_id,
|
113 |
-
"This log channel has been deleted - unsetting.",
|
114 |
-
)
|
115 |
-
sql.stop_chat_logging(orig_chat_id)
|
116 |
-
else:
|
117 |
-
LOGGER.warning(excp.message)
|
118 |
-
LOGGER.warning(result)
|
119 |
-
LOGGER.exception("Could not parse")
|
120 |
-
|
121 |
-
await bot.send_message(
|
122 |
-
log_chat_id,
|
123 |
-
result
|
124 |
-
+ "\n\nFormatting has been disabled due to an unexpected error.",
|
125 |
-
)
|
126 |
-
|
127 |
-
@check_admin(is_user=True)
|
128 |
-
async def logging(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
129 |
-
bot = context.bot
|
130 |
-
message = update.effective_message
|
131 |
-
chat = update.effective_chat
|
132 |
-
|
133 |
-
log_channel = sql.get_chat_log_channel(chat.id)
|
134 |
-
if log_channel:
|
135 |
-
log_channel_info = await bot.get_chat(log_channel)
|
136 |
-
await message.reply_text(
|
137 |
-
f"This group has all its logs sent to: {escape_markdown(log_channel_info.title)} (`{log_channel}`)",
|
138 |
-
parse_mode=ParseMode.MARKDOWN,
|
139 |
-
)
|
140 |
-
|
141 |
-
else:
|
142 |
-
await message.reply_text("No log channel has been set for this group!")
|
143 |
-
|
144 |
-
@check_admin(is_user=True)
|
145 |
-
async def setlog(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
146 |
-
bot = context.bot
|
147 |
-
message = update.effective_message
|
148 |
-
chat = update.effective_chat
|
149 |
-
if chat.type == ChatType.CHANNEL:
|
150 |
-
await bot.send_message(
|
151 |
-
chat.id,
|
152 |
-
"Now, forward the /setlog to the group you want to tie this channel to!",
|
153 |
-
)
|
154 |
-
|
155 |
-
elif message.forward_from_chat:
|
156 |
-
sql.set_chat_log_channel(chat.id, message.forward_from_chat.id)
|
157 |
-
|
158 |
-
try:
|
159 |
-
await bot.send_message(
|
160 |
-
message.forward_from_chat.id,
|
161 |
-
f"This channel has been set as the log channel for {chat.title or chat.first_name}.",
|
162 |
-
)
|
163 |
-
except Forbidden as excp:
|
164 |
-
if excp.message == "Forbidden: Bot is not a member of the channel chat":
|
165 |
-
if chat.is_forum:
|
166 |
-
await bot.send_message(
|
167 |
-
chat.id,
|
168 |
-
"Successfully set log channel!",
|
169 |
-
message_thread_id=message.message_thread_id,
|
170 |
-
)
|
171 |
-
else:
|
172 |
-
await bot.send_message(chat.id, "Successfully set log channel!")
|
173 |
-
else:
|
174 |
-
LOGGER.exception("Error in setting the log channel.")
|
175 |
-
|
176 |
-
if chat.is_forum:
|
177 |
-
await bot.send_message(
|
178 |
-
chat.id,
|
179 |
-
"Successfully set log channel!",
|
180 |
-
message_thread_id=message.message_thread_id,
|
181 |
-
)
|
182 |
-
else:
|
183 |
-
await bot.send_message(chat.id, "Successfully set log channel!")
|
184 |
-
|
185 |
-
else:
|
186 |
-
await message.reply_text(
|
187 |
-
"The steps to set a log channel are:\n"
|
188 |
-
" - Add bot to the desired channel (as an admin!)\n"
|
189 |
-
" - Send /setlog in the channel\n"
|
190 |
-
" - Forward the /setlog to the group\n",
|
191 |
-
)
|
192 |
-
|
193 |
-
@check_admin(is_user=True)
|
194 |
-
async def unsetlog(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
195 |
-
bot = context.bot
|
196 |
-
message = update.effective_message
|
197 |
-
chat = update.effective_chat
|
198 |
-
|
199 |
-
log_channel = sql.stop_chat_logging(chat.id)
|
200 |
-
if log_channel:
|
201 |
-
await bot.send_message(
|
202 |
-
log_channel,
|
203 |
-
f"Channel has been unlinked from {chat.title}",
|
204 |
-
)
|
205 |
-
await message.reply_text("Log channel has been un-set.")
|
206 |
-
|
207 |
-
else:
|
208 |
-
await message.reply_text("No log channel is set yet!")
|
209 |
-
|
210 |
-
def __stats__():
|
211 |
-
return f"• {sql.num_logchannels()} log channels set."
|
212 |
-
|
213 |
-
def __migrate__(old_chat_id, new_chat_id):
|
214 |
-
sql.migrate_chat(old_chat_id, new_chat_id)
|
215 |
-
|
216 |
-
async def __chat_settings__(chat_id, user_id):
|
217 |
-
log_channel = sql.get_chat_log_channel(chat_id)
|
218 |
-
if log_channel:
|
219 |
-
log_channel_info = await dispatcher.bot.get_chat(log_channel)
|
220 |
-
return f"This group has all its logs sent to: {escape_markdown(log_channel_info.title)} (`{log_channel}`)"
|
221 |
-
return "No log channel is set for this group!"
|
222 |
-
|
223 |
-
# <=================================================== HELP ====================================================>
|
224 |
-
|
225 |
-
__help__ = """
|
226 |
-
➠ *Admins Only*:
|
227 |
-
|
228 |
-
» /logchannel: Get log channel info.
|
229 |
-
|
230 |
-
» /setlog: Set the log channel.
|
231 |
-
|
232 |
-
» /unsetlog: Unset the log channel.
|
233 |
-
|
234 |
-
➠ *Setting the log channel is done by:*
|
235 |
-
➠ *Adding the bot to the desired channel (as an admin!)*
|
236 |
-
|
237 |
-
» Sending /setlog in the channel
|
238 |
-
» Forwarding the /setlog to the group
|
239 |
-
"""
|
240 |
-
|
241 |
-
__mod_name__ = "LOG-SET"
|
242 |
-
|
243 |
-
# <================================================ HANDLER =======================================================>
|
244 |
-
function(CommandHandler("logchannel", logging, block=False))
|
245 |
-
function(CommandHandler("setlog", setlog, block=False))
|
246 |
-
function(CommandHandler("unsetlog", unsetlog, block=False))
|
247 |
-
|
248 |
-
else:
|
249 |
-
# run anyway if module not loaded
|
250 |
-
def loggable(func):
|
251 |
-
return func
|
252 |
-
|
253 |
-
def gloggable(func):
|
254 |
-
return func
|
255 |
-
|
256 |
-
|
257 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/mute.py
DELETED
@@ -1,261 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import html
|
3 |
-
from typing import Union
|
4 |
-
|
5 |
-
from telegram import Bot, Chat, ChatMember, ChatPermissions, Update
|
6 |
-
from telegram.constants import ParseMode
|
7 |
-
from telegram.error import BadRequest
|
8 |
-
from telegram.ext import CommandHandler, ContextTypes
|
9 |
-
from telegram.helpers import mention_html
|
10 |
-
|
11 |
-
from Mikobot import LOGGER, function
|
12 |
-
from Mikobot.plugins.helper_funcs.chat_status import (
|
13 |
-
check_admin,
|
14 |
-
connection_status,
|
15 |
-
is_user_admin,
|
16 |
-
)
|
17 |
-
from Mikobot.plugins.helper_funcs.extraction import extract_user, extract_user_and_text
|
18 |
-
from Mikobot.plugins.helper_funcs.string_handling import extract_time
|
19 |
-
from Mikobot.plugins.log_channel import loggable
|
20 |
-
|
21 |
-
# <=======================================================================================================>
|
22 |
-
|
23 |
-
|
24 |
-
# <================================================ FUNCTION =======================================================>
|
25 |
-
async def check_user(user_id: int, bot: Bot, chat: Chat) -> Union[str, None]:
|
26 |
-
if not user_id:
|
27 |
-
reply = "You don't seem to be referring to a user or the ID specified is incorrect.."
|
28 |
-
return reply
|
29 |
-
|
30 |
-
try:
|
31 |
-
member = await chat.get_member(user_id)
|
32 |
-
except BadRequest as excp:
|
33 |
-
if excp.message == "User not found":
|
34 |
-
reply = "I can't seem to find this user"
|
35 |
-
return reply
|
36 |
-
else:
|
37 |
-
raise
|
38 |
-
|
39 |
-
if user_id == bot.id:
|
40 |
-
reply = "I'm not gonna MUTE myself, How high are you?"
|
41 |
-
return reply
|
42 |
-
|
43 |
-
if await is_user_admin(chat, user_id, member):
|
44 |
-
reply = "Sorry can't do that, this user is admin here."
|
45 |
-
return reply
|
46 |
-
|
47 |
-
return None
|
48 |
-
|
49 |
-
|
50 |
-
@connection_status
|
51 |
-
@loggable
|
52 |
-
@check_admin(permission="can_restrict_members", is_both=True)
|
53 |
-
async def mute(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
54 |
-
bot = context.bot
|
55 |
-
args = context.args
|
56 |
-
|
57 |
-
chat = update.effective_chat
|
58 |
-
user = update.effective_user
|
59 |
-
message = update.effective_message
|
60 |
-
|
61 |
-
user_id, reason = await extract_user_and_text(message, context, args)
|
62 |
-
reply = await check_user(user_id, bot, chat)
|
63 |
-
|
64 |
-
if reply:
|
65 |
-
await message.reply_text(reply)
|
66 |
-
return ""
|
67 |
-
|
68 |
-
member = await chat.get_member(user_id)
|
69 |
-
|
70 |
-
log = (
|
71 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
72 |
-
f"#MUTE\n"
|
73 |
-
f"<b>Admin:</b> {mention_html(user.id, user.first_name)}\n"
|
74 |
-
f"<b>User:</b> {mention_html(member.user.id, member.user.first_name)}"
|
75 |
-
)
|
76 |
-
|
77 |
-
if reason:
|
78 |
-
log += f"\n<b>Reason:</b> {reason}"
|
79 |
-
|
80 |
-
if member.status in [ChatMember.RESTRICTED, ChatMember.MEMBER]:
|
81 |
-
chat_permissions = ChatPermissions(can_send_messages=False)
|
82 |
-
await bot.restrict_chat_member(chat.id, user_id, chat_permissions)
|
83 |
-
await bot.sendMessage(
|
84 |
-
chat.id,
|
85 |
-
f"Muted <b>{html.escape(member.user.first_name)}</b> with no expiration date!",
|
86 |
-
parse_mode=ParseMode.HTML,
|
87 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
88 |
-
)
|
89 |
-
return log
|
90 |
-
|
91 |
-
else:
|
92 |
-
await message.reply_text("This user is already muted!")
|
93 |
-
|
94 |
-
return ""
|
95 |
-
|
96 |
-
|
97 |
-
@connection_status
|
98 |
-
@loggable
|
99 |
-
@check_admin(permission="can_restrict_members", is_both=True)
|
100 |
-
async def unmute(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
101 |
-
bot, args = context.bot, context.args
|
102 |
-
chat = update.effective_chat
|
103 |
-
user = update.effective_user
|
104 |
-
message = update.effective_message
|
105 |
-
|
106 |
-
user_id = await extract_user(message, context, args)
|
107 |
-
if not user_id:
|
108 |
-
await message.reply_text(
|
109 |
-
"You'll need to either give me a username to unmute, or reply to someone to be unmuted.",
|
110 |
-
)
|
111 |
-
return ""
|
112 |
-
|
113 |
-
member = await chat.get_member(int(user_id))
|
114 |
-
|
115 |
-
if member.status not in [ChatMember.LEFT, ChatMember.BANNED]:
|
116 |
-
if member.status != ChatMember.RESTRICTED:
|
117 |
-
await message.reply_text("This user already has the right to speak.")
|
118 |
-
else:
|
119 |
-
chat_permissions = ChatPermissions(
|
120 |
-
can_send_messages=True,
|
121 |
-
can_invite_users=True,
|
122 |
-
can_pin_messages=True,
|
123 |
-
can_send_polls=True,
|
124 |
-
can_change_info=True,
|
125 |
-
can_send_media_messages=True,
|
126 |
-
can_send_other_messages=True,
|
127 |
-
can_add_web_page_previews=True,
|
128 |
-
)
|
129 |
-
try:
|
130 |
-
await bot.restrict_chat_member(chat.id, int(user_id), chat_permissions)
|
131 |
-
except BadRequest:
|
132 |
-
pass
|
133 |
-
await bot.sendMessage(
|
134 |
-
chat.id,
|
135 |
-
f"I shall allow <b>{html.escape(member.user.first_name)}</b> to text!",
|
136 |
-
parse_mode=ParseMode.HTML,
|
137 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
138 |
-
)
|
139 |
-
return (
|
140 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
141 |
-
f"#UNMUTE\n"
|
142 |
-
f"<b>Admin:</b> {mention_html(user.id, user.first_name)}\n"
|
143 |
-
f"<b>User:</b> {mention_html(member.user.id, member.user.first_name)}"
|
144 |
-
)
|
145 |
-
else:
|
146 |
-
await message.reply_text(
|
147 |
-
"This user isn't even in the chat, unmuting them won't make them talk more than they "
|
148 |
-
"already do!",
|
149 |
-
)
|
150 |
-
|
151 |
-
return ""
|
152 |
-
|
153 |
-
|
154 |
-
@connection_status
|
155 |
-
@loggable
|
156 |
-
@check_admin(permission="can_restrict_members", is_both=True)
|
157 |
-
async def temp_mute(update: Update, context: ContextTypes.DEFAULT_TYPE) -> str:
|
158 |
-
bot, args = context.bot, context.args
|
159 |
-
chat = update.effective_chat
|
160 |
-
user = update.effective_user
|
161 |
-
message = update.effective_message
|
162 |
-
|
163 |
-
user_id, reason = await extract_user_and_text(message, context, args)
|
164 |
-
reply = await check_user(user_id, bot, chat)
|
165 |
-
|
166 |
-
if reply:
|
167 |
-
await message.reply_text(reply)
|
168 |
-
return ""
|
169 |
-
|
170 |
-
member = await chat.get_member(user_id)
|
171 |
-
|
172 |
-
if not reason:
|
173 |
-
await message.reply_text("You haven't specified a time to mute this user for!")
|
174 |
-
return ""
|
175 |
-
|
176 |
-
split_reason = reason.split(None, 1)
|
177 |
-
|
178 |
-
time_val = split_reason[0].lower()
|
179 |
-
if len(split_reason) > 1:
|
180 |
-
reason = split_reason[1]
|
181 |
-
else:
|
182 |
-
reason = ""
|
183 |
-
|
184 |
-
mutetime = await extract_time(message, time_val)
|
185 |
-
|
186 |
-
if not mutetime:
|
187 |
-
return ""
|
188 |
-
|
189 |
-
log = (
|
190 |
-
f"<b>{html.escape(chat.title)}:</b>\n"
|
191 |
-
f"#TEMP MUTED\n"
|
192 |
-
f"<b>Admin:</b> {mention_html(user.id, user.first_name)}\n"
|
193 |
-
f"<b>User:</b> {mention_html(member.user.id, member.user.first_name)}\n"
|
194 |
-
f"<b>Time:</b> {time_val}"
|
195 |
-
)
|
196 |
-
if reason:
|
197 |
-
log += f"\n<b>Reason:</b> {reason}"
|
198 |
-
|
199 |
-
try:
|
200 |
-
if member.status in [ChatMember.RESTRICTED, ChatMember.MEMBER]:
|
201 |
-
chat_permissions = ChatPermissions(can_send_messages=False)
|
202 |
-
await bot.restrict_chat_member(
|
203 |
-
chat.id,
|
204 |
-
user_id,
|
205 |
-
chat_permissions,
|
206 |
-
until_date=mutetime,
|
207 |
-
)
|
208 |
-
await bot.sendMessage(
|
209 |
-
chat.id,
|
210 |
-
f"Muted <b>{html.escape(member.user.first_name)}</b> for {time_val}!",
|
211 |
-
parse_mode=ParseMode.HTML,
|
212 |
-
message_thread_id=message.message_thread_id if chat.is_forum else None,
|
213 |
-
)
|
214 |
-
return log
|
215 |
-
else:
|
216 |
-
await message.reply_text("This user is already muted.")
|
217 |
-
|
218 |
-
except BadRequest as excp:
|
219 |
-
if excp.message == "Reply message not found":
|
220 |
-
# Do not reply
|
221 |
-
await message.reply_text(f"Muted for {time_val}!", quote=False)
|
222 |
-
return log
|
223 |
-
else:
|
224 |
-
LOGGER.warning(update)
|
225 |
-
LOGGER.exception(
|
226 |
-
"ERROR muting user %s in chat %s (%s) due to %s",
|
227 |
-
user_id,
|
228 |
-
chat.title,
|
229 |
-
chat.id,
|
230 |
-
excp.message,
|
231 |
-
)
|
232 |
-
await message.reply_text("Well damn, I can't mute that user.")
|
233 |
-
|
234 |
-
return ""
|
235 |
-
|
236 |
-
|
237 |
-
# <=================================================== HELP ====================================================>
|
238 |
-
|
239 |
-
|
240 |
-
__help__ = """
|
241 |
-
➠ *Admins only:*
|
242 |
-
|
243 |
-
» /mute <userhandle>: silences a user. Can also be used as a reply, muting the replied to user.
|
244 |
-
|
245 |
-
» /tmute <userhandle> x(m/h/d): mutes a user for x time. (via handle, or reply). `m` = `minutes`, `h` = `hours`, `d` = `days`.
|
246 |
-
|
247 |
-
» /unmute <userhandle>: unmutes a user. Can also be used as a reply, muting the replied to user.
|
248 |
-
"""
|
249 |
-
|
250 |
-
# <================================================ HANDLER =======================================================>
|
251 |
-
MUTE_HANDLER = CommandHandler("mute", mute, block=False)
|
252 |
-
UNMUTE_HANDLER = CommandHandler("unmute", unmute, block=False)
|
253 |
-
TEMPMUTE_HANDLER = CommandHandler(["tmute", "tempmute"], temp_mute, block=False)
|
254 |
-
|
255 |
-
function(MUTE_HANDLER)
|
256 |
-
function(UNMUTE_HANDLER)
|
257 |
-
function(TEMPMUTE_HANDLER)
|
258 |
-
|
259 |
-
__mod_name__ = "MUTE"
|
260 |
-
__handlers__ = [MUTE_HANDLER, UNMUTE_HANDLER, TEMPMUTE_HANDLER]
|
261 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/nekomode.py
DELETED
@@ -1,131 +0,0 @@
|
|
1 |
-
# SOURCE https://github.com/Team-ProjectCodeX
|
2 |
-
# CREATED BY https://t.me/O_okarma
|
3 |
-
# PROVIDED BY https://t.me/ProjectCodeX
|
4 |
-
# NEKOS
|
5 |
-
|
6 |
-
# <============================================== IMPORTS =========================================================>
|
7 |
-
import nekos
|
8 |
-
from telethon import events
|
9 |
-
|
10 |
-
from Database.mongodb.toggle_mongo import is_nekomode_on, nekomode_off, nekomode_on
|
11 |
-
from Mikobot import tbot
|
12 |
-
from Mikobot.state import state # Import the state function
|
13 |
-
|
14 |
-
# <=======================================================================================================>
|
15 |
-
|
16 |
-
url_sfw = "https://api.waifu.pics/sfw/"
|
17 |
-
|
18 |
-
allowed_commands = [
|
19 |
-
"waifu",
|
20 |
-
"neko",
|
21 |
-
"shinobu",
|
22 |
-
"megumin",
|
23 |
-
"bully",
|
24 |
-
"cuddle",
|
25 |
-
"cry",
|
26 |
-
"hug",
|
27 |
-
"awoo",
|
28 |
-
"kiss",
|
29 |
-
"lick",
|
30 |
-
"pat",
|
31 |
-
"smug",
|
32 |
-
"bonk",
|
33 |
-
"yeet",
|
34 |
-
"blush",
|
35 |
-
"smile",
|
36 |
-
"spank",
|
37 |
-
"wave",
|
38 |
-
"highfive",
|
39 |
-
"handhold",
|
40 |
-
"nom",
|
41 |
-
"bite",
|
42 |
-
"glomp",
|
43 |
-
"slap",
|
44 |
-
"hTojiy",
|
45 |
-
"wink",
|
46 |
-
"poke",
|
47 |
-
"dance",
|
48 |
-
"cringe",
|
49 |
-
"tickle",
|
50 |
-
]
|
51 |
-
|
52 |
-
|
53 |
-
# <================================================ FUNCTION =======================================================>
|
54 |
-
@tbot.on(events.NewMessage(pattern="/wallpaper"))
|
55 |
-
async def wallpaper(event):
|
56 |
-
chat_id = event.chat_id
|
57 |
-
nekomode_status = await is_nekomode_on(chat_id)
|
58 |
-
if nekomode_status:
|
59 |
-
target = "wallpaper"
|
60 |
-
img_url = nekos.img(
|
61 |
-
target
|
62 |
-
) # Replace nekos.img(target) with the correct function call
|
63 |
-
await event.reply(file=img_url)
|
64 |
-
|
65 |
-
|
66 |
-
@tbot.on(events.NewMessage(pattern="/nekomode on"))
|
67 |
-
async def enable_nekomode(event):
|
68 |
-
chat_id = event.chat_id
|
69 |
-
await nekomode_on(chat_id)
|
70 |
-
await event.reply("Nekomode has been enabled.")
|
71 |
-
|
72 |
-
|
73 |
-
@tbot.on(events.NewMessage(pattern="/nekomode off"))
|
74 |
-
async def disable_nekomode(event):
|
75 |
-
chat_id = event.chat_id
|
76 |
-
await nekomode_off(chat_id)
|
77 |
-
await event.reply("Nekomode has been disabled.")
|
78 |
-
|
79 |
-
|
80 |
-
@tbot.on(events.NewMessage(pattern=r"/(?:{})".format("|".join(allowed_commands))))
|
81 |
-
async def nekomode_commands(event):
|
82 |
-
chat_id = event.chat_id
|
83 |
-
nekomode_status = await is_nekomode_on(chat_id)
|
84 |
-
if nekomode_status:
|
85 |
-
target = event.raw_text[1:].lower() # Remove the slash before the command
|
86 |
-
if target in allowed_commands:
|
87 |
-
url = f"{url_sfw}{target}"
|
88 |
-
|
89 |
-
response = await state.get(url)
|
90 |
-
result = response.json()
|
91 |
-
animation_url = result["url"]
|
92 |
-
|
93 |
-
# Send animation
|
94 |
-
await event.respond(file=animation_url)
|
95 |
-
|
96 |
-
|
97 |
-
__help__ = """
|
98 |
-
*✨ Sends fun Gifs/Images*
|
99 |
-
|
100 |
-
➥ /nekomode on : Enables fun neko mode.
|
101 |
-
➥ /nekomode off : Disables fun neko mode
|
102 |
-
|
103 |
-
» /bully: sends random bully gifs.
|
104 |
-
» /neko: sends random neko gifs.
|
105 |
-
» /wallpaper: sends random wallpapers.
|
106 |
-
» /highfive: sends random highfive gifs.
|
107 |
-
» /tickle: sends random tickle GIFs.
|
108 |
-
» /wave: sends random wave GIFs.
|
109 |
-
» /smile: sends random smile GIFs.
|
110 |
-
» /feed: sends random feeding GIFs.
|
111 |
-
» /blush: sends random blush GIFs.
|
112 |
-
» /avatar: sends random avatar stickers.
|
113 |
-
» /waifu: sends random waifu stickers.
|
114 |
-
» /kiss: sends random kissing GIFs.
|
115 |
-
» /cuddle: sends random cuddle GIFs.
|
116 |
-
» /cry: sends random cry GIFs.
|
117 |
-
» /bonk: sends random cuddle GIFs.
|
118 |
-
» /smug: sends random smug GIFs.
|
119 |
-
» /slap: sends random slap GIFs.
|
120 |
-
» /hug: get hugged or hug a user.
|
121 |
-
» /pat: pats a user or get patted.
|
122 |
-
» /spank: sends a random spank gif.
|
123 |
-
» /dance: sends a random dance gif.
|
124 |
-
» /poke: sends a random poke gif.
|
125 |
-
» /wink: sends a random wink gif.
|
126 |
-
» /bite: sends random bite GIFs.
|
127 |
-
» /handhold: sends random handhold GIFs.
|
128 |
-
"""
|
129 |
-
|
130 |
-
__mod_name__ = "NEKO"
|
131 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/notes.py
DELETED
@@ -1,629 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import ast
|
3 |
-
import random
|
4 |
-
import re
|
5 |
-
from io import BytesIO
|
6 |
-
|
7 |
-
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Message, Update
|
8 |
-
from telegram.constants import MessageLimit, ParseMode
|
9 |
-
from telegram.error import BadRequest
|
10 |
-
from telegram.ext import (
|
11 |
-
CallbackQueryHandler,
|
12 |
-
CommandHandler,
|
13 |
-
ContextTypes,
|
14 |
-
MessageHandler,
|
15 |
-
filters,
|
16 |
-
)
|
17 |
-
from telegram.helpers import escape_markdown, mention_markdown
|
18 |
-
|
19 |
-
import Database.sql.notes_sql as sql
|
20 |
-
from Mikobot import DRAGONS, LOGGER, MESSAGE_DUMP, SUPPORT_CHAT, dispatcher, function
|
21 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
22 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin, connection_status
|
23 |
-
from Mikobot.plugins.helper_funcs.misc import build_keyboard, revert_buttons
|
24 |
-
from Mikobot.plugins.helper_funcs.msg_types import get_note_type
|
25 |
-
from Mikobot.plugins.helper_funcs.string_handling import (
|
26 |
-
escape_invalid_curly_brackets,
|
27 |
-
markdown_to_html,
|
28 |
-
)
|
29 |
-
|
30 |
-
from .cust_filters import MessageHandlerChecker
|
31 |
-
|
32 |
-
# <=======================================================================================================>
|
33 |
-
|
34 |
-
FILE_MATCHER = re.compile(r"^###file_id(!photo)?###:(.*?)(?:\s|$)")
|
35 |
-
STICKER_MATCHER = re.compile(r"^###sticker(!photo)?###:")
|
36 |
-
BUTTON_MATCHER = re.compile(r"^###button(!photo)?###:(.*?)(?:\s|$)")
|
37 |
-
MYFILE_MATCHER = re.compile(r"^###file(!photo)?###:")
|
38 |
-
MYPHOTO_MATCHER = re.compile(r"^###photo(!photo)?###:")
|
39 |
-
MYAUDIO_MATCHER = re.compile(r"^###audio(!photo)?###:")
|
40 |
-
MYVOICE_MATCHER = re.compile(r"^###voice(!photo)?###:")
|
41 |
-
MYVIDEO_MATCHER = re.compile(r"^###video(!photo)?###:")
|
42 |
-
MYVIDEONOTE_MATCHER = re.compile(r"^###video_note(!photo)?###:")
|
43 |
-
|
44 |
-
ENUM_FUNC_MAP = {
|
45 |
-
sql.Types.TEXT.value: dispatcher.bot.send_message,
|
46 |
-
sql.Types.BUTTON_TEXT.value: dispatcher.bot.send_message,
|
47 |
-
sql.Types.STICKER.value: dispatcher.bot.send_sticker,
|
48 |
-
sql.Types.DOCUMENT.value: dispatcher.bot.send_document,
|
49 |
-
sql.Types.PHOTO.value: dispatcher.bot.send_photo,
|
50 |
-
sql.Types.AUDIO.value: dispatcher.bot.send_audio,
|
51 |
-
sql.Types.VOICE.value: dispatcher.bot.send_voice,
|
52 |
-
sql.Types.VIDEO.value: dispatcher.bot.send_video,
|
53 |
-
}
|
54 |
-
|
55 |
-
|
56 |
-
# <================================================ FUNCTION =======================================================>
|
57 |
-
async def get(
|
58 |
-
update: Update,
|
59 |
-
context: ContextTypes.DEFAULT_TYPE,
|
60 |
-
notename,
|
61 |
-
show_none=True,
|
62 |
-
no_format=False,
|
63 |
-
):
|
64 |
-
bot = context.bot
|
65 |
-
chat_id = update.effective_message.chat.id
|
66 |
-
chat = update.effective_chat
|
67 |
-
note_chat_id = update.effective_chat.id
|
68 |
-
note = sql.get_note(note_chat_id, notename)
|
69 |
-
message = update.effective_message # type: Optional[Message]
|
70 |
-
|
71 |
-
if note:
|
72 |
-
if MessageHandlerChecker.check_user(update.effective_user.id):
|
73 |
-
return
|
74 |
-
# If we're replying to a message, reply to that message (unless it's an error)
|
75 |
-
if (
|
76 |
-
message.reply_to_message
|
77 |
-
and not message.reply_to_message.forum_topic_created
|
78 |
-
):
|
79 |
-
reply_id = message.reply_to_message.message_id
|
80 |
-
else:
|
81 |
-
reply_id = message.message_id
|
82 |
-
if note.is_reply:
|
83 |
-
if MESSAGE_DUMP:
|
84 |
-
try:
|
85 |
-
await bot.forward_message(
|
86 |
-
chat_id=chat_id,
|
87 |
-
from_chat_id=MESSAGE_DUMP,
|
88 |
-
message_id=note.value,
|
89 |
-
)
|
90 |
-
except BadRequest as excp:
|
91 |
-
if excp.message == "Message to forward not found":
|
92 |
-
await message.reply_text(
|
93 |
-
"This message seems to have been lost - I'll remove it "
|
94 |
-
"from your notes list.",
|
95 |
-
)
|
96 |
-
sql.rm_note(note_chat_id, notename)
|
97 |
-
else:
|
98 |
-
raise
|
99 |
-
else:
|
100 |
-
try:
|
101 |
-
await bot.forward_message(
|
102 |
-
chat_id=chat_id,
|
103 |
-
from_chat_id=chat_id,
|
104 |
-
message_id=markdown_to_html(note.value),
|
105 |
-
)
|
106 |
-
except BadRequest as excp:
|
107 |
-
if excp.message == "Message to forward not found":
|
108 |
-
await message.reply_text(
|
109 |
-
"Looks like the original sender of this note has deleted "
|
110 |
-
"their message - sorry! Get your bot admin to start using a "
|
111 |
-
"message dump to avoid this. I'll remove this note from "
|
112 |
-
"your saved notes.",
|
113 |
-
)
|
114 |
-
sql.rm_note(note_chat_id, notename)
|
115 |
-
else:
|
116 |
-
raise
|
117 |
-
else:
|
118 |
-
VALID_NOTE_FORMATTERS = [
|
119 |
-
"first",
|
120 |
-
"last",
|
121 |
-
"fullname",
|
122 |
-
"username",
|
123 |
-
"id",
|
124 |
-
"chatname",
|
125 |
-
"mention",
|
126 |
-
]
|
127 |
-
valid_format = escape_invalid_curly_brackets(
|
128 |
-
note.value,
|
129 |
-
VALID_NOTE_FORMATTERS,
|
130 |
-
)
|
131 |
-
if valid_format:
|
132 |
-
if not no_format:
|
133 |
-
if "%%%" in valid_format:
|
134 |
-
split = valid_format.split("%%%")
|
135 |
-
if all(split):
|
136 |
-
text = random.choice(split)
|
137 |
-
else:
|
138 |
-
text = valid_format
|
139 |
-
else:
|
140 |
-
text = valid_format
|
141 |
-
else:
|
142 |
-
text = valid_format
|
143 |
-
text = text.format(
|
144 |
-
first=escape_markdown(message.from_user.first_name),
|
145 |
-
last=escape_markdown(
|
146 |
-
message.from_user.last_name or message.from_user.first_name,
|
147 |
-
),
|
148 |
-
fullname=escape_markdown(
|
149 |
-
" ".join(
|
150 |
-
[message.from_user.first_name, message.from_user.last_name]
|
151 |
-
if message.from_user.last_name
|
152 |
-
else [message.from_user.first_name],
|
153 |
-
),
|
154 |
-
),
|
155 |
-
username="@" + message.from_user.username
|
156 |
-
if message.from_user.username
|
157 |
-
else mention_markdown(
|
158 |
-
message.from_user.id,
|
159 |
-
message.from_user.first_name,
|
160 |
-
),
|
161 |
-
mention=mention_markdown(
|
162 |
-
message.from_user.id,
|
163 |
-
message.from_user.first_name,
|
164 |
-
),
|
165 |
-
chatname=escape_markdown(
|
166 |
-
message.chat.title
|
167 |
-
if message.chat.type != "private"
|
168 |
-
else message.from_user.first_name,
|
169 |
-
),
|
170 |
-
id=message.from_user.id,
|
171 |
-
)
|
172 |
-
else:
|
173 |
-
text = ""
|
174 |
-
|
175 |
-
keyb = []
|
176 |
-
parseMode = ParseMode.HTML
|
177 |
-
buttons = sql.get_buttons(note_chat_id, notename)
|
178 |
-
if no_format:
|
179 |
-
parseMode = None
|
180 |
-
text += revert_buttons(buttons)
|
181 |
-
else:
|
182 |
-
keyb = build_keyboard(buttons)
|
183 |
-
|
184 |
-
keyboard = InlineKeyboardMarkup(keyb)
|
185 |
-
|
186 |
-
try:
|
187 |
-
if note.msgtype in (sql.Types.BUTTON_TEXT, sql.Types.TEXT):
|
188 |
-
await bot.send_message(
|
189 |
-
chat_id,
|
190 |
-
markdown_to_html(text),
|
191 |
-
reply_to_message_id=reply_id,
|
192 |
-
parse_mode=parseMode,
|
193 |
-
disable_web_page_preview=True,
|
194 |
-
reply_markup=keyboard,
|
195 |
-
message_thread_id=message.message_thread_id
|
196 |
-
if chat.is_forum
|
197 |
-
else None,
|
198 |
-
)
|
199 |
-
else:
|
200 |
-
await ENUM_FUNC_MAP[note.msgtype](
|
201 |
-
chat_id,
|
202 |
-
note.file,
|
203 |
-
caption=markdown_to_html(text),
|
204 |
-
reply_to_message_id=reply_id,
|
205 |
-
parse_mode=parseMode,
|
206 |
-
disable_web_page_preview=True,
|
207 |
-
reply_markup=keyboard,
|
208 |
-
message_thread_id=message.message_thread_id
|
209 |
-
if chat.is_forum
|
210 |
-
else None,
|
211 |
-
)
|
212 |
-
|
213 |
-
except BadRequest as excp:
|
214 |
-
if excp.message == "Entity_mention_user_invalid":
|
215 |
-
await message.reply_text(
|
216 |
-
"Looks like you tried to mention someone I've never seen before. If you really "
|
217 |
-
"want to mention them, forward one of their messages to me, and I'll be able "
|
218 |
-
"to tag them!",
|
219 |
-
)
|
220 |
-
elif FILE_MATCHER.match(note.value):
|
221 |
-
await message.reply_text(
|
222 |
-
"This note was an incorrectly imported file from another bot - I can't use "
|
223 |
-
"it. If you really need it, you'll have to save it again. In "
|
224 |
-
"the meantime, I'll remove it from your notes list.",
|
225 |
-
)
|
226 |
-
sql.rm_note(note_chat_id, notename)
|
227 |
-
else:
|
228 |
-
await message.reply_text(
|
229 |
-
"This note could not be sent, as it is incorrectly formatted. Ask in "
|
230 |
-
f"@{SUPPORT_CHAT} if you can't figure out why!",
|
231 |
-
)
|
232 |
-
LOGGER.exception(
|
233 |
-
"Could not parse message #%s in chat %s",
|
234 |
-
notename,
|
235 |
-
str(note_chat_id),
|
236 |
-
)
|
237 |
-
LOGGER.warning("Message was: %s", str(note.value))
|
238 |
-
return
|
239 |
-
elif show_none:
|
240 |
-
await message.reply_text("This note doesn't exist")
|
241 |
-
|
242 |
-
|
243 |
-
@connection_status
|
244 |
-
async def cmd_get(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
245 |
-
bot, args = context.bot, context.args
|
246 |
-
if len(args) >= 2 and args[1].lower() == "noformat":
|
247 |
-
await get(update, context, args[0].lower(), show_none=True, no_format=True)
|
248 |
-
elif len(args) >= 1:
|
249 |
-
await get(update, context, args[0].lower(), show_none=True)
|
250 |
-
else:
|
251 |
-
await update.effective_message.reply_text("Get rekt")
|
252 |
-
|
253 |
-
|
254 |
-
@connection_status
|
255 |
-
async def hash_get(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
256 |
-
message = update.effective_message.text
|
257 |
-
fst_word = message.split()[0]
|
258 |
-
no_hash = fst_word[1:].lower()
|
259 |
-
await get(update, context, no_hash, show_none=False)
|
260 |
-
|
261 |
-
|
262 |
-
@connection_status
|
263 |
-
async def slash_get(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
264 |
-
message, chat_id = update.effective_message.text, update.effective_chat.id
|
265 |
-
no_slash = message[1:]
|
266 |
-
note_list = sql.get_all_chat_notes(chat_id)
|
267 |
-
|
268 |
-
try:
|
269 |
-
noteid = note_list[int(no_slash) - 1]
|
270 |
-
note_name = str(noteid).strip(">").split()[1]
|
271 |
-
await get(update, context, note_name, show_none=False)
|
272 |
-
except IndexError:
|
273 |
-
await update.effective_message.reply_text("Wrong Note ID 😾")
|
274 |
-
|
275 |
-
|
276 |
-
@connection_status
|
277 |
-
@check_admin(is_user=True)
|
278 |
-
async def save(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
279 |
-
chat_id = update.effective_chat.id
|
280 |
-
msg = update.effective_message # type: Optional[Message]
|
281 |
-
if len(context.args) < 1:
|
282 |
-
await msg.reply_text("You should give the note a name.")
|
283 |
-
return
|
284 |
-
|
285 |
-
note_name, text, data_type, content, buttons = get_note_type(msg)
|
286 |
-
note_name = note_name.lower()
|
287 |
-
if data_type is None:
|
288 |
-
await msg.reply_text("Dude, there's no note content")
|
289 |
-
return
|
290 |
-
|
291 |
-
sql.add_note_to_db(
|
292 |
-
chat_id,
|
293 |
-
note_name,
|
294 |
-
text,
|
295 |
-
data_type,
|
296 |
-
buttons=buttons,
|
297 |
-
file=content,
|
298 |
-
)
|
299 |
-
|
300 |
-
await msg.reply_text(
|
301 |
-
f"Yas! Added `{note_name}`.\nGet it with /get `{note_name}`, or `#{note_name}`",
|
302 |
-
parse_mode=ParseMode.MARKDOWN,
|
303 |
-
)
|
304 |
-
|
305 |
-
if (
|
306 |
-
msg.reply_to_message
|
307 |
-
and msg.reply_to_message.from_user.is_bot
|
308 |
-
and not msg.reply_to_message.forum_topic_created
|
309 |
-
):
|
310 |
-
if text:
|
311 |
-
await msg.reply_text(
|
312 |
-
"Seems like you're trying to save a message from a bot. Unfortunately, "
|
313 |
-
"bots can't forward bot messages, so I can't save the exact message. "
|
314 |
-
"\nI'll save all the text I can, but if you want more, you'll have to "
|
315 |
-
"forward the message yourself, and then save it.",
|
316 |
-
)
|
317 |
-
else:
|
318 |
-
await msg.reply_text(
|
319 |
-
"Bots are kinda handicapped by telegram, making it hard for bots to "
|
320 |
-
"interact with other bots, so I can't save this message "
|
321 |
-
"like I usually would - do you mind forwarding it and "
|
322 |
-
"then saving that new message? Thanks!",
|
323 |
-
)
|
324 |
-
return
|
325 |
-
|
326 |
-
|
327 |
-
@connection_status
|
328 |
-
@check_admin(is_user=True)
|
329 |
-
async def clear(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
330 |
-
args = context.args
|
331 |
-
chat_id = update.effective_chat.id
|
332 |
-
if len(args) >= 1:
|
333 |
-
notename = args[0].lower()
|
334 |
-
|
335 |
-
if sql.rm_note(chat_id, notename):
|
336 |
-
await update.effective_message.reply_text("Successfully removed note.")
|
337 |
-
else:
|
338 |
-
await update.effective_message.reply_text(
|
339 |
-
"That's not a note in my database!"
|
340 |
-
)
|
341 |
-
|
342 |
-
|
343 |
-
async def clearall(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
344 |
-
chat = update.effective_chat
|
345 |
-
user = update.effective_user
|
346 |
-
member = await chat.get_member(user.id)
|
347 |
-
if member.status != "creator" and user.id not in DRAGONS:
|
348 |
-
await update.effective_message.reply_text(
|
349 |
-
"Only the chat owner can clear all notes at once.",
|
350 |
-
)
|
351 |
-
else:
|
352 |
-
buttons = InlineKeyboardMarkup(
|
353 |
-
[
|
354 |
-
[
|
355 |
-
InlineKeyboardButton(
|
356 |
-
text="Delete all notes",
|
357 |
-
callback_data="notes_rmall",
|
358 |
-
),
|
359 |
-
],
|
360 |
-
[InlineKeyboardButton(text="Cancel", callback_data="notes_cancel")],
|
361 |
-
],
|
362 |
-
)
|
363 |
-
await update.effective_message.reply_text(
|
364 |
-
f"Are you sure you would like to clear ALL notes in {chat.title}? This action cannot be undone.",
|
365 |
-
reply_markup=buttons,
|
366 |
-
parse_mode=ParseMode.MARKDOWN,
|
367 |
-
)
|
368 |
-
|
369 |
-
|
370 |
-
async def clearall_btn(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
371 |
-
query = update.callback_query
|
372 |
-
chat = update.effective_chat
|
373 |
-
message = update.effective_message
|
374 |
-
member = await chat.get_member(query.from_user.id)
|
375 |
-
if query.data == "notes_rmall":
|
376 |
-
if member.status == "creator" or query.from_user.id in DRAGONS:
|
377 |
-
note_list = sql.get_all_chat_notes(chat.id)
|
378 |
-
try:
|
379 |
-
for notename in note_list:
|
380 |
-
note = notename.name.lower()
|
381 |
-
sql.rm_note(chat.id, note)
|
382 |
-
await message.edit_text("Deleted all notes.")
|
383 |
-
except BadRequest:
|
384 |
-
return
|
385 |
-
|
386 |
-
if member.status == "administrator":
|
387 |
-
await query.answer("Only owner of the chat can do this.")
|
388 |
-
|
389 |
-
if member.status == "member":
|
390 |
-
await query.answer("You need to be admin to do this.")
|
391 |
-
elif query.data == "notes_cancel":
|
392 |
-
if member.status == "creator" or query.from_user.id in DRAGONS:
|
393 |
-
await message.edit_text("Clearing of all notes has been cancelled.")
|
394 |
-
return
|
395 |
-
if member.status == "administrator":
|
396 |
-
await query.answer("Only owner of the chat can do this.")
|
397 |
-
if member.status == "member":
|
398 |
-
await query.answer("You need to be admin to do this.")
|
399 |
-
|
400 |
-
|
401 |
-
@connection_status
|
402 |
-
async def list_notes(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
403 |
-
chat_id = update.effective_chat.id
|
404 |
-
note_list = sql.get_all_chat_notes(chat_id)
|
405 |
-
notes = len(note_list) + 1
|
406 |
-
msg = "Get note by `/notenumber` or `#notename` \n\n *ID* *Note* \n"
|
407 |
-
for note_id, note in zip(range(1, notes), note_list):
|
408 |
-
if note_id < 10:
|
409 |
-
note_name = f"`{note_id:2}.` `#{(note.name.lower())}`\n"
|
410 |
-
else:
|
411 |
-
note_name = f"`{note_id}.` `#{(note.name.lower())}`\n"
|
412 |
-
if len(msg) + len(note_name) > MessageLimit.MAX_TEXT_LENGTH:
|
413 |
-
await update.effective_message.reply_text(
|
414 |
-
msg, parse_mode=ParseMode.MARKDOWN
|
415 |
-
)
|
416 |
-
msg = ""
|
417 |
-
msg += note_name
|
418 |
-
|
419 |
-
if not note_list:
|
420 |
-
try:
|
421 |
-
await update.effective_message.reply_text("No notes in this chat!")
|
422 |
-
except BadRequest:
|
423 |
-
await update.effective_message.reply_text(
|
424 |
-
"No notes in this chat!", quote=False
|
425 |
-
)
|
426 |
-
|
427 |
-
elif len(msg) != 0:
|
428 |
-
await update.effective_message.reply_text(msg, parse_mode=ParseMode.MARKDOWN)
|
429 |
-
|
430 |
-
|
431 |
-
async def __import_data__(chat_id, data, message: Message):
|
432 |
-
failures = []
|
433 |
-
for notename, notedata in data.get("extra", {}).items():
|
434 |
-
match = FILE_MATCHER.match(notedata)
|
435 |
-
matchsticker = STICKER_MATCHER.match(notedata)
|
436 |
-
matchbtn = BUTTON_MATCHER.match(notedata)
|
437 |
-
matchfile = MYFILE_MATCHER.match(notedata)
|
438 |
-
matchphoto = MYPHOTO_MATCHER.match(notedata)
|
439 |
-
matchaudio = MYAUDIO_MATCHER.match(notedata)
|
440 |
-
matchvoice = MYVOICE_MATCHER.match(notedata)
|
441 |
-
matchvideo = MYVIDEO_MATCHER.match(notedata)
|
442 |
-
matchvn = MYVIDEONOTE_MATCHER.match(notedata)
|
443 |
-
|
444 |
-
if match:
|
445 |
-
failures.append(notename)
|
446 |
-
notedata = notedata[match.end() :].strip()
|
447 |
-
if notedata:
|
448 |
-
sql.add_note_to_db(chat_id, notename[1:], notedata, sql.Types.TEXT)
|
449 |
-
elif matchsticker:
|
450 |
-
content = notedata[matchsticker.end() :].strip()
|
451 |
-
if content:
|
452 |
-
sql.add_note_to_db(
|
453 |
-
chat_id,
|
454 |
-
notename[1:],
|
455 |
-
notedata,
|
456 |
-
sql.Types.STICKER,
|
457 |
-
file=content,
|
458 |
-
)
|
459 |
-
elif matchbtn:
|
460 |
-
parse = notedata[matchbtn.end() :].strip()
|
461 |
-
notedata = parse.split("<###button###>")[0]
|
462 |
-
buttons = parse.split("<###button###>")[1]
|
463 |
-
buttons = ast.literal_eval(buttons)
|
464 |
-
if buttons:
|
465 |
-
sql.add_note_to_db(
|
466 |
-
chat_id,
|
467 |
-
notename[1:],
|
468 |
-
notedata,
|
469 |
-
sql.Types.BUTTON_TEXT,
|
470 |
-
buttons=buttons,
|
471 |
-
)
|
472 |
-
elif matchfile:
|
473 |
-
file = notedata[matchfile.end() :].strip()
|
474 |
-
file = file.split("<###TYPESPLIT###>")
|
475 |
-
notedata = file[1]
|
476 |
-
content = file[0]
|
477 |
-
if content:
|
478 |
-
sql.add_note_to_db(
|
479 |
-
chat_id,
|
480 |
-
notename[1:],
|
481 |
-
notedata,
|
482 |
-
sql.Types.DOCUMENT,
|
483 |
-
file=content,
|
484 |
-
)
|
485 |
-
elif matchphoto:
|
486 |
-
photo = notedata[matchphoto.end() :].strip()
|
487 |
-
photo = photo.split("<###TYPESPLIT###>")
|
488 |
-
notedata = photo[1]
|
489 |
-
content = photo[0]
|
490 |
-
if content:
|
491 |
-
sql.add_note_to_db(
|
492 |
-
chat_id,
|
493 |
-
notename[1:],
|
494 |
-
notedata,
|
495 |
-
sql.Types.PHOTO,
|
496 |
-
file=content,
|
497 |
-
)
|
498 |
-
elif matchaudio:
|
499 |
-
audio = notedata[matchaudio.end() :].strip()
|
500 |
-
audio = audio.split("<###TYPESPLIT###>")
|
501 |
-
notedata = audio[1]
|
502 |
-
content = audio[0]
|
503 |
-
if content:
|
504 |
-
sql.add_note_to_db(
|
505 |
-
chat_id,
|
506 |
-
notename[1:],
|
507 |
-
notedata,
|
508 |
-
sql.Types.AUDIO,
|
509 |
-
file=content,
|
510 |
-
)
|
511 |
-
elif matchvoice:
|
512 |
-
voice = notedata[matchvoice.end() :].strip()
|
513 |
-
voice = voice.split("<###TYPESPLIT###>")
|
514 |
-
notedata = voice[1]
|
515 |
-
content = voice[0]
|
516 |
-
if content:
|
517 |
-
sql.add_note_to_db(
|
518 |
-
chat_id,
|
519 |
-
notename[1:],
|
520 |
-
notedata,
|
521 |
-
sql.Types.VOICE,
|
522 |
-
file=content,
|
523 |
-
)
|
524 |
-
elif matchvideo:
|
525 |
-
video = notedata[matchvideo.end() :].strip()
|
526 |
-
video = video.split("<###TYPESPLIT###>")
|
527 |
-
notedata = video[1]
|
528 |
-
content = video[0]
|
529 |
-
if content:
|
530 |
-
sql.add_note_to_db(
|
531 |
-
chat_id,
|
532 |
-
notename[1:],
|
533 |
-
notedata,
|
534 |
-
sql.Types.VIDEO,
|
535 |
-
file=content,
|
536 |
-
)
|
537 |
-
elif matchvn:
|
538 |
-
video_note = notedata[matchvn.end() :].strip()
|
539 |
-
video_note = video_note.split("<###TYPESPLIT###>")
|
540 |
-
notedata = video_note[1]
|
541 |
-
content = video_note[0]
|
542 |
-
if content:
|
543 |
-
sql.add_note_to_db(
|
544 |
-
chat_id,
|
545 |
-
notename[1:],
|
546 |
-
notedata,
|
547 |
-
sql.Types.VIDEO_NOTE,
|
548 |
-
file=content,
|
549 |
-
)
|
550 |
-
else:
|
551 |
-
sql.add_note_to_db(chat_id, notename[1:], notedata, sql.Types.TEXT)
|
552 |
-
|
553 |
-
if failures:
|
554 |
-
with BytesIO(str.encode("\n".join(failures))) as output:
|
555 |
-
output.name = "failed_imports.txt"
|
556 |
-
await dispatcher.bot.send_document(
|
557 |
-
chat_id,
|
558 |
-
document=output,
|
559 |
-
filename="failed_imports.txt",
|
560 |
-
caption="These files/photos failed to import due to originating "
|
561 |
-
"from another bot. This is a telegram API restriction, and can't "
|
562 |
-
"be avoided. Sorry for the inconvenience!",
|
563 |
-
message_thread_id=message.message_thread_id
|
564 |
-
if message.chat.is_forum
|
565 |
-
else None,
|
566 |
-
)
|
567 |
-
|
568 |
-
|
569 |
-
def __stats__():
|
570 |
-
return f"• {sql.num_notes()} notes, across {sql.num_chats()} chats."
|
571 |
-
|
572 |
-
|
573 |
-
def __migrate__(old_chat_id, new_chat_id):
|
574 |
-
sql.migrate_chat(old_chat_id, new_chat_id)
|
575 |
-
|
576 |
-
|
577 |
-
def __chat_settings__(chat_id, user_id):
|
578 |
-
notes = sql.get_all_chat_notes(chat_id)
|
579 |
-
return f"There are `{len(notes)}` notes in this chat."
|
580 |
-
|
581 |
-
|
582 |
-
# <=================================================== HELP ====================================================>
|
583 |
-
|
584 |
-
|
585 |
-
__help__ = """
|
586 |
-
» /get <notename> : get the note with this notename
|
587 |
-
» #<notename> : same as /get
|
588 |
-
» /notes or /saved : list all saved notes in this chat
|
589 |
-
» /number : Will pull the note of that number in the list
|
590 |
-
➠ If you would like to retrieve the contents of a note without any formatting, use `/get <notename> noformat`. This can \
|
591 |
-
be useful when updating a current note
|
592 |
-
|
593 |
-
*Admins only:*
|
594 |
-
» /save <notename> <notedata> : saves notedata as a note with name notename
|
595 |
-
➠ A button can be added to a note by using standard markdown link syntax - the link should just be prepended with a \
|
596 |
-
`buttonurl:` section, as such: `[somelink](buttonurl:example.com)`. Check `/markdownhelp` for more info
|
597 |
-
» /save <notename> : save the replied message as a note with name notename
|
598 |
-
Separate diff replies by `%%%` to get random notes
|
599 |
-
➠ *Example:*
|
600 |
-
`/save notename
|
601 |
-
Reply 1
|
602 |
-
%%%
|
603 |
-
Reply 2
|
604 |
-
%%%
|
605 |
-
Reply 3`
|
606 |
-
» /clear <notename>: clear note with this name
|
607 |
-
» /removeallnotes: removes all notes from the group
|
608 |
-
➠ *Note:* Note names are case-insensitive, and they are automatically converted to lowercase before getting saved.
|
609 |
-
|
610 |
-
"""
|
611 |
-
|
612 |
-
__mod_name__ = "NOTES"
|
613 |
-
|
614 |
-
# <================================================ HANDLER =======================================================>
|
615 |
-
function(CommandHandler("get", cmd_get))
|
616 |
-
function(MessageHandler(filters.Regex(r"^#[^\s]+"), hash_get, block=False))
|
617 |
-
function(MessageHandler(filters.Regex(r"^/\d+$"), slash_get, block=False))
|
618 |
-
function(CommandHandler("save", save, block=False))
|
619 |
-
function(CommandHandler("clear", clear, block=False))
|
620 |
-
|
621 |
-
function(
|
622 |
-
DisableAbleCommandHandler(
|
623 |
-
["notes", "saved"], list_notes, admin_ok=True, block=False
|
624 |
-
)
|
625 |
-
)
|
626 |
-
|
627 |
-
function(DisableAbleCommandHandler("removeallnotes", clearall, block=False))
|
628 |
-
function(CallbackQueryHandler(clearall_btn, pattern=r"notes_.*", block=False))
|
629 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/ping.py
DELETED
@@ -1,39 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import time
|
3 |
-
|
4 |
-
from telegram import Update
|
5 |
-
from telegram.constants import ParseMode
|
6 |
-
from telegram.ext import CommandHandler, ContextTypes
|
7 |
-
|
8 |
-
from Mikobot import StartTime, function
|
9 |
-
from Mikobot.__main__ import get_readable_time
|
10 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin
|
11 |
-
|
12 |
-
# <=======================================================================================================>
|
13 |
-
|
14 |
-
|
15 |
-
# <================================================ FUNCTION =======================================================>
|
16 |
-
@check_admin(only_dev=True)
|
17 |
-
async def ptb_ping(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
18 |
-
msg = update.effective_message
|
19 |
-
|
20 |
-
start_time = time.time()
|
21 |
-
message = await msg.reply_text("Pining")
|
22 |
-
end_time = time.time()
|
23 |
-
telegram_ping = str(round((end_time - start_time) * 1000, 3)) + " ms"
|
24 |
-
uptime = get_readable_time((time.time() - StartTime))
|
25 |
-
|
26 |
-
await message.edit_text(
|
27 |
-
"🏓 <b>PONG</b>\n\n"
|
28 |
-
"<b>Time taken:</b> <code>{}</code>\n"
|
29 |
-
"<b>Uptime:</b> <code>{}</code>".format(telegram_ping, uptime),
|
30 |
-
parse_mode=ParseMode.HTML,
|
31 |
-
)
|
32 |
-
|
33 |
-
|
34 |
-
# <=======================================================================================================>
|
35 |
-
|
36 |
-
|
37 |
-
# <================================================ HANDLER =======================================================>
|
38 |
-
function(CommandHandler("ping", ptb_ping, block=False))
|
39 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/pokedex.py
DELETED
@@ -1,143 +0,0 @@
|
|
1 |
-
# SOURCE https://github.com/Team-ProjectCodeX
|
2 |
-
# CREATED BY https://t.me/O_okarma
|
3 |
-
# API BY https://www.github.com/SOME-1HING
|
4 |
-
# PROVIDED BY https://t.me/ProjectCodeX
|
5 |
-
|
6 |
-
# <============================================== IMPORTS =========================================================>
|
7 |
-
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
8 |
-
from telegram.ext import ContextTypes, CallbackQueryHandler, CommandHandler
|
9 |
-
|
10 |
-
from Mikobot import function
|
11 |
-
from Mikobot.state import state
|
12 |
-
|
13 |
-
# <=======================================================================================================>
|
14 |
-
|
15 |
-
|
16 |
-
# <================================================ FUNCTIONS =====================================================>
|
17 |
-
async def get_pokemon_info(name_or_id):
|
18 |
-
try:
|
19 |
-
response = await state.get(
|
20 |
-
f"https://sugoi-api.vercel.app/pokemon?name={name_or_id}"
|
21 |
-
)
|
22 |
-
if response.status_code == 200:
|
23 |
-
return response.json()
|
24 |
-
|
25 |
-
response = await state.get(
|
26 |
-
f"https://sugoi-api.vercel.app/pokemon?id={name_or_id}"
|
27 |
-
)
|
28 |
-
if response.status_code == 200:
|
29 |
-
return response.json()
|
30 |
-
|
31 |
-
except Exception as e:
|
32 |
-
print(f"An error occurred: {str(e)}")
|
33 |
-
|
34 |
-
return None
|
35 |
-
|
36 |
-
|
37 |
-
async def pokedex(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
38 |
-
try:
|
39 |
-
if context.args:
|
40 |
-
name_or_id = context.args[0]
|
41 |
-
pokemon_info = await get_pokemon_info(name_or_id)
|
42 |
-
|
43 |
-
if pokemon_info:
|
44 |
-
reply_message = (
|
45 |
-
f"🐾 𝗡𝗔𝗠𝗘: {pokemon_info['name']}\n"
|
46 |
-
f"•➥ 𝗜𝗗: {pokemon_info['id']}\n"
|
47 |
-
f"•➥ 𝗛𝗘𝗜𝗚𝗛𝗧: {pokemon_info['height']}\n"
|
48 |
-
f"•➥ 𝗪𝗘𝗜𝗚𝗛𝗧: {pokemon_info['weight']}\n"
|
49 |
-
)
|
50 |
-
|
51 |
-
abilities = ", ".join(
|
52 |
-
ability["ability"]["name"] for ability in pokemon_info["abilities"]
|
53 |
-
)
|
54 |
-
reply_message += f"•➥ 𝗔𝗕𝗜𝗟𝗜𝗧𝗜𝗘𝗦: {abilities}\n"
|
55 |
-
|
56 |
-
types = ", ".join(
|
57 |
-
type_info["type"]["name"] for type_info in pokemon_info["types"]
|
58 |
-
)
|
59 |
-
reply_message += f"•➥ 𝗧𝗬𝗣𝗘𝗦: {types}\n"
|
60 |
-
|
61 |
-
image_url = f"https://img.pokemondb.net/artwork/large/{pokemon_info['name']}.jpg"
|
62 |
-
|
63 |
-
# Create inline buttons
|
64 |
-
keyboard = [
|
65 |
-
[
|
66 |
-
InlineKeyboardButton(text="🔖 STATS", callback_data="stats"),
|
67 |
-
InlineKeyboardButton(text="⚜️ MOVES", callback_data="moves"),
|
68 |
-
]
|
69 |
-
]
|
70 |
-
|
71 |
-
reply_markup = InlineKeyboardMarkup(keyboard)
|
72 |
-
|
73 |
-
await update.message.reply_photo(
|
74 |
-
photo=image_url,
|
75 |
-
caption=reply_message,
|
76 |
-
reply_markup=reply_markup,
|
77 |
-
)
|
78 |
-
else:
|
79 |
-
await update.message.reply_text("Pokemon not found.")
|
80 |
-
else:
|
81 |
-
await update.message.reply_text("Please provide a Pokemon name or ID.")
|
82 |
-
except Exception as e:
|
83 |
-
await update.message.reply_text(f"An error occurred: {str(e)}")
|
84 |
-
|
85 |
-
|
86 |
-
async def callback_query_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
87 |
-
query = update.callback_query
|
88 |
-
await query.answer()
|
89 |
-
|
90 |
-
try:
|
91 |
-
name = query.message.caption.split("\n")[0].split(": ")[1]
|
92 |
-
pokemon_info = await get_pokemon_info(name)
|
93 |
-
|
94 |
-
if pokemon_info:
|
95 |
-
stats = "\n".join(
|
96 |
-
f"{stat['stat']['name'].upper()}: {stat['base_stat']}"
|
97 |
-
for stat in pokemon_info["stats"]
|
98 |
-
)
|
99 |
-
stats_message = f"•➥ STATS:\n{stats}\n"
|
100 |
-
|
101 |
-
moves = ", ".join(
|
102 |
-
move_info["move"]["name"] for move_info in pokemon_info["moves"]
|
103 |
-
)
|
104 |
-
moves_message = f"•➥ MOVES: {moves}"
|
105 |
-
|
106 |
-
if query.data == "stats":
|
107 |
-
await query.message.reply_text(stats_message)
|
108 |
-
elif query.data == "moves":
|
109 |
-
if len(moves_message) > 1000:
|
110 |
-
with open("moves.txt", "w") as file:
|
111 |
-
file.write(moves_message)
|
112 |
-
await query.message.reply_text(
|
113 |
-
"The moves exceed 1000 characters. Sending as a file.",
|
114 |
-
disable_web_page_preview=True,
|
115 |
-
)
|
116 |
-
await query.message.reply_document(document=open("moves.txt", "rb"))
|
117 |
-
else:
|
118 |
-
await query.message.reply_text(moves_message)
|
119 |
-
else:
|
120 |
-
await query.message.reply_text("Pokemon not found.")
|
121 |
-
except Exception as e:
|
122 |
-
await query.message.reply_text(f"An error occurred: {str(e)}")
|
123 |
-
|
124 |
-
|
125 |
-
# <================================================ HANDLER =======================================================>
|
126 |
-
# Add the command and callback query handlers to the dispatcher
|
127 |
-
function(CommandHandler("pokedex", pokedex, block=False))
|
128 |
-
function(
|
129 |
-
CallbackQueryHandler(callback_query_handler, pattern="^(stats|moves)$", block=False)
|
130 |
-
)
|
131 |
-
|
132 |
-
# <================================================ HANDLER =======================================================>
|
133 |
-
__help__ = """
|
134 |
-
|
135 |
-
🍥 *POKEMON SEARCH*
|
136 |
-
|
137 |
-
➠ *Commands*:
|
138 |
-
|
139 |
-
» /pokedex < Search > : Gives that pokemon info.
|
140 |
-
"""
|
141 |
-
|
142 |
-
__mod_name__ = "POKEDEX"
|
143 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/purge.py
DELETED
@@ -1,135 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from asyncio import sleep
|
3 |
-
|
4 |
-
from pyrogram import filters
|
5 |
-
from pyrogram.enums import ChatType
|
6 |
-
from pyrogram.errors import MessageDeleteForbidden, RPCError
|
7 |
-
from pyrogram.types import Message
|
8 |
-
|
9 |
-
from Mikobot import SUPPORT_CHAT, app
|
10 |
-
from Mikobot.utils.can_restrict import can_restrict
|
11 |
-
|
12 |
-
# <=======================================================================================================>
|
13 |
-
|
14 |
-
|
15 |
-
# <================================================ FUNCTION =======================================================>
|
16 |
-
@app.on_message(filters.command("purge"))
|
17 |
-
@can_restrict
|
18 |
-
async def purge(c: app, m: Message):
|
19 |
-
if m.chat.type != ChatType.SUPERGROUP:
|
20 |
-
await m.reply_text(text="Cannot purge messages in a basic group")
|
21 |
-
return
|
22 |
-
|
23 |
-
if m.reply_to_message:
|
24 |
-
message_ids = list(range(m.reply_to_message.id, m.id))
|
25 |
-
|
26 |
-
def divide_chunks(l: list, n: int = 100):
|
27 |
-
for i in range(0, len(l), n):
|
28 |
-
yield l[i : i + n]
|
29 |
-
|
30 |
-
# Dielete messages in chunks of 100 messages
|
31 |
-
m_list = list(divide_chunks(message_ids))
|
32 |
-
|
33 |
-
try:
|
34 |
-
for plist in m_list:
|
35 |
-
await c.delete_messages(
|
36 |
-
chat_id=m.chat.id,
|
37 |
-
message_ids=plist,
|
38 |
-
revoke=True,
|
39 |
-
)
|
40 |
-
await m.delete()
|
41 |
-
except MessageDeleteForbidden:
|
42 |
-
await m.reply_text(
|
43 |
-
text="Cannot delete all messages. The messages may be too old, I might not have delete rights, or this might not be a supergroup."
|
44 |
-
)
|
45 |
-
return
|
46 |
-
except RPCError as ef:
|
47 |
-
await m.reply_text(
|
48 |
-
text=f"""Some error occured, report to @{SUPPORT_CHAT}
|
49 |
-
|
50 |
-
<b>Error:</b> <code>{ef}</code>"""
|
51 |
-
)
|
52 |
-
|
53 |
-
count_del_msg = len(message_ids)
|
54 |
-
|
55 |
-
z = await m.reply_text(text=f"Deleted <i>{count_del_msg}</i> messages")
|
56 |
-
await sleep(3)
|
57 |
-
await z.delete()
|
58 |
-
return
|
59 |
-
await m.reply_text("Reply to a message to start purge !")
|
60 |
-
return
|
61 |
-
|
62 |
-
|
63 |
-
@app.on_message(filters.command("spurge"))
|
64 |
-
@can_restrict
|
65 |
-
async def spurge(c: app, m: Message):
|
66 |
-
if m.chat.type != ChatType.SUPERGROUP:
|
67 |
-
await m.reply_text(text="Cannot purge messages in a basic group")
|
68 |
-
return
|
69 |
-
|
70 |
-
if m.reply_to_message:
|
71 |
-
message_ids = list(range(m.reply_to_message.id, m.id))
|
72 |
-
|
73 |
-
def divide_chunks(l: list, n: int = 100):
|
74 |
-
for i in range(0, len(l), n):
|
75 |
-
yield l[i : i + n]
|
76 |
-
|
77 |
-
# Dielete messages in chunks of 100 messages
|
78 |
-
m_list = list(divide_chunks(message_ids))
|
79 |
-
|
80 |
-
try:
|
81 |
-
for plist in m_list:
|
82 |
-
await c.delete_messages(
|
83 |
-
chat_id=m.chat.id,
|
84 |
-
message_ids=plist,
|
85 |
-
revoke=True,
|
86 |
-
)
|
87 |
-
await m.delete()
|
88 |
-
except MessageDeleteForbidden:
|
89 |
-
await m.reply_text(
|
90 |
-
text="Cannot delete all messages. The messages may be too old, I might not have delete rights, or this might not be a supergroup."
|
91 |
-
)
|
92 |
-
return
|
93 |
-
except RPCError as ef:
|
94 |
-
await m.reply_text(
|
95 |
-
text=f"""Some error occured, report to @{SUPPORT_CHAT}
|
96 |
-
|
97 |
-
<b>Error:</b> <code>{ef}</code>"""
|
98 |
-
)
|
99 |
-
return
|
100 |
-
await m.reply_text("Reply to a message to start spurge !")
|
101 |
-
return
|
102 |
-
|
103 |
-
|
104 |
-
@app.on_message(
|
105 |
-
filters.command("del"),
|
106 |
-
group=9,
|
107 |
-
)
|
108 |
-
@can_restrict
|
109 |
-
async def del_msg(c: app, m: Message):
|
110 |
-
if m.chat.type != ChatType.SUPERGROUP:
|
111 |
-
return
|
112 |
-
|
113 |
-
if m.reply_to_message:
|
114 |
-
await m.delete()
|
115 |
-
await c.delete_messages(
|
116 |
-
chat_id=m.chat.id,
|
117 |
-
message_ids=m.reply_to_message.id,
|
118 |
-
)
|
119 |
-
else:
|
120 |
-
await m.reply_text(text="What do you wanna delete?")
|
121 |
-
return
|
122 |
-
|
123 |
-
|
124 |
-
# <=================================================== HELP ====================================================>
|
125 |
-
__help__ = """
|
126 |
-
❗️*Purge*
|
127 |
-
|
128 |
-
» /purge: Deletes messages upto replied message.
|
129 |
-
|
130 |
-
» /spurge: Deletes messages upto replied message without a success message.
|
131 |
-
|
132 |
-
» /del: Deletes a single message, used as a reply to message."""
|
133 |
-
|
134 |
-
__mod_name__ = "PURGE"
|
135 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/quotely.py
DELETED
@@ -1,294 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import base64
|
3 |
-
import os
|
4 |
-
from random import choice
|
5 |
-
|
6 |
-
from aiohttp import ContentTypeError
|
7 |
-
from PIL import Image
|
8 |
-
from telethon.tl import types
|
9 |
-
from telethon.utils import get_display_name, get_peer_id
|
10 |
-
|
11 |
-
from Mikobot import DEV_USERS
|
12 |
-
from Mikobot.events import register
|
13 |
-
|
14 |
-
# <=======================================================================================================>
|
15 |
-
|
16 |
-
|
17 |
-
# <================================================ CLASS & FUNCTION =======================================================>
|
18 |
-
class Quotly:
|
19 |
-
_API = "https://bot.lyo.su/quote/generate"
|
20 |
-
_entities = {
|
21 |
-
types.MessageEntityPhone: "phone_number",
|
22 |
-
types.MessageEntityMention: "mention",
|
23 |
-
types.MessageEntityBold: "bold",
|
24 |
-
types.MessageEntityCashtag: "cashtag",
|
25 |
-
types.MessageEntityStrike: "strikethrough",
|
26 |
-
types.MessageEntityHashtag: "hashtag",
|
27 |
-
types.MessageEntityEmail: "email",
|
28 |
-
types.MessageEntityMentionName: "text_mention",
|
29 |
-
types.MessageEntityUnderline: "underline",
|
30 |
-
types.MessageEntityUrl: "url",
|
31 |
-
types.MessageEntityTextUrl: "text_link",
|
32 |
-
types.MessageEntityBotCommand: "bot_command",
|
33 |
-
types.MessageEntityCode: "code",
|
34 |
-
types.MessageEntityPre: "pre",
|
35 |
-
}
|
36 |
-
|
37 |
-
async def _format_quote(self, event, reply=None, sender=None, type_="private"):
|
38 |
-
async def telegraph(file_):
|
39 |
-
file = file_ + ".png"
|
40 |
-
Image.open(file_).save(file, "PNG")
|
41 |
-
files = {"file": open(file, "rb").read()}
|
42 |
-
uri = (
|
43 |
-
"https://telegra.ph"
|
44 |
-
+ (
|
45 |
-
await async_searcher(
|
46 |
-
"https://telegra.ph/upload", post=True, data=files, re_json=True
|
47 |
-
)
|
48 |
-
)[0]["src"]
|
49 |
-
)
|
50 |
-
os.remove(file)
|
51 |
-
os.remove(file_)
|
52 |
-
return uri
|
53 |
-
|
54 |
-
reply = (
|
55 |
-
{
|
56 |
-
"name": get_display_name(reply.sender) or "Deleted Account",
|
57 |
-
"text": reply.raw_text,
|
58 |
-
"chatId": reply.chat_id,
|
59 |
-
}
|
60 |
-
if reply
|
61 |
-
else {}
|
62 |
-
)
|
63 |
-
|
64 |
-
is_fwd = event.fwd_from
|
65 |
-
name, last_name = None, None
|
66 |
-
|
67 |
-
if sender and sender.id not in DEV_USERS:
|
68 |
-
id_ = get_peer_id(sender)
|
69 |
-
name = get_display_name(sender)
|
70 |
-
elif not is_fwd:
|
71 |
-
id_ = event.sender_id
|
72 |
-
sender = await event.get_sender()
|
73 |
-
name = get_display_name(sender)
|
74 |
-
else:
|
75 |
-
id_, sender = None, None
|
76 |
-
name = is_fwd.from_name
|
77 |
-
if is_fwd.from_id:
|
78 |
-
id_ = get_peer_id(is_fwd.from_id)
|
79 |
-
try:
|
80 |
-
sender = await event.client.get_entity(id_)
|
81 |
-
name = get_display_name(sender)
|
82 |
-
except ValueError:
|
83 |
-
pass
|
84 |
-
if sender and hasattr(sender, "last_name"):
|
85 |
-
last_name = sender.last_name
|
86 |
-
|
87 |
-
entities = (
|
88 |
-
[
|
89 |
-
{
|
90 |
-
"type": self._entities[type(entity)],
|
91 |
-
**{k: v for k, v in entity.to_dict().items() if k != "_"},
|
92 |
-
}
|
93 |
-
for entity in event.entities
|
94 |
-
]
|
95 |
-
if event.entities
|
96 |
-
else []
|
97 |
-
)
|
98 |
-
|
99 |
-
message = {
|
100 |
-
"entities": entities,
|
101 |
-
"chatId": id_,
|
102 |
-
"avatar": True,
|
103 |
-
"from": {
|
104 |
-
"id": id_,
|
105 |
-
"first_name": (name or (sender.first_name if sender else None))
|
106 |
-
or "Deleted Account",
|
107 |
-
"last_name": last_name,
|
108 |
-
"username": sender.username if sender else None,
|
109 |
-
"language_code": "en",
|
110 |
-
"title": name,
|
111 |
-
"name": name or "Unknown",
|
112 |
-
"type": type_,
|
113 |
-
},
|
114 |
-
"text": event.raw_text,
|
115 |
-
"replyMessage": reply,
|
116 |
-
}
|
117 |
-
|
118 |
-
if event.document and event.document.thumbs:
|
119 |
-
file_ = await event.download_media(thumb=-1)
|
120 |
-
uri = await telegraph(file_)
|
121 |
-
message["media"] = {"url": uri}
|
122 |
-
|
123 |
-
return message
|
124 |
-
|
125 |
-
async def create_quotly(
|
126 |
-
self,
|
127 |
-
event,
|
128 |
-
url="https://quote-api.example.com/generate",
|
129 |
-
reply={},
|
130 |
-
bg=None,
|
131 |
-
sender=None,
|
132 |
-
OQAPI=True,
|
133 |
-
file_name="quote.webp",
|
134 |
-
):
|
135 |
-
if not isinstance(event, list):
|
136 |
-
event = [event]
|
137 |
-
if OQAPI:
|
138 |
-
url = Quotly._API
|
139 |
-
bg = bg or "#1b1429"
|
140 |
-
content = {
|
141 |
-
"type": "quote",
|
142 |
-
"format": "webp",
|
143 |
-
"backgroundColor": bg,
|
144 |
-
"width": 512,
|
145 |
-
"height": 768,
|
146 |
-
"scale": 2,
|
147 |
-
"messages": [
|
148 |
-
await self._format_quote(message, reply=reply, sender=sender)
|
149 |
-
for message in event
|
150 |
-
],
|
151 |
-
}
|
152 |
-
try:
|
153 |
-
request = await async_searcher(url, post=True, json=content, re_json=True)
|
154 |
-
except ContentTypeError as er:
|
155 |
-
if url != self._API:
|
156 |
-
return await self.create_quotly(
|
157 |
-
self._API, post=True, json=content, re_json=True
|
158 |
-
)
|
159 |
-
raise er
|
160 |
-
|
161 |
-
if request.get("ok"):
|
162 |
-
with open(file_name, "wb") as file:
|
163 |
-
image = base64.decodebytes(request["result"]["image"].encode("utf-8"))
|
164 |
-
file.write(image)
|
165 |
-
return file_name
|
166 |
-
raise Exception(str(request))
|
167 |
-
|
168 |
-
|
169 |
-
quotly = Quotly()
|
170 |
-
|
171 |
-
|
172 |
-
async def async_searcher(
|
173 |
-
url: str,
|
174 |
-
post: bool = None,
|
175 |
-
headers: dict = None,
|
176 |
-
params: dict = None,
|
177 |
-
json: dict = None,
|
178 |
-
data: dict = None,
|
179 |
-
ssl=None,
|
180 |
-
re_json: bool = False,
|
181 |
-
re_content: bool = False,
|
182 |
-
real: bool = False,
|
183 |
-
*args,
|
184 |
-
**kwargs
|
185 |
-
):
|
186 |
-
try:
|
187 |
-
import aiohttp
|
188 |
-
except ImportError:
|
189 |
-
raise DependencyMissingError(
|
190 |
-
"'aiohttp' is not installed!\nThis function requires aiohttp to be installed."
|
191 |
-
)
|
192 |
-
|
193 |
-
async with aiohttp.ClientSession(headers=headers) as client:
|
194 |
-
data = await (
|
195 |
-
client.post(url, json=json, data=data, ssl=ssl, *args, **kwargs)
|
196 |
-
if post
|
197 |
-
else client.get(url, params=params, ssl=ssl, *args, **kwargs)
|
198 |
-
)
|
199 |
-
return await (
|
200 |
-
data.json() if re_json else data.read() if re_content else data.text()
|
201 |
-
)
|
202 |
-
|
203 |
-
|
204 |
-
@register(pattern="^/q(?: |$)(.*)")
|
205 |
-
async def quott_(event):
|
206 |
-
match = event.pattern_match.group(1).strip()
|
207 |
-
if not event.is_reply:
|
208 |
-
return await event.reply("Please reply to a message.")
|
209 |
-
|
210 |
-
msg = await event.reply("Creating quote, please wait.")
|
211 |
-
reply = await event.get_reply_message()
|
212 |
-
replied_to, reply_ = None, None
|
213 |
-
|
214 |
-
if match:
|
215 |
-
spli_ = match.split(maxsplit=1)
|
216 |
-
if (spli_[0] in ["r", "reply"]) or (
|
217 |
-
spli_[0].isdigit() and int(spli_[0]) in range(1, 21)
|
218 |
-
):
|
219 |
-
if spli_[0].isdigit():
|
220 |
-
if not event.client.is_bot:
|
221 |
-
reply_ = await event.client.get_messages(
|
222 |
-
event.chat_id,
|
223 |
-
min_id=event.reply_to_msg_id - 1,
|
224 |
-
reverse=True,
|
225 |
-
limit=int(spli_[0]),
|
226 |
-
)
|
227 |
-
else:
|
228 |
-
id_ = reply.id
|
229 |
-
reply_ = []
|
230 |
-
for msg_ in range(id_, id_ + int(spli_[0])):
|
231 |
-
msh = await event.client.get_messages(event.chat_id, ids=msg_)
|
232 |
-
if msh:
|
233 |
-
reply_.append(msh)
|
234 |
-
else:
|
235 |
-
replied_to = await reply.get_reply_message()
|
236 |
-
try:
|
237 |
-
match = spli_[1]
|
238 |
-
except IndexError:
|
239 |
-
match = None
|
240 |
-
|
241 |
-
user = None
|
242 |
-
|
243 |
-
if not reply_:
|
244 |
-
reply_ = reply
|
245 |
-
|
246 |
-
if match:
|
247 |
-
match = match.split(maxsplit=1)
|
248 |
-
|
249 |
-
if match:
|
250 |
-
if match[0].startswith("@") or match[0].isdigit():
|
251 |
-
try:
|
252 |
-
match_ = await event.client.parse_id(match[0])
|
253 |
-
user = await event.client.get_entity(match_)
|
254 |
-
except ValueError:
|
255 |
-
pass
|
256 |
-
match = match[1] if len(match) == 2 else None
|
257 |
-
else:
|
258 |
-
match = match[0]
|
259 |
-
|
260 |
-
if match == "random":
|
261 |
-
match = choice(all_col)
|
262 |
-
|
263 |
-
try:
|
264 |
-
file = await quotly.create_quotly(
|
265 |
-
reply_, bg=match, reply=replied_to, sender=user
|
266 |
-
)
|
267 |
-
except Exception as er:
|
268 |
-
return await msg.edit(str(er))
|
269 |
-
|
270 |
-
message = await reply.reply("", file=file)
|
271 |
-
os.remove(file)
|
272 |
-
await msg.delete()
|
273 |
-
return message
|
274 |
-
|
275 |
-
|
276 |
-
# <=================================================== HELP ====================================================>
|
277 |
-
|
278 |
-
|
279 |
-
__mod_name__ = "QUOTELY"
|
280 |
-
|
281 |
-
__help__ = """
|
282 |
-
» /q : Create quote.
|
283 |
-
|
284 |
-
» /q r : Get replied quote.
|
285 |
-
|
286 |
-
» /q 2 ᴛᴏ 8 : Get multiple quotes.
|
287 |
-
|
288 |
-
» /q < any colour name > : Create any coloured quotes.
|
289 |
-
|
290 |
-
➠ Example:
|
291 |
-
|
292 |
-
» /q red , /q blue etc.
|
293 |
-
"""
|
294 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/reverse.py
DELETED
@@ -1,117 +0,0 @@
|
|
1 |
-
# CREATED BY: @Qewertyy
|
2 |
-
|
3 |
-
# <============================================== IMPORTS =========================================================>
|
4 |
-
import os
|
5 |
-
import traceback
|
6 |
-
|
7 |
-
from pyrogram import Client, filters
|
8 |
-
from pyrogram import types as t
|
9 |
-
|
10 |
-
from Mikobot import app
|
11 |
-
from Mikobot.state import state
|
12 |
-
|
13 |
-
from .telegraph import telegraph, upload_file
|
14 |
-
|
15 |
-
|
16 |
-
# <================================================ FUNCTIONS =====================================================>
|
17 |
-
@app.on_message(filters.command(["p", "pp", "reverse", "sauce"]))
|
18 |
-
async def reverseImageSearch(_: Client, m: t.Message):
|
19 |
-
try:
|
20 |
-
reply = await m.reply_text("`Downloading...`")
|
21 |
-
file = None
|
22 |
-
if not m.reply_to_message:
|
23 |
-
return await reply.edit("Reply to an image?")
|
24 |
-
if m.reply_to_message.document is False or m.reply_to_message.photo is False:
|
25 |
-
return await reply.edit("Reply to an image?")
|
26 |
-
if (
|
27 |
-
m.reply_to_message.document
|
28 |
-
and m.reply_to_message.document.mime_type
|
29 |
-
in ["image/png", "image/jpg", "image/jpeg"]
|
30 |
-
or m.reply_to_message.photo
|
31 |
-
):
|
32 |
-
if (
|
33 |
-
m.reply_to_message.document
|
34 |
-
and m.reply_to_message.document.file_size > 5242880
|
35 |
-
):
|
36 |
-
return await reply.edit("Reply to an image?")
|
37 |
-
file = await m.reply_to_message.download()
|
38 |
-
else:
|
39 |
-
return await reply.edit("Reply to an image?")
|
40 |
-
await reply.edit("`Uploading to the server...`")
|
41 |
-
imgUrl = upload_file(file)
|
42 |
-
os.remove(file)
|
43 |
-
if imgUrl is None:
|
44 |
-
return await reply.edit("Ran into an error.")
|
45 |
-
output = await reverse_image_search("google", f"https://graph.org/{imgUrl[0]}")
|
46 |
-
if output is None:
|
47 |
-
return await reply.edit("Ran into an error.")
|
48 |
-
|
49 |
-
names = output["content"]["bestResults"]["names"]
|
50 |
-
urls = output["content"]["bestResults"]["urls"]
|
51 |
-
btn = t.InlineKeyboardMarkup(
|
52 |
-
[[t.InlineKeyboardButton(text="IMAGE URL", url=urls[-1])]]
|
53 |
-
)
|
54 |
-
|
55 |
-
if len(names) > 10:
|
56 |
-
message = "\n".join(
|
57 |
-
[f"{index+1}. {name}" for index, name in enumerate(names[:10])]
|
58 |
-
)
|
59 |
-
htmlMessage = f"<br/>".join(
|
60 |
-
[f"{index+1}. {name}" for index, name in enumerate(names)]
|
61 |
-
)
|
62 |
-
htmlMessage += "<br/><br/><h3>URLS</h3><br/>"
|
63 |
-
htmlMessage += f"<br/>".join([f"{url}" for url in urls])
|
64 |
-
htmlMessage += (
|
65 |
-
"<br/><br/>By <a href='https://lexica.qewertyy.me'>LexicaAPI</a>"
|
66 |
-
)
|
67 |
-
telegraph_page = telegraph.create_page(
|
68 |
-
"More Results", html_content=htmlMessage
|
69 |
-
)
|
70 |
-
message += f"\n\n[More Results](https://telegra.ph/{telegraph_page['path']})\n\nBy @LexicaAPI"
|
71 |
-
await reply.delete()
|
72 |
-
return await m.reply_text(message, reply_markup=btn)
|
73 |
-
|
74 |
-
message = "\n".join([f"{index+1}. {name}" for index, name in enumerate(names)])
|
75 |
-
await reply.delete()
|
76 |
-
await m.reply_text(f"{message}\n\nBy @LexicaAPI", reply_markup=btn)
|
77 |
-
except Exception as E:
|
78 |
-
traceback.print_exc()
|
79 |
-
return await m.reply_text("Ran into an error.")
|
80 |
-
|
81 |
-
|
82 |
-
async def reverse_image_search(search_engine, img_url) -> dict:
|
83 |
-
try:
|
84 |
-
response = await state.post(
|
85 |
-
f"https://lexica.qewertyy.me/image-reverse/{search_engine}?img_url={img_url}",
|
86 |
-
)
|
87 |
-
if response.status_code != 200:
|
88 |
-
return None
|
89 |
-
output = response.json()
|
90 |
-
if output["code"] != 2:
|
91 |
-
return None
|
92 |
-
return output
|
93 |
-
except Exception as E:
|
94 |
-
raise Exception(f"API Error: {E}")
|
95 |
-
|
96 |
-
|
97 |
-
# <=================================================== HELP ====================================================>
|
98 |
-
|
99 |
-
|
100 |
-
__help__ = """
|
101 |
-
🖼 *IMAGE REVERSE*
|
102 |
-
|
103 |
-
» `/p`, `/pp`, `/reverse`, `/sauce`: Reverse image search using various search engines.
|
104 |
-
|
105 |
-
➠ *Usage:*
|
106 |
-
Reply to an image with one of the above commands to perform a reverse image search.
|
107 |
-
|
108 |
-
➠ *Example:*
|
109 |
-
» `/p` - Perform a reverse image search.
|
110 |
-
|
111 |
-
➠ *Note:*
|
112 |
-
- Supported image formats: PNG, JPG, JPEG.
|
113 |
-
- Maximum file size: 5 MB.
|
114 |
-
"""
|
115 |
-
|
116 |
-
__mod_name__ = "REVERSE"
|
117 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/rules.py
DELETED
@@ -1,169 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
3 |
-
from telegram.constants import ParseMode
|
4 |
-
from telegram.error import BadRequest
|
5 |
-
from telegram.ext import CommandHandler, ContextTypes, filters
|
6 |
-
from telegram.helpers import escape_markdown
|
7 |
-
|
8 |
-
import Database.sql.rules_sql as sql
|
9 |
-
from Mikobot import dispatcher, function
|
10 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin
|
11 |
-
from Mikobot.plugins.helper_funcs.string_handling import (
|
12 |
-
markdown_parser,
|
13 |
-
markdown_to_html,
|
14 |
-
)
|
15 |
-
|
16 |
-
# <=======================================================================================================>
|
17 |
-
|
18 |
-
|
19 |
-
# <================================================ FUNCTION =======================================================>
|
20 |
-
async def get_rules(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
21 |
-
chat_id = update.effective_chat.id
|
22 |
-
await send_rules(update, chat_id)
|
23 |
-
|
24 |
-
|
25 |
-
async def send_rules(update, chat_id, from_pm=False):
|
26 |
-
bot = dispatcher.bot
|
27 |
-
user = update.effective_user # type: Optional[User]
|
28 |
-
reply_msg = update.message.reply_to_message
|
29 |
-
try:
|
30 |
-
chat = await bot.get_chat(chat_id)
|
31 |
-
except BadRequest as excp:
|
32 |
-
if excp.message == "Chat not found" and from_pm:
|
33 |
-
await bot.send_message(
|
34 |
-
user.id,
|
35 |
-
"The rules shortcut for this chat hasn't been set properly! Ask admins to "
|
36 |
-
"fix this.\nMaybe they forgot the hyphen in ID",
|
37 |
-
message_thread_id=update.effective_message.message_thread_id
|
38 |
-
if chat.is_forum
|
39 |
-
else None,
|
40 |
-
)
|
41 |
-
return
|
42 |
-
else:
|
43 |
-
raise
|
44 |
-
|
45 |
-
rules = sql.get_rules(chat_id)
|
46 |
-
text = f"The rules for {escape_markdown(chat.title, 2)} are:\n\n{markdown_to_html(rules)}"
|
47 |
-
|
48 |
-
if from_pm and rules:
|
49 |
-
await bot.send_message(
|
50 |
-
user.id,
|
51 |
-
text,
|
52 |
-
parse_mode=ParseMode.MARKDOWN,
|
53 |
-
disable_web_page_preview=True,
|
54 |
-
)
|
55 |
-
elif from_pm:
|
56 |
-
await bot.send_message(
|
57 |
-
user.id,
|
58 |
-
"The group admins haven't set any rules for this chat yet. "
|
59 |
-
"This probably doesn't mean it's lawless though...!",
|
60 |
-
)
|
61 |
-
elif rules and reply_msg and not reply_msg.forum_topic_created:
|
62 |
-
await reply_msg.reply_text(
|
63 |
-
"Please click the button below to see the rules.",
|
64 |
-
reply_markup=InlineKeyboardMarkup(
|
65 |
-
[
|
66 |
-
[
|
67 |
-
InlineKeyboardButton(
|
68 |
-
text="RULES",
|
69 |
-
url=f"t.me/{bot.username}?start={chat_id}",
|
70 |
-
),
|
71 |
-
],
|
72 |
-
],
|
73 |
-
),
|
74 |
-
)
|
75 |
-
elif rules:
|
76 |
-
await update.effective_message.reply_text(
|
77 |
-
"Please click the button below to see the rules.",
|
78 |
-
reply_markup=InlineKeyboardMarkup(
|
79 |
-
[
|
80 |
-
[
|
81 |
-
InlineKeyboardButton(
|
82 |
-
text="RULES",
|
83 |
-
url=f"t.me/{bot.username}?start={chat_id}",
|
84 |
-
),
|
85 |
-
],
|
86 |
-
],
|
87 |
-
),
|
88 |
-
)
|
89 |
-
else:
|
90 |
-
await update.effective_message.reply_text(
|
91 |
-
"The group admins haven't set any rules for this chat yet. "
|
92 |
-
"This probably doesn't mean it's lawless though...!",
|
93 |
-
)
|
94 |
-
|
95 |
-
|
96 |
-
@check_admin(is_user=True)
|
97 |
-
async def set_rules(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
98 |
-
chat_id = update.effective_chat.id
|
99 |
-
msg = update.effective_message # type: Optional[Message]
|
100 |
-
raw_text = msg.text
|
101 |
-
args = raw_text.split(None, 1) # use python's maxsplit to separate cmd and args
|
102 |
-
if len(args) == 2:
|
103 |
-
txt = args[1]
|
104 |
-
offset = len(txt) - len(raw_text) # set correct offset relative to command
|
105 |
-
markdown_rules = markdown_parser(
|
106 |
-
txt,
|
107 |
-
entities=msg.parse_entities(),
|
108 |
-
offset=offset,
|
109 |
-
)
|
110 |
-
|
111 |
-
sql.set_rules(chat_id, markdown_rules)
|
112 |
-
await update.effective_message.reply_text(
|
113 |
-
"Successfully set rules for this group."
|
114 |
-
)
|
115 |
-
|
116 |
-
|
117 |
-
@check_admin(is_user=True)
|
118 |
-
async def clear_rules(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
119 |
-
chat_id = update.effective_chat.id
|
120 |
-
sql.set_rules(chat_id, "")
|
121 |
-
await update.effective_message.reply_text("Successfully cleared rules!")
|
122 |
-
|
123 |
-
|
124 |
-
def __stats__():
|
125 |
-
return f"• {sql.num_chats()} chats have rules set."
|
126 |
-
|
127 |
-
|
128 |
-
async def __import_data__(chat_id, data, message):
|
129 |
-
# set chat rules
|
130 |
-
rules = data.get("info", {}).get("rules", "")
|
131 |
-
sql.set_rules(chat_id, rules)
|
132 |
-
|
133 |
-
|
134 |
-
def __migrate__(old_chat_id, new_chat_id):
|
135 |
-
sql.migrate_chat(old_chat_id, new_chat_id)
|
136 |
-
|
137 |
-
|
138 |
-
def __chat_settings__(chat_id, user_id):
|
139 |
-
return f"This chat has had its rules set: `{bool(sql.get_rules(chat_id))}`"
|
140 |
-
|
141 |
-
|
142 |
-
# <=======================================================================================================>
|
143 |
-
|
144 |
-
|
145 |
-
# <================================================= HELP ======================================================>
|
146 |
-
__help__ = """
|
147 |
-
➠ /rules: Get the rules for this chat.
|
148 |
-
|
149 |
-
➠ *Admins only*:
|
150 |
-
» /setrules <your rules here>: Set the rules for this chat.
|
151 |
-
|
152 |
-
» /clearrules: Clear the rules for this chat.
|
153 |
-
"""
|
154 |
-
|
155 |
-
__mod_name__ = "RULES"
|
156 |
-
|
157 |
-
# <================================================ HANDLER =======================================================>
|
158 |
-
function(
|
159 |
-
CommandHandler("rules", get_rules, filters=filters.ChatType.GROUPS, block=False)
|
160 |
-
)
|
161 |
-
function(
|
162 |
-
CommandHandler("setrules", set_rules, filters=filters.ChatType.GROUPS, block=False)
|
163 |
-
)
|
164 |
-
function(
|
165 |
-
CommandHandler(
|
166 |
-
"clearrules", clear_rules, filters=filters.ChatType.GROUPS, block=False
|
167 |
-
)
|
168 |
-
)
|
169 |
-
# <================================================== END =====================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/search.py
DELETED
@@ -1,185 +0,0 @@
|
|
1 |
-
# SOURCE https://github.com/Team-ProjectCodeX
|
2 |
-
# CREATED BY https://t.me/O_okarma
|
3 |
-
# API BY https://www.github.com/SOME-1HING
|
4 |
-
# PROVIDED BY https://t.me/ProjectCodeX
|
5 |
-
|
6 |
-
# <============================================== IMPORTS =========================================================>
|
7 |
-
import json
|
8 |
-
import random
|
9 |
-
|
10 |
-
from pyrogram import Client, filters
|
11 |
-
from pyrogram.types import InputMediaPhoto, Message
|
12 |
-
|
13 |
-
from Mikobot import app
|
14 |
-
from Mikobot.state import state
|
15 |
-
|
16 |
-
# <=======================================================================================================>
|
17 |
-
|
18 |
-
BINGSEARCH_URL = "https://sugoi-api.vercel.app/search"
|
19 |
-
NEWS_URL = "https://sugoi-api.vercel.app/news?keyword={}"
|
20 |
-
|
21 |
-
|
22 |
-
# <================================================ FUNCTION =======================================================>
|
23 |
-
@app.on_message(filters.command("news"))
|
24 |
-
async def news(_, message: Message):
|
25 |
-
keyword = (
|
26 |
-
message.text.split(" ", 1)[1].strip() if len(message.text.split()) > 1 else ""
|
27 |
-
)
|
28 |
-
url = NEWS_URL.format(keyword)
|
29 |
-
|
30 |
-
try:
|
31 |
-
response = await state.get(url) # Assuming state is an asynchronous function
|
32 |
-
news_data = response.json()
|
33 |
-
|
34 |
-
if "error" in news_data:
|
35 |
-
error_message = news_data["error"]
|
36 |
-
await message.reply_text(f"Error: {error_message}")
|
37 |
-
else:
|
38 |
-
if len(news_data) > 0:
|
39 |
-
news_item = random.choice(news_data)
|
40 |
-
|
41 |
-
title = news_item["title"]
|
42 |
-
excerpt = news_item["excerpt"]
|
43 |
-
source = news_item["source"]
|
44 |
-
relative_time = news_item["relative_time"]
|
45 |
-
news_url = news_item["url"]
|
46 |
-
|
47 |
-
message_text = f"𝗧𝗜𝗧𝗟𝗘: {title}\n𝗦𝗢𝗨𝗥𝗖𝗘: {source}\n𝗧𝗜𝗠𝗘: {relative_time}\n𝗘𝗫𝗖𝗘𝗥𝗣𝗧: {excerpt}\n𝗨𝗥𝗟: {news_url}"
|
48 |
-
await message.reply_text(message_text)
|
49 |
-
else:
|
50 |
-
await message.reply_text("No news found.")
|
51 |
-
|
52 |
-
except Exception as e: # Replace with specific exception type if possible
|
53 |
-
await message.reply_text(f"Error: {str(e)}")
|
54 |
-
|
55 |
-
|
56 |
-
@app.on_message(filters.command("bingsearch"))
|
57 |
-
async def bing_search(client: Client, message: Message):
|
58 |
-
try:
|
59 |
-
if len(message.command) == 1:
|
60 |
-
await message.reply_text("Please provide a keyword to search.")
|
61 |
-
return
|
62 |
-
|
63 |
-
keyword = " ".join(
|
64 |
-
message.command[1:]
|
65 |
-
) # Assuming the keyword is passed as arguments
|
66 |
-
params = {"keyword": keyword}
|
67 |
-
|
68 |
-
response = await state.get(
|
69 |
-
BINGSEARCH_URL, params=params
|
70 |
-
) # Use the state.get method
|
71 |
-
|
72 |
-
if response.status_code == 200:
|
73 |
-
results = response.json()
|
74 |
-
if not results:
|
75 |
-
await message.reply_text("No results found.")
|
76 |
-
else:
|
77 |
-
message_text = ""
|
78 |
-
for result in results[:7]:
|
79 |
-
title = result.get("title", "")
|
80 |
-
link = result.get("link", "")
|
81 |
-
message_text += f"{title}\n{link}\n\n"
|
82 |
-
await message.reply_text(message_text.strip())
|
83 |
-
else:
|
84 |
-
await message.reply_text("Sorry, something went wrong with the search.")
|
85 |
-
except Exception as e:
|
86 |
-
await message.reply_text(f"An error occurred: {str(e)}")
|
87 |
-
|
88 |
-
|
89 |
-
# Command handler for the '/bingimg' command
|
90 |
-
@app.on_message(filters.command("bingimg"))
|
91 |
-
async def bingimg_search(client: Client, message: Message):
|
92 |
-
try:
|
93 |
-
text = message.text.split(None, 1)[
|
94 |
-
1
|
95 |
-
] # Extract the query from command arguments
|
96 |
-
except IndexError:
|
97 |
-
return await message.reply_text(
|
98 |
-
"Provide me a query to search!"
|
99 |
-
) # Return error if no query is provided
|
100 |
-
|
101 |
-
search_message = await message.reply_text("🔎") # Display searching message
|
102 |
-
|
103 |
-
# Send request to Bing image search API using state function
|
104 |
-
bingimg_url = "https://sugoi-api.vercel.app/bingimg?keyword=" + text
|
105 |
-
resp = await state.get(bingimg_url)
|
106 |
-
images = json.loads(resp.text) # Parse the response JSON into a list of image URLs
|
107 |
-
|
108 |
-
media = []
|
109 |
-
count = 0
|
110 |
-
for img in images:
|
111 |
-
if count == 7:
|
112 |
-
break
|
113 |
-
|
114 |
-
# Create InputMediaPhoto object for each image URL
|
115 |
-
media.append(InputMediaPhoto(media=img))
|
116 |
-
count += 1
|
117 |
-
|
118 |
-
# Send the media group as a reply to the user
|
119 |
-
await message.reply_media_group(media=media)
|
120 |
-
|
121 |
-
# Delete the searching message and the original command message
|
122 |
-
await search_message.delete()
|
123 |
-
await message.delete()
|
124 |
-
|
125 |
-
|
126 |
-
# Command handler for the '/googleimg' command
|
127 |
-
@app.on_message(filters.command("googleimg"))
|
128 |
-
async def googleimg_search(client: Client, message: Message):
|
129 |
-
try:
|
130 |
-
text = message.text.split(None, 1)[
|
131 |
-
1
|
132 |
-
] # Extract the query from command arguments
|
133 |
-
except IndexError:
|
134 |
-
return await message.reply_text(
|
135 |
-
"Provide me a query to search!"
|
136 |
-
) # Return error if no query is provided
|
137 |
-
|
138 |
-
search_message = await message.reply_text("💭") # Display searching message
|
139 |
-
|
140 |
-
# Send request to Google image search API using state function
|
141 |
-
googleimg_url = "https://sugoi-api.vercel.app/googleimg?keyword=" + text
|
142 |
-
resp = await state.get(googleimg_url)
|
143 |
-
images = json.loads(resp.text) # Parse the response JSON into a list of image URLs
|
144 |
-
|
145 |
-
media = []
|
146 |
-
count = 0
|
147 |
-
for img in images:
|
148 |
-
if count == 7:
|
149 |
-
break
|
150 |
-
|
151 |
-
# Create InputMediaPhoto object for each image URL
|
152 |
-
media.append(InputMediaPhoto(media=img))
|
153 |
-
count += 1
|
154 |
-
|
155 |
-
# Send the media group as a reply to the user
|
156 |
-
await message.reply_media_group(media=media)
|
157 |
-
|
158 |
-
# Delete the searching message and the original command message
|
159 |
-
await search_message.delete()
|
160 |
-
await message.delete()
|
161 |
-
|
162 |
-
|
163 |
-
# <=======================================================================================================>
|
164 |
-
|
165 |
-
|
166 |
-
# <=================================================== HELP ====================================================>
|
167 |
-
__mod_name__ = "SEARCH"
|
168 |
-
|
169 |
-
__help__ = """
|
170 |
-
💭 𝗦𝗘𝗔𝗥𝗖𝗛
|
171 |
-
|
172 |
-
➠ *Available commands:*
|
173 |
-
|
174 |
-
» /googleimg <search query>: It retrieves and displays images obtained through a Google image search.
|
175 |
-
|
176 |
-
» /bingimg <search query>: It retrieves and displays images obtained through a Bing image search.
|
177 |
-
|
178 |
-
» /news <search query> : search news.
|
179 |
-
|
180 |
-
» /bingsearch <search query> : get search result with links.
|
181 |
-
|
182 |
-
➠ *Example:*
|
183 |
-
➠ `/bingsearch app`: return search results.
|
184 |
-
"""
|
185 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mikobot/plugins/speedtest.py
DELETED
@@ -1,74 +0,0 @@
|
|
1 |
-
# <============================================== IMPORTS =========================================================>
|
2 |
-
import speedtest
|
3 |
-
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
|
4 |
-
from telegram.constants import ParseMode
|
5 |
-
from telegram.ext import CallbackQueryHandler, ContextTypes
|
6 |
-
|
7 |
-
from Mikobot import DEV_USERS, function
|
8 |
-
from Mikobot.plugins.disable import DisableAbleCommandHandler
|
9 |
-
from Mikobot.plugins.helper_funcs.chat_status import check_admin
|
10 |
-
|
11 |
-
# <=======================================================================================================>
|
12 |
-
|
13 |
-
|
14 |
-
# <================================================ FUNCTION =======================================================>
|
15 |
-
def convert(speed):
|
16 |
-
return round(int(speed) / 1048576, 2)
|
17 |
-
|
18 |
-
|
19 |
-
@check_admin(only_dev=True)
|
20 |
-
async def speedtestxyz(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
21 |
-
buttons = [
|
22 |
-
[
|
23 |
-
InlineKeyboardButton("Image", callback_data="speedtest_image"),
|
24 |
-
InlineKeyboardButton("Text", callback_data="speedtest_text"),
|
25 |
-
],
|
26 |
-
]
|
27 |
-
await update.effective_message.reply_text(
|
28 |
-
"Select SpeedTest Mode",
|
29 |
-
reply_markup=InlineKeyboardMarkup(buttons),
|
30 |
-
)
|
31 |
-
|
32 |
-
|
33 |
-
async def speedtestxyz_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
34 |
-
query = update.callback_query
|
35 |
-
|
36 |
-
if query.from_user.id in DEV_USERS:
|
37 |
-
msg = await update.effective_message.edit_text("Running a speedtest....")
|
38 |
-
speed = speedtest.Speedtest()
|
39 |
-
speed.get_best_server()
|
40 |
-
speed.download()
|
41 |
-
speed.upload()
|
42 |
-
replymsg = "SpeedTest Results:"
|
43 |
-
|
44 |
-
if query.data == "speedtest_image":
|
45 |
-
speedtest_image = speed.results.share()
|
46 |
-
await update.effective_message.reply_photo(
|
47 |
-
photo=speedtest_image,
|
48 |
-
caption=replymsg,
|
49 |
-
)
|
50 |
-
await msg.delete()
|
51 |
-
|
52 |
-
elif query.data == "speedtest_text":
|
53 |
-
result = speed.results.dict()
|
54 |
-
replymsg += f"\nDownload: `{convert(result['download'])}Mb/s`\nUpload: `{convert(result['upload'])}Mb/s`\nPing: `{result['ping']}`"
|
55 |
-
await update.effective_message.edit_text(
|
56 |
-
replymsg, parse_mode=ParseMode.MARKDOWN
|
57 |
-
)
|
58 |
-
else:
|
59 |
-
await query.answer("You are required to join Black Bulls to use this command.")
|
60 |
-
|
61 |
-
|
62 |
-
# <================================================ HANDLER =======================================================>
|
63 |
-
SPEED_TEST_HANDLER = DisableAbleCommandHandler("speedtest", speedtestxyz, block=False)
|
64 |
-
SPEED_TEST_CALLBACKHANDLER = CallbackQueryHandler(
|
65 |
-
speedtestxyz_callback, pattern="speedtest_.*", block=False
|
66 |
-
)
|
67 |
-
|
68 |
-
function(SPEED_TEST_HANDLER)
|
69 |
-
function(SPEED_TEST_CALLBACKHANDLER)
|
70 |
-
|
71 |
-
__mod_name__ = "SpeedTest"
|
72 |
-
__command_list__ = ["speedtest"]
|
73 |
-
__handlers__ = [SPEED_TEST_HANDLER, SPEED_TEST_CALLBACKHANDLER]
|
74 |
-
# <================================================ END =======================================================>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|