base commit
This commit is contained in:
parent
7e7f2d959c
commit
39026bb4e0
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
config.ini
|
||||
__pycache__
|
35
code/bot.py
Normal file
35
code/bot.py
Normal file
@ -0,0 +1,35 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import os
|
||||
|
||||
from validate_config import create_config
|
||||
from global_variables import LOG, BOT_TOKEN
|
||||
|
||||
|
||||
class MyBot(commands.Bot):
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
command_prefix="***",
|
||||
activity=discord.Game(name='music!'),
|
||||
intents=discord.Intents.default(),
|
||||
)
|
||||
|
||||
async def setup_hook(self):
|
||||
create_config()
|
||||
for ext in os.listdir("./code/cogs"):
|
||||
if ext.endswith(".py"):
|
||||
await self.load_extension(f"cogs.{ext[:-3]}")
|
||||
|
||||
|
||||
bot = MyBot()
|
||||
bot.count_hold = 0
|
||||
bot.remove_command("help")
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
LOG.info(f"{bot.user} has connected to Discord.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
bot.run(BOT_TOKEN)
|
36
code/cogs/cog_commands.py
Normal file
36
code/cogs/cog_commands.py
Normal file
@ -0,0 +1,36 @@
|
||||
from discord.ext import commands
|
||||
|
||||
from global_variables import BOT_COLOR
|
||||
|
||||
|
||||
class ReloadCog(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command()
|
||||
@commands.dm_only()
|
||||
@commands.is_owner()
|
||||
async def reloadcog(self, ctx: commands.Context, cog: str = None):
|
||||
if not cog:
|
||||
return await ctx.send("No cog provided.")
|
||||
|
||||
cog = cog.lower()
|
||||
await self.bot.reload_extension(f"cogs.{cog}")
|
||||
|
||||
await ctx.send(f"Cog {cog} has been reloaded")
|
||||
|
||||
@commands.command()
|
||||
@commands.dm_only()
|
||||
@commands.is_owner()
|
||||
async def loadcog(self, ctx: commands.Context, cog: str = None):
|
||||
if not cog:
|
||||
return await ctx.send("No cog provided.")
|
||||
|
||||
cog = cog.lower()
|
||||
await self.bot.load_extension(f"cogs.{cog}")
|
||||
|
||||
await ctx.send(f"Cog {cog} has been loaded")
|
||||
|
||||
|
||||
async def setup(bot):
|
||||
await bot.add_cog(ReloadCog(bot))
|
34
code/cogs/tree_sync.py
Normal file
34
code/cogs/tree_sync.py
Normal file
@ -0,0 +1,34 @@
|
||||
from discord.ext import commands
|
||||
from discord import Object
|
||||
|
||||
|
||||
class TreeSync(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
|
||||
@commands.command()
|
||||
@commands.dm_only()
|
||||
@commands.is_owner()
|
||||
async def sync(self, ctx: commands.Context, *, guild: Object = None) -> None:
|
||||
if not guild or guild == None:
|
||||
await self.bot.tree.sync()
|
||||
await ctx.author.send("Synced commands globally")
|
||||
return
|
||||
|
||||
elif guild != None:
|
||||
self.bot.tree.copy_global_to(guild=guild)
|
||||
await self.bot.tree.sync(guild=guild)
|
||||
|
||||
await ctx.author.send(f"Synced the tree to 1 test guild.")
|
||||
|
||||
@sync.error
|
||||
async def error_sync(self, ctx, error):
|
||||
if isinstance(error, commands.errors.PrivateMessageOnly):
|
||||
pass
|
||||
else:
|
||||
await ctx.author.send("That is not a valid guild ID")
|
||||
|
||||
|
||||
async def setup(bot):
|
||||
await bot.add_cog(TreeSync(bot))
|
45
code/cogs/user_count.py
Normal file
45
code/cogs/user_count.py
Normal file
@ -0,0 +1,45 @@
|
||||
from discord.ext import commands
|
||||
import discord
|
||||
|
||||
from global_variables import BOT_COLOR
|
||||
|
||||
|
||||
class UserCount(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command()
|
||||
@commands.dm_only()
|
||||
@commands.is_owner()
|
||||
async def info(self, ctx: commands.Context):
|
||||
total_guilds = {}
|
||||
|
||||
for guild in self.bot.guilds:
|
||||
total_guilds[guild.name] = guild.member_count
|
||||
|
||||
# Sort the dictionary by value descending
|
||||
total_guilds = dict(
|
||||
sorted(total_guilds.items(), key=lambda item: item[1], reverse=True)
|
||||
)
|
||||
|
||||
total_members = 0
|
||||
|
||||
for guild in total_guilds:
|
||||
total_members += total_guilds[guild]
|
||||
|
||||
embed = discord.Embed(
|
||||
title="User Count",
|
||||
description=f"Total Members: `{total_members:,}`\nTotal Guilds: `{len(self.bot.guilds):,}`",
|
||||
color=BOT_COLOR,
|
||||
)
|
||||
# Add the top 5 guilds to the embed
|
||||
for guild in list(total_guilds)[:5]:
|
||||
embed.add_field(
|
||||
name=guild, value=f"```{total_guilds[guild]:,}```", inline=False
|
||||
)
|
||||
|
||||
await ctx.send(embed=embed)
|
||||
|
||||
|
||||
async def setup(bot):
|
||||
await bot.add_cog(UserCount(bot))
|
56
code/global_variables.py
Normal file
56
code/global_variables.py
Normal file
@ -0,0 +1,56 @@
|
||||
import configparser
|
||||
import logging
|
||||
from colorlog import ColoredFormatter
|
||||
import discord
|
||||
|
||||
|
||||
log_level = logging.DEBUG
|
||||
log_format = (
|
||||
" %(log_color)s%(levelname)-8s%(reset)s | %(log_color)s%(message)s%(reset)s"
|
||||
)
|
||||
|
||||
logging.root.setLevel(log_level)
|
||||
formatter = ColoredFormatter(log_format)
|
||||
|
||||
stream = logging.StreamHandler()
|
||||
stream.setLevel(log_level)
|
||||
stream.setFormatter(formatter)
|
||||
|
||||
LOG = logging.getLogger("pythonConfig")
|
||||
LOG.setLevel(log_level)
|
||||
LOG.addHandler(stream)
|
||||
|
||||
try:
|
||||
with open("config.ini", "r") as f:
|
||||
file_contents = f.read()
|
||||
except FileNotFoundError:
|
||||
config = configparser.ConfigParser()
|
||||
config["BOT_INFO"] = {
|
||||
"TOKEN": "",
|
||||
"BOT_COLOR": "",
|
||||
}
|
||||
|
||||
config["LAVALINK"] = {
|
||||
"HOST": "",
|
||||
"PORT": "",
|
||||
"PASSWORD": ""
|
||||
}
|
||||
|
||||
with open("config.ini", "w") as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
LOG.error(
|
||||
"Configuration file `config.ini` has been generated. Please fill out all of the necessary information. Refer to the docs for information on what a specific configuration option is."
|
||||
)
|
||||
exit()
|
||||
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read_string(file_contents)
|
||||
|
||||
BOT_TOKEN = config["BOT_INFO"]["TOKEN"]
|
||||
BOT_COLOR = discord.Color(int((config["BOT_INFO"]["BOT_COLOR"]).replace("#", ""), 16))
|
||||
|
||||
LAVALINK_HOST = config["LAVALINK"]["HOST"]
|
||||
LAVALINK_PORT = config["LAVALINK"]["PORT"]
|
||||
LAVALINK_PASSWORD = config["LAVALINK"]["PASSWORD"]
|
78
code/validate_config.py
Normal file
78
code/validate_config.py
Normal file
@ -0,0 +1,78 @@
|
||||
import configparser
|
||||
import re
|
||||
|
||||
from global_variables import LOG
|
||||
|
||||
|
||||
pattern_1 = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"
|
||||
pattern_2 = "^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"
|
||||
|
||||
|
||||
def validate_config(file_contents):
|
||||
config = configparser.ConfigParser()
|
||||
config.read_string(file_contents)
|
||||
|
||||
errors = 0
|
||||
|
||||
try:
|
||||
# Validate TOKEN
|
||||
if not config["BOT_INFO"]["TOKEN"]:
|
||||
LOG.critical("TOKEN has not been set.")
|
||||
errors += 1
|
||||
# Validate BOT_COLOR
|
||||
if not config["BOT_INFO"]["BOT_COLOR"]:
|
||||
LOG.critical("BOT_COLOR has not been set.")
|
||||
errors += 1
|
||||
|
||||
elif not bool(
|
||||
re.match(pattern_1, config["BOT_INFO"]["BOT_COLOR"])
|
||||
) and not bool(re.match(pattern_2, config["BOT_INFO"]["BOT_COLOR"])):
|
||||
LOG.critical("BOT_COLOR is not a valid hex color.")
|
||||
errors += 1
|
||||
|
||||
# Validate LAVALINK
|
||||
# Validate HOST
|
||||
if not config["LAVALINK"]["HOST"]:
|
||||
LOG.critical("HOST has not been set.")
|
||||
errors += 1
|
||||
# Validate PORT
|
||||
if not config["LAVALINK"]["PORT"]:
|
||||
LOG.critical("PORT has not been set.")
|
||||
errors += 1
|
||||
# Validate PASSWORD
|
||||
if not config["LAVALINK"]["PASSWORD"]:
|
||||
LOG.critical("HOST has not been set.")
|
||||
errors += 1
|
||||
|
||||
else:
|
||||
LOG.info("Configuration checks passed. Starting bot.")
|
||||
|
||||
except KeyError:
|
||||
LOG.critical(
|
||||
"You are missing at least one of the configuration options from your config.ini file. In order to regenerate this file with all of the proper options, please delete it and re-run the `bot.py` file."
|
||||
)
|
||||
exit()
|
||||
|
||||
|
||||
def create_config():
|
||||
try:
|
||||
with open("config.ini", "r") as f:
|
||||
file_contents = f.read()
|
||||
validate_config(file_contents)
|
||||
|
||||
except FileNotFoundError:
|
||||
config = configparser.ConfigParser()
|
||||
config["BOT_INFO"] = {
|
||||
"TOKEN": "",
|
||||
"BOT_COLOR": "",
|
||||
}
|
||||
|
||||
config["LAVALINK"] = {"HOST": "", "PORT": "", "PASSWORD": ""}
|
||||
|
||||
with open("config.ini", "w") as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
LOG.error(
|
||||
"Configuration file `config.ini` has been generated. Please fill out all of the necessary information. Refer to the docs for information on what a specific configuration option is."
|
||||
)
|
||||
exit()
|
Loading…
x
Reference in New Issue
Block a user