Added slash-commands to reload all cogs aswell as print general information
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
[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>
|
||||
@@ -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))
|
||||
@@ -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")
|
||||
@@ -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
@@ -14,6 +14,9 @@ import discord
|
||||
from discord.ext import commands
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
from utils.portal import Portal
|
||||
|
||||
source_path = Path(__file__).resolve()
|
||||
base_path = source_path.parents[1]
|
||||
@@ -26,6 +29,12 @@ class MyBot(commands.Bot):
|
||||
def __init__(self):
|
||||
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_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"]):
|
||||
@@ -41,6 +50,16 @@ else:
|
||||
async def on_ready():
|
||||
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:
|
||||
bot.run(bot_config["DISCORD"]["TOKEN"], log_handler = None)
|
||||
except discord.errors.LoginFailure:
|
||||
|
||||
@@ -28,5 +28,10 @@ class Custom_Logger:
|
||||
utils_logger.addHandler(cls.console_handler)
|
||||
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")
|
||||
@@ -0,0 +1,6 @@
|
||||
from utils.singleton import Singleton
|
||||
|
||||
@Singleton
|
||||
class Portal:
|
||||
PROGRAM_VERSION = "0.1"
|
||||
bot_config = None
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user