commit 2ccb1e6bbc6e4ead93542f983384de4e7c642e4a Author: Nemika <33802693+Nemijus@users.noreply.github.com> Date: Sun Mar 7 20:55:27 2021 +0200 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..510c73d --- /dev/null +++ b/.gitignore @@ -0,0 +1,114 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..61de2b7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.pythonPath": "C:\\Users\\mmnem\\AppData\\Local\\Programs\\Python\\Python39\\python.exe" +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..51d9913 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Nemika + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..79006a5 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# BytesBump + A bump bot written in Discord.py! diff --git a/cogs/handler.py b/cogs/handler.py new file mode 100644 index 0000000..7bb43bd --- /dev/null +++ b/cogs/handler.py @@ -0,0 +1,26 @@ +import discord +from core import embeds + +commands = discord.ext.commands + +class ErrorHandler(commands.Cog): + def __init__(self, bot): + self.bot = bot + + @commands.Cog.listener() + async def on_command_error(self, ctx, error): + if isinstance(error, commands.MissingRequiredArgument): + return await ctx.send(embed=embeds.Embeds(f"Missing `{error.param}` as a required argument.").error()) + elif isinstance(error, commands.CommandNotFound): + return + elif isinstance(error, commands.CheckAnyFailure): + return await ctx.send(embed=embeds.Embeds("You are not allowed to do this.").error()) + elif isinstance(error, commands.CommandOnCooldown): + seconds = error.retry_after + return await ctx.send(embed=embeds.Embeds(f"**You are on cooldown!** You can use this command again in **{seconds} seconds**.").error()) + else: + await ctx.send(embed=embeds.Embeds("There was an error executing this command.").error(Error=error)) + raise error + +def setup(bot): + bot.add_cog(ErrorHandler(bot)) \ No newline at end of file diff --git a/core/asyncHandler.py b/core/asyncHandler.py new file mode 100644 index 0000000..105b4df --- /dev/null +++ b/core/asyncHandler.py @@ -0,0 +1,6 @@ +import aiohttp + +async def get(url, json=True): + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + return (await response.json()) if json else (await response.text()) \ No newline at end of file diff --git a/core/checks.py b/core/checks.py new file mode 100644 index 0000000..1a1fb87 --- /dev/null +++ b/core/checks.py @@ -0,0 +1,9 @@ +from .files import Data +from discord.ext import commands + +config = Data("config").yaml_read() + +def manager(): + def predicate(ctx): + return ctx.author.id in config["managers"] + return commands.check(predicate) \ No newline at end of file diff --git a/core/embeds.py b/core/embeds.py new file mode 100644 index 0000000..a0946cf --- /dev/null +++ b/core/embeds.py @@ -0,0 +1,33 @@ +import random +from discord import Embed, Color + +class Embeds: + def __init__(self, message): + self.message = message + + def success(self, **kwargs): + embed = Embed( + description=self.message, + color=Color.green() + ) + for i in kwargs: + embed.add_field(name=i.replace("_", " "), value=kwargs[i]) + return embed + + def error(self, **kwargs): + embed = Embed( + description=self.message, + color=Color.red() + ) + for i in kwargs: + embed.add_field(name=i.replace("_", " "), value=kwargs[i]) + return embed + + def warn(self, **kwargs): + embed = Embed( + description=self.message, + color=Color.orange() + ) + for i in kwargs: + embed.add_field(name=i.replace("_", " "), value=kwargs[i]) + return embed \ No newline at end of file diff --git a/core/files.py b/core/files.py new file mode 100644 index 0000000..ff47363 --- /dev/null +++ b/core/files.py @@ -0,0 +1,16 @@ +from yaml import load as yload, FullLoader +from json import load as jload +class Data: + def __init__(self, filename:str): + self.file = filename + + def yaml_read(self): + with open(f"data/{self.file}.yml", "r") as f: + return yload(f, Loader=FullLoader) + + def json_read(self): + with open(f"data/{self.file}.json", "r") as f: + return jload(f) + + def read(self): + return open(f"data/{self.file}.txt", "r").read() \ No newline at end of file diff --git a/data/config-example.yml b/data/config-example.yml new file mode 100644 index 0000000..e69de29 diff --git a/data/config.yml b/data/config.yml new file mode 100644 index 0000000..9258a66 --- /dev/null +++ b/data/config.yml @@ -0,0 +1,5 @@ +managers: +- 219567539049594880 +prefix: '=' +token: ODAzNTc1Mzc5MDgzNzg4MzQ4.YA_x5A.tU9N1ZUsbK31Yq7e28X3dSVRozE +version: '1.0' diff --git a/main.py b/main.py new file mode 100644 index 0000000..8c99d63 --- /dev/null +++ b/main.py @@ -0,0 +1,118 @@ +import discord, os, textwrap, io, traceback + +from contextlib import redirect_stdout + +from core.files import Data +from core import checks + +from discord.ext import commands + +config = Data("config").yaml_read() + +bot = commands.Bot(command_prefix=config["prefix"], case_insensitive=True, help_command=None, intents=discord.Intents.default()) + +@bot.event +async def on_ready(): + print("Bot is ready!") + +@checks.manager() +@bot.command(aliases=["e"]) +async def eval(ctx, *, body: str): + raw = False + """Evaluates a code""" + + env = { + 'bot': bot, + 'ctx': ctx, + 'channel': ctx.message.channel, + 'author': ctx.message.author, + 'guild': ctx.message.guild, + 'message': ctx.message, + } + + env.update(globals()) + + stdout = io.StringIO() + + to_compile = f'async def func():\n{textwrap.indent(body, " ")}' + + try: + exec(to_compile, env) + except Exception as e: + return await ctx.send(f'```py\n{e.__class__.__name__}: {e}\n```') + + func = env['func'] + try: + with redirect_stdout(stdout): + ret = await func() + except Exception: + value = stdout.getvalue() + await ctx.send(f'```py\n{value}{traceback.format_exc()}\n```') + else: + value = stdout.getvalue() + try: + await ctx.message.add_reaction('\u2705') + except: + pass + + if ret is None: + if value: + if raw: + await ctx.send(f"{value}") + else: + await ctx.send(f'```py\n{value}\n```') + else: + pass + +@checks.manager() +@bot.command(hidden=True) +async def load(ctx, *, module): + try: + bot.load_extension(f"cogs.{module}") + except commands.ExtensionError as e: + await ctx.send(f'{e.__class__.__name__}: {e}') + else: + embed=discord.Embed(title=f"Loaded {str(module).capitalize()}", description=f"Successfully loaded cogs.{str(module).lower()}!", color=0x2cf818) + await ctx.send(embed=embed) + +@checks.manager() +@bot.command(hidden=True) +async def unload(ctx, *, module): + try: + bot.unload_extension(f"cogs.{module}") + except commands.ExtensionError as e: + await ctx.send(f'{e.__class__.__name__}: {e}') + else: + embed=discord.Embed(title=f"Unloaded {str(module).capitalize()}", description=f"Successfully unloaded cogs.{str(module).lower()}!", color=0xeb1b2c) + await ctx.send(embed=embed) + +@checks.manager() +@bot.command(name="reload", hidden=True) +async def _reload(ctx, *, module): + try: + bot.reload_extension(f"cogs.{module}") + except commands.ExtensionError as e: + await ctx.send(f'{e.__class__.__name__}: {e}') + else: + embed=discord.Embed(title=f"Reloaded {str(module).capitalize()}", description=f"Successfully reloaded cogs.{str(module).lower()}!", color=0x00d4ff) + await ctx.send(embed=embed) + +for file in [i for i in os.listdir("cogs") if i.endswith(".py")]: + try: + bot.load_extension(f"cogs.{file[:-3]}") + print(f"Loaded {file}") + except Exception as e: + print(f"######\nFailed to load {file}: {e}\n######") + + +dirs = [i for i in [x for x in os.walk("cogs")][0][1] if i.find(".") == -1] + +for folder in dirs: + for file in [i for i in os.listdir(f"cogs/{folder}") if i.endswith(".py")]: + try: + bot.load_extension(f"cogs.{folder}.{file[:-3]}") + print(f"Loaded {file}") + except Exception as e: + print(f"######\nFailed to load {folder}.{file}: {e}\n######") + +bot.run(config["token"])