Skip to content

Commit

Permalink
🔧 Move to ini configs
Browse files Browse the repository at this point in the history
  • Loading branch information
zachlagden committed Aug 31, 2024
1 parent 5c6dbc5 commit 3b2238e
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 194 deletions.
2 changes: 1 addition & 1 deletion cogs/rickbot/cmds_botinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class RickBot_BotInfoCommands(commands.Cog):
def __init__(self, bot):
self.bot = bot

self.GITHUB_REPO = CONFIG["repo"]["url"]
self.GITHUB_REPO = CONFIG["REPO"]["url"]

if self.GITHUB_REPO is not None:
self.GITHUB_API = convert_repo_url_to_api(self.GITHUB_REPO)
Expand Down
2 changes: 1 addition & 1 deletion cogs/rickbot/cmds_botutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __init__(self, bot):
self.bot = bot

def botownercheck(ctx):
return ctx.author.id in CONFIG["devs"]
return ctx.author.id == int(CONFIG["MAIN"]["dev"])

@commands.command()
@commands.check(botownercheck)
Expand Down
2 changes: 1 addition & 1 deletion cogs/rickbot/slashcmds_botinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class RickBot_BotInfoSlashCommands(commands.Cog):
def __init__(self, bot):
self.bot = bot

self.GITHUB_REPO = CONFIG["repo"]["url"]
self.GITHUB_REPO = CONFIG["REPO"]["url"]

if self.GITHUB_REPO is not None:
self.GITHUB_API = convert_repo_url_to_api(self.GITHUB_REPO)
Expand Down
40 changes: 36 additions & 4 deletions cogs/rickbot/slashcmds_botutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

# Python standard library
import os
import subprocess

# Third-party libraries
Expand Down Expand Up @@ -37,6 +38,13 @@ def __init__(self, bot):
"""
self.bot = bot

# Check the mode in the config file
if CONFIG["MAIN"]["mode"] != "dev":
# Disable the commands if the bot is not in development mode
self.eval = self.exec = self.cmd = self.testerror = self.restart = (
self.disabled_command
)

def botownercheck(interaction: discord.Interaction) -> bool:
"""
Checks if the user who invoked the command is a bot developer.
Expand All @@ -47,7 +55,7 @@ def botownercheck(interaction: discord.Interaction) -> bool:
Returns:
bool: True if the user is a bot developer, False otherwise.
"""
return interaction.user.id in CONFIG["devs"]
return interaction.user.id == int(CONFIG["MAIN"]["dev"])

async def _send_embed(self, interaction, title, description, color):
"""
Expand Down Expand Up @@ -100,7 +108,7 @@ async def eval_error(self, interaction: discord.Interaction, error):
await self._send_embed(
interaction,
"Error",
"Only the bot developer can run this command as it is dangerous.",
"Only the bot developer can run this command.",
ERROR_EMBED_COLOR,
)
else:
Expand Down Expand Up @@ -146,7 +154,7 @@ async def exec_error(self, interaction: discord.Interaction, error):
await self._send_embed(
interaction,
"Error",
"Only the bot developer can run this command as it is dangerous.",
"Only the bot developer can run this command.",
ERROR_EMBED_COLOR,
)
else:
Expand Down Expand Up @@ -191,7 +199,7 @@ async def cmd_error(self, interaction: discord.Interaction, error):
await self._send_embed(
interaction,
"Error",
"Only the bot developer can run this command as it is dangerous.",
"Only the bot developer can run this command.",
ERROR_EMBED_COLOR,
)
else:
Expand Down Expand Up @@ -235,6 +243,30 @@ async def testerror_error(self, interaction: discord.Interaction, error):
# Handle other errors using the global error handler
await handle_error(interaction, error)

@app_commands.command(
name="restart", description="Restart the bot. Restricted to bot developers."
)
@commands.check(botownercheck)
async def restart(self, interaction: discord.Interaction):
"""
Restarts the bot.
Args:
ctx (commands.Context): The context of the command.
"""

if not CONFIG["advanced"]["linux_service_name"]:
return await interaction.response.send_message(
"The Linux service name is not set in the config file.", ephemeral=True
)

