Added slash-commands to reload all cogs aswell as print general information

This commit is contained in:
2024-10-12 23:44:42 +02:00
parent 57282d9c56
commit 709f5df4db
8 changed files with 154 additions and 1 deletions
+2 -1
View File
@@ -1,2 +1,3 @@
[DISCORD] [DISCORD]
TOKEN = <PLACE YOUR DISCORD TOKEN FROM THE DEV PORTAL HERE> TOKEN = <PLACE YOUR DISCORD TOKEN FROM THE DEV PORTAL HERE>
OWNER_ID = <PLACE THE USER ID OF THE OWNER HERE>
+45
View File
@@ -0,0 +1,45 @@
import discord
from discord import app_commands
from discord.ext import commands
from cogs.base_cog import Base_Cog
import logging
from utils.portal import Portal
class About_Command(Base_Cog):
def __init__(self, bot:commands.Bot):
self.__bot = bot
super().__init__(logging.getLogger("cmds.about"))
@app_commands.command(name = "about", description = "Provides general information about the bot")
async def about(self, ctx: discord.Interaction):
portal:Portal = Portal.instance()
embed = discord.Embed(title=f"POST IT - `{portal.PROGRAM_VERSION}`",
description="### Übersicht der Befehle\n- `/post` Veröffentlicht einen Post einer anderen Plattform, mit beliebigen Bildern als Anhang\n- `/help` Zeigt diese Übersicht an\n- `/settings` Persönliche Einstellungen für das verhalten des Bots\n- `/stats` Zeigt persönliche und globale Statistiken\n- `/debug` Erweiterte Informationen zum Betriebszustandes des Bots",
colour=0x5a5a5a)
embed.add_field(name="Status des Bots",
value="Fehlerfrei :green_circle:",
inline=True)
embed.add_field(name="Besitzer der Bot Instanz",
value=f"<@{portal.bot_config['DISCORD']['OWNER_ID']}>",
inline=True)
await ctx.response.send_message(embed = embed, ephemeral = True)
async def setup(bot:commands.Bot):
await bot.add_cog(About_Command(bot))
# class AddCog(commands.Cog):
# def __init__(self, bot):
# self.bot = bot
# @app_commands.command(name="add", description="Füge ein neues Wort zur Liste hinzu")
# async def add(self, interaction: discord.Interaction, new_word: str):
# if new_word.lower() not in self.bot.known_words:
# self.bot.known_words.append(new_word.lower())
# await interaction.response.send_message(f"Wort '{new_word}' wurde zur Liste hinzugefügt.")
# else:
# await interaction.response.send_message(f"Wort '{new_word}' existiert bereits.")
# async def setup(bot):
# await bot.add_cog(AddCog(bot))
+14
View File
@@ -0,0 +1,14 @@
import discord
from discord import app_commands
from discord.ext import commands
import logging
class Base_Cog(commands.Cog):
def __init__(self, logger:logging.Logger):
self._logger = logger
async def cog_load(self):
self._logger.debug(f"Cog for the '{self.__class__.__name__}' command got loaded")
async def cog_unload(self):
self._logger.debug(f"Cog for the '{self.__class__.__name__}' command got unloaded")
+25
View File
@@ -0,0 +1,25 @@
import discord
from discord import app_commands
from discord.ext import commands
from cogs.base_cog import Base_Cog
import logging
from datetime import datetime
class Reload_Command(Base_Cog):
def __init__(self, bot:commands.Bot):
self.__bot = bot
super().__init__(logging.getLogger("cmds.reload"))
@app_commands.command(name = "reload_all", description = "Reloads all cogs")
async def about(self, ctx: discord.Interaction):
self._logger.info("Reloading all cogs ...")
task_start = datetime.now().timestamp()
cog_names = list(self.__bot.extensions.keys())
for extension_name in cog_names:
await self.__bot.reload_extension(extension_name)
await ctx.response.send_message("Cogs successfully reloaded.")
async def setup(bot:commands.Bot):
await bot.add_cog(Reload_Command(bot))
+19
View File
@@ -14,6 +14,9 @@ import discord
from discord.ext import commands from discord.ext import commands
from pathlib import Path from pathlib import Path
import re import re
import sys
import traceback
from utils.portal import Portal
source_path = Path(__file__).resolve() source_path = Path(__file__).resolve()
base_path = source_path.parents[1] base_path = source_path.parents[1]
@@ -26,6 +29,12 @@ class MyBot(commands.Bot):
def __init__(self): def __init__(self):
super().__init__(command_prefix=None, help_command=None, intents=intents) super().__init__(command_prefix=None, help_command=None, intents=intents)
async def setup_hook(self):
# Register cogs to handle commands
for cog_name in ["about", "reload"]:
await self.load_extension(f"cogs.{cog_name}")
await self.tree.sync()
bot = MyBot() bot = MyBot()
bot_config = Advanced_ConfigParser(Path.joinpath(base_path, "config", "bot.ini")) bot_config = Advanced_ConfigParser(Path.joinpath(base_path, "config", "bot.ini"))
if re.match(r'[A-Za-z\d]{24}\.[\w-]{6}\.[\w-]{27}', bot_config["DISCORD"]["TOKEN"]): if re.match(r'[A-Za-z\d]{24}\.[\w-]{6}\.[\w-]{27}', bot_config["DISCORD"]["TOKEN"]):
@@ -41,6 +50,16 @@ else:
async def on_ready(): async def on_ready():
app_logger.info(f"Successfully logged in (after {get_elapsed_time_smal(datetime.now().timestamp() - startup)}) as {bot.user}") app_logger.info(f"Successfully logged in (after {get_elapsed_time_smal(datetime.now().timestamp() - startup)}) as {bot.user}")
@bot.tree.error
async def on_app_command_error(ctx, error):
# Traceback für mehr Informationen zum Fehler
print('Ignoring exception in command {}:'.format(ctx.command), file=sys.stderr)
traceback.print_exception(type(error), error, error.__traceback__)
# Execute some housekeeping actions
portal = Portal.instance()
portal.bot_config = bot_config
try: try:
bot.run(bot_config["DISCORD"]["TOKEN"], log_handler = None) bot.run(bot_config["DISCORD"]["TOKEN"], log_handler = None)
except discord.errors.LoginFailure: except discord.errors.LoginFailure:
+5
View File
@@ -28,5 +28,10 @@ class Custom_Logger:
utils_logger.addHandler(cls.console_handler) utils_logger.addHandler(cls.console_handler)
utils_logger.setLevel(logging.DEBUG) utils_logger.setLevel(logging.DEBUG)
commands_logger = logging.getLogger("cmds")
commands_logger.addHandler(cls.console_handler)
commands_logger.setLevel(logging.DEBUG)
logging.getLogger('discord.app_commands.tree').setLevel(logging.DEBUG)
app_logger.debug("Logging successfully initialized") app_logger.debug("Logging successfully initialized")
+6
View File
@@ -0,0 +1,6 @@
from utils.singleton import Singleton
@Singleton
class Portal:
PROGRAM_VERSION = "0.1"
bot_config = None
+38
View File
@@ -0,0 +1,38 @@
class Singleton:
"""
A non-thread-safe helper class to ease implementing singletons.
This should be used as a decorator -- not a metaclass -- to the
class that should be a singleton.
The decorated class can define one `__init__` function that
takes only the `self` argument. Also, the decorated class cannot be
inherited from. Other than that, there are no restrictions that apply
to the decorated class.
To get the singleton instance, use the `instance` method. Trying
to use `__call__` will result in a `TypeError` being raised.
"""
# Source: https://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons
def __init__(self, decorated):
self._decorated = decorated
def instance(self):
"""
Returns the singleton instance. Upon its first call, it creates a
new instance of the decorated class and calls its `__init__` method.
On all subsequent calls, the already created instance is returned.
"""
try:
return self._instance
except AttributeError:
self._instance = self._decorated()
return self._instance
def __call__(self):
raise TypeError('Singletons must be accessed through `instance()`.')
def __instancecheck__(self, inst):
return isinstance(inst, self._decorated)