3
3
~~~~~~~~~~~~~~~~~~
4
4
This file contains elements that are under the following licenses:
5
5
Copyright (c) 2015 Rapptz
6
- license MIT, see https://github.com/Rapptz/RoboDanny/blob/e1c3c28fe20eb192463f7fc224a399141f0d915d/LICENSE.txt for more details.
6
+ license MIT, see
7
+ https://github.com/Rapptz/RoboDanny/blob/e1c3c28fe20eb192463f7fc224a399141f0d915d/LICENSE.txt
8
+ for more details.
7
9
"""
8
10
9
11
import discord
10
12
import time
11
13
import asyncio
12
14
import re
15
+ import asyncpg
13
16
import os
14
17
import url_parser
15
18
import inspect
@@ -22,45 +25,50 @@ async def filter_links(bot, message):
22
25
return
23
26
if message .author .permissions_in (message .channel ).manage_messages :
24
27
return
25
- regex = r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
28
+ regex = (r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*(),]|'
29
+ r'(?:%[0-9a-fA-F][0-9a-fA-F]))+' )
26
30
27
31
matches = re .findall (regex , message .content , re .MULTILINE )
28
32
urls = []
29
33
for link in matches :
30
34
try :
31
- urls = [] #[url_parser.get_url(link)] #[''.join(url_parser.get_base_url(str(link)).split('//')[1:])]
35
+ urls = []
32
36
async with bot .http ._HTTPClient__session .get (link ) as resp :
33
37
urls .append (url_parser .get_url (link )._asdict ())
34
38
for redirect in resp .history :
35
- urls .append (url_parser . get_url ( redirect . real_url ). _asdict ())
36
- #str(''.join( url_parser.get_base_url(str(resp .real_url)).split('//')[1:]) ))
39
+ urls .append (
40
+ url_parser .get_url ( redirect .real_url ). _asdict ( ))
37
41
for url in urls :
38
- for blocked in [ # "*" means any
39
- # [http[s]://][sub.]<name>.<domain>[/path] # Reason
40
- ########################################################################
41
-
42
- '*.grabify.link/*' , # Ip Grabber
43
- '*.pornhub.com/*' , # Porn
42
+ for blocked in [ # "*" means any
43
+ # [http[s]://][sub.]<name>.<domain>[/path] # Reason
44
+ ###########################################################
45
+
46
+ '*.grabify.link/*' , # Ip Grabber
47
+ '*.pornhub.com/*' , # Porn
44
48
]:
45
- parsed_blocked = url_parser .get_url (blocked .replace ('*' ,'-' ))._asdict ()
49
+ parsed_blocked = url_parser .get_url (
50
+ blocked .replace ('*' , '-' ))._asdict ()
46
51
for k , v in parsed_blocked .items ():
47
- if k in ['protocol' , 'www' , 'dir' , 'file' , 'fragment' , 'query' ]:
52
+ if k in ['protocol' , 'www' , 'dir' , 'file' , 'fragment' ,
53
+ 'query' ]:
48
54
continue
49
55
if v == url [k ]:
50
56
continue
51
57
if isinstance (v , str ):
52
- if v .replace ('.' ,'' ) == '-' :
58
+ if v .replace ('.' , '' ) == '-' :
53
59
continue
54
60
if k == 'path' :
55
61
if v [1 :] == '-' :
56
62
continue
57
- return
63
+ return
58
64
await message .delete ()
59
- await message .channel .send (f':warning: { message .author .mention } That link is not allowed :warning:' , delete_after = 15 )
65
+ await message .channel .send ((
66
+ f':warning: { message .author .mention } That link is not '
67
+ 'allowed :warning:' ), delete_after = 15 )
60
68
return
61
69
except Exception as e :
62
70
print (e )
63
-
71
+
64
72
65
73
async def filter_invite (bot , message , content = None ):
66
74
if message .author .permissions_in (message .channel ).manage_messages :
@@ -70,34 +78,40 @@ async def filter_invite(bot, message, content=None):
70
78
801641781028454420
71
79
]:
72
80
return
73
- pattern = r"discord(?:(?:(?:app)?\.com)\/invite|\.gg)/([a-zA-z0-9\-]{2,})(?!\S)"
74
- matches = re .findall (pattern ,message .content , re .MULTILINE )
81
+ pattern = (
82
+ r'discord(?:(?:(?:app)?\.com)\/invite|\.gg)/([a-zA-z0-9\-]{2,})(?!\S)' )
83
+ matches = re .findall (pattern , message .content , re .MULTILINE )
75
84
if len (matches ) > 5 :
76
85
await message .delete ()
77
- await message .channel .send (f':warning: { message .author .mention } Invite links are not allowed :warning:' , delete_after = 15 )
86
+ await message .channel .send ((
87
+ f':warning: { message .author .mention } Invite links are not allowed '
88
+ ':warning:' ), delete_after = 15 )
78
89
return True
79
90
for code in matches :
80
91
try :
81
92
invite = await bot .fetch_invite (code )
82
93
except discord .errors .NotFound :
83
- invite = None # invite is fine
94
+ invite = None # invite is fine
84
95
if invite :
85
- if not invite .guild .id in [message .guild .id , 681882711945641997 , 782903894468198450 ]:
96
+ if invite .guild .id not in [message .guild .id , 681882711945641997 ,
97
+ 782903894468198450 ]:
86
98
await message .delete ()
87
- await message .channel .send (f':warning: { message .author .mention } Invite links are not allowed :warning:' , delete_after = 15 )
99
+ await message .channel .send ((
100
+ f':warning: { message .author .mention } Invite links are not '
101
+ 'allowed :warning:' ), delete_after = 15 )
88
102
return True
89
-
103
+
90
104
91
105
class General (commands .Cog ):
92
106
93
107
def __init__ (self , bot ):
94
108
self .bot = bot
95
109
96
-
97
110
@commands .Cog .listener ()
98
111
async def on_message_edit (self , before , after ):
99
- if before .content != after .content : # invoke the command again if it is edited
100
- ctx = await self .bot .get_context (after , cls = self .bot .helpers .Context )
112
+ if before .content != after .content : # invoke the command again on edit
113
+ ctx = await self .bot .get_context (after ,
114
+ cls = self .bot .helpers .Context )
101
115
await self .bot .invoke (ctx )
102
116
if after .guild :
103
117
if after .guild .id == 681882711945641997 :
@@ -112,7 +126,7 @@ async def on_message(self, message):
112
126
invite = await filter_invite (self .bot , message )
113
127
if not invite :
114
128
await filter_links (self .bot , message )
115
-
129
+
116
130
@commands .command (name = "source" , aliases = ["github" , "code" ])
117
131
@commands .cooldown (1 , 1 , commands .BucketType .channel )
118
132
async def _source (self , ctx , * , command : str = None ):
@@ -135,8 +149,6 @@ async def _source(self, ctx, *, command: str = None):
135
149
if obj is None :
136
150
return await ctx .send ('Could not find command.' )
137
151
138
- # since we found the command we're looking for, presumably anyway, let's
139
- # try to access the code itself
140
152
src = obj .callback .__code__
141
153
module = obj .callback .__module__
142
154
filename = src .co_filename
@@ -150,67 +162,96 @@ async def _source(self, ctx, *, command: str = None):
150
162
source_url = 'https://github.com/Rapptz/discord.py'
151
163
branch = 'master'
152
164
153
- final_url = f'<{ source_url } /blob/{ branch } /{ location } #L{ firstlineno } -L{ firstlineno + len (lines ) - 1 } >'
154
- embed = ctx .embed (title = '<:githubwhite:804344724621230091> GitHub <:githubwhite:804344724621230091>' , description = f'[Click Here]({ final_url } )' )
165
+ final_url = (f'<{ source_url } /blob/{ branch } /{ location } #L{ firstlineno } -L'
166
+ f'{ firstlineno + len (lines ) - 1 } >' )
167
+ github = '<:githubwhite:804344724621230091>'
168
+ embed = ctx .embed (title = f'{ github } GitHub { github } ' ,
169
+ description = f'[Click Here]({ final_url } )' )
155
170
await ctx .send (embed = embed )
156
171
157
- @commands .command (name = "mystbin" ,aliases = ["mb" ])
172
+ @commands .command (name = "mystbin" , aliases = ["mb" ])
158
173
@commands .cooldown (1 , 1 , commands .BucketType .channel )
159
174
async def _mystbin (self , ctx , * , code : codeblock_converter = None ):
160
- """Send your code to Mystb.in. You may use codeblocks, no codeblocks, or inside a file."""
175
+ """Send your code to Mystb.in. You may use codeblocks if you want,
176
+ or use code from inside a file."""
161
177
code = code .content if code else None
162
178
attachments = None
163
179
164
180
if len (ctx .message .attachments ) != 0 :
165
181
attachments = ctx .message .attachments
166
182
elif ctx .message .reference :
167
- message = await ctx .channel .fetch_message (ctx .message .reference .message_id )
183
+ message = await ctx .channel .fetch_message (
184
+ ctx .message .reference .message_id )
168
185
attachments = message .attachments
169
186
if attachments :
170
187
for attachment in attachments :
171
188
code = await attachment .read ()
172
189
173
190
if not code :
174
- return await ctx .send (embed = ctx .error ('Please either provide code in the command, attach a file, or react to a message that contains a file.' ))
175
- async with self .bot .http ._HTTPClient__session .post ('https://mystb.in/documents' , data = code ) as r :
191
+ return await ctx .send (embed = ctx .error ((
192
+ 'Please either provide code in the command, attach a file, or '
193
+ 'react to a message that contains a file.' )))
194
+ async with self .bot .http ._HTTPClient__session .post (
195
+ 'https://mystb.in/documents' , data = code ) as r :
176
196
res = await r .json ()
177
197
key = res ["key" ]
178
- embed = ctx .embed (title = "Mystb.in Link" , description = 'I pasted your code into a bin, click on the title access it!' , url = f'https://mystb.in/{ key } ' ).set_thumbnail (url = 'https://cdn.discordapp.com/avatars/569566608817782824/14f120e096fb515d770eea38f9cddd88.png' )
198
+ embed = ctx .embed (title = "Mystb.in Link" , description = (
199
+ 'I pasted your code into a bin, click on the title access it!' ),
200
+ url = f'https://mystb.in/{ key } ' )
201
+ embed .set_thumbnail (url = (
202
+ 'https://cdn.discordapp.com/avatars/569566608817782824/'
203
+ '14f120e096fb515d770eea38f9cddd88.png' ))
179
204
await ctx .send (embed = embed )
180
205
181
206
@commands .command (name = 'ping' )
182
207
async def _ping (self , ctx ):
183
- embed = ctx .embed (title = 'PONG! :ping_pong:' ,description = f'**<a:DiscordSpin:795546311319355393> Websocket:** { (self .bot .latency * 1000 ):.2f} ms\n **:repeat: Round-Trip:** Calculating...\n **:elephant: Database:** Calculating...' )
208
+ loading = '<a:DiscordSpin:795546311319355393>'
209
+ embed = ctx .embed (title = 'PONG! :ping_pong:' , description = (
210
+ f'**<{ loading } Websocket:** { (self .bot .latency * 1000 ):.2f} ms\n **'
211
+ ':repeat: Round-Trip:** Calculating...\n **:elephant: Database:** '
212
+ 'Calculating...' ))
184
213
start = time .perf_counter ()
185
214
message = await ctx .send (embed = embed )
186
215
await asyncio .sleep (0.5 )
187
216
end = time .perf_counter ()
188
217
trip = end - start
189
- embed .description = f'**<a:DiscordSpin:795546311319355393> Websocket:** { (self .bot .latency * 1000 ):.2f} ms\n **:repeat: Round-Trip:** { (trip * 1000 ):.2f} ms\n **:elephant: Database:** Calcuating...'
218
+ embed .description = (
219
+ f'**{ loading } Websocket:** { (self .bot .latency * 1000 ):.2f} ms\n **'
220
+ f':repeat: Round-Trip:** { (trip * 1000 ):.2f} ms\n **:elephant: '
221
+ 'Database:** Calculating...' )
190
222
await message .edit (embed = embed )
191
223
await asyncio .sleep (0.5 )
192
224
start = time .perf_counter ()
193
225
try :
194
226
async with self .bot .pools .config .acquire () as connection :
195
- await connection .fetchval ('SELECT prefixes FROM serverconf WHERE id = 0' )
227
+ await connection .fetchval (
228
+ 'SELECT prefixes FROM serverconf WHERE id = 0' )
196
229
end = time .perf_counter ()
197
230
database = end - start
198
- embed .description = f'**<a:DiscordSpin:795546311319355393> Websocket:** { (self .bot .latency * 1000 ):.2f} ms\n **:repeat: Round-Trip:** { (trip * 1000 ):.2f} ms\n **:elephant: Database:** { (database * 1000 ):.2f} ms'
199
- except :
200
- embed .description = f'**<a:DiscordSpin:795546311319355393> Websocket:** { (self .bot .latency * 1000 ):.2f} ms\n **:repeat: Round-Trip:** { (trip * 1000 ):.2f} ms\n **:elephant: Database:** *Did not respond!*'
231
+ embed .description = (
232
+ f'**{ loading } Websocket:** { (self .bot .latency * 1000 ):.2f} ms\n '
233
+ f'**:repeat: Round-Trip:** { (trip * 1000 ):.2f} ms\n **:elephant:'
234
+ f' Database:** { (database * 1000 ):.2f} ms' )
235
+ except asyncpg .exceptions ._base .InterfaceError :
236
+ embed .description = (
237
+ f'**<{ loading } Websocket:** { (self .bot .latency * 1000 ):.2f} ms'
238
+ f'\n **:repeat: Round-Trip:** { (trip * 1000 ):.2f} ms\n **'
239
+ ':elephant: Database:** *Did not respond!*' )
201
240
await message .edit (embed = embed )
202
-
203
- @commands .command (name = 'revive' , aliases = ['revivechat' , 'chatrevive' , 'revchat' , 'chatrev' ])
241
+
242
+ @commands .command (name = 'revive' , aliases = ['revivechat' , 'chatrevive' ,
243
+ 'revchat' , 'chatrev' ])
204
244
@commands .guild_only ()
205
245
@commands .cooldown (1 , 1800 , commands .BucketType .guild )
206
- @commands .has_any_role (729530191109554237 , 795136568805294097 , 725899526350831616 )
246
+ @commands .has_any_role (729530191109554237 , 795136568805294097 ,
247
+ 725899526350831616 ) # Senior Mod +
207
248
async def _revive (self , ctx ):
208
- try :
209
- mention = ctx .guild .get_role (759219083639783448 ).mention
210
- except :
211
- mention = f'<@&759219083639783448>'
212
- embed = ctx .embed (title = 'Revive Chat Ping!' , description = 'Come back to chat and make it alive again!' )
249
+ mention = ctx .guild .get_role (759219083639783448 ).mention
250
+ embed = ctx .embed (
251
+ title = 'Revive Chat Ping!' ,
252
+ description = 'Come back to chat and make it alive again!' )
213
253
await ctx .send (content = mention , embed = embed )
214
254
255
+
215
256
def setup (bot ):
216
257
bot .add_cog (General (bot ))
0 commit comments