await interaction.response.send_message("Restarting the bot...", ephemeral=True)

# Restart the bot using the Linux service
os.system(
"systemctl restart {}".format(CONFIG["advanced"]["linux_service_name"])
)


async def setup(bot: commands.Bot):
"""
Expand Down
24 changes: 0 additions & 24 deletions config.json

This file was deleted.

168 changes: 16 additions & 152 deletions config.py
Original file line number Diff line number Diff line change
@@ -1,160 +1,24 @@
"""
(c) 2024 Zachariah Michael Lagden (All Rights Reserved)
You may not use, copy, distribute, modify, or sell this code without the express permission of the author.
This is the config file for RickBot.
"""

# Import the required modules

# Python standard library
import json
import os
import configparser

# Helpers
from helpers.logs import RICKLOG_MAIN

# DEFAULT CONFIG

DEFAULT_CONFIG = {
"mode": "dev", # "dev" or "prod"
"devs": [123456789],
"bot": {
"token": "BOT TOKEN",
"prefix": "!",
"status": {
"type": "playing",
"message": "a game",
},
},
"behaviour": {
"continue_to_load_cogs_after_failure": False,
# "afk_timeout": 300,
},
"mongo": {
"uri": "mongodb uri",
"bot_specific_db": "bot",
},
}

# Custom Config

# Check if the customconfig.json file exists
if os.path.exists("customconfig.json"):
with open("customconfig.json", "r") as f:
CUSTOM_CONFIG = json.load(f)
else:
RICKLOG_MAIN.warning("customconfig.json file not found. Creating a new one.")
with open("customconfig.json", "w") as f:
json.dump(
{"Use this config": "To add custom config data your cogs need."},
f,
indent=2,
)
CUSTOM_CONFIG = {}


# Main Config

# Check if the config.json file exists
if os.path.exists("config.json"):
with open("config.json", "r") as f:
CONFIG = json.load(f)
else:
RICKLOG_MAIN.critical(
"config.json file not found. Bot cannot start. Creating a new one."
)
RICKLOG_MAIN.warning("Please fill in the required fields in the config.json file.")
RICKLOG_MAIN.warning(
"Once you have filled in the required fields, restart the bot to apply the changes."
)

# Create a new config.json file
with open("config.json", "w") as f:
json.dump(DEFAULT_CONFIG, f, indent=2)
CONFIG = {}

# Exit the bot
exit()

"""
Ensure the CONFIG has all the required fields
If the config.json file is missing any required fields, abort the bot and tell the user to fill in the required fields.
We can tell if any fields are missing by ensuring no fields match the default config or are empty.
"""

need_to_exit = False

# Ensure a mode is set
if CONFIG.get("mode") in [None, ""]:
RICKLOG_MAIN.critical("The 'mode' field in the config.json file is missing.")
need_to_exit = True

# Ensure the devs list is set
if CONFIG.get("devs") in [None, ""]:
RICKLOG_MAIN.critical("The 'devs' field in the config.json file is missing.")
need_to_exit = True

# Ensure the bot settings are set
bot_config = CONFIG.get("bot")

if bot_config.get("token") in [None, ""]:
RICKLOG_MAIN.critical(
"The 'token' field in the bot settings in the config.json file is missing."
)
need_to_exit = True

if bot_config.get("prefix") in [None, ""]:
RICKLOG_MAIN.critical(
"The 'prefix' field in the bot settings in the config.json file is missing."
)
need_to_exit = True

bot_config_status = bot_config.get("status")

if bot_config_status.get("type") in [None, ""]:
RICKLOG_MAIN.critical(
"The 'type' field in the bot status settings in the config.json file is missing."
)
need_to_exit = True

if bot_config_status.get("message") in [None, ""]:
RICKLOG_MAIN.critical(
"The 'message' field in the bot status settings in the config.json file is missing."
)
need_to_exit = True

# Ensure the behaviour settings are set
behaviour_config = CONFIG.get("behaviour")

if behaviour_config.get("continue_to_load_cogs_after_failure") in [None, ""]:
RICKLOG_MAIN.critical(
"The 'continue_to_load_cogs_after_failure' field in the behaviour settings in the config.json file is missing."
)
need_to_exit = True
CONFIG = configparser.ConfigParser()
CUSTOM_CONFIG = configparser.ConfigParser()

# Ensure the mongo settings are set
mongo_config = CONFIG.get("mongo")
# Ensure the config file exists
if not os.path.exists("config.ini"):
RICKLOG_MAIN.warning("Config file not found, exiting.")
exit(1)

if mongo_config.get("uri") in [None, ""]:
RICKLOG_MAIN.critical(
"The 'uri' field in the mongo settings in the config.json file is missing."
)
need_to_exit = True
# Read the config file
CONFIG.read("config.ini")

if mongo_config.get("bot_specific_db") in [None, ""]:
RICKLOG_MAIN.critical(
"The 'bot_specific_db' field in the mongo settings in the config.json file is missing."
)
need_to_exit = True
# Ensure the custom config file exists
if not os.path.exists("custom_config.ini"):
RICKLOG_MAIN.warning("Custom config file not found, creating one.")
with open("custom_config.ini", "w+") as f:
f.write("[DEFAULT]\n")

# Exit the bot if any required fields are missing
if need_to_exit:
RICKLOG_MAIN.critical(
"Bot cannot start. Please fill in the required fields in the config.json file."
)
RICKLOG_MAIN.warning(
"Once you have filled in the required fields, restart the bot to apply the changes."
)
exit()
# Read the custom config file
CUSTOM_CONFIG.read("custom_config.ini")
1 change: 1 addition & 0 deletions custom_config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[DEFAULT]
4 changes: 0 additions & 4 deletions customconfig.json

This file was deleted.

14 changes: 7 additions & 7 deletions rickbot/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class WebhookFailedError(Exception):


def get_prefix(bot, message):
return commands.when_mentioned_or(CONFIG["bot"]["prefix"])(bot, message)
return commands.when_mentioned_or(CONFIG["BOT"]["prefix"])(bot, message)


# Classes
Expand Down Expand Up @@ -80,7 +80,7 @@ def setup_logging(self):
setup_discord_logging(logging.INFO)

def load_config(self):
if CONFIG["mode"] == "dev":
if CONFIG["MAIN"]["mode"] == "dev":
RICKLOG.setLevel(logging.DEBUG)
else:
RICKLOG.setLevel(logging.INFO)
Expand Down Expand Up @@ -127,8 +127,8 @@ async def set_status(self):
Update the bot's status based on the configuration file.
"""

