diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a3e89b..43e8d22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Unreleased changes can be found in the [development](https://github.com/sea-auca/servitor/tree/dev) branch. +### [1.2.0] - 2022-04-13 + +### Added + +- Command to retrieve user avatar +- Functional for logger to share its logfile path + +### Changed + +- Change `retrieve_logs` command and allow it accept zero arguments and send actual logfile as attachment. + +### Deprecated + +- Deprecate `retrieve_logs` command's version accepting one argument. Will be removed in the next major update. + +### Fixed + +- Fix channel mentions in greeting message +- Set limit for bytes written to `10000000` bytes as it should be (instead of `0` as it was incorrectly) + ### [1.1.0] - 2022-04-13 + ### Added - Internal log rotation at exceeding limit of bytes written in logfile (limit is set to `10000000` bytes). @@ -27,5 +48,6 @@ Unreleased changes can be found in the [development](https://github.com/sea-auca - Base version of Servitor Discord bot. -[1.1.0]: https://github.com/sea-auca/servitor/compare/1.0.0..1.10 +[1.2.0]: https://github.com/sea-auca/servitor/compare/1.1.0..1.2.0 +[1.1.0]: https://github.com/sea-auca/servitor/compare/1.0.0..1.1.0 [1.0.0]: https://github.com/sea-auca/servitor/releases/tag/1.0.0 diff --git a/Cargo.lock b/Cargo.lock index 2f0dedd..373e368 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1064,7 +1064,7 @@ dependencies = [ [[package]] name = "servitor" -version = "1.0.0" +version = "1.2.0" dependencies = [ "chrono", "envy", diff --git a/Cargo.toml b/Cargo.toml index 9a4c3db..d8532e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "servitor" -version = "1.0.0" +version = "1.2.0" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/commands/basic.rs b/src/commands/basic.rs index 59b2bee..9d52d4d 100644 --- a/src/commands/basic.rs +++ b/src/commands/basic.rs @@ -7,7 +7,7 @@ const ABOUT_MSG: &str = "Hello! This is simple utility bot developed by our comm We are still in process of development and new features will be added later"; #[group] -#[commands(ping, echo, fortune, about, member_me)] +#[commands(ping, echo, fortune, about, member_me, avatar)] struct General; #[command] @@ -20,10 +20,14 @@ async fn ping(ctx: &Context, msg: &Message) -> CommandResult { } #[command] -#[min_args(1)] +#[min_args(0)] #[description("Returns arguments provided to function.")] #[usage("[args]")] async fn echo(ctx: &Context, msg: &Message, args: Args) -> CommandResult { + if args.len() == 0 { + msg.channel_id.say(&ctx.http, "Joe who? Joe mama!").await?; + return Ok(()) + } msg.channel_id.say(&ctx.http, args.message()).await?; Ok(()) } @@ -71,3 +75,33 @@ async fn member_me(ctx: &Context, msg: &Message) -> CommandResult { } Ok(()) } + +#[command] +#[description("get avatar of user specified")] +#[num_args(1)] +async fn avatar(ctx: &Context, msg: &Message) -> CommandResult +{ + if msg.mentions.len() == 0 { + return Ok(()) + } + let avatar_url = msg.mentions.get(0).unwrap().avatar_url(); + match avatar_url { + None => { + msg.channel_id + .say(&ctx.http, "How can I give you an avatar if there is no one? Shame on you") + .await?; + } + Some(avatar_url) => { + msg.channel_id.send_message(&ctx.http, |m| { + m.embed(|e| { + e.title(format!("{}'s avatar", msg.mentions.get(0).unwrap().name)); + e.image(avatar_url.as_str()); + e.url(avatar_url.as_str()); + e + }); + m + }).await?; + } + } + Ok(()) +} diff --git a/src/commands/sudo.rs b/src/commands/sudo.rs index 947e653..6819b12 100644 --- a/src/commands/sudo.rs +++ b/src/commands/sudo.rs @@ -2,7 +2,7 @@ use crate::global::shared::{BOT_DATABASE, LOGGER}; use serenity::framework::standard::{macros::command, macros::group, Args, CommandResult}; use serenity::model::{guild, id, prelude::*, user::*, channel::GuildChannel}; use serenity::prelude::*; -use serenity::builder::GetMessages; +use serenity::builder; use crate::utilities::logging::Level; #[group] @@ -17,12 +17,32 @@ async fn sudo(ctx: &Context, msg: &Message) -> CommandResult { } #[command] -#[num_args(1)] +#[max_args(1)] async fn retrieve_logs(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult { - let num_of_lines = args.single::()?; - let dump = LOGGER.lock().await.extract_entries(num_of_lines).await; - msg.channel_id.say(&ctx.http, dump).await?; - Ok(()) + if args.len() == 1 { + let num_of_lines = args.single::()?; + let dump = LOGGER.lock().await.extract_entries(num_of_lines).await; + msg.channel_id.say(&ctx.http, dump).await?; + return Ok(()) + } + let filepath = LOGGER.lock().await.get_logfile_path(); + match filepath + { + None => { + msg.channel_id.say(&ctx.http, "No logfile exist").await?; + Ok(()) + } + Some(filepath) => { + let body = String::from("The logfile is attached!"); + msg.channel_id.send_message(&ctx.http, |m| { + m.content(body); + m.add_file(filepath.as_str()); + m + }).await?; + Ok(()) + } + + } } #[command] @@ -63,10 +83,7 @@ async fn purge_channel(ctx: &Context, msg: &Message) -> CommandResult { } msg.channel_id.say(&ctx.http, "Purged channel").await?; } - let result = msg.delete(&ctx.http).await; - if let _ = result { - - } + let _result = msg.delete(&ctx.http).await; } else { diff --git a/src/frameworks/framework.rs b/src/frameworks/framework.rs index 7dca5eb..f4503bf 100644 --- a/src/frameworks/framework.rs +++ b/src/frameworks/framework.rs @@ -69,7 +69,7 @@ async fn after(_ctx: &Context, _msg: &Message, command_name: &str, command_resul } #[hook] -async fn normal_message(ctx: &Context, msg: &Message) { +async fn normal_message(_ctx: &Context, msg: &Message) { LOGGER .lock() .await @@ -78,25 +78,4 @@ async fn normal_message(ctx: &Context, msg: &Message) { Level::Trace, ) .await; - if msg.content.contains("Яман") || msg.content.contains("яман") { - let reaction_type = ReactionType::Custom { - animated: false, - id: EmojiId(798454339134816256), - name: Some(String::from(":shit_taster:")), - }; - if let Err(why) = msg.react(&ctx, reaction_type).await { - LOGGER - .lock() - .await - .write_log(format!("Error adding reaction {:?}", why), Level::Warning) - .await; - } - if let Err(why) = msg.channel_id.say(&ctx.http, "Курлык-курлык!").await { - LOGGER - .lock() - .await - .write_log(format!("Error sending message {:?}", why), Level::Warning) - .await; - } - } } diff --git a/src/handlers/handler.rs b/src/handlers/handler.rs index 6a76088..0036439 100644 --- a/src/handlers/handler.rs +++ b/src/handlers/handler.rs @@ -34,10 +34,17 @@ impl EventHandler for Handler { async fn guild_member_addition(&self, ctx: Context, _guild_id: GuildId, new_member: Member) { let general_channel_id = ChannelId(882988311138959430); + let (rules_channel, announcements, roles_channel) = + (ChannelId(709439871512477756),ChannelId(896342671973572618),ChannelId(888679233948377109)); let greeting = MessageBuilder::new() .push("Hello, ") .mention(&new_member) - .push("! Please familiarize yourself with #rules and #announcements") + .push("! Please familiarize yourself with ") + .channel(rules_channel) + .push(", ") + .channel(announcements) + .push(" and ") + .channel(roles_channel) .build(); if let Err(why) = general_channel_id.say(&ctx.http, &greeting).await { LOGGER @@ -78,38 +85,54 @@ impl EventHandler for Handler { return; } let role = role_id.parse::().unwrap(); - if let Some(guild_id) = add_reaction.guild_id { - if let Some(guild) = guild_id.to_guild_cached(&ctx).await { - match add_reaction.user_id { - Some(user_id) => { - if let Ok(mut member) = guild.member(&ctx, &user_id).await { - match member.add_role(&ctx, RoleId(role)).await { - Ok(_) => { - LOGGER.lock().await.write_log( - format!("Given role {} to user {}", role, member.user.name), - Level::Trace, - ).await; - } - Err(_) => { - LOGGER.lock().await.write_log( - format!( - "Error giving role {} to user {}", - role, member.user.name - ), - Level::Warning, - ).await; - } - }; - } - } - None => { - LOGGER - .lock() - .await - .write_log(format!("No user id provided in reaction"), Level::Trace) - .await; - } - } + let guild_id = add_reaction.guild_id; + if guild_id == None { + return + } + let guild = guild_id + .unwrap() + .to_guild_cached(&ctx) + .await; + let guild = match guild { + Some(guild) => { + guild + } + None => { + return + } + }; + if add_reaction.user_id == None { + LOGGER + .lock() + .await + .write_log(format!("No user id provided in reaction"), Level::Trace) + .await; + return + } + let member = guild.member(&ctx, add_reaction.user_id.unwrap()).await; + let mut member = match member { + Ok(member) => { + member + } + Err(_) => { + return + } + }; + match member.add_role(&ctx, RoleId(role)).await { + Ok(_) => { + LOGGER.lock().await.write_log( + format!("Given role {} to user {}", role, member.user.name), + Level::Trace, + ).await; + } + Err(_) => { + LOGGER.lock().await.write_log( + format!( + "Error giving role {} to user {}", + role, member.user.name + ), + Level::Warning, + ).await; } } } diff --git a/src/utilities/logging.rs b/src/utilities/logging.rs index 3ca899e..b64d939 100644 --- a/src/utilities/logging.rs +++ b/src/utilities/logging.rs @@ -42,7 +42,7 @@ impl Logger { path: String::new(), file: None, bytes_written: 0, - max_bytes: 0 as usize + 1 + max_bytes: 1e7 as usize + 1 } } pub async fn configure_logger(&mut self, path: &str) { @@ -74,6 +74,19 @@ impl Logger { self.bytes_written += bytes_len; self.rotate_on_overflow().await; } + + pub fn get_logfile_path(&mut self) -> Option + { + match self.file { + None => { + None + } + Some(_) => { + Some(self.path.clone()) + } + } + } + pub async fn extract_entries(&mut self, amount: usize) -> String { if let None = self.file { return String::from("No log file!");