use chrono::Duration; use either::Left; use lazy_static::lazy_static; use log::debug; use rand::{ seq::SliceRandom, thread_rng, }; use serenity::{ framework::standard::{ macros::command, Args, CommandResult, }, model::channel::Message, prelude::*, }; use crate::{ audio::{ PlayArgs, PlayQueue, }, util, }; mod prelude; mod nov_5; mod sept_21; mod france; mod halloween; mod putin; mod shrek; mod ussr; mod thursday; mod tomorrow; mod wednesday; mod pianoman; pub type TodayIter = Box>; #[derive(Clone, Debug, Hash, Default)] pub struct TodayArgs { pub url: &'static str, pub start: Option, pub end: Option, } impl TodayArgs { #[inline] pub fn as_play_args(&self, msg: &Message) -> PlayArgs { PlayArgs { initiator: "you have done this to yourself :^)".to_string(), data: Left(self.url.to_owned()), sender_channel: msg.channel_id, start: self.start, end: self.end, } } } lazy_static! { static ref ALL: Vec TodayIter> = vec![ sept_21::sept_21, nov_5::nov_5, halloween::halloween, ussr::ussr, france::france, shrek::shrek, putin::putin, wednesday::wednesday, thursday::thursday, tomorrow::tomorrow, pianoman::pianoman, ]; } #[command] pub async fn today(ctx: &Context, msg: &Message, _args: Args) -> CommandResult { let today = { #[allow(unused_mut)] let mut result = chrono::Local::now().naive_local(); #[cfg(debug_assertions)] { let dt = _args.parse::().or_else(|_| { _args.parse::().map(|date| { let time = chrono::NaiveTime::from_hms_opt(12, 0, 0).unwrap(); date.and_time(time) }) }); match dt { Ok(dt) => { log::debug!("overriding with datetime: {}", dt); result = dt; }, Err(e) => { log::debug!("parsing datetime: {:?}", e); }, }; } result }; let options: Vec = ALL.iter().flat_map(|f| f(today)).collect(); debug!("{} options for {}", options.len(), today); let play_args = options.choose(&mut thread_rng()).map(|x| x.as_play_args(msg)); if let Some(play_args) = play_args { play_args.data.as_ref().left().iter().for_each(|url| { debug!("today selected: {}", url); }); let queue_lock = ctx.data.write().await.get::().cloned().unwrap(); let mut play_queue = queue_lock.write().unwrap(); play_queue.general_queue.push_front(play_args); } else { util::send(ctx, msg.channel_id, "no", false).await?; util::send(ctx, msg.channel_id, ":angry:", false).await?; } Ok(()) }