Added slash-commands to reload all cogs aswell as print general information
This commit is contained in:
@@ -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>
|
||||||
@@ -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 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:
|
||||||
|
|||||||
@@ -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")
|
||||||
@@ -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