1
0
Fork 0
mirror of https://github.com/myned/modufur.git synced 2024-11-02 05:02:39 +00:00

Merge branch 'dev'

This commit is contained in:
Myned 2017-11-19 23:44:46 -05:00
commit 2c4fb8b400
7 changed files with 457 additions and 436 deletions

File diff suppressed because it is too large Load diff

View file

@ -25,8 +25,8 @@ class Administration:
temp = self.bot.get_channel(channel) temp = self.bot.get_channel(channel)
self.bot.loop.create_task(self.queue_for_deletion(temp)) self.bot.loop.create_task(self.queue_for_deletion(temp))
print('AUTO-DELETING : #{}'.format(temp.id)) print('AUTO-DELETING : #{}'.format(temp.id))
self.bot.loop.create_task(self.delete())
self.deleting = True self.deleting = True
self.bot.loop.create_task(self.delete())
@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()
@ -99,14 +99,13 @@ class Administration:
await del_sent.unpin() await del_sent.unpin()
await ctx.send('\N{WASTEBASKET} `{}` **of** <@{}>**\'s messages left in** {}****'.format(len(history) - c, user, ctx.guild.name)) await ctx.send('\N{WASTEBASKET} `{}` **of** <@{}>**\'s messages left in** {}****'.format(len(history) - c, user, ctx.guild.name))
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
except exc.CheckFail: except exc.CheckFail:
await ctx.send('**Deletion aborted**', delete_after=10) await ctx.send('**Deletion aborted**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
except TimeoutError: except TimeoutError:
await ctx.send('**Deletion timed out**', delete_after=10) await ctx.send('**Deletion timed out**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
async def delete(self): async def delete(self):
@ -160,12 +159,11 @@ class Administration:
self.deleting = True self.deleting = True
print('AUTO-DELETING : #{}'.format(ctx.channel.id)) print('AUTO-DELETING : #{}'.format(ctx.channel.id))
await ctx.send('**Auto-deleting all messages in {}**'.format(ctx.channel.mention), delete_after=5) await ctx.send('**Auto-deleting all messages in {}**'.format(ctx.channel.mention), delete_after=5)
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
else: else:
raise exc.Exists raise exc.Exists
except exc.Exists: except exc.Exists:
await ctx.send('**Already auto-deleting in {}.** Type `stop` to stop.'.format(ctx.channel.mention), delete_after=10) await ctx.send('**Already auto-deleting in {}.** Type `stop` to stop.'.format(ctx.channel.mention), delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
@commands.command(name='deletecommands', aliases=['delcmds']) @commands.command(name='deletecommands', aliases=['delcmds'])
@ -178,7 +176,6 @@ class Administration:
u.dump(u.settings, 'settings.pkl') u.dump(u.settings, 'settings.pkl')
await ctx.send('**Delete command invocations:** `{}`'.format(ctx.guild.id in u.settings['del_ctx'])) await ctx.send('**Delete command invocations:** `{}`'.format(ctx.guild.id in u.settings['del_ctx']))
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
@commands.command(name='setprefix', aliases=['setpre', 'spre']) @commands.command(name='setprefix', aliases=['setpre', 'spre'])
@commands.has_permissions(administrator=True) @commands.has_permissions(administrator=True)
@ -190,4 +187,3 @@ class Administration:
del u.settings['prefixes'][ctx.guild.id] del u.settings['prefixes'][ctx.guild.id]
await ctx.send(f'**Prefix set to:** `{"` or `".join(prefix if ctx.guild.id in u.settings["prefixes"] else u.config["prefix"])}`') await ctx.send(f'**Prefix set to:** `{"` or `".join(prefix if ctx.guild.id in u.settings["prefixes"] else u.config["prefix"])}`')
await ctx.message.add_reaction('')

View file

@ -70,7 +70,7 @@ class Bot:
async def invite(self, ctx): async def invite(self, ctx):
await ctx.message.add_reaction('\N{ENVELOPE}') await ctx.message.add_reaction('\N{ENVELOPE}')
await ctx.send('https://discordapp.com/oauth2/authorize?&client_id={}&scope=bot&permissions={}'.format(u.config['client_id'], u.config['permissions']), delete_after=10) await ctx.send('https://discordapp.com/oauth2/authorize?&client_id={}&scope=bot&permissions={}'.format(u.config['client_id'], u.config['permissions']), delete_after=5)
@commands.command(name=',status', aliases=[',presence', ',game'], hidden=True) @commands.command(name=',status', aliases=[',presence', ',game'], hidden=True)
@commands.is_owner() @commands.is_owner()
@ -85,8 +85,6 @@ class Bot:
u.config['playing'] = 'None' u.config['playing'] = 'None'
u.dump(u.config, 'config.json', json=True) u.dump(u.config, 'config.json', json=True)
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
class Tools: class Tools:
@ -189,8 +187,6 @@ class Tools:
sys.stderr = sys.__stderr__ sys.stderr = sys.__stderr__
print('Reset sys output.') print('Reset sys output.')
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
@commands.command(name=',execute', aliases=[',exec'], hidden=True) @commands.command(name=',execute', aliases=[',exec'], hidden=True)
@commands.is_owner() @commands.is_owner()
@checks.del_ctx() @checks.del_ctx()
@ -198,13 +194,10 @@ class Tools:
try: try:
with io.StringIO() as buff, redirect_stdout(buff): with io.StringIO() as buff, redirect_stdout(buff):
exec(exe) exec(exe)
await self.generate(ctx, exe, buff.getvalue()) await self.generate(ctx, exe, f'\n{buff.getvalue()}')
except Exception: except Exception:
await ctx.send('```\n{}```'.format(tb.format_exc())) await self.generate(ctx, exe, f'\n{tb.format_exc()}')
finally:
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
@commands.command(name=',evaluate', aliases=[',eval'], hidden=True) @commands.command(name=',evaluate', aliases=[',eval'], hidden=True)
@commands.is_owner() @commands.is_owner()
@ -213,13 +206,10 @@ class Tools:
try: try:
with io.StringIO() as buff, redirect_stdout(buff): with io.StringIO() as buff, redirect_stdout(buff):
eval(evl) eval(evl)
await self.generate(ctx, evl, buff.getvalue()) await self.generate(ctx, evl, f'\n{buff.getvalue()}')
except Exception: except Exception:
await ctx.send('```\n{}```'.format(tb.format_exc())) await self.generate(ctx, evl, f'\n{tb.format_exc()}')
finally:
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
@commands.group(aliases=[',db'], hidden=True) @commands.group(aliases=[',db'], hidden=True)
@commands.is_owner() @commands.is_owner()

View file

@ -1,5 +1,5 @@
import asyncio import asyncio
import datetime as dt from datetime import datetime as dt
import mimetypes import mimetypes
import os import os
import tempfile import tempfile
@ -25,39 +25,37 @@ youtube = None
tempfile.tempdir = os.getcwd() tempfile.tempdir = os.getcwd()
command_dict = {}
class Utils: class Utils:
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
@commands.command(name='last', aliases=['l', ','], brief='Reinvokes last command', description='Reinvokes previous command executed', hidden=True) @commands.command(name='lastcommand', aliases=['last', 'l', ','], brief='Reinvokes last successful command', description='Executes last successfully executed command')
async def last_command(self, ctx): async def last_command(self, ctx, arg='None'):
global command_dict try:
context = u.last_commands[ctx.author.id]
if command_dict.get(str(ctx.author.id), {}).get('args', None) is not None: if arg == 'show' or arg == 'sh' or arg == 's':
args = command_dict.get(str(ctx.author.id), {})['args'] await ctx.send(f'`{context.prefix}{context.invoked_with} {" ".join(context.args[2:])}`', delete_after=7)
print(command_dict) else:
await ctx.invoke(command_dict.get(str(ctx.author.id), {}).get('command', None), args) await ctx.invoke(context.command, *context.args[2:], **context.kwargs)
except KeyError:
await ctx.send('**No last command**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
# Displays latency # Displays latency
@commands.command(aliases=['p'], brief='Pong!', description='Returns latency from bot to Discord servers, not to user') @commands.command(aliases=['p'], brief='Pong!', description='Returns latency from bot to Discord servers, not to user')
@checks.del_ctx() @checks.del_ctx()
async def ping(self, ctx): async def ping(self, ctx):
global command_dict
await ctx.message.add_reaction('\N{TABLE TENNIS PADDLE AND BALL}') await ctx.message.add_reaction('\N{TABLE TENNIS PADDLE AND BALL}')
await ctx.send(ctx.author.mention + ' \N{TABLE TENNIS PADDLE AND BALL} `' + str(round(self.bot.latency * 1000)) + 'ms`', delete_after=5) await ctx.send(ctx.author.mention + ' \N{TABLE TENNIS PADDLE AND BALL} `' + str(round(self.bot.latency * 1000)) + 'ms`', delete_after=5)
command_dict.setdefault(str(ctx.author.id), {}).update({'command': ctx.command})
@commands.command(aliases=['pre'], brief='List bot prefixes', description='Shows all used prefixes') @commands.command(aliases=['pre'], brief='List bot prefixes', description='Shows all used prefixes')
@checks.del_ctx() @checks.del_ctx()
async def prefix(self, ctx): async def prefix(self, ctx):
await ctx.send('**Prefix:** `{}`'.format('` or `'.join(u.settings['prefixes'][ctx.guild.id] if ctx.guild.id in u.settings['prefixes'] else u.config['prefix']))) await ctx.send('**Prefix:** `{}`'.format('` or `'.join(u.settings['prefixes'][ctx.guild.id] if ctx.guild.id in u.settings['prefixes'] else u.config['prefix'])))
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
@commands.group(name=',send', aliases=[',s'], hidden=True) @commands.group(name=',send', aliases=[',s'], hidden=True)
@commands.is_owner() @commands.is_owner()
@ -73,20 +71,18 @@ class Utils:
try: try:
await tempchannel.send(message) await tempchannel.send(message)
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
except AttributeError: except AttributeError:
await ctx.send('**Invalid channel**', delete_after=10) await ctx.send('**Invalid channel**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
except AttributeError: except AttributeError:
await ctx.send('**Invalid guild**', delete_after=10) await ctx.send('**Invalid guild**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}') await ctx.message.add_reaction('\N{CROSS MARK}')
@send.command(name='user', aliases=['u', 'member', 'm']) @send.command(name='user', aliases=['u', 'member', 'm'])
async def send_user(self, ctx, user, *, message): async def send_user(self, ctx, user, *, message):
await d.utils.get(self.bot.get_all_members(), id=int(user)).send(message) await d.utils.get(self.bot.get_all_members(), id=int(user)).send(message)
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
@commands.command(aliases=['authenticateupload', 'authupload', 'authup', 'auth']) @commands.command(aliases=['authenticateupload', 'authupload', 'authup', 'auth'])
async def authenticate_upload(self, ctx): async def authenticate_upload(self, ctx):
@ -118,11 +114,11 @@ class Utils:
print('https://www.youtube.com/watch?v=' + youtube.videos().insert(part='snippet', print('https://www.youtube.com/watch?v=' + youtube.videos().insert(part='snippet',
body={'categoryId': '24', 'title': 'Test'}, media_body=http.MediaFileUpload(temp.name, chunksize=-1))) body={'categoryId': '24', 'title': 'Test'}, media_body=http.MediaFileUpload(temp.name, chunksize=-1)))
except exc.InvalidVideoFile as e: except exc.InvalidVideoFile as e:
await ctx.send('`' + str(e) + '` **invalid video type**', delete_after=10) await ctx.send('`' + str(e) + '` **invalid video type**', delete_after=7)
except exc.TooManyAttachments as e: except exc.TooManyAttachments as e:
await ctx.send('`' + str(e) + '` **too many attachments.** Only one attachment is permitted to upload.', delete_after=10) await ctx.send('`' + str(e) + '` **too many attachments.** Only one attachment is permitted to upload.', delete_after=7)
except exc.MissingAttachment: except exc.MissingAttachment:
await ctx.send('**Missing attachment**', delete_after=10) await ctx.send('**Missing attachment**', delete_after=7)
@upload.error @upload.error
async def upload_error(self, ctx, error): async def upload_error(self, ctx, error):

View file

@ -1,12 +1,14 @@
import asyncio import asyncio
import datetime as dt from datetime import datetime as dt
import json import json
# import logging as log import logging as log
import subprocess import subprocess
import sys import sys
import traceback as tb import traceback as tb
from contextlib import suppress from contextlib import suppress
from pprint import pprint from pprint import pprint
from hurry.filesize import size, alternative
from urllib.parse import urlparse
import discord as d import discord as d
from discord import errors as err from discord import errors as err
@ -18,7 +20,7 @@ from misc import exceptions as exc
from misc import checks from misc import checks
from utils import utils as u from utils import utils as u
# log.basicConfig(level=log.INFO) log.basicConfig(level=log.WARNING)
class HelpFormatter(commands.HelpFormatter): class HelpFormatter(commands.HelpFormatter):
@ -73,7 +75,7 @@ async def on_message(message):
async def on_error(error, *args, **kwargs): async def on_error(error, *args, **kwargs):
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()
await bot.get_user(u.config['owner_id']).send('**ERROR** \N{WARNING SIGN}\n```\n{}```'.format(''.join(tb.format_exception(type(error), error, error.__traceback__)))) await bot.get_user(u.config['owner_id']).send('**ERROR** \N{WARNING SIGN}\n```\n{}```'.format(error))
await bot.get_channel(u.config['info_channel']).send('**ERROR** \N{WARNING SIGN}\n```\n{}```'.format(error)) await bot.get_channel(u.config['info_channel']).send('**ERROR** \N{WARNING SIGN}\n```\n{}```'.format(error))
if u.temp: if u.temp:
channel = bot.get_channel(u.temp['startup_chan']) channel = bot.get_channel(u.temp['startup_chan'])
@ -105,6 +107,13 @@ async def on_command_error(ctx, error):
await ctx.message.add_reaction('\N{WARNING SIGN}') await ctx.message.add_reaction('\N{WARNING SIGN}')
# u.notify('C O M M A N D E R R O R') # u.notify('C O M M A N D E R R O R')
@bot.event
async def on_command_completion(ctx):
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
if ctx.command.name != 'lastcommand':
u.last_commands[ctx.author.id] = ctx
# d.opus.load_opus('opus') # d.opus.load_opus('opus')
@ -118,13 +127,52 @@ def after(voice, error):
future = asyncio.run_coroutine_threadsafe(coro, voice.loop) future = asyncio.run_coroutine_threadsafe(coro, voice.loop)
future.result() future.result()
# suggested = u.setdefault('cogs/suggested.pkl', {'last_update': 'None', 'tags': {}, 'total': 0})
@bot.command(name=',test', hidden=True) @bot.command(name=',test', hidden=True)
@commands.is_owner() @commands.is_owner()
@checks.del_ctx() @checks.del_ctx()
async def test(ctx, *, test): async def test(ctx):
print(ctx.args) post = await u.fetch('https://e621.net/post/show.json?id=1145042', json=True)
print(ctx.kwargs)
tags = []
if post['tags']:
temptags = post['tags'].split(' ')
cis = []
for tag in suggested:
pass
for tag in temptags:
tags.append(f'[{tag}](https://e621.net/post?tags={tag})')
# tags = ' '.join(tags)
else:
tags = 'None'
if post['description']:
post_description = post['description'] if len(post['description']) < 200 else f'{post["description"][:200]}...'
else:
post_description = 'None'
title = ', '.join(post['artist'])
description = f'posted by: *[{post["author"]}](https://e621.net/post?tags=user:{post["author"]})*'
url = f'https://e621.net/post?tags={",".join(post["artist"])}'
# timestamp = dt.utcnow()
color = ctx.me.color
footer = {'text': post['score'], 'icon_url': 'https://images-ext-1.discordapp.net/external/W2k0ZzhU7ngvN_-CdqAa3H3FmkfCNYQTxPG_DsvacB4/https/emojipedia-us.s3.amazonaws.com/thumbs/320/twitter/103/sparkles_2728.png'}
# image = 'https://e621.net/post/show/54360'
thumbnail = post['file_url']
author = {'name': post['id'], 'url': f'https://e621.net/post/show/{post["id"]}', 'icon_url': ctx.author.avatar_url}
fields = []
names = ('File', 'Sources', 'Description', 'tags', 'tags (ext.)')
values = (f'[{post["md5"]}]({post["file_url"]}) | [{post["file_ext"]}](https://e621.net/post?tags=type:{post["file_ext"]})\n\n**Size** [{size(post["file_size"], system=alternative)}](https://e621.net/post?tags=filesize:{post["file_size"]})\n**Resolution** [{post["width"]} x {post["height"]}](https://e621.net/post?tags=width:{post["width"]},height:{post["height"]}) | [{u.get_aspectratio(post["width"], post["height"])}](https://e621.net/post?tags=ratio:{post["width"]/post["height"]:.2f})', '\n'.join([f'[{urlparse(source).netloc}]({source})' for source in post['sources']]), post_description, ' '.join(tags[:20]), ' '.join(tags[20:]))
inlines = (False, False, False, True, True)
for name, value, inline in zip(names, values, inlines):
fields.append({'name': name, 'value': value, 'inline': inline})
embed = u.generate_embed(ctx, title=title, description=description, url=url, colour=color, footer=footer, thumbnail=thumbnail, author=author, fields=fields)
await ctx.send(embed=embed)
# print(ctx.args)
# print(ctx.kwargs)
# if '<:N_:368917475531816962>' in message: # if '<:N_:368917475531816962>' in message:
# await ctx.send('<:N_:368917475531816962>') # await ctx.send('<:N_:368917475531816962>')
# logs = [] # logs = []

View file

@ -16,7 +16,9 @@ async def get_post(url):
try: try:
value = BeautifulSoup(content, 'html.parser').find_all('a')[1].get('href') value = BeautifulSoup(content, 'html.parser').find_all('a')[1].get('href')
if value != '#': if value != '#':
return value ident = re.search('show/([0-9]+)', value).group(1)
post = await u.fetch('http://e621.net/post/show.json', params={'id': ident}, json=True)
return post
else: else:
raise IndexError raise IndexError

View file

@ -4,6 +4,8 @@ import os
import pickle as pkl import pickle as pkl
import subprocess import subprocess
from contextlib import suppress from contextlib import suppress
from fractions import gcd
import math
import aiohttp import aiohttp
import discord as d import discord as d
@ -71,6 +73,7 @@ temp = setdefault('temp.pkl', {})
RATE_LIMIT = 2.2 RATE_LIMIT = 2.2
color = d.Color(0x1A1A1A) color = d.Color(0x1A1A1A)
session = aiohttp.ClientSession() session = aiohttp.ClientSession()
last_commands = {}
# async def clear(obj, interval=10 * 60, replace=None): # async def clear(obj, interval=10 * 60, replace=None):
@ -111,8 +114,21 @@ async def fetch(url, *, params={}, json=False):
return await r.read() return await r.read()
# def geneate_embed(**kwargs): def generate_embed(ctx, *, title=d.Embed.Empty, type='rich', description=d.Embed.Empty, url=d.Embed.Empty, timestamp=d.Embed.Empty, colour=color, footer={}, image=d.Embed.Empty, thumbnail=d.Embed.Empty, author={}, fields=[]):
# embed = d.Embed(title=kwargs['title'], ) embed = d.Embed(title=title, type=type, description=description, url=url, timestamp=timestamp, colour=colour if isinstance(ctx.channel, d.TextChannel) else color)
if footer:
embed.set_footer(text=footer.get('text', d.Embed.Empty), icon_url=footer.get('icon_url', d.Embed.Empty))
if image:
embed.set_image(url=image)
if thumbnail:
embed.set_thumbnail(url=thumbnail)
if author:
embed.set_author(name=author.get('name', d.Embed.Empty), url=author.get('url', d.Embed.Empty), icon_url=author.get('icon_url', d.Embed.Empty))
for field in fields:
embed.add_field(name=field.get('name', d.Embed.Empty), value=field.get('value', d.Embed.Empty), inline=field.get('inline', True))
return embed
def get_kwargs(ctx, args, *, limit=False): def get_kwargs(ctx, args, *, limit=False):
destination = ctx destination = ctx
@ -143,3 +159,15 @@ def get_kwargs(ctx, args, *, limit=False):
raise exc.BoundsError(arg) raise exc.BoundsError(arg)
return {'destination': destination, 'remaining': remaining, 'remove': rm, 'limit': lim} return {'destination': destination, 'remaining': remaining, 'remove': rm, 'limit': lim}
def get_aspectratio(a, b):
divisor = gcd(a, b)
return f'{int(a / divisor)}:{int(b / divisor)}'
def ci(pos, n):
z = 1.96
phat = float(pos) / n
return (phat + z*z/(2*n) - z * math.sqrt((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n)