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

File map update

This commit is contained in:
Myned 2018-03-31 16:36:30 -04:00
parent 91b86ca3ed
commit 9f487cb57c
6 changed files with 2361 additions and 2358 deletions

View file

@ -4,6 +4,8 @@ url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"
[requires]
python_version = "3.6"
[packages]
@ -25,4 +27,3 @@ pynacl = "*"
[dev-packages]

52
Pipfile.lock generated
View file

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "19fd84259fea739bf9a47e9ea60f364a06fd636ae4eaf50d40683569f9830f7e"
"sha256": "c8426f63f07b00a7dcc5220e1210acfc6279bb1eccb40d9a884d34e203bf8f85"
},
"host-environment-markers": {
"implementation_name": "cpython",
@ -17,7 +17,9 @@
"sys_platform": "darwin"
},
"pipfile-spec": 6,
"requires": {},
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
@ -29,30 +31,23 @@
"default": {
"aiohttp": {
"hashes": [
"sha256:834f687b806fbf49cb135b5a208b5c27338e19c219d6e09e9049936e01e8bea8",
"sha256:6b8c5a00432b8a5a083792006e8fdfb558b8b10019ce254200855264d3a25895",
"sha256:7b407c22b0ab473ffe0a7d3231f2084a8ae80fdb64a31842b88d57d6b7bdab7c",
"sha256:14821eb8613bfab9118be3c55afc87bf4cef97689896fa0874c6877b117afbeb",
"sha256:8f32a4e157bad9c60ebc38c3bb93fcc907a020b017ddf8f7ab1580390e21940e",
"sha256:82a9068d9cb15eb2d99ecf39f8d56b4ed9f931a77a3622a0de747465fd2a7b96",
"sha256:7ac6378ae364d8e5e5260c7224ea4a1965cb6f4719f15d0552349d0b0cc93953",
"sha256:5a952d4af7de5f78dfb3206dbc352717890b37d447f0bbd4b5969b3c8bb713af",
"sha256:b25c7720c495048ed658086a29925ab485ac7ececf1b346f2b459e5431d85016",
"sha256:528b0b811b6260a79222b055664b82093d01f35fe5c82521d8659cb2b28b8044",
"sha256:46ace48789865a89992419205024ae451d577876f9919fbb0f22f71189822dea",
"sha256:5436ca0ed752bb05a399fc07dc86dc23c756db523a3b7d5da46a457eacf4c4b5",
"sha256:f5e7d41d924a1d5274060c467539ee0c4f3bab318c1671ad65abd91f6b637baf",
"sha256:a8c12f3184c7cad8f66cae6c945d2c97e598b0cb7afd655a5b9471475e67f30e",
"sha256:756fc336a29c551b02252685f01bc87116bc9b04bbd02c1a6b8a96b3c6ad713b",
"sha256:cf790e61c2af0278f39dcedad9a22532bf81fb029c2cd73b1ceba7bea062c908",
"sha256:44c9cf24e63576244c13265ef0786b56d6751f5fb722225ecc021d6ecf91b4d2",
"sha256:ef1a36a16e72b6689ce0a6c7fc6bd88837d8fef4590b16bd72817644ae1f414d",
"sha256:3a4cdb9ca87c099d8ba5eb91cb8f000b60c21f8c1b50c75e04e8777e903bd278",
"sha256:f72bb19cece43483171264584bbaaf8b97717d9c0f244d1ef4a51df1cdb34085",
"sha256:c77e29243a79e376a1b51d71a13df4a61bc54fd4d9597ce3790b8d82ec6eb44d",
"sha256:8adda6583ba438a4c70693374e10b60168663ffa6564c5c75d3c7a9055290964"
"sha256:2e8be4c46083ced9d9bc9ff4d77f31bfcd3e7486613f6138c5aa302d33ea54ed",
"sha256:4634dd3bbb68d0c7e5e4bca7571369d53c497b3300d9d678f939038e1b1231ee",
"sha256:25825c61688fc95e09d6be19e513e925cb4f08aae4d7a7c38a1fa75e0e4c22bd",
"sha256:9e6d6f0bca955923b515f8b5631c4c4f43aa152763852284cbefc89bd544069e",
"sha256:6eef1d7eff9e6fa1029f7a62504f88b2b0afce89ced5c95d3a4cf1c2faef1231",
"sha256:040eecbc37aa5bd007108388fab6c42b2a01b964c4feac26bdffc8fe8af6c110",
"sha256:53988a8cf76c3fb74a759e77b1c2f55ab36880d57c6e7d0d59ad28743a2535fe",
"sha256:d51673140330c660e68c182e14164ddba47810dca873bbd28662f31d7d8c0185",
"sha256:2fe26e836a1803c7414613c376fe29fc4ae0e5145e3813e1db1854cb05c91a3c",
"sha256:15ad4d76bddfd98bf9e48263c70f6603e96d823c5a5c0c842646e9871be72c64",
"sha256:7910089093296b5c8f683965044f553b0c5c9c2dbf310a219db76c6e793fea55",
"sha256:a19b96f77763ddf0249420438ebfc4d9a470daeb26f6614366d913ff520fa29b",
"sha256:b53bc7b44b1115af50bd18d9671972603e5a4934e98dd3f4d671104c070e331d",
"sha256:4b6fa00885ec778154244b010acecb862d277e6652b87fcd85c0f4735d26451c",
"sha256:7aee5c0750584946fde40da70f0b28fe769f85182f1171acef18a35fd8ecd221"
],
"version": "==2.3.10"
"version": "==3.0.1"
},
"appdirs": {
"hashes": [
@ -68,6 +63,13 @@
],
"version": "==2.0.0"
},
"attrs": {
"hashes": [
"sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450",
"sha256:1c7960ccfd6a005cd9f7ba884e6316b5e430a3f1a6c37c5f87d8b43f83b54ec9"
],
"version": "==17.4.0"
},
"beautifulsoup4": {
"hashes": [
"sha256:7015e76bf32f1f574636c4288399a6de66ce08fb7b2457f628a8d70c0fbabb11",

File diff suppressed because it is too large Load diff

View file

@ -1,235 +1,235 @@
import asyncio
import traceback as tb
from contextlib import suppress
from datetime import datetime as dt
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
from misc import exceptions as exc
from misc import checks
from utils import utils as u
class Administration:
def __init__(self, bot):
self.bot = bot
self.RATE_LIMIT = u.RATE_LIMIT
self.queue = asyncio.Queue()
self.deleting = False
if u.tasks['auto_del']:
for channel in u.tasks['auto_del']:
temp = self.bot.get_channel(channel)
self.bot.loop.create_task(self.queue_for_deletion(temp))
print('STARTED : auto-deleting in #{}'.format(temp.name))
self.deleting = True
self.bot.loop.create_task(self.delete())
@cmds.group(aliases=['pru', 'purge', 'pur', 'clear', 'cl'], hidden=True)
@cmds.is_owner()
async def prune(self, ctx):
pass
@prune.group(name='user', aliases=['u', 'member', 'm'])
async def _prune_user(self, ctx):
pass
@_prune_user.command(name='channel', aliases=['channels', 'chans', 'chan', 'ch', 'c'])
async def _prune_user_channel(self, ctx, user: d.User, *channels: d.TextChannel):
def confirm(r, u):
if u is ctx.author:
if r.emoji == '\N{OCTAGONAL SIGN}':
raise exc.Abort
if r.emoji == '\N{THUMBS UP SIGN}':
return True
return False
if not channels:
channels = [ctx.channel]
try:
pruning = await ctx.send(f'\N{HOURGLASS} **Pruning** {user.mention}**\'s messages from** {"**,** ".join([channel.mention for channel in channels])} **might take some time.** Proceed, {ctx.author.mention}?')
await pruning.add_reaction('\N{THUMBS UP SIGN}')
await pruning.add_reaction('\N{OCTAGONAL SIGN}')
await asyncio.sleep(1)
await self.bot.wait_for('reaction_add', check=confirm, timeout=10 * 60)
deleting = await ctx.send(f'\N{WASTEBASKET} **Deleting** {user.mention}**\'s messages...**')
await asyncio.sleep(1)
c = 0
for channel in channels:
await deleting.edit(content=f'\N{WASTEBASKET} **Deleting** {user.mention}**\'s messages from** {channel.mention}')
deleted = await channel.purge(check=lambda m: m.author.id == user.id, before=pruning, limit=None)
c += len(deleted)
await asyncio.sleep(1)
for channel in channels:
missed = 0
async for message in channel.history(before=pruning, limit=None):
if message.author.id == user.id:
missed += 1
if missed > 0:
await ctx.send(f'\N{DOUBLE EXCLAMATION MARK} `{missed}` **messages were not deleted in** {channel.mention}')
await ctx.send(f'\N{WHITE HEAVY CHECK MARK} **Finished deleting** `{c}` **of** {user.mention}**\'s messages**')
except exc.Abort:
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=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
@_prune_user.command(name='all', aliases=['a'], 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\}', hidden=True)
@cmds.is_owner()
async def _prune_user_all(self, ctx, user: d.User):
def confirm(r, u):
if u is ctx.author:
if r.emoji == '\N{OCTAGONAL SIGN}':
raise exc.Abort
if r.emoji == '\N{THUMBS UP SIGN}':
return True
return False
try:
pruning = await ctx.send(f'\N{HOURGLASS} **Pruning** {user.mention}**\'s messages might take some time.** Proceed, {ctx.author.mention}?')
await pruning.add_reaction('\N{THUMBS UP SIGN}')
await pruning.add_reaction('\N{OCTAGONAL SIGN}')
await asyncio.sleep(1)
await self.bot.wait_for('reaction_add', check=confirm, timeout=10 * 60)
deleting = await ctx.send(f'\N{WASTEBASKET} **Deleting** {user.mention}**\'s messages...**')
await asyncio.sleep(1)
c = 0
for channel in ctx.guild.text_channels:
await deleting.edit(content=f'\N{WASTEBASKET} **Deleting** {user.mention}**\'s messages from** {channel.mention}')
deleted = await channel.purge(check=lambda m: m.author.id == user.id, before=pruning, limit=None)
c += len(deleted)
await asyncio.sleep(1)
for channel in ctx.guild.text_channels:
missed = 0
async for message in channel.history(before=pruning, limit=None):
if message.author.id == user.id:
missed += 1
if missed > 0:
await ctx.send(f'\N{DOUBLE EXCLAMATION MARK} `{missed}` **messages were not deleted in** {channel.mention}')
await ctx.send(f'\N{WHITE HEAVY CHECK MARK} **Finished deleting** `{c}` **of** {user.mention}**\'s messages**')
except exc.Abort:
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=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()
await asyncio.sleep(self.RATE_LIMIT)
with suppress(err.NotFound):
if not message.pinned:
await message.delete()
print('STOPPED : deleting')
async def queue_for_deletion(self, channel):
def check(msg):
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
return False
try:
async for message in channel.history(limit=None):
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)
while not self.bot.is_closed():
message = await self.bot.wait_for('message', check=check)
await self.queue.put(message)
except exc.Abort:
u.tasks['auto_del'].remove(channel.id)
u.dump(u.tasks, 'cogs/tasks.pkl')
if not u.tasks['auto_del']:
self.deleting = False
print('STOPPED : deleting #{}'.format(channel.name))
await channel.send('**Stopped queueing messages for deletion in** {}'.format(channel.mention), delete_after=5)
@cmds.command(name='autodelete', aliases=['autodel'])
@cmds.has_permissions(administrator=True)
async def auto_delete(self, ctx):
try:
if ctx.channel.id not in u.tasks['auto_del']:
u.tasks['auto_del'].append(ctx.channel.id)
u.dump(u.tasks, 'cogs/tasks.pkl')
self.bot.loop.create_task(self.queue_for_deletion(ctx.channel))
if not self.deleting:
self.bot.loop.create_task(self.delete())
self.deleting = True
print('STARTED : auto-deleting in #{}'.format(ctx.channel.name))
await ctx.send('**Auto-deleting all messages in {}**'.format(ctx.channel.mention), delete_after=5)
else:
raise exc.Exists
except exc.Exists:
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'])
@cmds.has_permissions(administrator=True)
async def settings(self, ctx):
pass
@settings.command(name='deletecommands', aliases=['delcmds', 'delcmd'])
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:
u.settings['del_ctx'].remove(ctx.guild.id)
u.dump(u.settings, 'settings.pkl')
await ctx.send('**Delete command invocations:** `{}`'.format(ctx.guild.id in u.settings['del_ctx']))
@settings.command(name='prefix', aliases=['pre', 'p'])
async def _settings_prefix(self, ctx, *prefixes):
if prefixes:
u.settings['prefixes'][ctx.guild.id] = prefixes
else:
with suppress(KeyError):
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"]}`')
import asyncio
import traceback as tb
from contextlib import suppress
from datetime import datetime as dt
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
from misc import exceptions as exc
from misc import checks
from utils import utils as u
class Administration:
def __init__(self, bot):
self.bot = bot
self.RATE_LIMIT = u.RATE_LIMIT
self.queue = asyncio.Queue()
self.deleting = False
if u.tasks['auto_del']:
for channel in u.tasks['auto_del']:
temp = self.bot.get_channel(channel)
self.bot.loop.create_task(self.queue_for_deletion(temp))
print('STARTED : auto-deleting in #{}'.format(temp.name))
self.deleting = True
self.bot.loop.create_task(self.delete())
@cmds.group(aliases=['pru', 'purge', 'pur', 'clear', 'cl'], hidden=True)
@cmds.is_owner()
async def prune(self, ctx):
pass
@prune.group(name='user', aliases=['u', 'member', 'm'])
async def _prune_user(self, ctx):
pass
@_prune_user.command(name='channel', aliases=['channels', 'chans', 'chan', 'ch', 'c'])
async def _prune_user_channel(self, ctx, user: d.User, *channels: d.TextChannel):
def confirm(r, u):
if u is ctx.author:
if r.emoji == '\N{OCTAGONAL SIGN}':
raise exc.Abort
if r.emoji == '\N{THUMBS UP SIGN}':
return True
return False
if not channels:
channels = [ctx.channel]
try:
pruning = await ctx.send(f'\N{HOURGLASS} **Pruning** {user.mention}**\'s messages from** {"**,** ".join([channel.mention for channel in channels])} **might take some time.** Proceed, {ctx.author.mention}?')
await pruning.add_reaction('\N{THUMBS UP SIGN}')
await pruning.add_reaction('\N{OCTAGONAL SIGN}')
await asyncio.sleep(1)
await self.bot.wait_for('reaction_add', check=confirm, timeout=10 * 60)
deleting = await ctx.send(f'\N{WASTEBASKET} **Deleting** {user.mention}**\'s messages...**')
await asyncio.sleep(1)
c = 0
for channel in channels:
await deleting.edit(content=f'\N{WASTEBASKET} **Deleting** {user.mention}**\'s messages from** {channel.mention}')
deleted = await channel.purge(check=lambda m: m.author.id == user.id, before=pruning, limit=None)
c += len(deleted)
await asyncio.sleep(1)
for channel in channels:
missed = 0
async for message in channel.history(before=pruning, limit=None):
if message.author.id == user.id:
missed += 1
if missed > 0:
await ctx.send(f'\N{DOUBLE EXCLAMATION MARK} `{missed}` **messages were not deleted in** {channel.mention}')
await ctx.send(f'\N{WHITE HEAVY CHECK MARK} **Finished deleting** `{c}` **of** {user.mention}**\'s messages**')
except exc.Abort:
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=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
@_prune_user.command(name='all', aliases=['a'], 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\}', hidden=True)
@cmds.is_owner()
async def _prune_user_all(self, ctx, user: d.User):
def confirm(r, u):
if u is ctx.author:
if r.emoji == '\N{OCTAGONAL SIGN}':
raise exc.Abort
if r.emoji == '\N{THUMBS UP SIGN}':
return True
return False
try:
pruning = await ctx.send(f'\N{HOURGLASS} **Pruning** {user.mention}**\'s messages might take some time.** Proceed, {ctx.author.mention}?')
await pruning.add_reaction('\N{THUMBS UP SIGN}')
await pruning.add_reaction('\N{OCTAGONAL SIGN}')
await asyncio.sleep(1)
await self.bot.wait_for('reaction_add', check=confirm, timeout=10 * 60)
deleting = await ctx.send(f'\N{WASTEBASKET} **Deleting** {user.mention}**\'s messages...**')
await asyncio.sleep(1)
c = 0
for channel in ctx.guild.text_channels:
await deleting.edit(content=f'\N{WASTEBASKET} **Deleting** {user.mention}**\'s messages from** {channel.mention}')
deleted = await channel.purge(check=lambda m: m.author.id == user.id, before=pruning, limit=None)
c += len(deleted)
await asyncio.sleep(1)
for channel in ctx.guild.text_channels:
missed = 0
async for message in channel.history(before=pruning, limit=None):
if message.author.id == user.id:
missed += 1
if missed > 0:
await ctx.send(f'\N{DOUBLE EXCLAMATION MARK} `{missed}` **messages were not deleted in** {channel.mention}')
await ctx.send(f'\N{WHITE HEAVY CHECK MARK} **Finished deleting** `{c}` **of** {user.mention}**\'s messages**')
except exc.Abort:
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=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()
await asyncio.sleep(self.RATE_LIMIT)
with suppress(err.NotFound):
if not message.pinned:
await message.delete()
print('STOPPED : deleting')
async def queue_for_deletion(self, channel):
def check(msg):
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
return False
try:
async for message in channel.history(limit=None):
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)
while not self.bot.is_closed():
message = await self.bot.wait_for('message', check=check)
await self.queue.put(message)
except exc.Abort:
u.tasks['auto_del'].remove(channel.id)
u.dump(u.tasks, 'cogs/tasks.pkl')
if not u.tasks['auto_del']:
self.deleting = False
print('STOPPED : deleting #{}'.format(channel.name))
await channel.send('**Stopped queueing messages for deletion in** {}'.format(channel.mention), delete_after=5)
@cmds.command(name='autodelete', aliases=['autodel'])
@cmds.has_permissions(administrator=True)
async def auto_delete(self, ctx):
try:
if ctx.channel.id not in u.tasks['auto_del']:
u.tasks['auto_del'].append(ctx.channel.id)
u.dump(u.tasks, 'cogs/tasks.pkl')
self.bot.loop.create_task(self.queue_for_deletion(ctx.channel))
if not self.deleting:
self.bot.loop.create_task(self.delete())
self.deleting = True
print('STARTED : auto-deleting in #{}'.format(ctx.channel.name))
await ctx.send('**Auto-deleting all messages in {}**'.format(ctx.channel.mention), delete_after=5)
else:
raise exc.Exists
except exc.Exists:
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'])
@cmds.has_permissions(administrator=True)
async def settings(self, ctx):
pass
@settings.command(name='deletecommands', aliases=['delcmds', 'delcmd'])
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:
u.settings['del_ctx'].remove(ctx.guild.id)
u.dump(u.settings, 'settings.pkl')
await ctx.send('**Delete command invocations:** `{}`'.format(ctx.guild.id in u.settings['del_ctx']))
@settings.command(name='prefix', aliases=['pre', 'p'])
async def _settings_prefix(self, ctx, *prefixes):
if prefixes:
u.settings['prefixes'][ctx.guild.id] = prefixes
else:
with suppress(KeyError):
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"]}`')

View file

@ -1,245 +1,245 @@
import asyncio
import code
import io
import os
import re
import sys
import traceback as tb
from contextlib import redirect_stdout, suppress
import discord as d
import pyrasite as pyr
from discord.ext import commands as cmds
from misc import exceptions as exc
from misc import checks
from utils import utils as u
class Bot:
def __init__(self, bot):
self.bot = bot
# Close connection to Discord - immediate offline
@cmds.command(name=',die', aliases=[',d'], brief='Kills the bot', description='BOT OWNER ONLY\nCloses the connection to Discord', hidden=True)
@cmds.is_owner()
async def die(self, ctx):
await ctx.message.add_reaction('\N{CRESCENT MOON}')
await self.bot.get_channel(u.config['info_channel']).send('**Shutting down** \N{CRESCENT MOON} . . .')
chantype = 'guild' if isinstance(ctx.channel, d.TextChannel) else 'private'
u.temp['startup'] = (chantype, ctx.channel.id if chantype == 'guild' else ctx.author.id, ctx.message.id)
u.dump(u.temp, 'temp/temp.pkl')
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
await self.bot.logout()
u.close(self.bot.loop)
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')
@cmds.command(name=',restart', aliases=[',res', ',r'], hidden=True)
@cmds.is_owner()
async def restart(self, ctx):
await ctx.message.add_reaction('\N{SLEEPING SYMBOL}')
print('\n^ ^ ^ ^ ^ ^ ^ ^ ^ ^\nR E S T A R T I N G\n^ ^ ^ ^ ^ ^ ^ ^ ^ ^\n')
await self.bot.get_channel(u.config['info_channel']).send('**Restarting** \N{SLEEPING SYMBOL} . . .')
# u.notify('R E S T A R T I N G')
chantype = 'guild' if isinstance(ctx.channel, d.TextChannel) else 'private'
u.temp['startup'] = (chantype, ctx.channel.id if chantype == 'guild' else ctx.author.id, ctx.message.id)
u.dump(u.temp, 'temp/temp.pkl')
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
await self.bot.logout()
u.close(self.bot.loop)
os.execl(sys.executable, 'python3', 'run.py')
# Invite bot to bot owner's server
@cmds.command(name=',invite', aliases=[',inv', ',link'], brief='Invite the bot', description='BOT OWNER ONLY\nInvite the bot to a server (Requires admin)', hidden=True)
@cmds.is_owner()
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=5)
@cmds.command(name=',guilds', aliases=[',glds', ',servers', ',servs'])
@cmds.is_owner()
async def guilds(self, ctx):
paginator = cmds.Paginator()
for guild in self.bot.guilds:
paginator.add_line(guild.name)
for page in paginator.pages:
await ctx.send(f'**Guilds:**\n{page}')
@cmds.command(name=',status', aliases=[',presence', ',game'], hidden=True)
@cmds.is_owner()
async def change_status(self, ctx, *, game=None):
if game:
await self.bot.change_presence(game=d.Game(name=game))
u.config['playing'] = game
u.dump(u.config, 'config.json', json=True)
await ctx.send(f'**Game changed to** `{game}`')
else:
await self.bot.change_presence(game=None)
u.config['playing'] = ''
u.dump(u.config, 'config.json', json=True)
await ctx.send('**Game changed to** ` `')
@cmds.command(name=',username', aliases=[',user'], hidden=True)
@cmds.is_owner()
async def change_username(self, ctx, *, username=None):
if username:
await self.bot.user.edit(username=username)
await ctx.send(f'**Username changed to** `{username}`')
else:
await ctx.send('**Invalid string**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
class Tools:
def __init__(self, bot):
self.bot = bot
def format(self, i='', o=''):
if len(o) > 1:
return '>>> {}\n{}'.format(i, o)
else:
return '>>> {}'.format(i)
async def generate(self, d, i='', o=''):
return await d.send('```python\n{}```'.format(self.format(i, o)))
async def refresh(self, m, i='', o=''):
output = m.content[9:-3]
if len(re.findall('\n', output)) <= 20:
await m.edit(content='```python\n{}\n{}\n>>>```'.format(output, self.format(i, o)))
else:
await m.edit(content='```python\n{}```'.format(self.format(i, o)))
async def generate_err(self, d, o=''):
return await d.send('```\n{}```'.format(o))
async def refresh_err(self, m, o=''):
await m.edit(content='```\n{}```'.format(o))
@cmds.command(name=',console', aliases=[',con', ',c'], hidden=True)
@cmds.is_owner()
async def console(self, ctx):
def execute(msg):
if msg.content.lower().startswith('exec ') and msg.author is ctx.author and msg.channel is ctx.channel:
msg.content = msg.content[5:]
return True
return False
def evaluate(msg):
if msg.content.lower().startswith('eval ') and msg.author is ctx.author and msg.channel is ctx.channel:
msg.content = msg.content[5:]
return True
return False
def exit(reaction, user):
if reaction.emoji == '\N{OCTAGONAL SIGN}' and user is ctx.author and reaction.message.id == ctx.message.id:
raise exc.Abort
return False
try:
console = await self.generate(ctx)
exception = await self.generate_err(ctx)
await ctx.message.add_reaction('\N{OCTAGONAL SIGN}')
while not self.bot.is_closed():
try:
done, pending = await asyncio.wait([self.bot.wait_for('message', check=execute), self.bot.wait_for('message', check=evaluate), self.bot.wait_for('reaction_add', check=exit)], return_when=asyncio.FIRST_COMPLETED)
message = done.pop().result()
print(message.content)
except exc.Execute:
try:
sys.stdout = io.StringIO()
sys.stderr = io.StringIO()
exec(message.content)
except Exception:
await self.refresh_err(exception, tb.format_exc(limit=1))
finally:
await self.refresh(console, message.content, sys.stdout.getvalue() if sys.stdout.getvalue() != console.content else None)
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
with suppress(d.NotFound):
await message.delete()
except exc.Evaluate:
try:
sys.stdout = io.StringIO()
sys.stderr = io.StringIO()
eval(message.content)
except Exception:
await self.refresh_err(exception, tb.format_exc(limit=1))
finally:
await self.refresh(console, message.content, sys.stdout.getvalue() if sys.stdout.getvalue() != console.content else None)
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
with suppress(d.NotFound):
await message.delete()
except exc.Abort:
pass
finally:
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
print('RESET : sys.std output/error')
@cmds.command(name=',execute', aliases=[',exec'], hidden=True)
@cmds.is_owner()
async def execute(self, ctx, *, exe):
try:
with io.StringIO() as buff, redirect_stdout(buff):
exec(exe)
await self.generate(ctx, exe, f'\n{buff.getvalue()}')
except Exception:
await self.generate(ctx, exe, f'\n{tb.format_exc()}')
@cmds.command(name=',evaluate', aliases=[',eval'], hidden=True)
@cmds.is_owner()
async def evaluate(self, ctx, *, evl):
try:
with io.StringIO() as buff, redirect_stdout(buff):
eval(evl)
await self.generate(ctx, evl, f'\n{buff.getvalue()}')
except Exception:
await self.generate(ctx, evl, f'\n{tb.format_exc()}')
@cmds.group(aliases=[',db'], hidden=True)
@cmds.is_owner()
async def debug(self, ctx):
console = await self.generate(ctx)
@debug.command(name='inject', aliases=['inj'])
async def _inject(self, ctx, *, input_):
pass
@debug.command(name='inspect', aliases=['ins'])
async def _inspect(self, ctx, *, input_):
pass
# @cmds.command(name='endpoint', aliases=['end'])
# async def get_endpoint(self, ctx, *args):
# await ctx.send(f'```\n{await u.fetch(f"https://{args[0]}/{args[1]}/{args[2]}", params={args[3]: args[4], "limit": 1}, json=True)}```')
import asyncio
import code
import io
import os
import re
import sys
import traceback as tb
from contextlib import redirect_stdout, suppress
import discord as d
import pyrasite as pyr
from discord.ext import commands as cmds
from misc import exceptions as exc
from misc import checks
from utils import utils as u
class Bot:
def __init__(self, bot):
self.bot = bot
# Close connection to Discord - immediate offline
@cmds.command(name=',die', aliases=[',d'], brief='Kills the bot', description='BOT OWNER ONLY\nCloses the connection to Discord', hidden=True)
@cmds.is_owner()
async def die(self, ctx):
await ctx.message.add_reaction('\N{CRESCENT MOON}')
await self.bot.get_channel(u.config['info_channel']).send('**Shutting down** \N{CRESCENT MOON} . . .')
chantype = 'guild' if isinstance(ctx.channel, d.TextChannel) else 'private'
u.temp['startup'] = (chantype, ctx.channel.id if chantype == 'guild' else ctx.author.id, ctx.message.id)
u.dump(u.temp, 'temp/temp.pkl')
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
await self.bot.logout()
u.close(self.bot.loop)
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')
@cmds.command(name=',restart', aliases=[',res', ',r'], hidden=True)
@cmds.is_owner()
async def restart(self, ctx):
await ctx.message.add_reaction('\N{SLEEPING SYMBOL}')
print('\n^ ^ ^ ^ ^ ^ ^ ^ ^ ^\nR E S T A R T I N G\n^ ^ ^ ^ ^ ^ ^ ^ ^ ^\n')
await self.bot.get_channel(u.config['info_channel']).send('**Restarting** \N{SLEEPING SYMBOL} . . .')
# u.notify('R E S T A R T I N G')
chantype = 'guild' if isinstance(ctx.channel, d.TextChannel) else 'private'
u.temp['startup'] = (chantype, ctx.channel.id if chantype == 'guild' else ctx.author.id, ctx.message.id)
u.dump(u.temp, 'temp/temp.pkl')
# loop = self.bot.loop.all_tasks()
# for task in loop:
# task.cancel()
await self.bot.logout()
u.close(self.bot.loop)
os.execl(sys.executable, 'python3', 'run.py')
# Invite bot to bot owner's server
@cmds.command(name=',invite', aliases=[',inv', ',link'], brief='Invite the bot', description='BOT OWNER ONLY\nInvite the bot to a server (Requires admin)', hidden=True)
@cmds.is_owner()
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=5)
@cmds.command(name=',guilds', aliases=[',glds', ',servers', ',servs'])
@cmds.is_owner()
async def guilds(self, ctx):
paginator = cmds.Paginator()
for guild in self.bot.guilds:
paginator.add_line(guild.name)
for page in paginator.pages:
await ctx.send(f'**Guilds:**\n{page}')
@cmds.command(name=',status', aliases=[',presence', ',game'], hidden=True)
@cmds.is_owner()
async def change_status(self, ctx, *, game=None):
if game:
await self.bot.change_presence(game=d.Game(name=game))
u.config['playing'] = game
u.dump(u.config, 'config.json', json=True)
await ctx.send(f'**Game changed to** `{game}`')
else:
await self.bot.change_presence(game=None)
u.config['playing'] = ''
u.dump(u.config, 'config.json', json=True)
await ctx.send('**Game changed to** ` `')
@cmds.command(name=',username', aliases=[',user'], hidden=True)
@cmds.is_owner()
async def change_username(self, ctx, *, username=None):
if username:
await self.bot.user.edit(username=username)
await ctx.send(f'**Username changed to** `{username}`')
else:
await ctx.send('**Invalid string**', delete_after=7)
await ctx.message.add_reaction('\N{CROSS MARK}')
class Tools:
def __init__(self, bot):
self.bot = bot
def format(self, i='', o=''):
if len(o) > 1:
return '>>> {}\n{}'.format(i, o)
else:
return '>>> {}'.format(i)
async def generate(self, d, i='', o=''):
return await d.send('```python\n{}```'.format(self.format(i, o)))
async def refresh(self, m, i='', o=''):
output = m.content[9:-3]
if len(re.findall('\n', output)) <= 20:
await m.edit(content='```python\n{}\n{}\n>>>```'.format(output, self.format(i, o)))
else:
await m.edit(content='```python\n{}```'.format(self.format(i, o)))
async def generate_err(self, d, o=''):
return await d.send('```\n{}```'.format(o))
async def refresh_err(self, m, o=''):
await m.edit(content='```\n{}```'.format(o))
@cmds.command(name=',console', aliases=[',con', ',c'], hidden=True)
@cmds.is_owner()
async def console(self, ctx):
def execute(msg):
if msg.content.lower().startswith('exec ') and msg.author is ctx.author and msg.channel is ctx.channel:
msg.content = msg.content[5:]
return True
return False
def evaluate(msg):
if msg.content.lower().startswith('eval ') and msg.author is ctx.author and msg.channel is ctx.channel:
msg.content = msg.content[5:]
return True
return False
def exit(reaction, user):
if reaction.emoji == '\N{OCTAGONAL SIGN}' and user is ctx.author and reaction.message.id == ctx.message.id:
raise exc.Abort
return False
try:
console = await self.generate(ctx)
exception = await self.generate_err(ctx)
await ctx.message.add_reaction('\N{OCTAGONAL SIGN}')
while not self.bot.is_closed():
try:
done, pending = await asyncio.wait([self.bot.wait_for('message', check=execute), self.bot.wait_for('message', check=evaluate), self.bot.wait_for('reaction_add', check=exit)], return_when=asyncio.FIRST_COMPLETED)
message = done.pop().result()
print(message.content)
except exc.Execute:
try:
sys.stdout = io.StringIO()
sys.stderr = io.StringIO()
exec(message.content)
except Exception:
await self.refresh_err(exception, tb.format_exc(limit=1))
finally:
await self.refresh(console, message.content, sys.stdout.getvalue() if sys.stdout.getvalue() != console.content else None)
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
with suppress(d.NotFound):
await message.delete()
except exc.Evaluate:
try:
sys.stdout = io.StringIO()
sys.stderr = io.StringIO()
eval(message.content)
except Exception:
await self.refresh_err(exception, tb.format_exc(limit=1))
finally:
await self.refresh(console, message.content, sys.stdout.getvalue() if sys.stdout.getvalue() != console.content else None)
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
with suppress(d.NotFound):
await message.delete()
except exc.Abort:
pass
finally:
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
print('RESET : sys.std output/error')
@cmds.command(name=',execute', aliases=[',exec'], hidden=True)
@cmds.is_owner()
async def execute(self, ctx, *, exe):
try:
with io.StringIO() as buff, redirect_stdout(buff):
exec(exe)
await self.generate(ctx, exe, f'\n{buff.getvalue()}')
except Exception:
await self.generate(ctx, exe, f'\n{tb.format_exc()}')
@cmds.command(name=',evaluate', aliases=[',eval'], hidden=True)
@cmds.is_owner()
async def evaluate(self, ctx, *, evl):
try:
with io.StringIO() as buff, redirect_stdout(buff):
eval(evl)
await self.generate(ctx, evl, f'\n{buff.getvalue()}')
except Exception:
await self.generate(ctx, evl, f'\n{tb.format_exc()}')
@cmds.group(aliases=[',db'], hidden=True)
@cmds.is_owner()
async def debug(self, ctx):
console = await self.generate(ctx)
@debug.command(name='inject', aliases=['inj'])
async def _inject(self, ctx, *, input_):
pass
@debug.command(name='inspect', aliases=['ins'])
async def _inspect(self, ctx, *, input_):
pass
# @cmds.command(name='endpoint', aliases=['end'])
# async def get_endpoint(self, ctx, *args):
# await ctx.send(f'```\n{await u.fetch(f"https://{args[0]}/{args[1]}/{args[2]}", params={args[3]: args[4], "limit": 1}, json=True)}```')