status_type = CONFIG["bot"]["status"]["type"]
message = CONFIG["bot"]["status"]["message"]
status_type = CONFIG["BOT"]["status_type"]
message = CONFIG["BOT"]["status_text"]

if status_type == "playing":
await self.change_presence(activity=discord.Game(name=message))
Expand All @@ -148,7 +148,7 @@ async def set_status(self):
)

elif status_type == "streaming":
url = CONFIG["bot"]["status"]["url"]
url = CONFIG["BOT"]["status_url"]
await self.change_presence(
activity=discord.Streaming(name=message, url=url)
)
Expand All @@ -169,7 +169,7 @@ async def on_message(self, message):
f"<@{self.user.id}>" # type: ignore
):
await message.reply(
f"Hey there, {message.author.mention}! Use `{CONFIG['bot']['prefix']}help` to see what I can do.",
f"Hey there, {message.author.mention}! Use `{CONFIG['BOT']['prefix']}help` to see what I can do.",
mention_author=False,
)
return
Expand All @@ -188,7 +188,7 @@ async def on_command_error(self, ctx, error):
async def start_bot(self):
try:
RICKLOG_MAIN.info("Starting RickBot...")
await self.start(CONFIG["bot"]["token"])
await self.start(CONFIG["BOT"]["token"])
finally:
RICKLOG_MAIN.info("RickBot has shut down gracefully.")

Expand Down

0 comments on commit 3b2238e

Please sign in to comment.