1
0
Fork 0
mirror of https://github.com/myned/modufur.git synced 2024-12-24 22:27:28 +00:00

Merge branch 'dev'

This commit is contained in:
Myned 2017-10-15 12:58:41 -04:00
commit 246f7a7ad2
7 changed files with 105 additions and 189 deletions

View file

@ -1,6 +1,7 @@
import asyncio import asyncio
import json import json
import traceback as tb import traceback as tb
from contextlib import suppress
import discord as d import discord as d
from discord import errors as err from discord import errors as err
@ -79,21 +80,13 @@ class MsG:
return await ctx.send('❌ **Invalid url.**', delete_after=10) return await ctx.send('❌ **Invalid url.**', delete_after=10)
async def return_pool(self, *, ctx, booru='e621', query=[]): async def return_pool(self, *, ctx, booru='e621', query=[]):
channel = ctx.channel
user = ctx.author
def on_message(msg): def on_message(msg):
if msg.content.lower() == 'cancel' and msg.author is user and msg.channel is channel: if msg.content.lower() == 'cancel' and msg.author is ctx.author and msg.channel is ctx.channel:
raise exc.Abort raise exc.Abort
try: with suppress(ValueError):
if int(msg.content) <= len(pools) and int(msg.content) > 0 and msg.author is user and msg.channel is channel: if int(msg.content) <= len(pools) and int(msg.content) > 0 and msg.author is ctx.author and msg.channel is ctx.channel:
return True return True
return False
except ValueError:
pass
else:
return False
posts = {} posts = {}
pool = {} pool = {}
@ -133,33 +126,25 @@ class MsG:
@commands.command(name='pool', aliases=['e6pp'], brief='e621 pool paginator', description='e621 | NSFW\nShow pools in a page format', hidden=True) @commands.command(name='pool', aliases=['e6pp'], brief='e621 pool paginator', description='e621 | NSFW\nShow pools in a page format', hidden=True)
@checks.del_ctx() @checks.del_ctx()
async def pool_paginator(self, ctx, *kwords): async def pool_paginator(self, ctx, *kwords):
channel = ctx.channel
user = ctx.author
def on_react(reaction, user): def on_react(reaction, user):
if reaction.emoji == '🚫' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): if reaction.emoji == '🚫' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.Abort raise exc.Abort
elif reaction.emoji == '📁' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): elif reaction.emoji == '📁' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.Save raise exc.Save
elif reaction.emoji == '' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): elif reaction.emoji == '' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.Left raise exc.Left
elif reaction.emoji == '🔢' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): elif reaction.emoji == '🔢' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.GoTo raise exc.GoTo
elif reaction.emoji == '' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): elif reaction.emoji == '' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.Right raise exc.Right
else: else:
return False return False
def on_message(msg): def on_message(msg):
try: with suppress(ValueError):
if int(msg.content) <= len(posts) and msg.author is user and msg.channel is channel: if int(msg.content) <= len(posts) and msg.author is ctx.author and msg.channel is ctx.channel:
return True return True
return False
except ValueError:
pass
else:
return False
starred = [] starred = []
c = 1 c = 1
@ -173,7 +158,7 @@ class MsG:
embed = d.Embed( embed = d.Embed(
title=values[c - 1]['author'], url='https://e621.net/post/show/{}'.format(keys[c - 1]), color=ctx.me.color).set_image(url=values[c - 1]['url']) title=values[c - 1]['author'], url='https://e621.net/post/show/{}'.format(keys[c - 1]), color=ctx.me.color).set_image(url=values[c - 1]['url'])
embed.set_author(name=pool['name'], embed.set_author(name=pool['name'],
url='https://e621.net/pool/show?id={}'.format(pool['id']), icon_url=user.avatar_url) url='https://e621.net/pool/show?id={}'.format(pool['id']), icon_url=ctx.author.avatar_url)
embed.set_footer(text='{} / {}'.format(c, len(posts)), embed.set_footer(text='{} / {}'.format(c, len(posts)),
icon_url='icon_e6.png') icon_url='icon_e6.png')
@ -256,7 +241,7 @@ class MsG:
finally: finally:
for url in starred: for url in starred:
await user.send(url) await ctx.author.send(url)
if len(starred) > 5: if len(starred) > 5:
await asyncio.sleep(2.1) await asyncio.sleep(2.1)
@ -264,16 +249,14 @@ class MsG:
async def check_return_posts(self, *, ctx, booru='e621', tags=[], limit=1, previous={}): async def check_return_posts(self, *, ctx, booru='e621', tags=[], limit=1, previous={}):
guild = ctx.guild if isinstance( guild = ctx.guild if isinstance(
ctx.guild, d.Guild) else ctx.channel ctx.guild, d.Guild) else ctx.channel
channel = ctx.channel
user = ctx.author
blacklist = set() blacklist = set()
# Creates temp blacklist based on context # Creates temp blacklist based on context
for tag in self.blacklists['global_blacklist']: for tag in self.blacklists['global_blacklist']:
blacklist.update(list(self.aliases[tag]) + [tag]) blacklist.update(list(self.aliases[tag]) + [tag])
for tag in self.blacklists['guild_blacklist'].get(guild.id, {}).get(channel.id, set()): for tag in self.blacklists['guild_blacklist'].get(guild.id, {}).get(ctx.channel.id, set()):
blacklist.update(list(self.aliases[tag]) + [tag]) blacklist.update(list(self.aliases[tag]) + [tag])
for tag in self.blacklists['user_blacklist'].get(user.id, set()): for tag in self.blacklists['user_blacklist'].get(ctx.author.id, set()):
blacklist.update(list(self.aliases[tag]) + [tag]) blacklist.update(list(self.aliases[tag]) + [tag])
# Checks if tags are in local blacklists # Checks if tags are in local blacklists
if tags: if tags:
@ -316,33 +299,25 @@ class MsG:
@checks.del_ctx() @checks.del_ctx()
@checks.is_nsfw() @checks.is_nsfw()
async def e621_paginator(self, ctx, *args): async def e621_paginator(self, ctx, *args):
channel = ctx.channel
user = ctx.author
def on_react(reaction, user): def on_react(reaction, user):
if reaction.emoji == '🚫' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): if reaction.emoji == '🚫' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.Abort raise exc.Abort
elif reaction.emoji == '📁' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): elif reaction.emoji == '📁' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.Save raise exc.Save
elif reaction.emoji == '' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): elif reaction.emoji == '' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.Left raise exc.Left
elif reaction.emoji == '🔢' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): elif reaction.emoji == '🔢' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.GoTo raise exc.GoTo
elif reaction.emoji == '' and reaction.message.content == paginator.content and (user is user or user.id == u.config['owner_id']): elif reaction.emoji == '' and reaction.message.content == paginator.content and (user is ctx.author or user.id == u.config['owner_id']):
raise exc.Right raise exc.Right
else: else:
return False return False
def on_message(msg): def on_message(msg):
try: with suppress(ValueError):
if int(msg.content) <= len(posts) and msg.author is user and msg.channel is channel: if int(msg.content) <= len(posts) and msg.author is ctx.author and msg.channel is ctx.channel:
return True return True
return False
except ValueError:
pass
else:
return False
args = list(args) args = list(args)
limit = self.LIMIT / 5 limit = self.LIMIT / 5
@ -358,7 +333,7 @@ class MsG:
embed = d.Embed( embed = d.Embed(
title=values[c - 1]['author'], url='https://e621.net/post/show/{}'.format(keys[c - 1]), color=ctx.me.color).set_image(url=values[c - 1]['url']) title=values[c - 1]['author'], url='https://e621.net/post/show/{}'.format(keys[c - 1]), color=ctx.me.color).set_image(url=values[c - 1]['url'])
embed.set_author(name=formatter.tostring(args, random=True), embed.set_author(name=formatter.tostring(args, random=True),
url='https://e621.net/post?tags={}'.format(','.join(args)), icon_url=user.avatar_url) url='https://e621.net/post?tags={}'.format(','.join(args)), icon_url=ctx.author.avatar_url)
embed.set_footer(text='{} / {}'.format(c, len(posts)), embed.set_footer(text='{} / {}'.format(c, len(posts)),
icon_url='icon_e6.png') icon_url='icon_e6.png')
@ -447,7 +422,7 @@ class MsG:
finally: finally:
for url in starred: for url in starred:
await user.send(url) await ctx.author.send(url)
if len(starred) > 5: if len(starred) > 5:
await asyncio.sleep(2.1) await asyncio.sleep(2.1)
@ -461,7 +436,6 @@ class MsG:
@checks.del_ctx() @checks.del_ctx()
@checks.is_nsfw() @checks.is_nsfw()
async def e621(self, ctx, *args): async def e621(self, ctx, *args):
user = ctx.author
args = list(args) args = list(args)
limit = 1 limit = 1
@ -470,21 +444,18 @@ class MsG:
# Checks for, defines, and removes limit from args # Checks for, defines, and removes limit from args
for arg in args: for arg in args:
if len(arg) == 1: if len(arg) == 1:
try: with suppress(ValueError):
if int(arg) <= 6 and int(arg) >= 1: if int(arg) <= 6 and int(arg) >= 1:
limit = int(arg) limit = int(arg)
args.remove(arg) args.remove(arg)
else: else:
raise exc.BoundsError(arg) raise exc.BoundsError(arg)
except ValueError:
pass
posts = await self.check_return_posts(ctx=ctx, booru='e621', tags=args, limit=limit) posts = await self.check_return_posts(ctx=ctx, booru='e621', tags=args, limit=limit)
for ident, post in posts.items(): for ident, post in posts.items():
embed = d.Embed(title=post['author'], url='https://e621.net/post/show/{}'.format(ident), embed = d.Embed(title=post['author'], url='https://e621.net/post/show/{}'.format(ident),
color=ctx.me.color).set_image(url=post['url']) color=ctx.me.color).set_image(url=post['url'])
embed.set_author(name=formatter.tostring(args, random=True), embed.set_author(name=formatter.tostring(args, random=True),
url='https://e621.net/post?tags={}'.format(','.join(args)), icon_url=user.avatar_url) url='https://e621.net/post?tags={}'.format(','.join(args)), icon_url=ctx.author.avatar_url)
embed.set_footer( embed.set_footer(
text=str(ident), icon_url='icon_e6.png') text=str(ident), icon_url='icon_e6.png')
await ctx.send(embed=embed) await ctx.send(embed=embed)
@ -504,7 +475,7 @@ class MsG:
except exc.Timeout: except exc.Timeout:
await ctx.send('❌ **Request timed out.**') await ctx.send('❌ **Request timed out.**')
tools.command_dict.setdefault(str(user.id), {}).update( tools.command_dict.setdefault(str(ctx.author.id), {}).update(
{'command': ctx.command, 'args': ctx.args}) {'command': ctx.command, 'args': ctx.args})
@e621.error @e621.error
@ -516,7 +487,6 @@ class MsG:
@commands.command(aliases=['e9', '9'], brief='e926 | SFW', description='e926 | SFW\nTag-based search for e926.net\n\nYou can only search 5 tags and 6 images at once for now.\ne9 [tags...] ([# of images])') @commands.command(aliases=['e9', '9'], brief='e926 | SFW', description='e926 | SFW\nTag-based search for e926.net\n\nYou can only search 5 tags and 6 images at once for now.\ne9 [tags...] ([# of images])')
@checks.del_ctx() @checks.del_ctx()
async def e926(self, ctx, *args): async def e926(self, ctx, *args):
user = ctx.author
args = list(args) args = list(args)
limit = 1 limit = 1
@ -525,21 +495,18 @@ class MsG:
# Checks for, defines, and removes limit from args # Checks for, defines, and removes limit from args
for arg in args: for arg in args:
if len(arg) == 1: if len(arg) == 1:
try: with suppress(ValueError):
if int(arg) <= 6 and int(arg) >= 1: if int(arg) <= 6 and int(arg) >= 1:
limit = int(arg) limit = int(arg)
args.remove(arg) args.remove(arg)
else: else:
raise exc.BoundsError(arg) raise exc.BoundsError(arg)
except ValueError:
pass
posts = await self.check_return_posts(ctx=ctx, booru='e926', tags=args, limit=limit) posts = await self.check_return_posts(ctx=ctx, booru='e926', tags=args, limit=limit)
for ident, post in posts.items(): for ident, post in posts.items():
embed = d.Embed(title=post['author'], url='https://e926.net/post/show/{}'.format(ident), embed = d.Embed(title=post['author'], url='https://e926.net/post/show/{}'.format(ident),
color=ctx.me.color).set_image(url=post['url']) color=ctx.me.color).set_image(url=post['url'])
embed.set_author(name=formatter.tostring(args, random=True), embed.set_author(name=formatter.tostring(args, random=True),
url='https://e621.net/post?tags={}'.format(','.join(args)), icon_url=user.avatar_url) url='https://e621.net/post?tags={}'.format(','.join(args)), icon_url=ctx.author.avatar_url)
embed.set_footer( embed.set_footer(
text=str(ident), icon_url='icon_e6.png') text=str(ident), icon_url='icon_e6.png')
await ctx.send(embed=embed) await ctx.send(embed=embed)
@ -570,45 +537,39 @@ class MsG:
@favorites.command(name='get', aliases=['g']) @favorites.command(name='get', aliases=['g'])
async def _get_favorites(self, ctx): async def _get_favorites(self, ctx):
user = ctx.author await ctx.send('{}**\'s favorites:**\n```\n{}```'.format(ctx.author.mention, formatter.tostring(self.favorites.get(ctx.author.id, set()))))
await ctx.send('{}**\'s favorites:**\n```\n{}```'.format(user.mention, formatter.tostring(self.favorites.get(user.id, set()))))
@favorites.command(name='add', aliases=['a']) @favorites.command(name='add', aliases=['a'])
async def _add_favorites(self, ctx, *tags): async def _add_favorites(self, ctx, *tags):
user = ctx.author self.favorites.setdefault(ctx.author.id, set()).update(tags)
self.favorites.setdefault(user.id, set()).update(tags)
u.dump(self.favorites, 'cogs/favorites.pkl') u.dump(self.favorites, 'cogs/favorites.pkl')
await ctx.send('{} **added:**\n```\n{}```'.format(user.mention, formatter.tostring(tags))) await ctx.send('{} **added:**\n```\n{}```'.format(ctx.author.mention, formatter.tostring(tags)))
@favorites.command(name='remove', aliases=['r']) @favorites.command(name='remove', aliases=['r'])
async def _remove_favorites(self, ctx, *tags): async def _remove_favorites(self, ctx, *tags):
user = ctx.author
try: try:
for tag in tags: for tag in tags:
try: try:
self.favorites[user.id].remove(tag) self.favorites[ctx.author.id].remove(tag)
except KeyError: except KeyError:
raise exc.TagError(tag) raise exc.TagError(tag)
u.dump(self.favorites, 'cogs/favorites.pkl') u.dump(self.favorites, 'cogs/favorites.pkl')
await ctx.send('{} **removed:**\n```\n{}```'.format(user.mention, formatter.tostring(tags)), delete_after=5) await ctx.send('{} **removed:**\n```\n{}```'.format(ctx.author.mention, formatter.tostring(tags)), delete_after=5)
except exc.TagError as e: except exc.TagError as e:
await ctx.send('❌ `{}` **not in favorites.**'.format(e), delete_after=10) await ctx.send('❌ `{}` **not in favorites.**'.format(e), delete_after=10)
@favorites.command(name='clear', aliases=['c']) @favorites.command(name='clear', aliases=['c'])
async def _clear_favorites(self, ctx): async def _clear_favorites(self, ctx):
user = ctx.author with suppress(KeyError):
del self.favorites[ctx.author.id]
u.dump(self.favorites, 'cogs/favorites.pkl')
del self.favorites[user.id] await ctx.send('{}**\'s favorites cleared.**'.format(ctx.author.mention))
await ctx.send('{}**\'s favorites cleared.**'.format(user.mention))
# Umbrella command structure to manage global, channel, and user blacklists # Umbrella command structure to manage global, channel, and user blacklists
@commands.group(aliases=['bl', 'b'], brief='Manage blacklists', description='Blacklist base command for managing blacklists\n\n`bl get [blacklist]` to show a blacklist\n`bl set [blacklist] [tags]` to replace a blacklist\n`bl clear [blacklist]` to clear a blacklist\n`bl add [blacklist] [tags]` to add tags to a blacklist\n`bl remove [blacklist] [tags]` to remove tags from a blacklist', usage='[flag] [blacklist] ([tags])') @commands.group(aliases=['bl', 'b'], brief='Manage blacklists', description='Blacklist base command for managing blacklists\n\n`bl get [blacklist]` to show a blacklist\n`bl set [blacklist] [tags]` to replace a blacklist\n`bl clear [blacklist]` to clear a blacklist\n`bl add [blacklist] [tags]` to add tags to a blacklist\n`bl remove [blacklist] [tags]` to remove tags from a blacklist', usage='[flag] [blacklist] ([tags])')
@ -637,23 +598,19 @@ class MsG:
async def __get_channel_blacklist(self, ctx): async def __get_channel_blacklist(self, ctx):
guild = ctx.guild if isinstance( guild = ctx.guild if isinstance(
ctx.guild, d.Guild) else ctx.channel ctx.guild, d.Guild) else ctx.channel
channel = ctx.channel
await ctx.send('🚫 {} **blacklist:**\n```\n{}```'.format(channel.mention, formatter.tostring(self.blacklists['guild_blacklist'].get(guild.id, {}).get(channel.id, set())))) await ctx.send('🚫 {} **blacklist:**\n```\n{}```'.format(ctx.channel.mention, formatter.tostring(self.blacklists['guild_blacklist'].get(guild.id, {}).get(ctx.channel.id, set()))))
@_get_blacklist.command(name='me', aliases=['m']) @_get_blacklist.command(name='me', aliases=['m'])
async def __get_user_blacklist(self, ctx): async def __get_user_blacklist(self, ctx):
user = ctx.author await ctx.send('🚫 {}**\'s blacklist:**\n```\n{}```'.format(ctx.author.mention, formatter.tostring(self.blacklists['user_blacklist'].get(ctx.author.id, set()))), delete_after=10)
await ctx.send('🚫 {}**\'s blacklist:**\n```\n{}```'.format(user.mention, formatter.tostring(self.blacklists['user_blacklist'].get(user.id, set()))), delete_after=10)
@_get_blacklist.command(name='here', aliases=['h']) @_get_blacklist.command(name='here', aliases=['h'])
async def __get_here_blacklists(self, ctx): async def __get_here_blacklists(self, ctx):
guild = ctx.guild if isinstance( guild = ctx.guild if isinstance(
ctx.guild, d.Guild) else ctx.channel ctx.guild, d.Guild) else ctx.channel
channel = ctx.channel
await ctx.send('🚫 **__Blacklisted:__**\n\n**Global:**\n```\n{}```\n**{}:**\n```\n{}```'.format(formatter.tostring(self.blacklists['global_blacklist']), channel.mention, formatter.tostring(self.blacklists['guild_blacklist'].get(guild.id, {}).get(channel.id, set())))) await ctx.send('🚫 **__Blacklisted:__**\n\n**Global:**\n```\n{}```\n**{}:**\n```\n{}```'.format(formatter.tostring(self.blacklists['global_blacklist']), ctx.channel.mention, formatter.tostring(self.blacklists['guild_blacklist'].get(guild.id, {}).get(ctx.channel.id, set()))))
@_get_blacklist.group(name='all', aliases=['a']) @_get_blacklist.group(name='all', aliases=['a'])
async def __get_all_blacklists(self, ctx): async def __get_all_blacklists(self, ctx):
@ -681,6 +638,8 @@ class MsG:
@_add_tags.command(name='global', aliases=['gl', 'g']) @_add_tags.command(name='global', aliases=['gl', 'g'])
@commands.is_owner() @commands.is_owner()
async def __add_global_tags(self, ctx, *tags): async def __add_global_tags(self, ctx, *tags):
await ctx.trigger_typing()
self.blacklists['global_blacklist'].update(tags) self.blacklists['global_blacklist'].update(tags)
for tag in tags: for tag in tags:
alias_request = await u.fetch('https://e621.net/tag_alias/index.json', params={'aliased_to': tag, 'approved': 'true'}, json=True) alias_request = await u.fetch('https://e621.net/tag_alias/index.json', params={'aliased_to': tag, 'approved': 'true'}, json=True)
@ -697,10 +656,11 @@ class MsG:
async def __add_channel_tags(self, ctx, *tags): async def __add_channel_tags(self, ctx, *tags):
guild = ctx.guild if isinstance( guild = ctx.guild if isinstance(
ctx.guild, d.Guild) else ctx.channel ctx.guild, d.Guild) else ctx.channel
channel = ctx.channel
await ctx.trigger_typing()
self.blacklists['guild_blacklist'].setdefault( self.blacklists['guild_blacklist'].setdefault(
guild.id, {}).setdefault(channel.id, set()).update(tags) guild.id, {}).setdefault(ctx.channel.id, set()).update(tags)
for tag in tags: for tag in tags:
alias_request = await u.fetch('https://e621.net/tag_alias/index.json', params={'aliased_to': tag, 'approved': 'true'}, json=True) alias_request = await u.fetch('https://e621.net/tag_alias/index.json', params={'aliased_to': tag, 'approved': 'true'}, json=True)
if alias_request: if alias_request:
@ -709,13 +669,13 @@ class MsG:
u.dump(self.blacklists, 'cogs/blacklists.pkl') u.dump(self.blacklists, 'cogs/blacklists.pkl')
u.dump(self.aliases, 'cogs/aliases.pkl') u.dump(self.aliases, 'cogs/aliases.pkl')
await ctx.send('✅ **Added to** {} **blacklist:**\n```\n{}```'.format(channel.mention, formatter.tostring(tags)), delete_after=5) await ctx.send('✅ **Added to** {} **blacklist:**\n```\n{}```'.format(ctx.channel.mention, formatter.tostring(tags)), delete_after=5)
@_add_tags.command(name='me', aliases=['m']) @_add_tags.command(name='me', aliases=['m'])
async def __add_user_tags(self, ctx, *tags): async def __add_user_tags(self, ctx, *tags):
user = ctx.author await ctx.trigger_typing()
self.blacklists['user_blacklist'].setdefault(user.id, set()).update(tags) self.blacklists['user_blacklist'].setdefault(ctx.author.id, set()).update(tags)
for tag in tags: for tag in tags:
alias_request = await u.fetch('https://e621.net/tag_alias/index.json', params={'aliased_to': tag, 'approved': 'true'}, json=True) alias_request = await u.fetch('https://e621.net/tag_alias/index.json', params={'aliased_to': tag, 'approved': 'true'}, json=True)
if alias_request: if alias_request:
@ -724,7 +684,7 @@ class MsG:
u.dump(self.blacklists, 'cogs/blacklists.pkl') u.dump(self.blacklists, 'cogs/blacklists.pkl')
u.dump(self.aliases, 'cogs/aliases.pkl') u.dump(self.aliases, 'cogs/aliases.pkl')
await ctx.send('{} **added:**\n```\n{}```'.format(user.mention, formatter.tostring(tags)), delete_after=5) await ctx.send('{} **added:**\n```\n{}```'.format(ctx.author.mention, formatter.tostring(tags)), delete_after=5)
@blacklist.group(name='remove', aliases=['rm', 'r']) @blacklist.group(name='remove', aliases=['rm', 'r'])
async def _remove_tags(self, ctx): async def _remove_tags(self, ctx):
@ -754,38 +714,35 @@ class MsG:
async def __remove_channel_tags(self, ctx, *tags): async def __remove_channel_tags(self, ctx, *tags):
guild = ctx.guild if isinstance( guild = ctx.guild if isinstance(
ctx.guild, d.Guild) else ctx.channel ctx.guild, d.Guild) else ctx.channel
channel = ctx.channel
try: try:
for tag in tags: for tag in tags:
try: try:
self.blacklists['guild_blacklist'][guild.id][channel.id].remove(tag) self.blacklists['guild_blacklist'][guild.id][ctx.channel.id].remove(tag)
except KeyError: except KeyError:
raise exc.TagError(tag) raise exc.TagError(tag)
u.dump(self.blacklists, 'cogs/blacklists.pkl') u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('✅ **Removed from** {} **blacklist:**\n```\n{}```'.format(channel.mention, formatter.tostring(tags), delete_after=5)) await ctx.send('✅ **Removed from** {} **blacklist:**\n```\n{}```'.format(ctx.channel.mention, formatter.tostring(tags), delete_after=5))
except exc.TagError as e: except exc.TagError as e:
await ctx.send('❌ `{}` **not in blacklist.**'.format(e), delete_after=10) await ctx.send('❌ `{}` **not in blacklist.**'.format(e), delete_after=10)
@_remove_tags.command(name='me', aliases=['m']) @_remove_tags.command(name='me', aliases=['m'])
async def __remove_user_tags(self, ctx, *tags): async def __remove_user_tags(self, ctx, *tags):
user = ctx.author
try: try:
for tag in tags: for tag in tags:
try: try:
self.blacklists['user_blacklist'][user.id].remove(tag) self.blacklists['user_blacklist'][ctx.author.id].remove(tag)
except KeyError: except KeyError:
raise exc.TagError(tag) raise exc.TagError(tag)
u.dump(self.blacklists, 'cogs/blacklists.pkl') u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('{} **removed:**\n```\n{}```'.format(user.mention, formatter.tostring(tags)), delete_after=5) await ctx.send('{} **removed:**\n```\n{}```'.format(ctx.author.mention, formatter.tostring(tags)), delete_after=5)
except exc.TagError as e: except exc.TagError as e:
await ctx.send('❌ `{}` **not in blacklist.**'.format(e), delete_after=10) await ctx.send('❌ `{}` **not in blacklist.**'.format(e), delete_after=10)
@ -798,7 +755,7 @@ class MsG:
@_clear_blacklist.command(name='global', aliases=['gl', 'g']) @_clear_blacklist.command(name='global', aliases=['gl', 'g'])
@commands.is_owner() @commands.is_owner()
async def __clear_global_blacklist(self, ctx): async def __clear_global_blacklist(self, ctx):
del self.blacklists['global_blacklist'] self.blacklists['global_blacklist'].clear()
u.dump(self.blacklists, 'cogs/blacklists.pkl') u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('✅ **Global blacklist cleared.**', delete_after=5) await ctx.send('✅ **Global blacklist cleared.**', delete_after=5)
@ -808,18 +765,17 @@ class MsG:
async def __clear_channel_blacklist(self, ctx): async def __clear_channel_blacklist(self, ctx):
guild = ctx.guild if isinstance( guild = ctx.guild if isinstance(
ctx.guild, d.Guild) else ctx.channel ctx.guild, d.Guild) else ctx.channel
channel = ctx.channel
del self.blacklists['guild_blacklist'][str(guild.id)][channel.id] with suppress(KeyError):
u.dump(self.blacklists, 'cogs/blacklists.pkl') del self.blacklists['guild_blacklist'][guild.id][ctx.channel.id]
u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('{} **blacklist cleared.**'.format(channel.mention), delete_after=5) await ctx.send('{} **blacklist cleared.**'.format(ctx.channel.mention), delete_after=5)
@_clear_blacklist.command(name='me', aliases=['m']) @_clear_blacklist.command(name='me', aliases=['m'])
async def __clear_user_blacklist(self, ctx): async def __clear_user_blacklist(self, ctx):
user = ctx.author with suppress(KeyError):
del self.blacklists['user_blacklist'][ctx.author.id]
u.dump(self.blacklists, 'cogs/blacklists.pkl')
del self.blacklists['user_blacklist'][user.id] await ctx.send('{}**\'s blacklist cleared.**'.format(ctx.author.mention), delete_after=5)
u.dump(self.blacklists, 'cogs/blacklists.pkl')
await ctx.send('{}**\'s blacklist cleared.**'.format(user.mention), delete_after=5)

