1
0
Fork 0
mirror of https://github.com/myned/modufur.git synced 2024-11-01 21:02:38 +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)
self.bot.loop.create_task(self.queue_for_deletion(temp))
print('AUTO-DELETING : #{}'.format(temp.id))
self.bot.loop.create_task(self.delete())
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.is_owner()
@ -99,14 +99,13 @@ class Administration:
await del_sent.unpin()
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:
await ctx.send('**Deletion aborted**', delete_after=10)
await ctx.send('**Deletion aborted**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
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}')
async def delete(self):
@ -160,12 +159,11 @@ class Administration:
self.deleting = True
print('AUTO-DELETING : #{}'.format(ctx.channel.id))
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:
raise 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}')
@commands.command(name='deletecommands', aliases=['delcmds'])
@ -178,7 +176,6 @@ class Administration:
u.dump(u.settings, 'settings.pkl')
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.has_permissions(administrator=True)
@ -190,4 +187,3 @@ class Administration:
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.message.add_reaction('')

View file

@ -70,7 +70,7 @@ class Bot:
async def invite(self, ctx):
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.is_owner()
@ -85,8 +85,6 @@ class Bot:
u.config['playing'] = 'None'
u.dump(u.config, 'config.json', json=True)
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
class Tools:
@ -189,8 +187,6 @@ class Tools:
sys.stderr = sys.__stderr__
print('Reset sys output.')
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
@commands.command(name=',execute', aliases=[',exec'], hidden=True)
@commands.is_owner()
@checks.del_ctx()
@ -198,13 +194,10 @@ class Tools:
try:
with io.StringIO() as buff, redirect_stdout(buff):
exec(exe)
await self.generate(ctx, exe, buff.getvalue())
await self.generate(ctx, exe, f'\n{buff.getvalue()}')
except Exception:
await ctx.send('```\n{}```'.format(tb.format_exc()))
finally:
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
await self.generate(ctx, exe, f'\n{tb.format_exc()}')
@commands.command(name=',evaluate', aliases=[',eval'], hidden=True)
@commands.is_owner()
@ -213,13 +206,10 @@ class Tools:
try:
with io.StringIO() as buff, redirect_stdout(buff):
eval(evl)
await self.generate(ctx, evl, buff.getvalue())
await self.generate(ctx, evl, f'\n{buff.getvalue()}')
except Exception:
await ctx.send('```\n{}```'.format(tb.format_exc()))
finally:
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
await self.generate(ctx, evl, f'\n{tb.format_exc()}')
@commands.group(aliases=[',db'], hidden=True)
@commands.is_owner()

View file

@ -1,5 +1,5 @@
import asyncio
import datetime as dt
from datetime import datetime as dt
import mimetypes
import os
import tempfile
@ -25,39 +25,37 @@ youtube = None
tempfile.tempdir = os.getcwd()
command_dict = {}
class Utils:
def __init__(self, bot):
self.bot = bot
@commands.command(name='last', aliases=['l', ','], brief='Reinvokes last command', description='Reinvokes previous command executed', hidden=True)
async def last_command(self, ctx):
global command_dict
@commands.command(name='lastcommand', aliases=['last', 'l', ','], brief='Reinvokes last successful command', description='Executes last successfully executed command')
async def last_command(self, ctx, arg='None'):
try:
context = u.last_commands[ctx.author.id]
if command_dict.get(str(ctx.author.id), {}).get('args', None) is not None:
args = command_dict.get(str(ctx.author.id), {})['args']
print(command_dict)
await ctx.invoke(command_dict.get(str(ctx.author.id), {}).get('command', None), args)
if arg == 'show' or arg == 'sh' or arg == 's':
await ctx.send(f'`{context.prefix}{context.invoked_with} {" ".join(context.args[2:])}`', delete_after=7)
else:
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
@commands.command(aliases=['p'], brief='Pong!', description='Returns latency from bot to Discord servers, not to user')
@checks.del_ctx()
async def ping(self, ctx):
global command_dict
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)
command_dict.setdefault(str(ctx.author.id), {}).update({'command': ctx.command})
@commands.command(aliases=['pre'], brief='List bot prefixes', description='Shows all used prefixes')
@checks.del_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.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
@commands.group(name=',send', aliases=[',s'], hidden=True)
@commands.is_owner()
@ -73,20 +71,18 @@ class Utils:
try:
await tempchannel.send(message)
await ctx.message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
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}')
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}')
@send.command(name='user', aliases=['u', 'member', 'm'])
async def send_user(self, ctx, user, *, 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'])
async def authenticate_upload(self, ctx):
@ -118,11 +114,11 @@ class Utils:
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)))
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:
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:
await ctx.send('**Missing attachment**', delete_after=10)
await ctx.send('**Missing attachment**', delete_after=7)
@upload.error
async def upload_error(self, ctx, error):

View file

@ -1,12 +1,14 @@
import asyncio
import datetime as dt
from datetime import datetime as dt
import json
# import logging as log
import logging as log
import subprocess
import sys
import traceback as tb
from contextlib import suppress
from pprint import pprint
from hurry.filesize import size, alternative
from urllib.parse import urlparse
import discord as d
from discord import errors as err
@ -18,7 +20,7 @@ from misc import exceptions as exc
from misc import checks
from utils import utils as u
# log.basicConfig(level=log.INFO)
log.basicConfig(level=log.WARNING)
class HelpFormatter(commands.HelpFormatter):
@ -73,7 +75,7 @@ async def on_message(message):
async def on_error(error, *args, **kwargs):
print('\n! ! ! ! !\nE R R O R : {}\n! ! ! ! !\n'.format(error), file=sys.stderr)
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))
if u.temp:
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}')
# 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')
@ -118,13 +127,52 @@ def after(voice, error):
future = asyncio.run_coroutine_threadsafe(coro, voice.loop)
future.result()
# suggested = u.setdefault('cogs/suggested.pkl', {'last_update': 'None', 'tags': {}, 'total': 0})
@bot.command(name=',test', hidden=True)
@commands.is_owner()
@checks.del_ctx()
async def test(ctx, *, test):
print(ctx.args)
print(ctx.kwargs)
async def test(ctx):
post = await u.fetch('https://e621.net/post/show.json?id=1145042', json=True)
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:
# await ctx.send('<:N_:368917475531816962>')
# logs = []

View file

@ -16,7 +16,9 @@ async def get_post(url):
try:
value = BeautifulSoup(content, 'html.parser').find_all('a')[1].get('href')
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:
raise IndexError

View file

@ -4,6 +4,8 @@ import os
import pickle as pkl
import subprocess
from contextlib import suppress
from fractions import gcd
import math
import aiohttp
import discord as d
@ -71,6 +73,7 @@ temp = setdefault('temp.pkl', {})
RATE_LIMIT = 2.2
color = d.Color(0x1A1A1A)
session = aiohttp.ClientSession()
last_commands = {}
# async def clear(obj, interval=10 * 60, replace=None):
@ -111,8 +114,21 @@ async def fetch(url, *, params={}, json=False):
return await r.read()
# def geneate_embed(**kwargs):
# embed = d.Embed(title=kwargs['title'], )
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=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):
destination = ctx
@ -143,3 +159,15 @@ def get_kwargs(ctx, args, *, limit=False):
raise exc.BoundsError(arg)
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)