Merge pull request 'feat: add listing logger channels in a guild' (#11) from feature/list-logging-channels into develop
Reviewed-on: #11
This commit is contained in:
		
						commit
						3bcef90fb9
					
				@ -7,7 +7,8 @@
 | 
				
			|||||||
-- them from the database. This operation is noop in Rust and should
 | 
					-- them from the database. This operation is noop in Rust and should
 | 
				
			||||||
-- therefore not cost a single CPU cycle.
 | 
					-- therefore not cost a single CPU cycle.
 | 
				
			||||||
CREATE TABLE IF NOT EXISTS guild_log_channels (
 | 
					CREATE TABLE IF NOT EXISTS guild_log_channels (
 | 
				
			||||||
       guild_id INTEGER PRIMARY KEY,
 | 
					       guild_id INTEGER NOT NULL,
 | 
				
			||||||
       channel_id INTEGER NOT NULL,
 | 
					       channel_id INTEGER NOT NULL,
 | 
				
			||||||
       UNIQUE(guild_id, channel_id)
 | 
					       UNIQUE(guild_id, channel_id)
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					CREATE INDEX IF NOT EXISTS guild_log_channels_guild_id ON guild_log_channels(guild_id);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,10 @@
 | 
				
			|||||||
 | 
					#![allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use std::env;
 | 
					use std::env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use poise::serenity_prelude::{ChannelId, GuildId};
 | 
					use poise::serenity_prelude::{ChannelId, GuildId};
 | 
				
			||||||
use sqlx::SqlitePool;
 | 
					use sqlx::SqlitePool;
 | 
				
			||||||
 | 
					use tracing::error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub type Result<T> = ::std::result::Result<T, sqlx::Error>;
 | 
					pub type Result<T> = ::std::result::Result<T, sqlx::Error>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,9 +25,9 @@ impl Database {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    pub async fn get_logging_channel(
 | 
					    pub async fn get_logging_channel(
 | 
				
			||||||
        &self,
 | 
					        &self,
 | 
				
			||||||
        guild_id: u64,
 | 
					        guild_id: GuildId,
 | 
				
			||||||
    ) -> Result<Vec<u64>> {
 | 
					    ) -> Result<Vec<u64>> {
 | 
				
			||||||
        let guild_id = guild_id as i64;
 | 
					        let guild_id = guild_id.0 as i64;
 | 
				
			||||||
        let channels = sqlx::query!(
 | 
					        let channels = sqlx::query!(
 | 
				
			||||||
            r#"
 | 
					            r#"
 | 
				
			||||||
SELECT channel_id
 | 
					SELECT channel_id
 | 
				
			||||||
@ -34,7 +37,11 @@ WHERE guild_id = ?1
 | 
				
			|||||||
            guild_id
 | 
					            guild_id
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        .fetch_all(&self.pool)
 | 
					        .fetch_all(&self.pool)
 | 
				
			||||||
        .await?;
 | 
					        .await
 | 
				
			||||||
 | 
					        .map_err(|e| {
 | 
				
			||||||
 | 
					            error!("Error getting logging channels for guild {guild_id}: {e:?}");
 | 
				
			||||||
 | 
					            e
 | 
				
			||||||
 | 
					        })?;
 | 
				
			||||||
        Ok(channels.iter().map(|id| id.channel_id as u64).collect())
 | 
					        Ok(channels.iter().map(|id| id.channel_id as u64).collect())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -57,6 +64,10 @@ VALUES ( ?1, ?2 )
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
        .execute(&mut *conn)
 | 
					        .execute(&mut *conn)
 | 
				
			||||||
        .await
 | 
					        .await
 | 
				
			||||||
 | 
					        .map_err(|e| {
 | 
				
			||||||
 | 
					            error!("Error setting channel {channel_id} as logger for guild {guild_id}: {e:?}");
 | 
				
			||||||
 | 
					            e
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
        .map(|_| ())
 | 
					        .map(|_| ())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,12 +2,13 @@ use super::{Context, Error};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use super::utils::serenity;
 | 
					use super::utils::serenity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[allow(clippy::unused_async)]
 | 
				
			||||||
#[poise::command(
 | 
					#[poise::command(
 | 
				
			||||||
    slash_command,
 | 
					    slash_command,
 | 
				
			||||||
    subcommands("add_channel"),
 | 
					    subcommands("add_channel", "list_channels"),
 | 
				
			||||||
    required_permissions = "ADMINISTRATOR"
 | 
					    required_permissions = "ADMINISTRATOR"
 | 
				
			||||||
)]
 | 
					)]
 | 
				
			||||||
pub async fn logging(_ctx: Context<'_>, _arg: String) -> Result<(), Error> {
 | 
					pub async fn logging(_ctx: Context<'_>) -> Result<(), Error> {
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -18,7 +19,7 @@ pub async fn add_channel(
 | 
				
			|||||||
) -> Result<(), Error> {
 | 
					) -> Result<(), Error> {
 | 
				
			||||||
    let channel_id = channel.id();
 | 
					    let channel_id = channel.id();
 | 
				
			||||||
    let response = match ctx.guild_id() {
 | 
					    let response = match ctx.guild_id() {
 | 
				
			||||||
        None => "Error: Could not determine the guild's ID.".to_owned(),
 | 
					        None => "Error: Could not determine the guild's ID".to_owned(),
 | 
				
			||||||
        Some(guild_id) => {
 | 
					        Some(guild_id) => {
 | 
				
			||||||
            match ctx
 | 
					            match ctx
 | 
				
			||||||
                .data()
 | 
					                .data()
 | 
				
			||||||
@ -26,7 +27,7 @@ pub async fn add_channel(
 | 
				
			|||||||
                .set_logging_channel(guild_id, channel_id)
 | 
					                .set_logging_channel(guild_id, channel_id)
 | 
				
			||||||
                .await
 | 
					                .await
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Ok(_) => format!(
 | 
					                Ok(()) => format!(
 | 
				
			||||||
                    "Added channel <#{channel_id}> as a logging channel"
 | 
					                    "Added channel <#{channel_id}> as a logging channel"
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Err(e) => {
 | 
					                Err(e) => {
 | 
				
			||||||
@ -34,7 +35,7 @@ pub async fn add_channel(
 | 
				
			|||||||
                        if db_error.is_unique_violation() {
 | 
					                        if db_error.is_unique_violation() {
 | 
				
			||||||
                            format!("Channel <#{channel_id}> is already a logging channel")
 | 
					                            format!("Channel <#{channel_id}> is already a logging channel")
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            format!("Error: {:?}", e)
 | 
					                            format!("Error: {e:?}")
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        format!(
 | 
					                        format!(
 | 
				
			||||||
@ -48,3 +49,31 @@ pub async fn add_channel(
 | 
				
			|||||||
    ctx.say(response).await?;
 | 
					    ctx.say(response).await?;
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[poise::command(slash_command, aliases("list-channels"))]
 | 
				
			||||||
 | 
					pub async fn list_channels(ctx: Context<'_>) -> Result<(), Error> {
 | 
				
			||||||
 | 
					    let response = match ctx.guild_id() {
 | 
				
			||||||
 | 
					        None => "Error: Could not determine the guild's ID".to_owned(),
 | 
				
			||||||
 | 
					        Some(guild_id) => {
 | 
				
			||||||
 | 
					            match ctx.data().database.get_logging_channel(guild_id).await {
 | 
				
			||||||
 | 
					                Ok(channels) => {
 | 
				
			||||||
 | 
					                    if channels.is_empty() {
 | 
				
			||||||
 | 
					                        "No channels registered as loggers".to_owned()
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        format!(
 | 
				
			||||||
 | 
					                            "Here are the channels currently set as loggers:\n{}",
 | 
				
			||||||
 | 
					                            channels
 | 
				
			||||||
 | 
					                                .iter()
 | 
				
			||||||
 | 
					                                .map(|channel| format!("- <#{channel}>"))
 | 
				
			||||||
 | 
					                                .collect::<Vec<String>>()
 | 
				
			||||||
 | 
					                                .join("\n")
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Err(e) => format!("Could not retrieve loggers: {e:?}"),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    ctx.say(response).await?;
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,9 +8,8 @@ use utils::serenity;
 | 
				
			|||||||
use commands::logging;
 | 
					use commands::logging;
 | 
				
			||||||
use utils::{BotData, Context, Error};
 | 
					use utils::{BotData, Context, Error};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn make_bot() -> color_eyre::Result<FrameworkBuilder<BotData, Error>>
 | 
					pub fn make_bot() -> FrameworkBuilder<BotData, Error> {
 | 
				
			||||||
{
 | 
					    poise::Framework::builder()
 | 
				
			||||||
    let framework = poise::Framework::builder()
 | 
					 | 
				
			||||||
        .options(poise::FrameworkOptions {
 | 
					        .options(poise::FrameworkOptions {
 | 
				
			||||||
            commands: vec![logging()],
 | 
					            commands: vec![logging()],
 | 
				
			||||||
            ..Default::default()
 | 
					            ..Default::default()
 | 
				
			||||||
@ -26,6 +25,5 @@ pub async fn make_bot() -> color_eyre::Result<FrameworkBuilder<BotData, Error>>
 | 
				
			|||||||
                .await?;
 | 
					                .await?;
 | 
				
			||||||
                Ok(BotData::new().await?)
 | 
					                Ok(BotData::new().await?)
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
        });
 | 
					        })
 | 
				
			||||||
    Ok(framework)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					#![warn(clippy::style, clippy::pedantic)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod utils;
 | 
					mod utils;
 | 
				
			||||||
mod db;
 | 
					mod db;
 | 
				
			||||||
mod discord;
 | 
					mod discord;
 | 
				
			||||||
@ -10,7 +12,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
 | 
				
			|||||||
    color_eyre::install()?;
 | 
					    color_eyre::install()?;
 | 
				
			||||||
    utils::setup_logging();
 | 
					    utils::setup_logging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let bot = discord::make_bot().await?;
 | 
					    let bot = discord::make_bot();
 | 
				
			||||||
    bot.run().await?;
 | 
					    bot.run().await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user