View file

@ -24,14 +24,12 @@ class Info:
@commands.command(hidden=True) @commands.command(hidden=True)
async def hi(self, ctx): async def hi(self, ctx):
user = ctx.author hello = 'Hewwo, {}.'.format(ctx.author.mention)
if ctx.author.id == checks.owner_id:
hello = 'Hewwo, {}.'.format(user.mention)
if user.id == checks.owner_id:
hello += '.. ***Master.*** uwu' hello += '.. ***Master.*** uwu'
elif user.guild_permissions.administrator: elif ctx.author.guild_permissions.administrator:
hello = '{} **Admin** {}'.format(hello[:7], hello[7:]) hello = '{} **Admin** {}'.format(hello[:7], hello[7:])
elif user.guild_permissions.ban_members: elif ctx.author.guild_permissions.ban_members:
hello = '{} **Mod** {}'.format(hello[:7], hello[7:]) hello = '{} **Mod** {}'.format(hello[:7], hello[7:])
await ctx.send(hello) await ctx.send(hello)

View file

@ -1,5 +1,6 @@
import asyncio import asyncio
import traceback as tb import traceback as tb
from contextlib import suppress
import discord as d import discord as d
from discord import errors as err from discord import errors as err
@ -26,47 +27,6 @@ class Administration:
self.bot.loop.create_task(self.delete()) self.bot.loop.create_task(self.delete())
self.deleting = True self.deleting = True
# @commands.group(aliases=['pr', 'clear', 'cl'])
# @commands.is_owner()
# @checks.del_ctx()
# async def prune(self, ctx):
# pass
#
# @prune.group(name='all', aliases=['a'])
# async def _all(self, ctx):
# pass
# @_all.group(name='user')
# async def __user(self, ctx, user: d.Member):
# channels = ctx.guild.text_channels
# bulk_history = {}
# bulk = {}
# history = []
# c = 0
# if ctx.invoked_subcommand is None:
# for channel in channels:
# bulk_history[channel] = await channel.history(limit=None, after=dt.datetime.utcnow() - dt.timedelta(days=14)).flatten()
# await ch_sent.edit(content='🗄 **Cached** `' + str(channels.index(channel) + 1) + '/' + str(len(channels)) + '` **channels.**')
# await asyncio.sleep(self.RATE_LIMIT)
# for channel, messages in bulk_history.items():
# bulk[channel] = [message for message in messages if message.author.id == int(uid)]
# for channel, messages in bulk_history.items():
# bulk[channel] = [bulk[channel][i:i+100] for i in range(0, len(bulk[channel]), 100)]
# await ctx.send('⏱ **Estimated time to delete `bulk-history`:** `' + str(int(self.RATE_LIMIT * sum([len(v) for v in bulk.values()]) / 60)) + ' mins ' + str(int(self.RATE_LIMIT * sum([len(v) for v in bulk.values()]) % 60)) + ' secs`')
# check = await ctx.send(ctx.author.mention + ' **Continue?** `Y` or `N`')
# await self.bot.wait_for('message', check=yes, timeout=60)
# del_sent = await ctx.send('🗑 **Deleting messages...**')
# for channel, messages in bulk.items():
# for chunk in messages:
# c += len(chunk)
# await channel.delete_messages(chunk)
# await del_sent.edit(content='🗑 **Deleted** `' + str(c) + '/' + str(sum([len(v) for v in bulk.values()])) + '` **messages.**')
# await asyncio.sleep(5)
# await ctx.send('✅ `' + str(sum([len(v) for v in bulk.values()])) + '` **of** <@' + uid + '>**\'s messages deleted from** ' + ctx.guild.name + '**.**')
# for channel in channels:
# history.extend(await channel.history(limit=None, before=dt.datetime.utcnow() - dt.timedelta(days=14)).flatten())
# await ch_sent.edit(content='🗄 **Cached** `' + str(channels.index(channel) + 1) + '/' + str(len(channels)) + '` **channels.**')
# await asyncio.sleep(self.RATE_LIMIT)
@commands.command(name=',prunefromguild', aliases=[',pfg', ',prunefromserver', ',pfs'], brief='Prune a user\'s messages from the guild', description='about flag centers on message 50 of 101 messages\n\npfg \{user id\} [before|after|about] [\{message id\}]\n\nExample:\npfg \{user id\} before \{message id\}') @commands.command(name=',prunefromguild', aliases=[',pfg', ',prunefromserver', ',pfs'], brief='Prune a user\'s messages from the guild', description='about flag centers on message 50 of 101 messages\n\npfg \{user id\} [before|after|about] [\{message id\}]\n\nExample:\npfg \{user id\} before \{message id\}')
@commands.is_owner() @commands.is_owner()
@checks.del_ctx() @checks.del_ctx()
@ -121,12 +81,9 @@ class Administration:
await cont_sent.delete() await cont_sent.delete()
del_sent = await ctx.send('🗑 **Deleting messages...**') del_sent = await ctx.send('🗑 **Deleting messages...**')
for message in history: for message in history:
try: with suppress(err.NotFound):
await message.delete() await message.delete()
except d.NotFound:
pass
# print('Deleted {}/{} messages.'.format(history.index(message) + 1, len(history))) # print('Deleted {}/{} messages.'.format(history.index(message) + 1, len(history)))
await del_sent.edit(content='🗑 **Deleted** `{}/{}` **messages.**'.format(history.index(message) + 1, len(history))) await del_sent.edit(content='🗑 **Deleted** `{}/{}` **messages.**'.format(history.index(message) + 1, len(history)))
await asyncio.sleep(self.RATE_LIMIT) await asyncio.sleep(self.RATE_LIMIT)
@ -142,11 +99,9 @@ class Administration:
while self.deleting: while self.deleting:
message = await self.queue.get() message = await self.queue.get()
await asyncio.sleep(self.RATE_LIMIT) await asyncio.sleep(self.RATE_LIMIT)
try: with suppress(err.NotFound):
if not message.pinned: if not message.pinned:
await message.delete() await message.delete()
except err.NotFound:
pass
async def queue_on_message(self, channel): async def queue_on_message(self, channel):
def check(msg): def check(msg):
@ -159,6 +114,8 @@ class Administration:
try: try:
async for message in channel.history(): async for message in channel.history():
if message.content.lower() == 'stop' and message.author.guild_permissions.administrator:
raise exc.Abort
if not message.pinned: if not message.pinned:
await self.queue.put(message) await self.queue.put(message)
@ -171,8 +128,9 @@ class Administration:
u.dump(u.tasks, 'cogs/tasks.pkl') u.dump(u.tasks, 'cogs/tasks.pkl')
if not u.tasks['auto_del']: if not u.tasks['auto_del']:
self.deleting = False self.deleting = False
print('Stopped looping {}'.format(channel.id)) print('Stopped deleting.')
await channel.send('✅ **Stopped deleting messages in** {}**.**'.format(channel.mention), delete_after=5) print('Stopped looping #{}'.format(channel.name))
await channel.send('✅ **Stopped queueing messages for deletion in** {}**.**'.format(channel.mention), delete_after=5)
except AttributeError: except AttributeError:
pass pass
@ -181,17 +139,15 @@ class Administration:
@commands.has_permissions(administrator=True) @commands.has_permissions(administrator=True)
@checks.del_ctx() @checks.del_ctx()
async def auto_delete(self, ctx): async def auto_delete(self, ctx):
channel = ctx.channel
try: try:
if channel.id not in u.tasks['auto_del']: if ctx.channel.id not in u.tasks['auto_del']:
u.tasks['auto_del'].append(channel.id) u.tasks['auto_del'].append(ctx.channel.id)
u.dump(u.tasks, 'cogs/tasks.pkl') u.dump(u.tasks, 'cogs/tasks.pkl')
self.bot.loop.create_task(self.queue_on_message(channel)) self.bot.loop.create_task(self.queue_on_message(ctx.channel))
if not self.deleting: if not self.deleting:
self.bot.loop.create_task(self.delete()) self.bot.loop.create_task(self.delete())
self.deleting = True self.deleting = True
print('Looping #{}'.format(channel.name)) print('Looping #{}'.format(ctx.channel.name))
await ctx.send('✅ **Auto-deleting all messages in this channel.**', delete_after=5) await ctx.send('✅ **Auto-deleting all messages in this channel.**', delete_after=5)
else: else:
raise exc.Exists raise exc.Exists
@ -202,12 +158,10 @@ class Administration:
@commands.command(name='deletecommands', aliases=['delcmds']) @commands.command(name='deletecommands', aliases=['delcmds'])
@commands.has_permissions(administrator=True) @commands.has_permissions(administrator=True)
async def delete_commands(self, ctx): async def delete_commands(self, ctx):
guild = ctx.guild if ctx.guild.id not in u.settings['del_ctx']:
u.settings['del_ctx'].append(ctx.guild.id)
if guild.id not in u.settings['del_ctx']:
u.settings['del_ctx'].append(guild.id)
else: else:
u.settings['del_ctx'].remove(guild.id) u.settings['del_ctx'].remove(ctx.guild.id)
u.dump(u.settings, 'settings.pkl') u.dump(u.settings, 'settings.pkl')
await ctx.send('✅ **Delete command invocations:** `{}`'.format(guild.id in u.settings['del_ctx'])) await ctx.send('✅ **Delete command invocations:** `{}`'.format(ctx.guild.id in u.settings['del_ctx']))

