Bot: Refactored DB management.

main
Abigaëlle Martin 2025-09-12 10:10:08 +02:00
parent ea9d2aa5f6
commit d8986643de
4 changed files with 207 additions and 141 deletions

View File

@ -1,19 +1,22 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import logging
# System packages
import sqlite3
from pathlib import Path
from typing import Optional, Dict
# PyPi packages
import discord
from bot.env_variable import path_sqldb
def initialize(path_sqldb: Path) -> None:
"""Initialize (if needed) the database needed by the bot.
class DBManager:
def __init__(self):
# If the table "people_words" does not exists, MarxBot creates it.
:param path_sqldb: Path where is the SQLite3 DB.
:return: None
"""
# If the table "people_words" does not exist, MarxBot creates it.
table_peoplewords = """
CREATE TABLE IF NOT EXISTS people_words(
user_id VARCHAR(100) NOT NULL,
@ -42,7 +45,14 @@ class DBManager:
connexion.commit()
connexion.close()
async def add_numberword(self, message: discord.Message) -> None:
async def add_numberword(path_sqldb: Path, message: discord.Message) -> None:
"""Add to the count of words of the message's author the number of words written in the message.
:param path_sqldb: Path where is the SQLite3 DB.
:param message: Message written by the person.
:return: None
"""
author_id = message.author.id
message_content = message.content
request = f"SELECT number_words, delta_words FROM people_words WHERE user_id={author_id};"
@ -72,7 +82,14 @@ class DBManager:
return
def get_numberwords(self, guild: discord.Guild) -> str:
def get_numberwords(path_sqldb: Path, guild: discord.Guild) -> str:
"""Get the number of words that have been said by people, resets the delta number of words since the last time.
:param path_sqldb: Path where is the SQLite3 DB.
:param guild: The server in which are the people, to get their pseudonyms.
:return:
"""
request = "SELECT user_id, number_words, delta_words FROM people_words ORDER BY number_words DESC;"
numberwords_str = "```\nStatistique du nombre de mots écrits:\n"
@ -94,8 +111,15 @@ class DBManager:
numberwords_str += "```"
return numberwords_str
def get_citation(self, author: Optional[str]) -> str:
# Request to have one random entry in the table "citation".
def get_citation(path_sqldb: Path, author: Optional[str]) -> str:
"""Request to have one random entry in the table "citation".
:param path_sqldb: Path where is the SQLite3 DB.
:param author: Optional name of the author of the citation requested.
:return: A random citation.
"""
assert author is None or author in ["Karl Marx", "Kadoc"]
author_option = ""
if author is not None:
@ -118,7 +142,15 @@ class DBManager:
return citation_str
def add_birthday(self, birthday_id: str, birthday_date: str) -> None:
def add_birthday(path_sqldb: Path, birthday_id: str, birthday_date: str) -> None:
"""Add the birthdate of someone.
:param path_sqldb: Path where is the SQLite3 DB.
:param birthday_id: ID of the person.
:param birthday_date: Birthdate of the person.
:return: None
"""
connexion = sqlite3.connect(path_sqldb)
cursor = connexion.cursor()
@ -131,7 +163,14 @@ class DBManager:
connexion.commit()
connexion.close()
def delete_birthday(self, birthday_id: str) -> None:
def delete_birthday(path_sqldb: Path, birthday_id: str) -> None:
"""Delete the birthday information of someone from the DB.
:param path_sqldb: Path where is the SQLite3 DB.
:param birthday_id: ID of the person.
:return: None
"""
connexion = sqlite3.connect(path_sqldb)
cursor = connexion.cursor()
@ -140,14 +179,21 @@ class DBManager:
connexion.commit()
connexion.close()
def get_all_birthday(self) -> Dict[str, str]:
def get_all_birthday(path_sqldb: Path) -> Dict[str, str]:
"""Prints all the birthday in the DB.
:param path_sqldb: Path where is the SQLite3 DB.
:param guild: The server in which are the people, to get their pseudonyms.
:return: None
"""
request = "SELECT birthday_id, birthday_txt FROM birthday ORDER BY birthday_id;"
birthday: Dict[str, str] = {}
connexion = sqlite3.connect(path_sqldb)
cursor = connexion.cursor()
for birthday_id, birthday_txt in cursor.execute(request).fetchall():
birthday[birthday_id] = birthday_txt
for user_id, birthday_txt in cursor.execute(request).fetchall():
birthday[user_id] = birthday_txt
connexion.close()
return birthday

View File

@ -1,7 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
path_project = "/home/toshuumilia/marxbot/"
path_sqldb = path_project + "marxbot.sqlite"
path_log = path_project + "marxbot.log"

View File

@ -1,16 +1,26 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# System packages
import json
import logging
import sys
from pathlib import Path
from typing import Dict, Any
# PyPi packages
import discord
from bot.env_variable import path_log
# Project packages
from bot.marxbot import MarxBot
if __name__ == '__main__':
# Activating logging
def setup_logger(path_log: Path) -> None:
"""Setup of the logger to keep logs in the given file.
:param path_log: Path to file where the logs should be kept.
:return: None
"""
logging.basicConfig(filename=path_log, filemode="a+", level=logging.INFO,
format="[%(asctime)s][%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
handler = logging.StreamHandler(sys.stdout)
@ -18,14 +28,22 @@ if __name__ == '__main__':
handler.setFormatter(logging.Formatter('[%(asctime)s][%(levelname)s] %(message)s'))
logging.getLogger().addHandler(handler)
# Launching MarxBot
if __name__ == '__main__':
# Load the bot configuration.
with open(Path("configuration.json"), "r") as file_config:
botconfig: Dict[str, Any] = json.loads(file_config.read())
# Activate the logs
setup_logger(Path(botconfig["path_root"]) / botconfig["path_log"])
# Launch MarxBot
logging.info("MarxBot is launching.")
token = sys.argv[1]
intents = discord.Intents.all()
client = MarxBot(dev_marx=False, intents=intents)
client = MarxBot(botconfig=botconfig, intents=intents)
try:
client.run(token)
client.run(botconfig["token"])
except Exception:
logging.error("Something went bad !", exc_info=True)
raise

View File

@ -1,19 +1,29 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# System packages
import logging
from pathlib import Path
from typing import Dict, Any
# PyPi packages
import discord
from bot.dbmanager import DBManager
import bot.dbmanager as dbmanager
class MarxBot(discord.Client):
def __init__(self, dev_marx: bool = False, *args, **kwargs):
def __init__(self, botconfig: Dict[str, Any], *args, **kwargs):
super().__init__(*args, **kwargs)
self.dbmanager = DBManager()
# Paths for various information.
self.path_root: Path = Path(botconfig["path_root"])
self.path_sqldb: Path = self.path_root / botconfig["path_sqldb"]
# Prefix of every command to call the bot.
self.command = botconfig["command"]
self.subcommand = {
"cite": {
"--marx": "Karl Marx",
@ -21,18 +31,17 @@ class MarxBot(discord.Client):
}
}
self.command = "!marx"
if dev_marx:
self.command = "!dev-marx"
# Server Tea-Tanches or Obi'lia
# Answer requests from these servers only (Tea-Tanches or Obi'lia)
self.authorized_servers = [93251981056970752, 363070323412697088]
# Initialize the DB.
dbmanager.initialize(self.path_sqldb)
async def on_ready(self):
logging.info(f"MarxBot is ready as {self.user}")
async def on_message(self, message):
# We don't want respond to ourselves
# Avoid responding to ourselves
if message.author == self.user:
return
@ -41,13 +50,13 @@ class MarxBot(discord.Client):
msg_guild = message.guild
msg_author = message.author
# If the bot is called from an unauthorized server:
# If called from an unauthorized server:
if msg_guild is None or msg_guild.id not in self.authorized_servers:
return
# We record the number of words from each member coming from the guild "Les Tea-Tanches".
if msg_guild is not None and msg_guild.id == 93251981056970752:
await self.dbmanager.add_numberword(message)
await dbmanager.add_numberword(self.path_sqldb, message)
# The bot is not called by someone.
if not msg_txt.startswith(self.command):
@ -106,7 +115,7 @@ class MarxBot(discord.Client):
async def send_msg_stats(self, msg_channel: discord.TextChannel, msg_guild: discord.Guild):
# Server Tea-Tanches or Obi'lia
if msg_guild.id == 93251981056970752 or msg_guild.id == 363070323412697088:
await msg_channel.send(self.dbmanager.get_numberwords(msg_guild))
await msg_channel.send(dbmanager.get_numberwords(self.path_sqldb, msg_guild))
async def send_msg_citation(self, msg_channel: discord.TextChannel, msg_txt: str):
options = msg_txt.split()
@ -116,7 +125,7 @@ class MarxBot(discord.Client):
elif "--kadoc" in options:
author = self.subcommand.get("cite").get("--kadoc")
await msg_channel.send(self.dbmanager.get_citation(author))
await msg_channel.send(dbmanager.get_citation(self.path_sqldb, author))
async def send_msg_music(self, msg_channel: discord.TextChannel):
await msg_channel.send(":notes: https://www.youtube.com/watch?v=wKDD1H-Hlpc :musical_note:")
@ -130,13 +139,13 @@ class MarxBot(discord.Client):
logging.warning(f"No --add or --ajouter parameter found: {msg_txt}")
return
self.dbmanager.add_birthday(msg_author.id, birthday_txt)
dbmanager.add_birthday(self.path_sqldb, str(msg_author.id), birthday_txt)
def delete_birthday(self, msg_author: discord.Member):
self.dbmanager.delete_birthday(msg_author.id)
dbmanager.delete_birthday(self.path_sqldb, str(msg_author.id))
async def send_msg_birthday(self, msg_channel: discord.TextChannel, msg_guild: discord.Guild):
birthday = self.dbmanager.get_all_birthday()
birthday = dbmanager.get_all_birthday(self.path_sqldb)
birthday_str = "```\nJours d'anniversaire :\n"
for birthday_id, birthday_txt in birthday.items():