From 81660a72df5f494b0373f2e1ff845385e7fea533 Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Sat, 2 May 2020 13:35:47 -0500 Subject: [PATCH] Added event organizer and event location + Event location is a new required field + Event organizer defaults to user that ran the command, or can be specified + Formatted code --- Cargo.lock | 1 + Cargo.toml | 1 + .../2020-04-22-222856_create_events/up.sql | 2 + src/database/models.rs | 10 ++++ src/database/schema.rs | 2 + src/discord/events.rs | 51 ++++++++++++++----- src/discord/mod.rs | 12 +++-- src/main.rs | 4 +- 8 files changed, 64 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d951c55..a556b63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -467,6 +467,7 @@ dependencies = [ "serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", "serenity 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "strfmt 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e7d4ae0..7e677b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ diesel_migrations = "1.4.0" log = "0.4.8" log4rs = "0.11.0" strfmt = "0.1.6" +url = "2.1.1" [dependencies.serenity] version = "0.8.4" diff --git a/migrations/2020-04-22-222856_create_events/up.sql b/migrations/2020-04-22-222856_create_events/up.sql index 60fad7a..8b1d411 100644 --- a/migrations/2020-04-22-222856_create_events/up.sql +++ b/migrations/2020-04-22-222856_create_events/up.sql @@ -3,6 +3,8 @@ CREATE TABLE events ( id INTEGER AUTO_INCREMENT PRIMARY KEY, event_name VARCHAR(255) NOT NULL, event_desc VARCHAR(255) NOT NULL, + event_loc VARCHAR(255) NOT NULL, + organizer VARCHAR(255) NOT NULL, event_time DATETIME NOT NULL, message_id VARCHAR(255) NOT NULL, thumbnail_link VARCHAR(255) NOT NULL, diff --git a/src/database/models.rs b/src/database/models.rs index 8c6346d..04814fb 100644 --- a/src/database/models.rs +++ b/src/database/models.rs @@ -9,6 +9,10 @@ pub struct Event { pub event_name: String, /// Event long description pub event_desc: String, + /// Event location + pub event_loc: String, + /// Event organizer + pub organizer: String, /// Event datetime pub event_time: NaiveDateTime, /// Event discord message id @@ -24,6 +28,8 @@ impl Into for Event { NewEvent { event_name: self.event_name.clone(), event_desc: self.event_desc.clone(), + organizer: self.organizer.clone(), + event_loc: self.event_loc.clone(), event_time: self.event_time.clone(), message_id: self.message_id.clone(), thumbnail_link: self.message_id.clone(), @@ -39,6 +45,10 @@ pub struct NewEvent { pub event_name: String, /// Event long description pub event_desc: String, + /// Event location + pub event_loc: String, + /// Event organizer + pub organizer: String, /// Event datetime pub event_time: NaiveDateTime, /// Event discord message id diff --git a/src/database/schema.rs b/src/database/schema.rs index 338ba43..6aae4d0 100644 --- a/src/database/schema.rs +++ b/src/database/schema.rs @@ -3,6 +3,8 @@ table! { id -> Integer, event_name -> Varchar, event_desc -> Varchar, + event_loc -> Varchar, + organizer -> Varchar, event_time -> Datetime, message_id -> Varchar, thumbnail_link -> Varchar, diff --git a/src/discord/events.rs b/src/discord/events.rs index d19f71a..eb1a73b 100644 --- a/src/discord/events.rs +++ b/src/discord/events.rs @@ -5,10 +5,11 @@ use crate::{DraftEvent, INTERESTED_EMOJI}; use chrono::offset::TimeZone; use chrono::{Datelike, NaiveDateTime, Timelike, Utc}; use chrono_tz::Tz; -use serenity::framework::standard::{macros::command, Args, CommandError, CommandResult}; -use serenity::model::prelude::{Message, User}; +use serenity::framework::standard::{macros::command, Args, CommandResult}; +use serenity::model::prelude::{Mentionable, Message, User}; use serenity::prelude::Context; use serenity::utils::{content_safe, ContentSafeOptions}; +use url::Url; #[command] /// Posts a previewed event @@ -46,47 +47,61 @@ fn confirm(ctx: &mut Context, msg: &Message, _args: Args) -> CommandResult { #[command] /// Creates an event and previews the announcement /// -/// `~create "event name" "04:20pm 2069-04-20" "event description" ` +/// `~create "event name" "04:20pm 2069-04-20" "event description" "http://optional.thumbnail.link" "optional organizer` /// /// **Time format** /// The time format is HH:MMam YYYY-MM-DD /// /// **Thumbnail Link** /// The thumbnail link is optional, if one is not provided, a default image is shown +/// +/// **Organizer** +/// The user or group that is organizing the event, defaults to the user creating the event fn create(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { // Get config let config = get_config(&ctx.data)?; - let guild_id = msg - .guild_id - .ok_or(CommandError("Unable to get guild ID".to_string()))?; // Parse args - let event_name = match args.single::() { + let event_name = match args.find::() { Ok(event_name) => event_name.replace("\"", ""), Err(_) => { msg.reply(&ctx, "No event name provided.".to_string())?; return Ok(()); } }; - let date_string = match args.single::() { + let date_string = match args.find::() { Ok(date_string) => date_string.replace("\"", ""), Err(_) => { msg.reply(&ctx, "No date provided.".to_string())?; return Ok(()); } }; - let description = match args.single::() { + let description = match args.find::() { Ok(desc) => desc.replace("\"", ""), Err(_) => { msg.reply(&ctx, "No description provided.".to_string())?; return Ok(()); } }; - let thumbnail_link = match args.single::() { - Ok(link) => link.replace("<", "").replace(">", ""), + + let location = match args.find::() { + Ok(desc) => desc.replace("\"", ""), + Err(_) => { + msg.reply(&ctx, "No location provided.".to_string())?; + return Ok(()); + } + }; + + let thumbnail_link = match args.find::() { + Ok(link) => link.into_string(), Err(_) => config.default_thumbnail_link.clone(), }; + let organizer = match args.find::() { + Ok(link) => link.replace("\"", ""), + Err(_) => msg.author.mention(), + }; + // Parse date let tz: Tz = config.event_timezone; let input_date = match NaiveDateTime::parse_from_str(date_string.as_str(), "%I:%M%P %Y-%m-%d") { @@ -114,21 +129,29 @@ fn create(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { let event_time = input_date.with_timezone(&Utc).naive_utc(); + if Utc::now().naive_utc() > event_time { + msg.reply(&ctx, "The scheduled time has already passed!")?; + return Ok(()); + } + // Clean channel, role, and everyone pings let settings = ContentSafeOptions::default() .clean_role(true) .clean_here(true) - .clean_user(true) - .clean_everyone(true) - .display_as_member_from(guild_id); + .clean_user(false) + .clean_everyone(true); let description = content_safe(&ctx.cache, description, &settings); let event_name = content_safe(&ctx.cache, event_name, &settings); + let location = content_safe(&ctx.cache, location, &settings); + let organizer = content_safe(&ctx.cache, organizer, &settings); update_draft_event( &ctx, event_name, description, + organizer, + location, thumbnail_link, event_time, msg.author.id.0, diff --git a/src/discord/mod.rs b/src/discord/mod.rs index 85d1e89..ef39613 100644 --- a/src/discord/mod.rs +++ b/src/discord/mod.rs @@ -9,9 +9,9 @@ use serenity::model::prelude::{ChannelId, Message, Reaction, User}; use serenity::prelude::{Context, RwLock, ShareMap}; use serenity::utils::Colour; use serenity::Result; +use std::collections::HashMap; use std::sync::Arc; use strfmt::strfmt; -use std::collections::HashMap; pub mod events; @@ -38,12 +38,10 @@ pub fn send_message_to_reaction_users(ctx: &Context, reaction: &Reaction, msg_te let mut fmt = HashMap::new(); fmt.insert("event".to_string(), event.event_name); msg = strfmt(msg_text, &fmt).unwrap(); - } - else { + } else { msg = format!("**{}** has already started!", &event.event_name) } - if let Ok(user) = reaction.user(&ctx.http) { send_dm_message(&ctx.http, user, &msg); } @@ -85,6 +83,8 @@ pub fn send_event_msg( .thumbnail(event.thumbnail_link.clone()) .footer(|f| f.text("Local Event Time")) .timestamp(utc_time.to_rfc3339()) + .field("Location", &event.event_loc, true) + .field("Organizer", &event.organizer, true) }) })?; @@ -102,6 +102,8 @@ pub fn update_draft_event( ctx: &Context, event_name: String, event_desc: String, + organizer: String, + location: String, thumbnail: String, event_time: NaiveDateTime, creator_id: u64, @@ -113,6 +115,8 @@ pub fn update_draft_event( draft_event.event.event_name = event_name; draft_event.event.event_desc = event_desc; + draft_event.event.event_loc = location; + draft_event.event.organizer = organizer; draft_event.event.thumbnail_link = thumbnail; draft_event.event.message_id = String::new(); draft_event.event.event_time = event_time; diff --git a/src/main.rs b/src/main.rs index 7137c01..1b9633c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -48,7 +48,7 @@ const UNINTERESTED_EMOJI: &str = "\u{274C}"; type HypeBotResult = std::result::Result>; -/// Event discord group +/// Event command group #[group] #[only_in(guilds)] #[description("Commands for Creating Events")] @@ -241,7 +241,9 @@ fn main() -> HypeBotResult<()> { message_id: String::new(), event_time: Utc::now().naive_utc(), event_name: String::new(), + organizer: String::new(), event_desc: String::new(), + event_loc: String::new(), thumbnail_link: String::new(), reminder_sent: 0 as i32, },