View file

@ -28,13 +28,12 @@ class Bot:
@checks.del_ctx() @checks.del_ctx()
async def die(self, ctx): async def die(self, ctx):
if isinstance(self.bot.get_channel(u.config['shutdown_channel']), d.TextChannel): if isinstance(self.bot.get_channel(u.config['shutdown_channel']), d.TextChannel):
await self.bot.get_channel(u.config['shutdown_channel']).send('**Shutting down . . .** 🌙') await self.bot.get_channel(u.config['shutdown_channel']).send('**Shutting down 🌙 . . .**')
# loop = self.bot.loop.all_tasks() # loop = self.bot.loop.all_tasks()
# for task in loop: # for task in loop:
# task.cancel() # task.cancel()
u.close()
await self.bot.logout() await self.bot.logout()
await self.bot.close() u.close(self.bot.loop)
print('\n/ / / / / / / / / / / /\nD I S C O N N E C T E D\n\\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\\n') print('\n/ / / / / / / / / / / /\nD I S C O N N E C T E D\n\\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\\n')
# u.notify('D I S C O N N E C T E D') # u.notify('D I S C O N N E C T E D')
@ -44,14 +43,13 @@ class Bot:
async def restart(self, ctx): async def restart(self, ctx):
print('\n| | | | | | | | | |\nR E S T A R T I N G\n| | | | | | | | | |\n') print('\n| | | | | | | | | |\nR E S T A R T I N G\n| | | | | | | | | |\n')
if isinstance(self.bot.get_channel(u.config['shutdown_channel']), d.TextChannel): if isinstance(self.bot.get_channel(u.config['shutdown_channel']), d.TextChannel):
await self.bot.get_channel(u.config['shutdown_channel']).send('**Restarting . . .** 💤') await self.bot.get_channel(u.config['shutdown_channel']).send('**Restarting 💤 . . .**')
# u.notify('R E S T A R T I N G') # u.notify('R E S T A R T I N G')
# loop = self.bot.loop.all_tasks() # loop = self.bot.loop.all_tasks()
# for task in loop: # for task in loop:
# task.cancel() # task.cancel()
u.close()
await self.bot.logout() await self.bot.logout()
await self.bot.close() u.close(self.bot.loop)
os.execl(sys.executable, 'python3', 'run.py') os.execl(sys.executable, 'python3', 'run.py')
# Invite bot to bot owner's server # Invite bot to bot owner's server

