1
- '''
1
+ """
2
2
MIT License
3
3
4
- Copyright (c) 2017 kyb3r
4
+ Copyright (c) 2017-2019 kyb3r
5
5
6
6
Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
of this software and associated documentation files (the "Software"), to deal
20
20
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
21
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
22
SOFTWARE.
23
- '''
23
+ """
24
24
25
25
__version__ = '2.0.0'
26
26
27
- from contextlib import redirect_stdout
28
- from copy import deepcopy
29
- import functools
30
27
import asyncio
31
28
import textwrap
32
- import traceback
33
29
import datetime
34
- import inspect
35
- import string
36
- import time
37
- import json
38
30
import os
39
31
import re
40
- import io
41
32
42
- from colorama import init , Fore , Back , Style
43
- import dateutil .parser
44
-
45
- init ()
46
-
47
- from discord .ext import commands
48
- from discord .ext .commands .view import StringView
49
33
import discord
50
34
import aiohttp
35
+ from discord .ext import commands
36
+ from discord .ext .commands .view import StringView
37
+ from colorama import init , Fore , Style
51
38
52
- from core .paginator import PaginatorSession
53
39
from core .api import Github , ModmailApiClient
54
40
from core .thread import ThreadManager
55
41
from core .config import ConfigManager
56
42
43
+
44
+ init ()
45
+
57
46
line = Fore .BLACK + Style .BRIGHT + '-------------------------' + Style .RESET_ALL
58
47
48
+
59
49
class ModmailBot (commands .Bot ):
60
50
61
51
mutable_config_keys = ['prefix' , 'status' , 'guild_id' , 'mention' , 'autoupdates' , 'modmail_guild_id' ]
@@ -64,7 +54,7 @@ def __init__(self):
64
54
super ().__init__ (command_prefix = self .get_pre )
65
55
self .version = __version__
66
56
self .start_time = datetime .datetime .utcnow ()
67
- self .threads = ThreadManager (self )
57
+ self .threads = ThreadManager (self )
68
58
self .session = aiohttp .ClientSession (loop = self .loop )
69
59
self .config = ConfigManager (self )
70
60
self .modmail_api = ModmailApiClient (self )
@@ -73,7 +63,7 @@ def __init__(self):
73
63
self ._add_commands ()
74
64
75
65
def _add_commands (self ):
76
- ''' Adds commands automatically'''
66
+ """ Adds commands automatically"""
77
67
self .remove_command ('help' )
78
68
79
69
print (line + Fore .CYAN )
@@ -84,33 +74,32 @@ def _add_commands(self):
84
74
print ('Authors: kyb3r, fourjr' + Style .RESET_ALL )
85
75
print (line + Fore .CYAN )
86
76
87
-
88
77
for file in os .listdir ('cogs' ):
89
78
if not file .endswith ('.py' ):
90
79
continue
91
80
cog = f'cogs.{ file [:- 3 ]} '
92
81
print (f'Loading { cog } ' )
93
82
self .load_extension (cog )
94
-
83
+
95
84
async def logout (self ):
96
85
await self .session .close ()
97
86
self .data_task .cancel ()
98
87
self .autoupdate_task .cancel ()
99
88
await super ().logout ()
100
-
89
+
101
90
def run (self ):
102
91
try :
103
92
super ().run (self .token )
104
93
finally :
105
94
print (Fore .CYAN + ' Shutting down bot' + Style .RESET_ALL )
106
-
95
+
107
96
@property
108
97
def snippets (self ):
109
98
return {k : v for k , v in self .config .get ('snippets' , {}).items () if v }
110
99
111
100
@property
112
101
def aliases (self ):
113
- return {k : v for k , v in self .config .get ('aliases' , {}).items () if v }
102
+ return {k : v for k , v in self .config .get ('aliases' , {}).items () if v }
114
103
115
104
@property
116
105
def token (self ):
@@ -119,16 +108,16 @@ def token(self):
119
108
@property
120
109
def guild_id (self ):
121
110
return int (self .config .guild_id )
122
-
111
+
123
112
@property
124
113
def guild (self ):
125
114
return discord .utils .get (self .guilds , id = self .guild_id )
126
-
115
+
127
116
@property
128
117
def modmail_guild (self ):
129
118
modmail_guild_id = self .config .get ('modmail_guild_id' )
130
119
if not modmail_guild_id :
131
- return self .guild
120
+ return self .guild
132
121
else :
133
122
return discord .utils .get (self .guilds , id = int (modmail_guild_id ))
134
123
@@ -142,14 +131,14 @@ def blocked_users(self):
142
131
if self .modmail_guild :
143
132
top_chan = self .main_category .channels [0 ]
144
133
return [int (i ) for i in re .findall (r'\d+' , top_chan .topic )]
145
-
134
+
146
135
@property
147
136
def prefix (self ):
148
137
return self .config .get ('prefix' , '?' )
149
138
150
139
@staticmethod
151
140
async def get_pre (bot , message ):
152
- ''' Returns the prefix.'''
141
+ """ Returns the prefix."""
153
142
return [bot .prefix , f'<@{ bot .user .id } > ' , f'<@!{ bot .user .id } > ' ]
154
143
155
144
async def on_connect (self ):
@@ -161,21 +150,21 @@ async def on_connect(self):
161
150
await self .change_presence (activity = discord .Game (status ))
162
151
163
152
async def on_ready (self ):
164
- ''' Bot startup, sets uptime.'''
165
- print (textwrap .dedent (f'''
153
+ """ Bot startup, sets uptime."""
154
+ print (textwrap .dedent (f"""
166
155
{ line }
167
156
{ Fore .CYAN } Client ready.
168
157
{ line }
169
158
{ Fore .CYAN } Logged in as: { self .user }
170
159
{ Fore .CYAN } User ID: { self .user .id }
171
160
{ Fore .CYAN } Guild ID: { self .guild .id if self .guild else 0 }
172
161
{ line }
173
- ''' ).strip ())
174
-
162
+ """ ).strip ())
163
+
175
164
await self .threads .populate_cache ()
176
165
177
166
async def process_modmail (self , message ):
178
- ''' Processes messages sent to the bot.'''
167
+ """ Processes messages sent to the bot."""
179
168
180
169
reaction = '🚫' if message .author .id in self .blocked_users else '✅'
181
170
@@ -185,10 +174,10 @@ async def process_modmail(self, message):
185
174
pass
186
175
187
176
blocked_em = discord .Embed (
188
- title = 'Message not sent!' ,
177
+ title = 'Message not sent!' ,
189
178
color = discord .Color .red (),
190
179
description = 'You have been blocked from using modmail.'
191
- )
180
+ )
192
181
193
182
if str (message .author .id ) in self .blocked_users :
194
183
await message .author .send (embed = blocked_em )
@@ -207,7 +196,6 @@ async def get_context(self, message, *, cls=commands.Context):
207
196
208
197
if self ._skip_check (message .author .id , self .user .id ):
209
198
return ctx
210
-
211
199
212
200
prefixes = [self .prefix , f'<@{ bot .user .id } > ' , f'<@!{ bot .user .id } >' ]
213
201
@@ -226,7 +214,7 @@ async def get_context(self, message, *, cls=commands.Context):
226
214
invoker = view .get_word ()
227
215
228
216
ctx .invoked_with = invoker
229
- ctx .prefix = self .prefix # Sane prefix (No mentions)
217
+ ctx .prefix = self .prefix # Sane prefix (No mentions)
230
218
ctx .command = self .all_commands .get (invoker )
231
219
232
220
# if hasattr(ctx, '_alias_invoked'):
@@ -246,11 +234,11 @@ async def on_message(self, message):
246
234
cmd = message .content [len (prefix ):].strip ()
247
235
if cmd in self .snippets :
248
236
message .content = f'{ prefix } reply { self .snippets [cmd ]} '
249
-
237
+
250
238
await self .process_commands (message )
251
-
239
+
252
240
async def on_message_delete (self , message ):
253
- ''' Support for deleting linked messages'''
241
+ """ Support for deleting linked messages"""
254
242
if message .embeds and not isinstance (message .channel , discord .DMChannel ):
255
243
matches = re .findall (r'\d+' , str (message .embeds [0 ].author .url ))
256
244
if matches :
@@ -261,10 +249,10 @@ async def on_message_delete(self, message):
261
249
262
250
async for msg in channel .history ():
263
251
if msg .embeds and msg .embeds [0 ].author :
264
- url = msg .embeds [0 ].author .url
252
+ url = msg .embeds [0 ].author .url
265
253
if message_id == re .findall (r'\d+' , url ):
266
254
return await msg .delete ()
267
-
255
+
268
256
async def on_message_edit (self , before , after ):
269
257
if before .author .bot :
270
258
return
@@ -279,15 +267,15 @@ async def on_message_edit(self, before, after):
279
267
embed .description = after .content
280
268
await msg .edit (embed = embed )
281
269
break
282
-
270
+
283
271
async def on_command_error (self , ctx , error ):
284
272
if isinstance (error , (commands .MissingRequiredArgument , commands .UserInputError )):
285
273
await ctx .invoke (self .get_command ('help' ), command = str (ctx .command ))
286
274
else :
287
275
raise error
288
276
289
277
def overwrites (self , ctx ):
290
- ''' Permision overwrites for the guild.'''
278
+ """ Permision overwrites for the guild."""
291
279
overwrites = {
292
280
ctx .guild .default_role : discord .PermissionOverwrite (read_messages = False )
293
281
}
@@ -297,7 +285,7 @@ def overwrites(self, ctx):
297
285
overwrites [role ] = discord .PermissionOverwrite (read_messages = True )
298
286
299
287
return overwrites
300
-
288
+
301
289
async def data_loop (self ):
302
290
await self .wait_until_ready ()
303
291
@@ -315,7 +303,7 @@ async def data_loop(self):
315
303
await self .session .post ('https://api.modmail.tk/metadata' , json = data )
316
304
317
305
await asyncio .sleep (3600 )
318
-
306
+
319
307
async def autoupdate_loop (self ):
320
308
while True :
321
309
if not self .config .get ('autoupdates' ):
@@ -334,7 +322,7 @@ async def autoupdate_loop(self):
334
322
commit_data = data ['data' ]
335
323
user = data ['user' ]
336
324
em .set_author (name = user ['username' ], icon_url = user ['avatar_url' ], url = user ['url' ])
337
- em .set_footer (text = f"Updating modmail v{ self .version } -> v{ metadata ['latest_version' ]} " )
325
+ em .set_footer (text = f"Updating modmail v{ self .version } -> v{ metadata ['latest_version' ]} " )
338
326
339
327
if commit_data :
340
328
em .description = 'Bot successfully updated, the bot will restart momentarily'
@@ -344,15 +332,14 @@ async def autoupdate_loop(self):
344
332
em .add_field (name = 'Merge Commit' , value = f"[`{ short_sha } `]({ html_url } ) { message } - { user ['username' ]} " )
345
333
else :
346
334
em .description = 'Already up to date with master repository.'
347
-
335
+
348
336
em .add_field (name = 'Latest Commit' , value = await self .get_latest_updates (limit = 1 ), inline = False )
349
337
350
338
channel = self .main_category .channels [0 ]
351
339
await channel .send (embed = em )
352
340
353
341
await asyncio .sleep (3600 )
354
342
355
-
356
343
async def get_latest_updates (self , limit = 3 ):
357
344
latest_commits = ''
358
345
@@ -361,7 +348,6 @@ async def get_latest_updates(self, limit=3):
361
348
short_sha = commit ['sha' ][:6 ]
362
349
html_url = commit ['html_url' ]
363
350
message = commit ['commit' ]['message' ].splitlines ()[0 ]
364
- author_name = commit ['author' ]['login' ]
365
351
366
352
latest_commits += f'[`{ short_sha } `]({ html_url } ) { message } \n '
367
353
@@ -381,6 +367,7 @@ def uptime(self):
381
367
382
368
return fmt .format (d = days , h = hours , m = minutes , s = seconds )
383
369
370
+
384
371
if __name__ == '__main__' :
385
372
bot = ModmailBot ()
386
373
bot .run ()
0 commit comments