aboutsummaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorromangraef <romangraef@loves.dicksinhisan.us>2018-08-21 16:12:39 +0200
committerromangraef <romangraef@loves.dicksinhisan.us>2018-08-21 16:12:39 +0200
commita4c058b5c0ec4e441c63ae2ef15235a4869d2bac (patch)
tree64a039e55976adace41fb56d4fc77e88333db802 /modules
downloadnotaselfbotv2finalforsure-a4c058b5c0ec4e441c63ae2ef15235a4869d2bac.tar.gz
notaselfbotv2finalforsure-a4c058b5c0ec4e441c63ae2ef15235a4869d2bac.tar.bz2
notaselfbotv2finalforsure-a4c058b5c0ec4e441c63ae2ef15235a4869d2bac.zip
Initial commit
Diffstat (limited to 'modules')
-rw-r--r--modules/admin.py126
-rw-r--r--modules/binary.py27
-rw-r--r--modules/converters.py42
-rw-r--r--modules/copypasta.py27
-rw-r--r--modules/dump.py78
-rw-r--r--modules/github.py68
-rw-r--r--modules/pypi.py48
-rw-r--r--modules/ragequit.py17
8 files changed, 433 insertions, 0 deletions
diff --git a/modules/admin.py b/modules/admin.py
new file mode 100644
index 0000000..fb50a2e
--- /dev/null
+++ b/modules/admin.py
@@ -0,0 +1,126 @@
+import asyncio
+import os
+import re
+from typing import List, Dict, Pattern
+
+import discord
+from discord import Embed, Color, Message
+from discord.ext import commands
+from discord.ext.commands import Context as CommandContext, Bot
+
+from config import config
+from utils import load_all_modules
+
+REPLACEMENTS: Dict[Pattern, str] = {
+ re.compile(r'<@!?(?P<id>[0-9]+)>'): '(guild.get_member({id}) if guild is not None else client.get_user({id}))',
+ re.compile(r'<#(?P<id>[0-9]+)>'): '(discord.utils.get(all_channels, id={id}))',
+ re.compile(r'<@&(?P<id>[0-9]+)>'): '(discord.utils.get(all_roles, id={id}))',
+ # Maybe later emoji support
+}
+
+
+async def handle_eval(message: discord.Message, client: discord.Client, to_eval: str):
+ channel: discord.TextChannel = message.channel
+ author: discord.Member = message.author
+
+ all_channels: List[discord.Guild] = []
+ all_roles: List[discord.Role] = []
+ for guild in client.guilds:
+ guild: discord.Guild = guild # for type hints
+ all_channels += guild.channels
+ all_roles += guild.roles
+
+ variables = {
+ 'message': message,
+ 'author': author,
+ 'channel': channel,
+ 'all_channels': all_channels,
+ 'all_roles': all_roles,
+ 'client': client,
+ 'discord': discord,
+ 'os': os,
+ 'github': config.github.github,
+ 'print': (lambda *text: client.loop.create_task(channel.send(' '.join(text)))),
+ 'guild': channel.guild if hasattr(channel, 'guild') else None,
+ }
+ lines: List[str] = to_eval.strip().split('\n')
+ lines[-1] = 'return ' + lines[-1]
+ block: str = '\n'.join(' ' + line for line in lines)
+ code = f"async def code({', '.join(variables.keys())}):\n" \
+ f"{block}"
+
+ for regex, replacement in REPLACEMENTS.items():
+ code = re.sub(regex, lambda match: replacement.format(**match.groupdict()), code)
+
+ _globals, _locals = {}, {}
+ try:
+ exec(code, _globals, _locals)
+ except Exception as e:
+ await message.channel.send(
+ embed=discord.Embed(color=discord.Color.red(), description="Compiler Error: `%s`" % (str(e))))
+ return
+ result = {**_globals, **_locals}
+ try:
+ result = await result["code"](**variables)
+ except Exception as e:
+ await message.channel.send(
+ embed=discord.Embed(color=discord.Color.red(), description="Runtime Error: `%s`" % (str(e))))
+ return
+
+ return await channel.send(
+ embed=Embed(
+ color=Color.red(),
+ description="📥 Evaluation success: ```py\n%r\n```" % result))
+
+
+class AdminCog(object):
+ def __init__(self, bot: commands.Bot):
+ self.bot: commands.Bot = bot
+
+ # noinspection PyMethodMayBeStatic
+ async def on_ready(self):
+ print('Logged in.')
+
+ @commands.command()
+ async def eval(self, ctx: CommandContext, *, to_eval: str = None):
+ if to_eval is None:
+ return await ctx.send(
+ embed=Embed(
+ description="<Insert generic insult about your stupidity here>",
+ color=Color.red()))
+ await handle_eval(ctx.message, self.bot, to_eval)
+
+ @commands.command()
+ async def reload(self, ctx: CommandContext, *extensions):
+ for extension in (extensions or self.bot.extensions.copy().keys()):
+ self.bot.unload_extension(extension)
+ messages: List[Message] = [
+ await ctx.send(
+ embed=Embed(
+ color=Color.red(),
+ description='Unloaded extensions')),
+ ctx.message]
+ if len(extensions) == 0:
+ load_all_modules(self.bot)
+ else:
+ for extension in extensions:
+ try:
+ self.bot.load_extension(extension)
+ except:
+ messages.append(
+ await ctx.send(
+ embed=Embed(
+ title=f"Failed to load module `{extension}`",
+ color=Color.red())))
+ messages.append(
+ await ctx.send(
+ embed=Embed(
+ title=f"Reloaded {len(extensions) or len(self.bot.extensions)} extension(s)",
+ color=Color.green())))
+ await asyncio.sleep(10)
+ for mes in messages:
+ await mes.delete()
+
+
+def setup(bot: Bot):
+ bot.add_cog(AdminCog(bot))
diff --git a/modules/binary.py b/modules/binary.py
new file mode 100644
index 0000000..70ed010
--- /dev/null
+++ b/modules/binary.py
@@ -0,0 +1,27 @@
+from discord import Message
+from discord.ext.commands import Bot, command, Context
+
+
+class BinaryCog(object):
+ def __init__(self, bot: Bot):
+ self.bot: Bot = bot
+
+ @command()
+ async def binary(self, ctx: Context, *, text: str):
+ binary = ' '.join(bin(ord(ch))[2:].zfill(8) for ch in text)
+ mes: Message = ctx.message
+ await mes.edit(content=binary)
+
+ @command()
+ async def un_binary(self, ctx: Context, message: Message):
+ text: str = message.content
+ print(text)
+ text.replace(' ', '').replace('\n', '')
+ chunks, chunk_size = len(text), len(text) // 4
+ await ctx.message.edit(
+ content=f"Decoded message {message.jump_url}: "
+ f"{''.join([chr(int(text[i:i + chunk_size], 2)) for i in range(0, chunks, chunk_size)])}")
+
+
+def setup(bot: Bot):
+ bot.add_cog(BinaryCog(bot))
diff --git a/modules/converters.py b/modules/converters.py
new file mode 100644
index 0000000..f86ff59
--- /dev/null
+++ b/modules/converters.py
@@ -0,0 +1,42 @@
+from string import digits
+
+from discord import TextChannel
+from discord.ext.commands import Converter, Context, Bot, BadArgument, converter
+
+
+def is_int(text):
+ return all(map(digits.__contains__, text))
+
+
+class GuildConverter(Converter):
+ async def convert(self, ctx: Context, argument):
+ bot: Bot = ctx.bot
+ try:
+ return bot.get_guild(int(argument))
+ except:
+ try:
+ return [guild for guild in bot.guilds if guild.name.casefold() == argument.casefold()][0]
+ except:
+ raise BadArgument(f"Could not find guild with id or name {argument}")
+
+
+class MessageConverter(Converter):
+ async def convert(self, ctx: Context, argument: str):
+ bot: Bot = ctx.bot
+ if is_int(argument):
+ message = int(argument)
+ channel: TextChannel = ctx.channel
+ else:
+ _, channel, message = list(map(int, filter(is_int, argument.split('/'))))
+ channel: TextChannel = bot.get_channel(channel)
+
+ if bot.user.bot:
+ return await channel.get_message(message)
+ else:
+ return (await channel.history(around=message, limit=2).flatten())[1]
+
+
+# noinspection PyUnusedLocal
+def setup(bot: Bot):
+ converter.MessageConverter = MessageConverter
+ converter.GuildConverter = GuildConverter
diff --git a/modules/copypasta.py b/modules/copypasta.py
new file mode 100644
index 0000000..4cb747f
--- /dev/null
+++ b/modules/copypasta.py
@@ -0,0 +1,27 @@
+from _contextvars import Context
+from string import digits, ascii_uppercase, ascii_lowercase
+
+from discord.ext.commands import Bot, command, Converter
+
+
+class CopyPastaTextConverter(Converter):
+
+ async def convert(self, ctx: Context, argument: str):
+ allowed_characters = ascii_uppercase + ascii_lowercase + digits + '_- '
+ if any(ch not in allowed_characters for ch in argument):
+ return
+ with open(f'copypasta/{argument}.txt') as fp:
+ return fp.read().strip()
+
+
+class CopyPasta(object):
+ def __init__(self, bot: Bot):
+ self.bot: Bot = bot
+
+ @command(aliases=['cp', 'copy-pasta', 'copypasta'])
+ async def copy_pasta(self, ctx: Context, copy_pasta: CopyPastaTextConverter):
+ await ctx.message.edit(content=str(copy_pasta))
+
+
+def setup(bot: Bot):
+ bot.add_cog(CopyPasta(bot))
diff --git a/modules/dump.py b/modules/dump.py
new file mode 100644
index 0000000..5281d7d
--- /dev/null
+++ b/modules/dump.py
@@ -0,0 +1,78 @@
+from typing import List
+
+from discord import User, Embed, Profile, Guild, Member, Permissions, Message
+from discord.ext.commands import Bot, command, Context as CommandContext, Context
+
+
+async def _context_react(self: Context, emoji):
+ await self.message.add_reaction(emoji)
+
+
+Context.react = _context_react
+
+
+def dump_perms(permissions: Permissions):
+ def perm_names():
+ for perm, value in permissions:
+ if value:
+ yield perm
+
+ return ', '.join(perm_names())
+
+
+class DumpCog(object):
+ def __init__(self, bot: Bot):
+ self.bot = bot
+
+ @command()
+ async def raw(self, ctx: CommandContext, message: Message):
+ content: str = message.content
+ escaped = content.replace('```', '``\u200B`')
+ await ctx.send(content=f'```\n{escaped}\n```')
+ await ctx.react('✅')
+
+ @command()
+ async def user(self, ctx: CommandContext, user: User, guild: Guild = None):
+ if guild is None and ctx.guild is not None:
+ guild: Guild = ctx.guild
+ profile: Profile = await user.profile()
+ description = ""
+ if profile.nitro:
+ description += f"i can haz animated emojis since {profile.premium_since}\n"
+ if profile.hypesquad:
+ description += f"they got some hype\n"
+ if profile.partner:
+ description += "insrt BLU INFINITY SYMBOL her\n"
+ if profile.staff:
+ description += "staff. if this is b1nzy, then FUCK him for banning selfbots\n"
+ mutual: List[Guild] = profile.mutual_guilds
+
+ mutual_text = '\n'.join(guild.name for guild in mutual)
+ if len(mutual_text) > 512:
+ mutual_text = f"Together in {len(mutual)} guilds. [Truncated]"
+
+ em = Embed(
+ title=str(user),
+ description=description,
+ )
+ if guild:
+ member: Member = guild.get_member(user.id)
+ if member:
+ if guild.owner_id == member.id:
+ em.add_field(name="Owner", value="Yeah", inline=True)
+ em.colour = member.color
+ em.add_field(name="Joined Guild", value=member.joined_at, inline=True)
+ em.add_field(name="Permissions", value=dump_perms(member.guild_permissions), inline=True)
+ em.set_author(name=user.display_name, icon_url=user.avatar_url)
+ em.add_field(name="Mutual guilds", value=mutual_text, inline=True)
+ em.add_field(name="Joined Discord", value=user.created_at, inline=True)
+ for connection in profile.connected_accounts:
+ em.add_field(name=connection['type'], value=('☑' if connection['verified'] else '') + connection['name'],
+ inline=True)
+ em.set_thumbnail(url=user.avatar_url)
+ await ctx.send(embed=em)
+ await ctx.react('✅')
+
+
+def setup(bot: Bot):
+ bot.add_cog(DumpCog(bot))
diff --git a/modules/github.py b/modules/github.py
new file mode 100644
index 0000000..cb639dc
--- /dev/null
+++ b/modules/github.py
@@ -0,0 +1,68 @@
+from typing import List
+
+from discord import Embed, Color
+from discord.ext.commands import Bot, Group
+from discord.ext.commands import Context as CommandContext, group
+from github.NamedUser import NamedUser
+from github.Repository import Repository
+
+from config import config
+
+github = config.github.github
+
+
+def find_repo(search):
+ repos: List[Repository] = list(github.get_repos())
+ checks = [
+ lambda r: r.id.lower() == search.lower(),
+ lambda r: search.lower() in r.name.lower(),
+ lambda r: search.lower() in repo.description.lower(),
+ ]
+ for check in checks:
+ for repo in repos:
+ if check(repo):
+ return repo
+
+
+class GithubCog(object):
+ def __init__(self, bot: Bot):
+ self.bot: Bot = bot
+
+ @group(invoke_without_subcommand=True)
+ async def github(self, ctx: CommandContext):
+ pass
+
+ github: Group = github
+
+ @github.command()
+ async def me(self, ctx: CommandContext):
+ user: NamedUser = github.get_user()
+ embed = Embed(
+ color=Color.blurple(),
+ title=user.login,
+ description=user.bio,
+ url=user.url,
+ )
+ embed.add_field(name='Followers', value=user.followers)
+ embed.add_field(name='Following', value=user.following)
+ embed.add_field(name='Repositories',
+ value=f'[{user.public_repos + user.total_private_repos}](https://github.com/{user.login})')
+ embed.set_thumbnail(url=user.avatar_url)
+ await ctx.send(embed=embed)
+
+ @github.command()
+ async def repo(self, ctx: CommandContext, *, search):
+ repo = find_repo(search)
+ print(repo)
+ print(search)
+ if repo:
+ embed = Embed(
+ title=repo.id,
+ description=repo.description,
+ url=repo.html_url
+ )
+ await ctx.send(embed=embed)
+
+
+def setup(bot: Bot):
+ bot.add_cog(GithubCog(bot))
diff --git a/modules/pypi.py b/modules/pypi.py
new file mode 100644
index 0000000..eebd3be
--- /dev/null
+++ b/modules/pypi.py
@@ -0,0 +1,48 @@
+import re
+from subprocess import Popen, PIPE
+from typing import List
+from typing import Pattern
+
+from discord import Message, Embed, Color
+from discord.ext.commands import Bot, Context as CommandContext, command
+
+matcher: Pattern = re.compile(r'(?P<name>\w+)[^(]+\((?P<version>[^)]+)\)[^\-]+(?P<description>.*)')
+
+
+class PyPiCog(object):
+ def __init__(self, bot: Bot):
+ self.bot: Bot = bot
+
+ @command()
+ async def pypi(self, ctx: CommandContext, search, *, text=''):
+ message: Message = ctx.message
+ proc = Popen(['pip', 'search', search], stdout=PIPE, stderr=PIPE)
+ if proc.wait() != 0:
+ await message.edit(
+ embed=Embed(
+ color=Color.red(),
+ description='Failed to search for `{search}` on pypi.'))
+ stdout, _ = proc.communicate()
+ stdout = stdout.decode(encoding='utf-8')
+ lines: List[str] = stdout.split('\n')
+ content = lines[0] + ' '.join(line.strip() for line in lines[1:] if line.startswith(' '))
+ match = matcher.match(content)
+ if not match:
+ await message.edit(
+ embed=Embed(
+ color=Color.dark_orange(),
+ description=f"Weird response format:```\n{stdout[:512]}```"))
+ name = match.group("name")
+ version = match.group("version")
+ description = match.group("description")
+ await message.edit(
+ content=text,
+ embed=Embed(
+ title=name,
+ url=f"https://pypi.org/project/{name}/",
+ description=description
+ ).set_footer(text=version))
+
+
+def setup(bot: Bot):
+ bot.add_cog(PyPiCog(bot))
diff --git a/modules/ragequit.py b/modules/ragequit.py
new file mode 100644
index 0000000..aaf43f8
--- /dev/null
+++ b/modules/ragequit.py
@@ -0,0 +1,17 @@
+from discord import Guild
+from discord.ext.commands import Bot, command, Context as CommandContext, guild_only
+
+
+class RageQuitCog(object):
+ def __init__(self, bot: Bot):
+ self.bot: Bot = bot
+
+ @command()
+ @guild_only()
+ async def ragequit(self, ctx: CommandContext):
+ guild: Guild = ctx.guild
+ await guild.leave()
+
+
+def setup(bot: Bot):
+ bot.add_cog(RageQuitCog(bot))