View file

@ -59,7 +59,7 @@ def is_nsfw():
def del_ctx(): def del_ctx():
async def predicate(ctx): async def predicate(ctx):
if ctx.me.permissions_in(ctx.channel).manage_messages is True and isinstance(ctx.message.channel, discord.TextChannel) and ctx.guild.id in u.settings['del_ctx']: if ctx.me.permissions_in(ctx.channel).manage_messages and isinstance(ctx.message.channel, discord.TextChannel) and ctx.guild.id in u.settings['del_ctx']:
try: try:
await ctx.message.delete() await ctx.message.delete()

View file

@ -35,7 +35,7 @@ async def on_ready():
# bot.loop.create_task(u.clear(booru.temp_urls, 30*60)) # bot.loop.create_task(u.clear(booru.temp_urls, 30*60))
if isinstance(bot.get_channel(u.config['startup_channel']), d.TextChannel): if isinstance(bot.get_channel(u.config['startup_channel']), d.TextChannel):
await bot.get_channel(u.config['startup_channel']).send('**Started.** ☀️') await bot.get_channel(u.config['startup_channel']).send('**Started ☀️ .**')
print('\n\\ \\ \\ \\ \\ \\ \\ \\ \\\nC O N N E C T E D : {}\n/ / / / / / / / /\n'.format(bot.user.name)) print('\n\\ \\ \\ \\ \\ \\ \\ \\ \\\nC O N N E C T E D : {}\n/ / / / / / / / /\n'.format(bot.user.name))
# u.notify('C O N N E C T E D') # u.notify('C O N N E C T E D')
@ -44,9 +44,8 @@ async def on_ready():
async def on_error(error, *args, **kwargs): async def on_error(error, *args, **kwargs):
if isinstance(bot.get_channel(u.config['shutdown_channel']), d.TextChannel): if isinstance(bot.get_channel(u.config['shutdown_channel']), d.TextChannel):
await bot.get_channel(u.config['shutdown_channel']).send('**ERROR** ⚠️ {}'.format(error)) await bot.get_channel(u.config['shutdown_channel']).send('**ERROR** ⚠️ {}'.format(error))
u.close()
await bot.logout() await bot.logout()
await bot.close() u.close(bot.loop)
print('\n! ! ! ! !\nE R R O R : {}\n! ! ! ! !\n'.format(error), file=sys.stderr) print('\n! ! ! ! !\nE R R O R : {}\n! ! ! ! !\n'.format(error), file=sys.stderr)
tb.print_exc() tb.print_exc()
# u.notify('E R R O R') # u.notify('E R R O R')

View file

@ -3,6 +3,7 @@ import json
import os import os
import pickle as pkl import pickle as pkl
import subprocess import subprocess
from contextlib import suppress
import aiohttp import aiohttp
from pync import Notifier from pync import Notifier
@ -72,12 +73,22 @@ async def clear(obj, interval=10 * 60, replace=None):
session = aiohttp.ClientSession() session = aiohttp.ClientSession()
def close(): def close(loop):
global session global session
if session: if session:
session.close() session.close()
loop.stop()
pending = asyncio.Task.all_tasks()
for task in pending:
task.cancel()
# with suppress(asyncio.CancelledError):
# loop.run_until_complete(task)
# loop.close()
print('Finished cancelling tasks.')
async def fetch(url, *, params={}, json=False): async def fetch(url, *, params={}, json=False):
global session global session