main: set up basic bot without commands
All checks were successful
/ test (push) Successful in 19s

As the summary says, this sets up a basic bot that doesn't listen to
any commands yet; the bot just runs and does nothing.

Signed-off-by: Max R. Carrara <max@aequito.sh>
This commit is contained in:
Max R. Carrara 2025-03-10 23:58:21 +01:00
parent ba829254d8
commit 663abf56bc

View file

@ -1,6 +1,189 @@
def main(): import asyncio
print("Hello world!") import logging
import logging.handlers
import os
import sys
if __name__ == "__main__": import discord
main() from discord.ext import commands
from bot.env import Environment
_log: logging.Logger
def setup_logging() -> logging.Logger:
root_logger = logging.getLogger(__name__)
log_level_map = {
"NOTSET": logging.NOTSET,
"DEBUG": logging.DEBUG,
"INFO": logging.INFO,
"WARNING": logging.WARNING,
"ERROR": logging.ERROR,
"CRITICAL": logging.CRITICAL,
}
env_log_level = Environment.bot_log_level()
log_level: int = log_level_map.get(env_log_level, logging.INFO)
root_logger.setLevel(log_level)
dt_fmt = "%Y-%m-%d %H:%M:%S"
log_formatter = logging.Formatter(
"[{asctime}] [{levelname}] {name}: {message}", dt_fmt, style="{"
)
# Log everything to rotating files
log_file_handler = logging.handlers.RotatingFileHandler(
filename="bot.log", encoding="utf-8", maxBytes=32 * 1024 * 1024, backupCount=5
)
log_file_handler.setFormatter(log_formatter)
root_logger.addHandler(log_file_handler)
# Log everything to stderr also
log_stream_handler = logging.StreamHandler()
log_stream_handler.setFormatter(log_formatter)
root_logger.addHandler(log_stream_handler)
# Also log errors to a separate file for easier debugging
log_error_file_handler = logging.FileHandler(
filename="bot_err.log", encoding="utf-8"
)
log_error_file_handler.setFormatter(log_formatter)
log_error_file_handler.setLevel(logging.ERROR)
root_logger.addHandler(log_error_file_handler)
return root_logger
def setup_bot() -> commands.Bot:
intents = discord.Intents.all()
desc_paragraphs = [
"""Der VW Phaeton ist eine viertürige Stufenheck-Limousine der Oberklasse
der Marke Volkswagen. Die Herstellung war ein Gemeinschaftsprojekt des
Volkswagenwerks Zwickau mit der Gläsernen Manufaktur Dresden, wo die
Endmontage großteils in Handarbeit erfolgte. Vom Produktionsstart am
11. Dezember 2001 bis zum Produktionsende am 18. März 2016 wurden
84.235 Fahrzeuge gebaut.""",
"""In der Nacht zum 11. Oktober 2008 kam Haider in Lambichl im Südwesten
der Landeshauptstadt Klagenfurt (Lage) auf der Loiblpass-Straße bei
einem Verkehrsunfall ums Leben. Nach dem Besuch mehrerer
Veranstaltungen und Gaststätten hatte sich Haider, stark alkoholisiert
(1,8 Blutalkoholkonzentration), allein auf den Weg zu seinem Haus im
Bärental gemacht. Nach Angaben des Leiters der Staatsanwaltschaft
Klagenfurt fuhr Haider bei Nebel mit stark überhöhter Geschwindigkeit
mit seinem Dienstwagen VW Phaeton V6.""",
]
description = "\n\n".join(
" ".join(line.strip() for line in paragraph) for paragraph in desc_paragraphs
)
command_prefix = Environment.bot_prefix()
return commands.Bot(
command_prefix=command_prefix, description=description, intents=intents
)
def read_token_file() -> str:
bot_token_path = Environment.bot_token_path()
if not bot_token_path.exists():
raise FileNotFoundError(
f'Cannot read bot token - path "{bot_token_path}" does not exist'
)
try:
token = bot_token_path.read_text("utf-8").strip()
return token
except Exception as e:
_log.error(
'Failed to read token from path "{bot_token_path}"', exc_info=sys.exc_info()
)
raise e
bot = setup_bot()
@bot.event
async def on_error(event: str, *args, **kwargs):
_log.error(
f"Encountered unexpected exception while processing event {event} ({args = }; {kwargs = }):",
exc_info=sys.exc_info(),
)
@bot.event
async def on_ready():
_log.info("Ready: Connected to Discord")
@bot.event
async def on_resumed():
_log.info("Resumed: Session with Discord resumed")
@bot.event
async def on_shard_ready(shard_id: int):
_log.info(f"Ready: Shard ID {shard_id} connected to Discord")
@bot.event
async def on_shard_resumed(shard_id: int):
_log.info(f"Resumed: Shard ID {shard_id} resumed session with Discord")
@bot.event
async def on_message(message: discord.Message):
_log.debug(f"Read message ({message.id = }): {message.content}")
@bot.event
async def on_command(ctx: commands.Context):
_log.debug(
f"Command invoked:"
f" {ctx.command = }; {ctx.message.author = }; {ctx.message.id = }"
)
@bot.event
async def on_command_completion(ctx: commands.Context):
_log.debug(
f"Command completed:"
f" {ctx.command = }; {ctx.message.author = }; {ctx.message.id = }"
)
@bot.event
async def on_command_error(ctx: commands.Context, error: commands.CommandError):
_log.error(
f"Failed to run command:"
f" {ctx.command = }; {ctx.message.author = }; {ctx.message.id = }",
exc_info=error,
)
async def main():
_log.debug("Entered main()")
token = read_token_file()
async with bot:
await bot.start(token=token, reconnect=True)
_log = setup_logging()
_log.debug("Logging initialised")
_log.debug(f"{sys.argv = }")
_log.debug(f"{os.getcwd() = }")
asyncio.run(main())