View file

@ -1,191 +1,191 @@
import asyncio
import json as jsn
import os
import pickle as pkl
import subprocess
from contextlib import suppress
from fractions import gcd
import math
import gmusicapi as gpm
import aiohttp
import discord as d
from misc import exceptions as exc
# from pync import Notifier
print('\nPID : {}\n'.format(os.getpid()))
# def notify(message):
# subprocess.run(['terminal-notifier', '-message', message, '-title',
# 'Modumind', '-activate', 'com.apple.Terminal', '-appIcon', 'icon.png', '-sound', 'Ping'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
try:
with open('config.json') as infile:
config = jsn.load(infile)
print('LOADED : config.json')
except FileNotFoundError:
with open('config.json', 'w') as outfile:
jsn.dump({'client_id': 0, 'info_channel': 0, 'owner_id': 0, 'permissions': 126016,
'playing': 'a game', 'prefix': [',', 'm,'], 'selfbot': False, 'token': 'str'}, outfile, indent=4, sort_keys=True)
print('FILE NOT FOUND : config.json created with abstract values. Restart run.py with correct values')
def setdefault(filename, default=None, json=False):
if json:
try:
with open(filename, 'r') as infile:
print(f'LOADED : {filename}')
return jsn.load(infile)
except FileNotFoundError:
with open(filename, 'w+') as iofile:
print(f'FILE NOT FOUND : {filename} created and loaded with default values')
jsn.dump(default, iofile)
iofile.seek(0)
return jsn.load(iofile)
else:
try:
with open(filename, 'rb') as infile:
print(f'LOADED : {filename}')
return pkl.load(infile)
except FileNotFoundError:
with open(filename, 'wb+') as iofile:
print(f'FILE NOT FOUND : {filename} created and loaded with default values')
pkl.dump(default, iofile)
iofile.seek(0)
return pkl.load(iofile)
def load(filename, *, json=False):
if not json:
with open(filename, 'rb') as infile:
return pkl.load(infile)
else:
with open(filename) as infile:
return jsn.load(infile)
def dump(obj, filename, *, json=False):
if not json:
with open(filename, 'wb') as outfile:
pkl.dump(obj, outfile)
else:
with open(filename, 'w') as outfile:
jsn.dump(obj, outfile, indent=4, sort_keys=True)
settings = setdefault('misc/settings.pkl', default={'del_ctx': [], 'del_resp': [], 'prefixes': {}})
tasks = setdefault('cogs/tasks.pkl', default={'auto_del': [], 'auto_hrt': [], 'auto_rev': [], 'periodic_gpm': []})
temp = setdefault('temp/temp.pkl', default={'startup': ()})
secrets = setdefault('secrets.json', default={'client_secrets': {'client_id': '', 'client_secret': ''}}, json=True)
RATE_LIMIT = 2.2
color = d.Color(0x1A1A1A)
session = aiohttp.ClientSession()
last_commands = {}
async def fetch(url, *, params={}, json=False, response=False):
async with session.get(url, params=params, headers={'User-Agent': 'Myned/Modufur'}) as r:
if response:
return r
elif json:
return await r.json()
return await r.read()
# async def clear(obj, interval=10 * 60, replace=None):
# if replace is None:
# if type(obj) is list:
# replace = []
# elif type(obj) is dict:
# replace = {}
# elif type(obj) is int:
# replace = 0
# elif type(obj) is str:
# replace = ''
#
# while True:
# obj = replace
# asyncio.sleep(interval)
def close(loop):
if session:
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.')
def generate_embed(ctx, *, title=d.Embed.Empty, kind='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=kind, 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
remaining = list(args[:])
rm = False
lim = 1
for flag in ('-d', '-dm'):
if flag in remaining:
destination = ctx.author
remaining.remove(flag)
for flag in ('-r', '-rm', '-remove', '-re', '-repl', '-replace'):
if flag in remaining and ctx.author.permissions_in(ctx.channel).manage_messages:
rm = True
remaining.remove(flag)
if limit:
for arg in remaining:
if arg.isdigit():
if 1 <= int(arg) <= limit:
lim = int(arg)
remaining.remove(arg)
break
else:
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)
import asyncio
import json as jsn
import os
import pickle as pkl
import subprocess
from contextlib import suppress
from fractions import gcd
import math
import gmusicapi as gpm
import aiohttp
import discord as d
from misc import exceptions as exc
# from pync import Notifier
print('\nPID : {}\n'.format(os.getpid()))
# def notify(message):
# subprocess.run(['terminal-notifier', '-message', message, '-title',
# 'Modumind', '-activate', 'com.apple.Terminal', '-appIcon', 'icon.png', '-sound', 'Ping'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
try:
with open('config.json') as infile:
config = jsn.load(infile)
print('LOADED : config.json')
except FileNotFoundError:
with open('config.json', 'w') as outfile:
jsn.dump({'client_id': 0, 'info_channel': 0, 'owner_id': 0, 'permissions': 126016,
'playing': 'a game', 'prefix': [',', 'm,'], 'selfbot': False, 'token': 'str'}, outfile, indent=4, sort_keys=True)
print('FILE NOT FOUND : config.json created with abstract values. Restart run.py with correct values')
def setdefault(filename, default=None, json=False):
if json:
try:
with open(filename, 'r') as infile:
print(f'LOADED : {filename}')
return jsn.load(infile)
except FileNotFoundError:
with open(filename, 'w+') as iofile:
print(f'FILE NOT FOUND : {filename} created and loaded with default values')
jsn.dump(default, iofile)
iofile.seek(0)
return jsn.load(iofile)
else:
try:
with open(filename, 'rb') as infile:
print(f'LOADED : {filename}')
return pkl.load(infile)
except FileNotFoundError:
with open(filename, 'wb+') as iofile:
print(f'FILE NOT FOUND : {filename} created and loaded with default values')
pkl.dump(default, iofile)
iofile.seek(0)
return pkl.load(iofile)
def load(filename, *, json=False):
if not json:
with open(filename, 'rb') as infile:
return pkl.load(infile)
else:
with open(filename) as infile:
return jsn.load(infile)
def dump(obj, filename, *, json=False):
if not json:
with open(filename, 'wb') as outfile:
pkl.dump(obj, outfile)
else:
with open(filename, 'w') as outfile:
jsn.dump(obj, outfile, indent=4, sort_keys=True)
settings = setdefault('misc/settings.pkl', default={'del_ctx': [], 'del_resp': [], 'prefixes': {}})
tasks = setdefault('cogs/tasks.pkl', default={'auto_del': [], 'auto_hrt': [], 'auto_rev': [], 'periodic_gpm': []})
temp = setdefault('temp/temp.pkl', default={'startup': ()})
secrets = setdefault('secrets.json', default={'client_secrets': {'client_id': '', 'client_secret': ''}}, json=True)
RATE_LIMIT = 2.2
color = d.Color(0x1A1A1A)
session = aiohttp.ClientSession()
last_commands = {}
async def fetch(url, *, params={}, json=False, response=False):
async with session.get(url, params=params, headers={'User-Agent': 'Myned/Modufur'}) as r:
if response:
return r
elif json:
return await r.json()
return await r.read()
# async def clear(obj, interval=10 * 60, replace=None):
# if replace is None:
# if type(obj) is list:
# replace = []
# elif type(obj) is dict:
# replace = {}
# elif type(obj) is int:
# replace = 0
# elif type(obj) is str:
# replace = ''
#
# while True:
# obj = replace
# asyncio.sleep(interval)
def close(loop):
if session:
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.')
def generate_embed(ctx, *, title=d.Embed.Empty, kind='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=kind, 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
remaining = list(args[:])
rm = False
lim = 1
for flag in ('-d', '-dm'):
if flag in remaining:
destination = ctx.author
remaining.remove(flag)
for flag in ('-r', '-rm', '-remove', '-re', '-repl', '-replace'):
if flag in remaining and ctx.author.permissions_in(ctx.channel).manage_messages:
rm = True
remaining.remove(flag)
if limit:
for arg in remaining:
if arg.isdigit():
if 1 <= int(arg) <= limit:
lim = int(arg)
remaining.remove(arg)
break
else:
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)