Commit 172a4a90 authored by Timothy du Heaume's avatar Timothy du Heaume

add some logging abstractions

parent 2a251abc
use core::fmt::Display;
use serenity::{
builder::EditMember,
http::{client::Http, CacheHttp},
model::{
channel::{Message, Reaction, ReactionType},
guild::Member,
id::{ChannelId, RoleId},
},
};
pub trait LoggingReaction {
fn try_delete(&self, cache_http: impl CacheHttp);
}
impl LoggingReaction for Reaction {
fn try_delete(&self, cache_http: impl CacheHttp) {
self.delete(cache_http)
.unwrap_or_else(|e| error!("Unable to delete react: {:?}", e));
}
}
pub trait LoggingMessage {
fn try_react<R: Into<ReactionType>>(&self, cache_http: impl CacheHttp, reaction_type: R);
fn try_delete(&self, cache_http: impl CacheHttp);
}
impl LoggingMessage for Message {
fn try_react<R: Into<ReactionType>>(&self, cache_http: impl CacheHttp, reaction_type: R) {
self.react(cache_http, reaction_type)
.unwrap_or_else(|e| error!("Unable to add reaction, {:?}", e));
}
fn try_delete(&self, cache_http: impl CacheHttp) {
self.delete(cache_http)
.unwrap_or_else(|e| error!("Unable to delete message: {:?}", e));
}
}
pub trait LoggingChannelId {
fn try_say(self, http: impl AsRef<Http>, content: impl Display);
}
impl LoggingChannelId for ChannelId {
fn try_say(self, http: impl AsRef<Http>, content: impl Display) {
if let Err(e) = self.say(http, content) {
error!("Error sending message {:?}", e)
}
}
}
pub trait LoggingMember {
fn try_edit<F: FnOnce(&mut EditMember) -> &mut EditMember>(&self, http: impl AsRef<Http>, f: F);
fn try_remove_role<R: Into<RoleId>>(&mut self, http: impl AsRef<Http>, role_id: R);
}
impl LoggingMember for Member {
fn try_edit<F: FnOnce(&mut EditMember) -> &mut EditMember>(
&self,
http: impl AsRef<Http>,
f: F,
) {
self.edit(http, f)
.unwrap_or_else(|e| error!("Unable to edit member: {:?}", e));
}
fn try_remove_role<R: Into<RoleId>>(&mut self, http: impl AsRef<Http>, role_id: R) {
self.remove_role(http, role_id)
.unwrap_or_else(|e| error!("Unable to remove role: {:?}", e));
}
}
...@@ -18,6 +18,7 @@ use serenity::{ ...@@ -18,6 +18,7 @@ use serenity::{
}; };
mod config; mod config;
mod logging;
mod reaction_roles; mod reaction_roles;
mod token_management; mod token_management;
mod user_management; mod user_management;
...@@ -25,18 +26,10 @@ mod util; ...@@ -25,18 +26,10 @@ mod util;
mod voting; mod voting;
use config::CONFIG; use config::CONFIG;
use logging::*;
use reaction_roles::{add_role_by_reaction, remove_role_by_reaction}; use reaction_roles::{add_role_by_reaction, remove_role_by_reaction};
use util::get_string_from_react; use util::get_string_from_react;
macro_rules! e {
($error: literal, $x:expr) => {
match $x {
Ok(_) => (),
Err(why) => error!($error, why),
}
};
}
struct Handler; struct Handler;
impl EventHandler for Handler { impl EventHandler for Handler {
...@@ -69,12 +62,9 @@ impl EventHandler for Handler { ...@@ -69,12 +62,9 @@ impl EventHandler for Handler {
voting::Commands::cowsay(ctx, msg.clone(), message_content[1]); voting::Commands::cowsay(ctx, msg.clone(), message_content[1]);
} }
"logreact" => { "logreact" => {
e!("Error deleting logreact prompt: {:?}", msg.delete(&ctx)); msg.try_delete(&ctx);
e!( msg.channel_id
"Error sending message {:?}", .try_say(&ctx.http, "React to this to log the ID (for the next 5min)")
msg.channel_id
.say(&ctx.http, "React to this to log the ID (for the next 5min)")
)
} }
"help" => { "help" => {
let mut message = MessageBuilder::new(); let mut message = MessageBuilder::new();
...@@ -86,20 +76,12 @@ impl EventHandler for Handler { ...@@ -86,20 +76,12 @@ impl EventHandler for Handler {
"Use {}poll <proposal> to see what people think about something", "Use {}poll <proposal> to see what people think about something",
&CONFIG.command_prefix &CONFIG.command_prefix
)); ));
e!( msg.channel_id.try_say(&ctx.http, message.build())
"Error sending message: {:?}",
msg.channel_id.say(&ctx.http, message.build())
);
}
_ => {
e!(
"Error sending message: {:?}",
msg.channel_id.say(
&ctx.http,
format!("Unrecognised command. Try {}help", &CONFIG.command_prefix)
)
);
} }
_ => msg.channel_id.try_say(
&ctx.http,
format!("Unrecognised command. Try {}help", &CONFIG.command_prefix),
),
} }
} }
...@@ -141,10 +123,7 @@ impl EventHandler for Handler { ...@@ -141,10 +123,7 @@ impl EventHandler for Handler {
add_reaction.emoji, add_reaction.emoji,
)); ));
msg.push_mono(react_as_string); msg.push_mono(react_as_string);
e!( message.channel_id.try_say(&ctx.http, msg.build())
"Error sending message: {:?}",
message.channel_id.say(&ctx.http, msg.build())
);
} }
_ => {} _ => {}
} }
......
use crate::config::{ReactRoleMap, CONFIG}; use crate::config::{ReactRoleMap, CONFIG};
use crate::logging::*;
use crate::util::{get_react_from_string, get_string_from_react}; use crate::util::{get_react_from_string, get_string_from_react};
use rayon::prelude::*; use rayon::prelude::*;
use serenity::{ use serenity::{
...@@ -8,15 +9,6 @@ use serenity::{ ...@@ -8,15 +9,6 @@ use serenity::{
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::iter::FromIterator; use std::iter::FromIterator;
macro_rules! e {
($error: literal, $x:expr) => {
match $x {
Ok(_) => (),
Err(why) => error!($error, why),
}
};
}
pub fn add_role_by_reaction(ctx: &Context, msg: Message, added_reaction: Reaction) { pub fn add_role_by_reaction(ctx: &Context, msg: Message, added_reaction: Reaction) {
let user = added_reaction let user = added_reaction
.user_id .user_id
...@@ -48,7 +40,7 @@ pub fn add_role_by_reaction(ctx: &Context, msg: Message, added_reaction: Reactio ...@@ -48,7 +40,7 @@ pub fn add_role_by_reaction(ctx: &Context, msg: Message, added_reaction: Reactio
.ok(); .ok();
} else { } else {
warn!("{} provided invalid react for role", user.name); warn!("{} provided invalid react for role", user.name);
e!("Unable to delete react: {:?}", added_reaction.delete(ctx)); added_reaction.try_delete(ctx);
} }
} }
...@@ -131,10 +123,7 @@ pub fn sync_all_role_reactions(ctx: &Context) { ...@@ -131,10 +123,7 @@ pub fn sync_all_role_reactions(ctx: &Context) {
// ensure bot has reacted // ensure bot has reacted
if !reactor_ids.contains(&UserId::from(CONFIG.bot_id)) { if !reactor_ids.contains(&UserId::from(CONFIG.bot_id)) {
e!( message.try_react(ctx, reaction_type);
"Unable to add reaction, {:?}",
message.react(ctx, reaction_type)
);
} }
for member in all_members.clone() { for member in all_members.clone() {
......
...@@ -6,6 +6,7 @@ use serenity::{ ...@@ -6,6 +6,7 @@ use serenity::{
}; };
use crate::config::CONFIG; use crate::config::CONFIG;
use crate::logging::*;
use crate::token_management::*; use crate::token_management::*;
macro_rules! e { macro_rules! e {
...@@ -24,16 +25,11 @@ pub fn new_member(ctx: &Context, mut new_member: Member) { ...@@ -24,16 +25,11 @@ pub fn new_member(ctx: &Context, mut new_member: Member) {
message.push_line("! Would you care to introduce yourself?"); message.push_line("! Would you care to introduce yourself?");
message.push_line("If you're not sure where to start, perhaps you could tell us about your projects, your first computer…"); message.push_line("If you're not sure where to start, perhaps you could tell us about your projects, your first computer…");
message.push_line("You should also know that we follow the Freenode Channel Guidelines: https://freenode.net/changuide, and try to avoid defamatory content"); message.push_line("You should also know that we follow the Freenode Channel Guidelines: https://freenode.net/changuide, and try to avoid defamatory content");
if let Err(why) = CONFIG.welcome_channel.say(&ctx, message.build()) { CONFIG.welcome_channel.try_say(&ctx, message.build());
error!("Error sending message: {:?}", why);
}
let mut message = MessageBuilder::new(); let mut message = MessageBuilder::new();
message.push(format!("Say hi to {} in ", new_member.display_name())); message.push(format!("Say hi to {} in ", new_member.display_name()));
message.mention(&CONFIG.welcome_channel); message.mention(&CONFIG.welcome_channel);
if let Err(why) = CONFIG.main_channel.say(&ctx, message.build()) { CONFIG.main_channel.try_say(&ctx, message.build());
error!("Error sending message: {:?}", why);
}
if let Err(why) = new_member.add_role(&ctx.http, CONFIG.unregistered_member_role) { if let Err(why) = new_member.add_role(&ctx.http, CONFIG.unregistered_member_role) {
error!("Error adding user role: {:?}", why); error!("Error adding user role: {:?}", why);
...@@ -44,20 +40,20 @@ pub struct Commands; ...@@ -44,20 +40,20 @@ pub struct Commands;
impl Commands { impl Commands {
pub fn register(ctx: Context, msg: Message, account_name: &str) { pub fn register(ctx: Context, msg: Message, account_name: &str) {
if account_name.is_empty() { if account_name.is_empty() {
e!( msg.channel_id
"Error sending message: {:?}", .try_say(&ctx.http, "Usage: !register <ucc username>");
msg.channel_id
.say(&ctx.http, "Usage: !register <ucc username>")
);
return; return;
} }
e!( // TODO convert to email
"Error sending message: {:?}", msg.channel_id.try_say(
// TODO convert to email &ctx.http,
msg.channel_id format!(
.say(&ctx.http, format!("Hey {} here's that token you ordered: {}\nIf this wasn't you just ignore this.", account_name, generate_token(&msg.author, account_name))) "Hey {} here's that token you ordered: {}\nIf this wasn't you just ignore this.",
account_name,
generate_token(&msg.author, account_name)
),
); );
e!("Error deleting register message: {:?}", msg.delete(ctx)); msg.try_delete(ctx);
} }
pub fn verify(ctx: Context, msg: Message, token: &str) { pub fn verify(ctx: Context, msg: Message, token: &str) {
match parse_token(&msg.author, token) { match parse_token(&msg.author, token) {
...@@ -71,42 +67,34 @@ impl Commands { ...@@ -71,42 +67,34 @@ impl Commands {
"Unable to remove role: {:?}", "Unable to remove role: {:?}",
member.remove_role(&ctx.http, CONFIG.unregistered_member_role) member.remove_role(&ctx.http, CONFIG.unregistered_member_role)
); );
e!( member.try_edit(&ctx.http, |m| {
"Unable to edit nickname: {:?}", let mut rng = rand::thread_rng();
member.edit(&ctx.http, |m| { m.nickname(format!(
let mut rng = rand::thread_rng(); "{}, {}",
m.nickname(format!( name,
"{}, {}", [
name, "The Big Cheese",
[ "The One and Only",
"The Big Cheese", "The Exalted One",
"The One and Only", "not to be trusted",
"The Exalted One", "The Scoundrel",
"not to be trusted", "A big fish in a small pond",
"The Scoundrel", ][rng.gen_range(0, 5)]
"A big fish in a small pond", ));
][rng.gen_range(0, 5)] m
)); });
m
})
);
let new_msg = msg let new_msg = msg
.channel_id .channel_id
.say(&ctx.http, "Verification succesful") .say(&ctx.http, "Verification succesful")
.expect("Error sending message"); .expect("Error sending message");
e!( new_msg.try_delete(&ctx);
"Error deleting register message: {:?}",
new_msg.delete(&ctx)
);
}) })
); );
} }
Err(reason) => e!( Err(reason) => msg
"Error sending message: {:?}", .channel_id
msg.channel_id .try_say(&ctx.http, format!("Verification error: {:?}", reason)),
.say(&ctx.http, format!("Verification error: {:?}", reason))
),
} }
e!("Error deleting register message: {:?}", msg.delete(&ctx)); msg.try_delete(&ctx);
} }
} }
...@@ -7,18 +7,11 @@ use std::collections::HashMap; ...@@ -7,18 +7,11 @@ use std::collections::HashMap;
use std::sync::Mutex; use std::sync::Mutex;
use crate::config::CONFIG; use crate::config::CONFIG;
use crate::logging::*;
use crate::util::get_string_from_react; use crate::util::get_string_from_react;
macro_rules! e {
($error: literal, $x:expr) => {
match $x {
Ok(_) => (),
Err(why) => error!($error, why),
}
};
}
pub struct Commands; pub struct Commands;
impl Commands { impl Commands {
pub fn move_something(ctx: Context, msg: Message, content: &str) { pub fn move_something(ctx: Context, msg: Message, content: &str) {
let motion = content; let motion = content;
...@@ -26,20 +19,16 @@ impl Commands { ...@@ -26,20 +19,16 @@ impl Commands {
create_motion(&ctx, &msg, motion); create_motion(&ctx, &msg, motion);
return; return;
} }
e!( msg.channel_id.try_say(
"Error sending message: {:?}", &ctx.http,
msg.channel_id.say( "If there's something you want to motion, put it after the !move keyword",
&ctx.http,
"If there's something you want to motion, put it after the !move keyword",
)
); );
} }
pub fn motion(ctx: Context, msg: Message, _content: &str) { pub fn motion(ctx: Context, msg: Message, _content: &str) {
e!("Error sending message: {:?}", msg.channel_id.try_say(
msg.channel_id.say( &ctx.http,
&ctx.http, "I hope you're not having a motion. You may have wanted to !move something instead.",
"I hope you're not having a motion. You may have wanted to !move something instead." );
));
} }
pub fn poll(ctx: Context, msg: Message, content: &str) { pub fn poll(ctx: Context, msg: Message, content: &str) {
let topic = content; let topic = content;
...@@ -47,12 +36,9 @@ impl Commands { ...@@ -47,12 +36,9 @@ impl Commands {
create_poll(&ctx, &msg, topic); create_poll(&ctx, &msg, topic);
return; return;
} }
e!( msg.channel_id.try_say(
"Error sending message: {:?}", &ctx.http,
msg.channel_id.say( "If there's something you want to motion, put it after the !move keyword",
&ctx.http,
"If there's something you want to motion, put it after the !move keyword",
)
); );
} }
pub fn cowsay(ctx: Context, msg: Message, content: &str) { pub fn cowsay(ctx: Context, msg: Message, content: &str) {
...@@ -78,10 +64,7 @@ impl Commands { ...@@ -78,10 +64,7 @@ impl Commands {
String::from_utf8(output.stdout).expect("unable to parse stdout to String"), String::from_utf8(output.stdout).expect("unable to parse stdout to String"),
None, None,
); );
e!( msg.channel_id.try_say(&ctx.http, message.build());
"Error sending message: {:?}",
msg.channel_id.say(&ctx.http, message.build())
);
} }
} }
...@@ -284,9 +267,9 @@ fn update_motion( ...@@ -284,9 +267,9 @@ fn update_motion(
message.push(" is now "); message.push(" is now ");
message.push_bold(status); message.push_bold(status);
message.push_italic(format!(" (was {})", last_status)); message.push_italic(format!(" (was {})", last_status));
if let Err(why) = CONFIG.announcement_channel.say(&ctx.http, message.build()) { CONFIG
error!("Error sending message: {:?}", why); .announcement_channel
}; .try_say(&ctx.http, message.build());
} }
}; };
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment