Advertisement
Guest User

Untitled

a guest
Apr 28th, 2017
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 23.72 KB | None | 0 0
  1. import asyncio, aiohttp, aiosocks, discord
  2. import os, sys, linecache, async_timeout, inspect, traceback
  3. import re, math, random, uuid, time, jsonpickle
  4. from pymysql.converters import escape_item, escape_string, encoders
  5. from contextlib import redirect_stdout
  6. from discord.ext import commands
  7. from discord.ext.commands.errors import CommandNotFound, CommandError
  8. from discord.ext.commands.context import Context
  9. from concurrent.futures import CancelledError, TimeoutError
  10. from io import BytesIO, StringIO
  11.  
  12. encoders[ord(':')] = '\:'
  13.  
  14. class DataProtocol(asyncio.SubprocessProtocol):
  15. def __init__(self, exit_future):
  16. self.exit_future = exit_future
  17. self.output = bytearray()
  18.  
  19. def pipe_data_received(self, fd, data):
  20. self.output.extend(data)
  21.  
  22. def process_exited(self):
  23. try:
  24. self.exit_future.set_result(True)
  25. except:
  26. pass
  27.  
  28. def pipe_connection_lost(self, fd, exc):
  29. try:
  30. self.exit_future.set_result(True)
  31. except:
  32. pass
  33. def connection_made(self, transport):
  34. self.transport = transport
  35.  
  36. def connection_lost(self, exc):
  37. try:
  38. self.exit_future.set_result(True)
  39. except:
  40. pass
  41.  
  42. class Funcs():
  43. def __init__(self, bot, cursor):
  44. self.bot = bot
  45. self.cursor = cursor
  46. self.bot.google_api_keys = open(self.discord_path('utils/keys.txt')).read().split('\n')
  47. self.bot.google_count = 0
  48. self.image_mimes = ['image/png', 'image/pjpeg', 'image/jpeg', 'image/x-icon']
  49. self.session = aiohttp.ClientSession()
  50. self.mention_regex = re.compile(r"<@!?(?P<id>\d+)>")
  51. self.colors = ['red', 'blue', 'green', 'gold', 'dark_blue', 'dark_gold', 'dark_green', 'dark_grey', 'dark_magenta', 'dark_orange', 'dark_purple', 'dark_red', 'dark_teal', 'darker_grey', 'default', 'light_grey', 'lighter_grey', 'magenta', 'orange', 'purple', 'teal']
  52. self.color_count = 0
  53.  
  54. def discord_path(self, path):
  55. return os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), path)
  56.  
  57. def files_path(self, path):
  58. return self.discord_path('files/'+path)
  59.  
  60. async def prefix_check(self, s, prefix, prefix_set):
  61. if prefix_set:
  62. return True
  63. count = 0
  64. for x in s:
  65. if count == 2:
  66. break
  67. elif count == 1:
  68. if x != prefix:
  69. break
  70. if x == prefix:
  71. count += 1
  72. if count == 1:
  73. return True
  74. return False
  75.  
  76. async def get_prefix(self, message):
  77. if self.bot.dev_mode:
  78. prefix = ','
  79. elif self.bot.self_bot:
  80. prefix = 'self.'
  81. else:
  82. prefix = '.'
  83. prefix_set = False
  84. if message.channel.is_private is False and message.content.startswith(prefix+"prefix") is False:
  85. sql = "SELECT prefix FROM `prefix` WHERE server={0}"
  86. sql = sql.format(message.server.id)
  87. sql_channel = "SELECT prefix,channel FROM `prefix_channel` WHERE server={0} AND channel={1}"
  88. sql_channel = sql_channel.format(message.server.id, message.channel.id)
  89. result = self.cursor.execute(sql_channel).fetchall()
  90. if result:
  91. for s in result:
  92. if s['channel'] == message.channel.id:
  93. prefix = s['prefix']
  94. prefix_set = True
  95. break
  96. elif not prefix_set:
  97. result = self.cursor.execute(sql).fetchall()
  98. if len(result) != 0:
  99. prefix = result[0]['prefix']
  100. prefix_set = True
  101. if prefix_set:
  102. prefix = prefix.lower()
  103. mention = commands.bot.when_mentioned(self.bot, message)
  104. if message.content.startswith(mention):
  105. check = True
  106. else:
  107. check = await self.prefix_check(message.content, prefix, prefix_set)
  108. return [prefix, mention], check
  109.  
  110. async def is_blacklisted(self, message):
  111. try:
  112. perms = message.channel.permissions_for(message.server.me)
  113. if perms.send_messages is False or perms.read_messages is False:
  114. return True
  115. except:
  116. pass
  117. if message.author.id == self.bot.owner.id:
  118. return False
  119. global_blacklist_result = self.cursor.execute('SELECT * FROM `global_blacklist` WHERE user={0}'.format(message.author.id)).fetchall()
  120. if message.channel.is_private:
  121. if len(global_blacklist_result) != 0 and message.author.id != bot.owner.id:
  122. return True
  123. return False
  124. muted_check_result = self.cursor.execute('SELECT * FROM `muted` WHERE server={0} AND id={1}'.format(message.server.id, message.author.id)).fetchall()
  125. if len(muted_check_result) != 0 and message.server.owner != message.author:
  126. return True
  127. server_blacklist_result = self.cursor.execute('SELECT * FROM `blacklist` WHERE server={0} AND user={1}'.format(message.server.id, message.author.id)).fetchall()
  128. channel_blacklist_result = self.cursor.execute('SELECT * FROM `channel_blacklist` WHERE server={0} AND channel={1}'.format(message.server.id, message.channel.id)).fetchall()
  129. if len(global_blacklist_result) != 0:
  130. return True
  131. elif len(server_blacklist_result) != 0:
  132. return True
  133. elif len(channel_blacklist_result) != 0:
  134. if 'blacklist' in message.content:
  135. return False
  136. return True
  137. return False
  138.  
  139. async def command_check(self, message, command, prefix='.'):
  140. if message.author.id == self.bot.owner.id:
  141. return False
  142. sql = 'SELECT * FROM `command_blacklist` WHERE type="global" AND command={0}'
  143. sql = sql.format(self.escape(command))
  144. result = self.cursor.execute(sql).fetchall()
  145. if len(result) != 0:
  146. return True
  147. if message.channel.is_private:
  148. return False
  149. sql = 'SELECT * FROM `command_blacklist` WHERE server={0}'
  150. sql = sql.format(message.server.id)
  151. result = self.cursor.execute(sql).fetchall()
  152. topic_match = None
  153. if message.channel.topic:
  154. command_escape = re.escape(command)
  155. topic_regex = re.compile(r"((\[|\{)(\+|\-)?"+command_escape+r"(\]|\}))", re.I|re.S)
  156. match = topic_regex.findall(message.channel.topic.lower())
  157. if match:
  158. if match[0][2] == '+' or not len(match[0][2]):
  159. topic_match = False
  160. elif match[0][2] == '-':
  161. topic_match = True
  162. is_admin = False
  163. try:
  164. perms = message.channel.permissions_for(message.author)
  165. if perms.administrator or perms.manage_server or perms.manage_roles:
  166. is_admin = True
  167. except:
  168. pass
  169. if topic_match:
  170. await self.bot.send_message(message.channel, ':no_entry: **That command is disabled in this channel.**{0}'.format('\nRemove `[-{1}]` from the channel description to enable the command.' if is_admin else ''))
  171. return True
  172. for s in result:
  173. if s['command'] != command:
  174. continue
  175. if s['type'] == 'server':
  176. if topic_match is False:
  177. return False
  178. await self.bot.send_message(message.channel, ':no_entry: **That command is disabled on this server.**{0}'.format("\n`{0}command enable {1}` to enable the command.\n**Alternatively** place `[{1}]` in the channel topic or name.".format(prefix, command) if is_admin else ''))
  179. return True
  180. elif s['type'] == 'channel':
  181. if str(s['channel']) == str(message.channel.id):
  182. await self.bot.send_message(message.channel, ':no_entry: **That command is disabled in this channel.**{0}'.format("\n`{0}command enable channel {1}` {2} to enable the command".format(prefix, command, message.channel.mention) if is_admin else ''))
  183. return True
  184. elif s['type'] == 'role':
  185. for role in message.author.roles:
  186. if str(role.id) == str(s['role']):
  187. await self.bot.send_message(message.channel, ':no_entry: **That command is disabled for role: {1}**{0}'.format("\n`{0}command enable channel {1}` {2} to enable the command.".format(prefix, command, role.mention) if is_admin else ''), role.mention)
  188. return True
  189. elif s['type'] == 'user':
  190. if str(s['user']) == str(message.author.id):
  191. return True
  192. return False
  193.  
  194. async def process_commands(self, message, c, p):
  195. _internal_channel = message.channel
  196. _internal_author = message.author
  197. view = commands.view.StringView(message.content)
  198. prefix = p
  199. invoked_prefix = prefix
  200. if not isinstance(p, (tuple, list)):
  201. if not view.skip_string(p):
  202. return
  203. else:
  204. invoked_prefix = discord.utils.find(view.skip_string, prefix)
  205. if invoked_prefix is None:
  206. return
  207. invoker = view.get_word()
  208. tmp = {
  209. 'bot': self.bot,
  210. 'invoked_with': invoker,
  211. 'message': message,
  212. 'view': view,
  213. 'prefix': invoked_prefix
  214. }
  215. ctx = Context(**tmp)
  216. del tmp
  217. if c in self.bot.commands:
  218. command = self.bot.commands[c]
  219. self.bot.dispatch('command', command, ctx)
  220. # import pdb; pdb.set_trace()
  221. try:
  222. if command in (self.bot.commands['repl'], self.bot.commands['debug']):
  223. await command.invoke(ctx)
  224. else:
  225. with async_timeout.timeout(60):
  226. await command.invoke(ctx)
  227. except (aiohttp.errors.TimeoutError, asyncio.TimeoutError, CancelledError, TimeoutError):
  228. try:
  229. await self.bot.send_message(message.channel, ':warning: **Command timed out...**')
  230. return
  231. except:
  232. return
  233. except CommandError as e:
  234. ctx.command.dispatch_error(e, ctx)
  235. else:
  236. self.bot.dispatch('command_completion', command, ctx)
  237. elif invoker:
  238. exc = commands.errors.CommandNotFound('Command "{0}" is not found'.format(invoker))
  239. self.bot.dispatch('command_error', exc, ctx)
  240.  
  241. async def queue_message(self, channel_id:str, msg):
  242. embed = '0'
  243. if type(msg) == discord.Embed:
  244. embed = '1'
  245. msg = jsonpickle.encode(msg)
  246. else:
  247. msg = str(msg)
  248. message_id = random.randint(0, 1000000)
  249. payload = {'key': 'verysecretkey', 'id': message_id, 'channel_id': channel_id, 'message': msg, 'embed': embed}
  250. try:
  251. with aiohttp.Timeout(15):
  252. async with self.session.post('http://ip:port/queue', data=payload) as r:
  253. return True
  254. except (asyncio.TimeoutError, aiohttp.errors.ClientConnectionError, aiohttp.errors.ClientError):
  255. await asyncio.sleep(5)
  256. return
  257. except Exception as e:
  258. print('queue error: '+str(e))
  259.  
  260. async def isimage(self, url:str):
  261. try:
  262. with aiohttp.Timeout(5):
  263. async with self.session.head(url) as resp:
  264. if resp.status == 200:
  265. mime = resp.headers.get('Content-type', '').lower()
  266. if any([mime == x for x in self.image_mimes]):
  267. return True
  268. else:
  269. return False
  270. except:
  271. return False
  272.  
  273. async def isgif(self, url:str):
  274. try:
  275. with aiohttp.Timeout(5):
  276. async with self.session.head(url) as resp:
  277. if resp.status == 200:
  278. mime = resp.headers.get('Content-type', '').lower()
  279. if mime == "image/gif":
  280. return True
  281. else:
  282. return False
  283. except:
  284. return False
  285.  
  286. async def download(self, url:str, path:str):
  287. try:
  288. with aiohttp.Timeout(5):
  289. async with self.session.get(url) as resp:
  290. data = await resp.read()
  291. with open(path, "wb") as f:
  292. f.write(data)
  293. except asyncio.TimeoutError:
  294. return False
  295.  
  296. async def bytes_download(self, url:str):
  297. try:
  298. with aiohttp.Timeout(5):
  299. async with self.session.get(url) as resp:
  300. data = await resp.read()
  301. b = BytesIO(data)
  302. b.seek(0)
  303. return b
  304. except asyncio.TimeoutError:
  305. return False
  306. except Exception as e:
  307. print(e)
  308. return False
  309.  
  310. async def get_json(self, url:str):
  311. try:
  312. with aiohttp.Timeout(5):
  313. async with self.session.get(url) as resp:
  314. try:
  315. load = await resp.json()
  316. return load
  317. except:
  318. return {}
  319. except asyncio.TimeoutError:
  320. return {}
  321.  
  322. async def get_text(self, url:str):
  323. try:
  324. with aiohttp.Timeout(5):
  325. async with self.session.get(url) as resp:
  326. try:
  327. text = await resp.text()
  328. return text
  329. except:
  330. return False
  331. except asyncio.TimeoutError:
  332. return False
  333.  
  334. async def run_process(self, code, response=False):
  335. try:
  336. loop = self.bot.loop
  337. exit_future = asyncio.Future(loop=loop)
  338. create = loop.subprocess_exec(lambda: DataProtocol(exit_future),
  339. *code, stdin=None, stderr=None)
  340. transport, protocol = await asyncio.wait_for(create, timeout=30)
  341. await exit_future
  342. if response:
  343. data = bytes(protocol.output)
  344. return data.decode('ascii').rstrip()
  345. return True
  346. except asyncio.TimeoutError:
  347. return False
  348. except Exception as e:
  349. print(e)
  350. finally:
  351. transport.close()
  352.  
  353. async def proxy_request(self, url, **kwargs):
  354. post = kwargs.get('post')
  355. post = True if post != {} else False
  356. post_data = kwargs.get('post_data')
  357. headers = kwargs.get('headers')
  358. j = kwargs.get('j')
  359. j = True if j != {} else False
  360. proxy_addr = aiosocks.Socks5Addr('', 1080)
  361. proxy_auth = aiosocks.Socks5Auth('', password='')
  362. proxy_connection = aiosocks.connector.SocksConnector(proxy=proxy_addr, proxy_auth=proxy_auth, remote_resolve=True)
  363. with aiohttp.ClientSession(connector=proxy_connection) as session:
  364. async with session.post(url, data=post_data if post else None, headers=headers) as resp:
  365. if j:
  366. return await resp.json()
  367. else:
  368. return await resp.text()
  369.  
  370. async def truncate(self, channel, msg):
  371. if len(msg) == 0:
  372. return
  373. split = [msg[i:i + 1999] for i in range(0, len(msg), 1999)]
  374. try:
  375. for s in split:
  376. await self.bot.send_message(channel, s)
  377. await asyncio.sleep(0.21)
  378. except Exception as e:
  379. await self.bot.send_message(channel, e)
  380.  
  381. async def get_attachment_images(self, ctx, check_func):
  382. last_attachment = None
  383. img_urls = []
  384. async for m in self.bot.logs_from(ctx.message.channel, before=ctx.message, limit=25):
  385. check = False
  386. if m.attachments:
  387. last_attachment = m.attachments[0]['url']
  388. check = await check_func(last_attachment)
  389. elif m.embeds:
  390. last_attachment = m.embeds[0]['url']
  391. check = await check_func(last_attachment)
  392. if check:
  393. img_urls.append(last_attachment)
  394. break
  395. return img_urls
  396.  
  397. async def get_images(self, ctx, **kwargs):
  398. try:
  399. message = ctx.message
  400. channel = ctx.message.channel
  401. attachments = ctx.message.attachments
  402. mentions = ctx.message.mentions
  403. limit = kwargs.pop('limit', 8)
  404. urls = kwargs.pop('urls', [])
  405. gif = kwargs.pop('gif', False)
  406. msg = kwargs.pop('msg', True)
  407. if gif:
  408. check_func = self.isgif
  409. else:
  410. check_func = self.isimage
  411. if urls is None:
  412. urls = []
  413. elif type(urls) != tuple:
  414. urls = [urls]
  415. else:
  416. urls = list(urls)
  417. scale = kwargs.pop('scale', None)
  418. scale_msg = None
  419. int_scale = None
  420. if gif is False:
  421. for user in mentions:
  422. if user.avatar:
  423. urls.append('https://discordapp.com/api/users/{0.id}/avatars/{0.avatar}.jpg'.format(user))
  424. else:
  425. urls.append(user.default_avatar_url)
  426. limit += 1
  427. for attachment in attachments:
  428. urls.append(attachment['url'])
  429. if scale:
  430. scale_limit = scale
  431. limit += 1
  432. if urls and len(urls) > limit:
  433. await self.bot.send_message(channel, ':no_entry: `Max image limit (<= {0})`'.format(limit))
  434. ctx.command.reset_cooldown(ctx)
  435. return False
  436. img_urls = []
  437. count = 1
  438. for url in urls:
  439. user = None
  440. if url.startswith('<@'):
  441. continue
  442. if not url.startswith('http'):
  443. url = 'http://'+url
  444. try:
  445. if scale:
  446. s_url = url[8:] if url.startswith('https://') else url[7:]
  447. if str(math.floor(float(s_url))).isdigit():
  448. int_scale = int(math.floor(float(s_url)))
  449. scale_msg = '`Scale: {0}`\n'.format(int_scale)
  450. if int_scale > scale_limit and ctx.message.author.id != self.bot.owner.id:
  451. int_scale = scale_limit
  452. scale_msg = '`Scale: {0} (Limit: <= {1})`\n'.format(int_scale, scale_limit)
  453. continue
  454. except Exception as e:
  455. pass
  456. check = await check_func(url)
  457. if check is False and gif is False:
  458. check = await self.isgif(url)
  459. if check:
  460. if msg:
  461. await self.bot.send_message(channel, ":warning: This command is for images, not gifs (use `gmagik` or `gascii`)!")
  462. ctx.command.reset_cooldown(ctx)
  463. return False
  464. elif len(img_urls) == 0:
  465. name = url[8:] if url.startswith('https://') else url[7:]
  466. member = self.find_member(message.server, name, 2)
  467. if member:
  468. img_urls.append('https://discordapp.com/api/users/{0.id}/avatars/{0.avatar}.jpg'.format(member) if member.avatar else member.default_avatar_url)
  469. count += 1
  470. continue
  471. if msg:
  472. await self.bot.send_message(channel, ':warning: Unable to download or verify URL is valid.')
  473. ctx.command.reset_cooldown(ctx)
  474. return False
  475. else:
  476. if msg:
  477. await self.bot.send_message(channel, ':warning: Image `{0}` is Invalid!'.format(count))
  478. continue
  479. elif gif and check is False:
  480. check = await self.isimage(url)
  481. if check:
  482. if msg:
  483. await self.bot.send_message(channel, ":warning: This command is for gifs, not images (use `magik`)!")
  484. ctx.command.reset_cooldown(ctx)
  485. return False
  486. elif len(img_urls) == 0:
  487. name = url[8:] if url.startswith('https://') else url[7:]
  488. member = self.find_member(message.server, name, 2)
  489. if member:
  490. img_urls.append('https://discordapp.com/api/users/{0.id}/avatars/{0.avatar}.jpg'.format(member) if member.avatar else member.default_avatar_url)
  491. count += 1
  492. continue
  493. if msg:
  494. await self.bot.send_message(channel, ':warning: Unable to download or verify URL is valid.')
  495. ctx.command.reset_cooldown(ctx)
  496. return False
  497. else:
  498. if msg:
  499. await self.bot.send_message(channel, ':warning: Gif `{0}` is Invalid!'.format(count))
  500. continue
  501. img_urls.append(url)
  502. count += 1
  503. else:
  504. if len(img_urls) == 0:
  505. attachment_images = await self.get_attachment_images(ctx, check_func)
  506. if attachment_images:
  507. img_urls.extend([*attachment_images])
  508. else:
  509. if msg:
  510. await self.bot.send_message(channel, ":no_entry: Please input url(s){0}or attachment(s).".format(', mention(s) ' if not gif else ' '))
  511. ctx.command.reset_cooldown(ctx)
  512. return False
  513. if scale:
  514. if len(img_urls) == 0:
  515. attachment_images = await self.get_attachment_images(ctx, check_func)
  516. if attachment_images:
  517. img_urls.extend([*attachment_images])
  518. else:
  519. if msg:
  520. await self.bot.send_message(channel, ":no_entry: Please input url(s){0}or attachment(s).".format(', mention(s) ' if not gif else ' '))
  521. ctx.command.reset_cooldown(ctx)
  522. return False
  523. return img_urls, int_scale, scale_msg
  524. if img_urls:
  525. return img_urls
  526. return False
  527. except Exception as e:
  528. print(e)
  529.  
  530. async def google_keys(self):
  531. keys = self.bot.google_api_keys
  532. if self.bot.google_count >= len(keys):
  533. self.bot.google_count = 0
  534. key = keys[self.bot.google_count]
  535. self.bot.google_count += 1
  536. return str(key)
  537.  
  538. def write_last_time(self):
  539. path = self.files_path('last_time_{0}{1}.txt'.format(self.bot.shard_id, '_self' if self.bot.self_bot else ''))
  540. utc = str(int(time.time()))
  541. with open(path, 'wb') as f:
  542. f.write(utc.encode())
  543. f.close()
  544.  
  545. def get_last_time(self):
  546. path = self.files_path('last_time_{0}{1}.txt'.format(self.bot.shard_id, '_self' if self.bot.self_bot else ''))
  547. try:
  548. return int(open(path, 'r').read())
  549. except:
  550. return False
  551.  
  552. def restart_program(self):
  553. python = sys.executable
  554. os.execl(python, python, * sys.argv)
  555.  
  556. async def cleanup_code(self, content):
  557. """Automatically removes code blocks from the code."""
  558. if content.startswith('```') and content.endswith('```'):
  559. clean = '\n'.join(content.split('\n')[1:-1])
  560. else:
  561. clean = content.strip('` \n')
  562. if clean.startswith('http'):
  563. async with self.session.get(clean) as r:
  564. clean = await r.text()
  565. return clean
  566.  
  567. def get_syntax_error(self, e):
  568. return '```py\n{0.text}{1:>{0.offset}}\n{2}: {0}```'.format(e, '^', type(e).__name__)
  569.  
  570. async def repl(self, ctx, code):
  571. msg = ctx.message
  572. variables = {
  573. 'ctx': ctx,
  574. 'bot': ctx.bot,
  575. 'message': msg,
  576. 'server': msg.server,
  577. 'channel': msg.channel,
  578. 'author': msg.author,
  579. 'last': None,
  580. 'commands': commands,
  581. 'discord': discord,
  582. 'asyncio': asyncio,
  583. 'cursor': self.cursor
  584. }
  585. cleaned = await self.cleanup_code(code)
  586. if cleaned in ('quit', 'exit', 'exit()'):
  587. await self.bot.say('Exiting.')
  588. return 'exit'
  589. executor = exec
  590. if cleaned.count('\n') == 0:
  591. try:
  592. code = compile(cleaned, '<repl session>', 'eval')
  593. except SyntaxError:
  594. pass
  595. else:
  596. executor = eval
  597. if executor is exec:
  598. try:
  599. code = compile(cleaned, '<repl session>', 'exec')
  600. except SyntaxError as e:
  601. await self.bot.say(self.get_syntax_error(e))
  602. return False
  603. fmt = None
  604. stdout = StringIO()
  605. try:
  606. with redirect_stdout(stdout):
  607. result = executor(code, variables)
  608. if inspect.isawaitable(result):
  609. result = await result
  610. except Exception as e:
  611. value = stdout.getvalue()
  612. fmt = '```py\n{}{}\n```'.format(value, traceback.format_exc())
  613. else:
  614. value = stdout.getvalue()
  615. if result is not None:
  616. fmt = '```py\n{}{}\n```'.format(value, result)
  617. variables['last'] = result
  618. elif value:
  619. fmt = '```py\n{}\n```'.format(value)
  620. return fmt
  621.  
  622. async def command_help(self, ctx):
  623. if ctx.invoked_subcommand:
  624. cmd = ctx.invoked_subcommand
  625. else:
  626. cmd = ctx.command
  627. pages = self.bot.formatter.format_help_for(ctx, cmd)
  628. for page in pages:
  629. await self.bot.send_message(ctx.message.channel, page.replace("\n", "fix\n", 1))
  630.  
  631. def escape(self, obj, mapping=encoders):
  632. if isinstance(obj, str):
  633. return "'" + escape_string(obj) + "'"
  634. return escape_item(obj, 'utf8mb4', mapping=mapping)
  635.  
  636. async def replace_mentions(self, txt:str):
  637. match = self.mention_regex.findall(txt)
  638. if match:
  639. for i in match:
  640. user = discord.utils.get(self.bot.get_all_members(), id=str(i))
  641. if user is None:
  642. user = await self.bot.get_user_info(i)
  643. txt = re.sub(re.compile('(<@\!?{0}>)'.format(user.id)), '@{0}'.format(user), txt)
  644. return txt
  645.  
  646. def find_member(self, server, name, steps=2):
  647. member = None
  648. match = self.mention_regex.search(name)
  649. if match:
  650. member = server.get_member(match.group('id'))
  651. if not member:
  652. name = name.lower()
  653. checks = [lambda m: m.name.lower() == name or m.display_name.lower() == name, lambda m: m.name.lower().startswith(name) or m.display_name.lower().startswith(name) or m.id == name, lambda m: name in m.display_name.lower() or name in m.name.lower()]
  654. for i in range(steps if steps <= len(checks) else len(checks)):
  655. if i == 3:
  656. member = discord.utils.find(checks[1], self.bot.get_all_members())
  657. else:
  658. member = discord.utils.find(checks[i], server.members)
  659. if member:
  660. break
  661. return member
  662.  
  663. def random(self, image=False, ext:str=False):
  664. h = str(uuid.uuid4().hex)
  665. if image:
  666. return '{0}.{1}'.format(h, ext) if ext else h+'.png'
  667. return h
  668.  
  669. async def is_nsfw(self, message):
  670. channel = message.channel
  671. if channel.is_private:
  672. return True
  673. name = channel.name.lower()
  674. if name == 'nsfw' or name == '[nsfw]':
  675. return True
  676. elif name == 'no-nsfw' or name == 'sfw':
  677. return False
  678. split = name.split()
  679. if 'nsfw' in name:
  680. try:
  681. i = split.index('nsfw')
  682. except:
  683. i = None
  684. if len(split) > 1 and i != None and split[i-1] != 'no':
  685. return True
  686. elif i is None:
  687. split = name.split('-')
  688. try:
  689. i = split.index('nsfw')
  690. except:
  691. i = None
  692. if len(split) > 1 and i != None and split[i-1] != 'no':
  693. return True
  694. if channel.topic != None:
  695. topic = channel.topic.lower()
  696. split = topic.split()
  697. if '{nsfw}' in topic or '[nsfw]' in topic or topic == 'nsfw':
  698. return True
  699. elif 'nsfw' in topic and 'sfw' not in split:
  700. try:
  701. i = split.index('nsfw')
  702. except:
  703. i = None
  704. if len(split) > 1 and i != None and split[i-1] != 'no':
  705. return True
  706. elif i is None:
  707. split = topic.split('-')
  708. try:
  709. i = split.index('nsfw')
  710. except:
  711. i = None
  712. if len(split) > 1 and i != None and split[i-1] != 'no':
  713. return True
  714. return False
  715.  
  716. def get_color(self):
  717. if self.color_count >= len(self.colors):
  718. self.color_count = 0
  719. color = self.colors[self.color_count]
  720. self.color_count += 1
  721. return getattr(discord.Color, color)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement