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-12-31 21:56:23 -05:00
commit 523ab37fe6
9 changed files with 2021 additions and 1868 deletions

View file

@ -55,6 +55,11 @@ class MsG:
print('STARTED : auto-reversifying in #{}'.format(temp.name))
self.reversifying = True
self.bot.loop.create_task(self._reversify())
if u.tasks['auto_hrt']:
for channel in u.tasks['auto_hrt']:
temp = self.bot.get_channel(channel)
self.bot.loop.create_task(self.queue_for_hearts(channel=temp))
print(f'STARTED : auto-hearting in #{temp.name}')
# if not self.updating:
# self.updating = True
# self.bot.loop.create_task(self._update_suggested())
@ -124,32 +129,92 @@ class MsG:
while self.hearting:
temp = await self.heartqueue.get()
await temp[0].send(embed=temp[1])
if isinstance(temp[1], d.Embed):
await temp[0].send(embed=temp[1])
await asyncio.sleep(self.RATE_LIMIT)
await asyncio.sleep(self.RATE_LIMIT)
elif isinstance(temp[1], d.Message):
for match in re.finditer('(https?:\/\/[^ ]*\.(?:gif|png|jpg|jpeg))', temp[1].content):
await temp[0].send(match)
await asyncio.sleep(self.RATE_LIMIT)
for attachment in temp[1].attachments:
await temp[0].send(attachment.url)
await asyncio.sleep(self.RATE_LIMIT)
print('STOPPED : hearting')
async def queue_for_hearts(self, *, message, send):
async def queue_for_hearts(self, *, message=None, send=None, channel=None, reaction=True, timeout=60 * 60):
def on_reaction(reaction, user):
if reaction.emoji == '\N{HEAVY BLACK HEART}' and reaction.message.id == message.id:
raise exc.Save(user)
return False
def on_message(msg):
if 'stop h' in msg.content.lower():
raise exc.Abort
return msg.channel.id == channel.id and (re.search('(https?:\/\/[^ ]*\.(?:gif|png|jpg|jpeg))', msg.content) or msg.attachments)
if message:
try:
if reaction:
await message.add_reaction('\N{HEAVY BLACK HEART}')
await asyncio.sleep(1)
while self.hearting:
try:
await self.bot.wait_for('reaction_add', check=on_reaction, timeout=timeout)
except exc.Save as e:
await self.heartqueue.put((e.user, send if send else message))
except asyncio.TimeoutError:
await message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
else:
try:
async for message in channel.history(limit=300):
if re.search('(https?:\/\/[^ ]*\.(?:gif|png|jpg|jpeg))', message.content) or message.attachments:
self.bot.loop.create_task(self._wait_for_reaction(message))
while self.hearting:
message = await self.bot.wait_for('message', check=on_message)
self.bot.loop.create_task(self._wait_for_reaction(message))
except exc.Abort:
u.tasks['auto_hrt'].remove(channel.id)
u.dump(u.tasks, 'cogs/tasks.pkl')
print('STOPPED : auto-hearting in #{}'.format(channel.name))
await channel.send('**Stopped queueing messages for hearting in** {}'.format(channel.mention), delete_after=5)
async def _wait_for_reaction(self, message):
def on_reaction(reaction, user):
if reaction.emoji == '\N{HEAVY BLACK HEART}' and reaction.message.id == message.id:
raise exc.Save(user)
return False
while self.hearting:
try:
await self.bot.wait_for('reaction_add', check=on_reaction)
except exc.Save as e:
await self.heartqueue.put((e.user, message))
@cmds.command(name='autoheart', aliases=['autohrt'])
@cmds.has_permissions(administrator=True)
async def auto_heart(self, ctx):
try:
await message.add_reaction('\N{HEAVY BLACK HEART}')
await asyncio.sleep(1)
if ctx.channel.id not in u.tasks['auto_hrt']:
u.tasks['auto_hrt'].append(ctx.channel.id)
u.dump(u.tasks, 'cogs/tasks.pkl')
self.bot.loop.create_task(self.queue_for_hearts(channel=ctx.channel))
print('STARTED : auto-hearting in #{}'.format(ctx.channel.name))
await ctx.send('**Auto-hearting all messages in {}**'.format(ctx.channel.mention), delete_after=5)
else:
raise exc.Exists
while self.hearting:
try:
await asyncio.gather(*[self.bot.wait_for('reaction_add', check=on_reaction, timeout=60 * 60),
self.bot.wait_for('reaction_remove', check=on_reaction, timeout=60 * 60)])
except exc.Save as e:
await self.heartqueue.put((e.user, send))
except asyncio.TimeoutError:
await message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
except exc.Exists:
await ctx.send('**Already auto-hearting in {}.** Type `stop h(earting)` to stop.'.format(ctx.channel.mention), delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
# @cmds.command()
# async def auto_post(self, ctx):
@ -261,7 +326,7 @@ class MsG:
embed = d.Embed(
title=', '.join(post['artist']), url=f'https://e621.net/post/show/{post["id"]}', color=ctx.me.color if isinstance(ctx.channel, d.TextChannel) else u.color)
embed.set_thumbnail(url=post['file_url'])
embed.set_author(name=f'{u.get_aspectratio(post["width"], post["height"])} \N{ZERO WIDTH SPACE} {post["width"]} x {post["height"]}',
embed.set_author(name=f'{post["width"]} x {post["height"]}',
url=f'https://e621.net/post?tags=ratio:{post["width"]/post["height"]:.2f}', icon_url=ctx.author.avatar_url)
embed.set_footer(text=post['score'],
icon_url=self._get_score(post['score']))
@ -373,7 +438,7 @@ class MsG:
embed = d.Embed(
title=', '.join(post['artist']), url=f'https://e621.net/post/show/{post["id"]}', color=ctx.me.color if isinstance(ctx.channel, d.TextChannel) else u.color)
embed.set_image(url=post['file_url'])
embed.set_author(name=f'{u.get_aspectratio(post["width"], post["height"])} \N{ZERO WIDTH SPACE} {post["width"]} x {post["height"]}',
embed.set_author(name=f'{post["width"]} x {post["height"]}',
url=f'https://e621.net/post?tags=ratio:{post["width"]/post["height"]:.2f}', icon_url=ctx.author.avatar_url)
embed.set_footer(text=post['score'],
icon_url=self._get_score(post['score']))
@ -436,7 +501,7 @@ class MsG:
embed = d.Embed(
title=', '.join(post['artist']), url=f'https://e621.net/post/show/{post["id"]}', color=ctx.me.color if isinstance(ctx.channel, d.TextChannel) else u.color)
embed.set_image(url=post['file_url'])
embed.set_author(name=f'{u.get_aspectratio(post["width"], post["height"])} \N{ZERO WIDTH SPACE} {post["width"]} x {post["height"]}',
embed.set_author(name=f'{post["width"]} x {post["height"]}',
url=f'https://e621.net/post?tags=ratio:{post["width"]/post["height"]:.2f}', icon_url=ctx.author.avatar_url)
embed.set_footer(
text=post['score'], icon_url=self._get_score(post['score']))
@ -492,33 +557,35 @@ class MsG:
embed = d.Embed(
title=', '.join(post['artist']), url=f'https://e621.net/post/show/{post["id"]}', color=message.channel.guild.me.color if isinstance(message.channel, d.TextChannel) else u.color)
embed.set_image(url=post['file_url'])
embed.set_author(name=f'{u.get_aspectratio(post["width"], post["height"])} \N{ZERO WIDTH SPACE} {post["width"]} x {post["height"]}',
embed.set_author(name=f'{post["width"]} x {post["height"]}',
url=f'https://e621.net/post?tags=ratio:{post["width"]/post["height"]:.2f}', icon_url=message.author.avatar_url)
embed.set_footer(text=post['score'],
icon_url=self._get_score(post['score']['score']))
icon_url=self._get_score(post['score']))
await message.channel.send('**Probable match from** {}'.format(message.author.display_name), embed=embed)
await message.add_reaction('\N{WHITE HEAVY CHECK MARK}')
await asyncio.sleep(self.RATE_LIMIT)
with suppress(err.NotFound):
await message.delete()
except exc.MatchError as e:
await message.channel.send('**No probable match for:** `{}`'.format(e), delete_after=7)
await message.add_reaction('\N{CROSS MARK}')
except exc.SizeError as e:
await message.channel.send(f'`{e}` **too large.** Maximum is 8 MB', delete_after=7)
await message.add_reaction('\N{CROSS MARK}')
finally:
await asyncio.sleep(self.RATE_LIMIT)
with suppress(err.NotFound):
await message.delete()
except Exception:
await message.channel.send(f'**An unknown error occurred.**', delete_after=7)
await message.add_reaction('\N{WARNING SIGN}')
print('STOPPED : reversifying')
async def queue_for_reversification(self, channel):
def check(msg):
if msg.content.lower() == 'stop' and msg.channel is channel and msg.author.guild_permissions.administrator:
if 'stop r' in msg.content.lower() and msg.channel is channel and msg.author.guild_permissions.administrator:
raise exc.Abort
elif msg.channel is channel and msg.author.id != self.bot.user.id and (re.search('(https?:\/\/[^ ]*\.(?:gif|png|jpg|jpeg))', msg.content) is not None or msg.attachments or msg.embeds):
return True
@ -553,7 +620,7 @@ class MsG:
print('STARTED : auto-reversifying in #{}'.format(ctx.channel.name))
await ctx.send('**Auto-reversifying all images in** {}'.format(ctx.channel.mention), delete_after=5)
else:
await ctx.send('**Already auto-reversifying in {}.** Type `stop` to stop.'.format(ctx.channel.mention), delete_after=7)
await ctx.send('**Already auto-reversifying in {}.** Type `stop r(eversifying)` to stop.'.format(ctx.channel.mention), delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
async def _get_pool(self, ctx, *, destination, booru='e621', query=[]):

View file

@ -116,6 +116,10 @@ class Administration:
await ctx.send('**Deletion timed out**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
@cmds.group(aliases=['task', 'tsk'])
async def tasks(self):
pass
async def delete(self):
while self.deleting:
message = await self.queue.get()
@ -128,7 +132,7 @@ class Administration:
async def queue_for_deletion(self, channel):
def check(msg):
if msg.content.lower() == 'stop' and msg.channel is channel and msg.author.guild_permissions.administrator:
if 'stop d' in msg.content.lower() and msg.channel is channel and msg.author.guild_permissions.administrator:
raise exc.Abort
elif msg.channel is channel and not msg.pinned:
return True
@ -136,7 +140,7 @@ class Administration:
try:
async for message in channel.history(limit=None):
if message.content.lower() == 'stop' and message.author.guild_permissions.administrator:
if 'stop d' in message.content.lower() and message.author.guild_permissions.administrator:
raise exc.Abort
if not message.pinned:
await self.queue.put(message)
@ -170,7 +174,7 @@ class Administration:
raise exc.Exists
except exc.Exists:
await ctx.send('**Already auto-deleting in {}.** Type `stop` to stop.'.format(ctx.channel.mention), delete_after=7)
await ctx.send('**Already auto-deleting in {}.** Type `stop d(eleting)` to stop.'.format(ctx.channel.mention), delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
@cmds.group(aliases=['setting', 'set', 's'])
@ -179,7 +183,7 @@ class Administration:
pass
@settings.command(name='deletecommands', aliases=['delcmds', 'delcmd'])
async def _settings_delete_commands(self, ctx):
async def _settings_deletecommands(self, ctx):
if ctx.guild.id not in u.settings['del_ctx']:
u.settings['del_ctx'].append(ctx.guild.id)
else:
@ -197,3 +201,13 @@ class Administration:
del u.settings['prefixes'][ctx.guild.id]
await ctx.send(f'**Prefix set to:** `{"` or `".join(prefixes if ctx.guild.id in u.settings["prefixes"] else u.config["prefix"])}`')
@settings.command(name='deleteresponses', aliases=['delresps', 'delresp'])
async def _settings_deleteresponses(self, ctx):
if ctx.guild.id not in u.settings['del_resp']:
u.settings['del_resp'].append(ctx.guild.id)
else:
u.settings['del_resp'].remove(ctx.guild.id)
u.dump(u.settings, 'settings.pkl')
await ctx.send(f'**Delete command responses:** `{ctx.guild.id in u.settings["del_resp"]}`')

57
src/cogs/music.py Normal file
View file

@ -0,0 +1,57 @@
import asyncio
import json
from datetime import datetime as dt
from urllib import parse
import re
from pprint import pprint
import discord as d
from discord import errors as err
from discord.ext import commands as cmds
from discord.ext.commands import errors as errext
import gmusicapi as gpm
import googleapiclient as gapic
import apiclient as apic
from misc import exceptions as exc
from misc import checks
from utils import utils as u
class Music:
def __init__(self, bot):
self.bot = bot
self.yt_service = apic.discovery.build('youtube', 'v3', developerKey=u.secrets['client_secrets']['client_secret'])
@cmds.group(aliases=['pl'], brief='(G) Play music', description='Play music from YouTube, Soundcloud, or Google Play Music')
async def play(self, ctx):
print(ctx.invoked_subcommand)
@play.command(name='youtube', aliases=['you', 'tube', 'yt', 'y'])
async def _play_youtube(self, ctx, *videos):
try:
if not videos:
raise exc.MissingArgument
vids = []
for video in videos:
if 'http' in video and 'youtube' in video:
vids.append(parse.parse_qs(parse.urlparse(video).query)['v'][0])
else:
vids.append(video)
print(vids)
response = self.yt_service.videos().list(part='snippet', id=','.join(vids)).execute()
pprint(response)
except exc.MissingArgument:
await ctx.send('**Invalid youtube url or ID**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
@play.command(name='googleplaymusic', aliases=['googleplay', 'googlemusic', 'playmusic', 'play', 'gpm'])
async def _play_googleplaymusic(self, ctx, query):
pass

View file

@ -23,3 +23,11 @@ class Post:
async def _check_posts(self, user, channel):
pass
@cmds.group(aliases=['update', 'up', 'u'])
async def updates(self, ctx):
pass
@updates.command(name='googleplaymusic', aliases=['googlemusic', 'playmusic', 'music', 'gpm'])
async def _updates_googleplaymusic(self, ctx):
pass

View file

@ -39,9 +39,9 @@ class Right(Exception):
class Save(Exception):
def __init__(self, user=None):
def __init__(self, user=None, message=None):
self.user = user
self.message = message
class GoTo(Exception):
pass

View file

@ -70,9 +70,11 @@ async def test(ctx):
@bot.event
async def on_ready():
if not checks.ready:
from cogs import booru, info, management, owner, tools
# d.opus.load_opus('opuslib')
for cog in (tools.Utils(bot), owner.Bot(bot), owner.Tools(bot), management.Administration(bot), info.Info(bot), booru.MsG(bot)):
from cogs import booru, info, management, music, owner, tools
for cog in (tools.Utils(bot), owner.Bot(bot), owner.Tools(bot), management.Administration(bot), music.Music(bot), info.Info(bot), booru.MsG(bot)):
bot.add_cog(cog)
print(f'COG : {type(cog).__name__}')
@ -157,6 +159,11 @@ 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(ctx):
# if ctx.guild.id in u.settings['del_resp']:
# pass
@bot.event
async def on_command_completion(ctx):
with suppress(err.NotFound):
@ -183,8 +190,6 @@ async def on_guild_remove(guild):
print(f'STOPPED : {task} in #{channel.id}')
u.dump(u.tasks, 'cogs/tasks.pkl')
# d.opus.load_opus('opus')
async def wait(voice):
asyncio.sleep(5)

0
src/temp/__init__.py Normal file
View file

View file

@ -15,6 +15,7 @@ async def get_post(url):
filesize = int(image.headers['Content-Length'])
if filesize > 8192 * 1024:
raise exc.SizeError(size(filesize, system=alternative))
except ValueError:
raise exc.MissingArgument

View file

@ -82,9 +82,10 @@ def dump(obj, filename, *, json=False):
jsn.dump(obj, outfile, indent=4, sort_keys=True)
settings = setdefault('misc/settings.pkl', {'del_ctx': [], 'prefixes': {}})
tasks = setdefault('cogs/tasks.pkl', {'auto_del': [], 'auto_rev': [], 'periodic_gpm': []})
settings = setdefault('misc/settings.pkl', {'del_ctx': [], 'del_resp': [], 'prefixes': {}})
tasks = setdefault('cogs/tasks.pkl', {'auto_del': [], 'auto_hrt': [], 'auto_rev': [], 'periodic_gpm': []})
temp = setdefault('temp/temp.pkl', {'startup': ()})
secrets = setdefault('secrets.json', {'client_secrets': {'client_id': '', 'client_secret': ''}}, json=True)
RATE_LIMIT = 2.2
color = d.Color(0x1A1A1A)