Karma commited on
Commit
d46212e
·
1 Parent(s): a1ddd36

Create approve.py

Browse files
Files changed (1) hide show
  1. Mikobot/plugins/approve.py +259 -0
Mikobot/plugins/approve.py ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 =======================================================>