-
Notifications
You must be signed in to change notification settings - Fork 0
/
admin.py
368 lines (290 loc) · 14 KB
/
admin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
from discord.ext.commands import Cog, command, has_permissions, has_any_role
from random import choice
import discord
import re
from contextlib import suppress
import time
import json
from utility import get_users, from_seconds, to_seconds
import defs
import logger
from file_handling import JSONFile
admin_file = JSONFile('admin.json')
admin_file.get('welcome_message', on_error='')
def get_role(rolename, roles):
for role in roles:
if role.name == rolename:
return role
return None
async def reaction_change(payload, guild, status):
reactions = admin_file.get('reactions', {})
channel_id = str(payload.channel_id)
if channel_id not in reactions:
return
message_id = str(payload.message_id)
if message_id not in reactions[channel_id]:
return
reactions = reactions[channel_id][message_id]
emoji = str(payload.emoji)
for reaction in reactions:
if reaction['reaction'] == emoji:
role = get_role(reaction['role'], guild.roles)
member = guild.get_member(payload.user_id)
if status:
await member.add_roles(role)
logger.log_event('addrole', 'added role {} to user {}.'.format(role, member))
else:
await member.remove_roles(role)
logger.log_event('removerole', 'removed role {} from user {}.'.format(role, member))
class Admin(Cog):
def __init__(self, bot):
self.bot = bot
self.reaction_dict = {}
@Cog.listener()
async def on_member_join(self, member):
await member.send(admin_file.get('welcome_message', on_error=''))
print(defs.timestamp(), member, 'joined server.')
@Cog.listener()
async def on_message(self, message):
if (isinstance(message.channel, discord.DMChannel)):
logger.log_message(message)
return
if ('bambi' in message.content.lower() and admin_file.get('reaction_bambi', False)):
emojis = list(message.guild.emojis)
for emoji in emojis:
if (emoji.name.lower() == 'bambi'):
await message.add_reaction(emoji)
return
if ('temp' in message.content.lower() and admin_file.get('reaction_tempia', False)):
emojis = list(message.guild.emojis)
for emoji in emojis:
if (emoji.name.lower() == 'ayaya'):
await message.add_reaction(emoji)
return
@command(name = 'echo', help='Echoes your input. Example:\'!echo Echo\'')
@has_any_role('Officer', 'Admin')
async def echo(self, ctx, *args):
logger.log_command(ctx, args)
with suppress(): await ctx.message.delete()
if len(ctx.message.content) == len(ctx.command.name) + 1:
emojis = list(ctx.message.guild.emojis)
await ctx.send(choice(emojis))
else:
await ctx.send(ctx.message.content[len(ctx.command.name) + 2:])
@command(name = 'announcementchannel', help='Sets the announcement channel to the channel this command is sent in.')
@has_any_role('Admin')
async def announcementchannel(self, ctx, *args):
logger.log_command(ctx, args)
with suppress(): await ctx.message.delete()
admin_file.set('announcement_channel_id', ctx.message.channel.id)
@command(name = 'annend', help='Sets the ending of all announcements to this message. Example: \'!annend Thank you for listening~\'')
@has_any_role('Admin')
async def announementend(self, ctx, *args):
logger.log_command(ctx, args)
with suppress(): await ctx.message.delete()
admin_file.set('announcement_end', ctx.message.content[len(ctx.command.name) + 2:])
@command(name = 'ann', help='Makes an announcement in the announcement channel. Example:\'!ann This is an announcement.\'')
@has_any_role('Officer', 'Admin')
async def announcement(self, ctx, *args):
logger.log_command(ctx, args)
with suppress():
await ctx.message.delete()
channel_id = admin_file.get('announcement_channel_id', on_error=-1)
if channel_id is -1:
channel = ctx
message = 'Announcement channel not set.'
else:
channel = self.bot.get_channel(channel_id)
message = ctx.message.content[len(ctx.command.name) + 2:] + '\n'
message += admin_file.get('announcement_end', on_error='')
await channel.send(message)
@command(name='welcome', help='Displays the welcome message.')
@has_any_role('Officer', 'Admin')
async def welcome(self, ctx, *args):
logger.log_command(ctx, args)
with suppress(): await ctx.message.delete()
await ctx.send(admin_file.get('welcome_message', on_error=''))
@command(name='setwelcome', help='Sets the welcome message.')
@has_permissions(administrator=True)
async def setwelcome(self, ctx, *args):
logger.log_command(ctx, args)
with suppress(): await ctx.message.delete()
message = ctx.message.content[len(ctx.command.name) + 2:]
admin_file.set('welcome_message', message)
await ctx.send('Welcome message set to \'{}\'.'.format(admin_file.get('welcome_message', on_error='')))
@command(name='clear', help='Clears X messages, where X is the argument. Example: \'!clear 50\'')
@has_permissions(administrator=True)
async def clear(self, ctx, *args):
logger.log_command(ctx, args)
with suppress(): await ctx.message.delete()
if (not admin_file.get(ctx.command.name, True)):
await ctx.send('Command disabled. Enable with \'!enable {}\''.format(ctx.command.name), delete_after=5)
return
if (len(args) == 0 or len(args) > 2):
await ctx.send('Incorrect amount of arguments received. ({})'.format(len(args)), delete_after=10)
return
mention_id = None
to_clear = -1
for arg in args:
if (arg.isdigit()):
to_clear = int(arg)
elif (re.compile('^<@[0-9]{18}>$').match(arg.replace('!', ''))):
mention_id = arg.replace('!', '')
mention_id = int(mention_id[2:-1])
else:
await ctx.send('Argument \'{}\' in message \'{}\' not understood.'.format(arg, ctx.message.content), delete_after=10)
return
if (mention_id != None and to_clear != -1):
while to_clear > 0 :
messages = await ctx.message.channel.history(limit=100).flatten()
messages = [message for message in messages if message.author.id == mention_id][:to_clear]
if (len(messages) == 0): break
to_clear -= len(messages)
await ctx.message.channel.delete_messages(messages)
elif (mention_id != None):
messages = await ctx.message.channel.history(limit=100).flatten()
messages = [message for message in messages if message.author.id == mention_id]
await ctx.message.channel.delete_messages(messages)
elif (to_clear != -1):
while to_clear > 0:
messages = await ctx.message.channel.history(limit=min(to_clear, 100)).flatten()
to_clear -= len(messages)
await ctx.message.channel.delete_messages(messages)
@command(name='clearuntil', help='Clears messages until a message starting with the argument is found. Example: \'!clearuntil Matitka Sucks\'')
@has_permissions(administrator=True)
async def clear_until(self, ctx, *args):
logger.log_command(ctx, args)
if (len(args) == 0):
await ctx.send()
return
arg = ' '.join(args)
messages = await ctx.message.channel.history(limit=100).flatten()
matches = [message.content.startswith(arg) for message in messages]
if True in matches:
messages = messages[:matches.index(True) + 1]
await ctx.message.channel.delete_messages(messages)
else:
await ctx.send('Message \'{}\' not found.'.format(arg), delete_after=10)
@command(name='clearreactions', help='Clears all role assignments and all reactions from the message. Template: \'!clearreactions MESSAGE_ID\'.')
@has_permissions(administrator=True)
async def clear_reactions(self, ctx, *args):
await ctx.message.delete()
logger.log_command(ctx, args)
message_id, *_ = args
try: message = await ctx.channel.fetch_message(message_id)
except discord.NotFound:
await ctx.send('Message with id \'{}\' not found in this channel. Please use \'!help {}\' for help on how to use this command.'.format(message_id, ctx.command.name))
return
reactions = admin_file.get('reactions', on_error={})
channel_id = str(ctx.channel.id)
if not channel_id in reactions:
await ctx.send('This channel has no reaction assignments.')
return
if not message_id in reactions[channel_id]:
await ctx.send('This message has no reaction assignments.')
return
await message.clear_reactions()
del reactions[channel_id][message_id]
if len(reactions[channel_id]) is 0:
del reactions[channel_id]
admin_file.set('reactions', reactions)
@command()
@has_permissions(administrator=True)
async def suspend(self, ctx, *args):
await ctx.message.delete()
members = await get_users(self.bot, user_string=args[0])
await ctx.send(str(members))
@command(name='reactionassignment', help='Assigns a specific role to a user depending on the reaction. Template: \'!reactionassignment MESSAGE_ID EMOJI ROLE\'.')
@has_permissions(administrator=True)
async def reaction_message(self, ctx, *args):
await ctx.message.delete()
logger.log_command(ctx, args)
if len(args) < 3:
await ctx.send('Too few arguments. Please use \'!help {}\' for help on how to use this command.'.format(ctx.command.name))
return
message_id, emoji, *args = args
rolename = ' '.join(args)
try: message = await ctx.channel.fetch_message(message_id)
except discord.NotFound:
await ctx.send('Message with id \'{}\' not found in this channel. Please use \'!help {}\' for help on how to use this command.'.format(message_id, ctx.command.name))
return
try: await message.add_reaction(emoji)
except discord.HTTPException:
await ctx.send('Emoji \'{}\' is not valid. Please use \'!help {}\' for help on how to use this command.'.format(emoji, ctx.command.name))
return
roles = ctx.guild.roles
role = get_role(rolename, roles)
if role is None:
await ctx.send('Role \'{}\' not found on this server. Please use \'!help {}\' for help on how to use this command.'.format(rolename, ctx.command.name))
return
reactions = admin_file.get('reactions', on_error={})
channel_id = str(ctx.channel.id)
if not channel_id in reactions:
reactions[channel_id] = {}
if not message_id in reactions[channel_id]:
reactions[channel_id][message_id] = []
reaction_list = reactions[channel_id][message_id]
reaction_list.append({
'reaction': emoji,
'role': rolename
})
admin_file.set('reactions', reactions)
@command()
@has_permissions(administrator=True)
async def export(self, ctx, *args):
await ctx.message.delete()
print(ctx.message)
messages = []
user_id = int(args[0])
print(user_id)
for guild in self.bot.guilds:
print(guild.name)
for channel in guild.text_channels:
print(channel.name)
try:
async for message in channel.history(limit=None):
if message.author.id == user_id:
messages.append(message)
except:
print('not enough permissions.')
await ctx.send(len(messages))
obj = {}
for message in messages:
obj.setdefault(str(message.channel), []).append(message.content)
with open('{}.json'.format(user_id), 'w') as f:
json.dump(obj, f, indent=4)
@command()
async def lastmeltdown(self, ctx, *args):
await ctx.message.delete()
last_meltdown = admin_file.get('last_meltdown', 0)
if last_meltdown == 0:
await ctx.send('There hasn\'t been any meltdowns yet.')
else:
diff = time.time() - last_meltdown
days = from_seconds(diff, 'day', floor_result=True)
diff -= to_seconds(days, 'days')
hours = from_seconds(diff, 'hours', floor_result=True)
await ctx.send('Last meltdown {} days and {} hours ago.'.format(days, hours))
@command()
async def setmeltdown(self, ctx, *args):
await ctx.message.delete()
if len(args) == 0:
admin_file.set('last_meltdown', time.time())
else:
admin_file.set('last_meltdown', int(args[0]))
@Cog.listener()
async def on_raw_reaction_add(self, payload):
if (payload.user_id == self.bot.user.id): return
guild = self.bot.get_guild(payload.guild_id)
await reaction_change(payload, guild, True)
@Cog.listener()
async def on_raw_reaction_remove(self, payload):
if (payload.user_id == self.bot.user.id): return
guild = self.bot.get_guild(payload.guild_id)
await reaction_change(payload, guild, False)
@Cog.listener()
async def on_member_update(self, before, after):
if after.id == defs.get_tempia(self.bot).id and after.nick != 'Tempia':
await after.edit(nick=None)
#if after.id == 652701117188145162 and after.nick != 'Poopooga':
#await after.edit(nick='Poopooga')