From 36c738bfaa37fa62c065af81e365ff4d6f8bf0b4 Mon Sep 17 00:00:00 2001 From: imcompiling Date: Wed, 15 May 2024 13:27:18 -0400 Subject: [PATCH] Finish the update messages function. --- cogs/clan_messages/__init__.py | 99 +++++++++++++++++++++++++++++----- database_setup/database.sql | 4 +- 2 files changed, 88 insertions(+), 15 deletions(-) diff --git a/cogs/clan_messages/__init__.py b/cogs/clan_messages/__init__.py index 04a0006..b94f405 100644 --- a/cogs/clan_messages/__init__.py +++ b/cogs/clan_messages/__init__.py @@ -1,11 +1,15 @@ import os +import nextcord import uvicorn from fastapi import FastAPI from git import Repo from nextcord.ext import commands +from sqlalchemy import select, update +from sqlalchemy.orm import Session from config import DakinyConfig +from database_setup.sql_data_classes import Messages, engine app = FastAPI() REPO_URL = "https://gitea.cheezers.org/imcompiling/dakiny-messages.git" @@ -40,6 +44,7 @@ class ClanMessages(commands.Cog, name="Clan Messages"): """ self.origin.pull() + guild: nextcord.Guild = self.bot.get_guild(self.config.params.guild_id) # for ever directory, sort the files by number then post # posting involves checking if there is a message for that particular file then editing it or creating a @@ -49,20 +54,88 @@ class ClanMessages(commands.Cog, name="Clan Messages"): for dir_name in os.listdir(MESSAGES_DIR) if os.path.isdir(f"{MESSAGES_DIR}/{dir_name}") ] - for dir_name in dirs: - dir_path = f"{MESSAGES_DIR}/{dir_name}" - sorted_files = sorted( - os.listdir(dir_path), key=lambda filename: int(filename.split(".")[0]) - ) - for file_name in sorted_files: - file_path = f"{dir_path}/{file_name}" - with open(file_path, "r", encoding="utf8") as reader: - print(reader.read(2000)) - # get the channel from dir_name - # if doesn't exist, make one - # write or edit message - # save message id if written + with Session(engine) as session: + for dir_name in dirs: + dir_path = f"{MESSAGES_DIR}/{dir_name}" + channel = await self.get_clan_message_channel(session, dir_name, guild) + sorted_files = sorted( + os.listdir(dir_path), + key=lambda filename: int(filename.split(".")[0]), + ) + + for file_name in sorted_files: + message_name = f"{dir_name}/{file_name}" + file_path = f"{dir_path}/{file_name}" + with open(file_path, "r", encoding="utf8") as reader: + stmt = select(Messages.Id).where(Messages.Path == message_name) + msg_id = session.scalar(stmt) + if msg_id is None: + # don't have a message for this file + msg = await channel.send(reader.read(2000)) + new_message = Messages(Path=message_name, Id=msg.id) + session.add(new_message) + session.commit() + else: + try: + msg: nextcord.Message = await channel.fetch_message( + msg_id + ) + await msg.edit(reader.read(2000)) + except nextcord.NotFound: + msg = await channel.send(reader.read(2000)) + stmt = ( + update(Messages) + .where(Messages.Path == message_name) + .values(Id=msg.id) + ) + session.execute(stmt) + session.commit() + + async def get_clan_message_channel( + self, session: Session, channel_name: str, guild: nextcord.Guild + ) -> nextcord.TextChannel: + """ + Used to obtain a channel from the guild object. Searches database for an id to get the channel. If that is not + found, then searches through all channels in the guild to find one with a matching name. If that also doesn't + turn up a channel, then creates it. Adds an entry into database for last two paths. + Assumes that there is an open session to the database. + + Args: + session (Session): Open connection to database. + channel_name (str): Name of channel to obtain. + guild (nextcord.Guild): Guild object to get channel from. + + Returns: + nextcord.TextChannel: Channel object with name channel_name. + """ + stmt = select(Messages.Id).where(Messages.Path == channel_name) + channel_id = session.scalar(stmt) + if channel_id is None: + ret_channel = None + # channel is not tracked. see if it exists + channels = await guild.fetch_channels() + for channel in channels: + if ( + channel.name == channel_name + and channel.__class__ is nextcord.TextChannel + ): + ret_channel = channel + + if ret_channel is None: + # channel doesn't exist, we must create it + ret_channel = await guild.create_text_channel( + channel_name, + reason="Creating channel as required for by design of Dakiny-Messages repo.", + ) + + # record channel information + new_item = Messages(Path=channel_name, Id=ret_channel.id) + session.add(new_item) + session.commit() + return ret_channel + + return await guild.fetch_channel(channel_id) def repo_setup(self): """ diff --git a/database_setup/database.sql b/database_setup/database.sql index 7f31fcf..bab1494 100644 --- a/database_setup/database.sql +++ b/database_setup/database.sql @@ -49,6 +49,6 @@ CREATE TABLE ParticipationPoints ( ); CREATE TABLE Messages ( - FileName varchar(100) PRIMARY KEY, - MessageId bigint unsigned not null + Path varchar(100) PRIMARY KEY, + Id bigint unsigned not null ); \ No newline at end of file