use crate::{commands::utils, Context, Error}; use cached::proc_macro::cached; use chrono::{DateTime, Utc}; use log::info; use super::{ cmore::{self, CmoreEvent}, eurosport::{self, ESEvents}, nfl::{self, NFLEvent}, viaplay::{self, ViaplayEvent}, Timeframe, }; #[derive(Clone)] enum Events { EuroSport(ESEvents), Viaplay(ViaplayEvent), NFL(NFLEvent), Cmore(CmoreEvent), } impl Events { fn filter(&self, filter: &str) -> bool { if filter.is_empty() { return true; }; match self { Events::EuroSport(event) => event.filter(&filter), Events::Viaplay(event) => event.filter(&filter), Events::NFL(event) => event.filter(&filter), Events::Cmore(event) => event.filter(&filter), } } fn to_string(&self) -> String { match self { Events::EuroSport(event) => event.to_string(), Events::Viaplay(event) => event.to_string(), Events::NFL(event) => event.to_string(), Events::Cmore(event) => event.to_string(), } } fn get_key(&self) -> (DateTime, String) { match self { Events::EuroSport(event) => event.get_key(), Events::Viaplay(event) => event.get_key(), Events::NFL(event) => event.get_key(), Events::Cmore(event) => event.get_key(), } } pub fn comp(&self, when: &Timeframe) -> bool { match self { Events::EuroSport(event) => event.comp(when), Events::Viaplay(event) => event.comp(when), Events::NFL(event) => event.comp(when), Events::Cmore(event) => event.comp(when), } } } async fn get_euro() -> Vec { let url = super::super::super::SETTINGS .read() .unwrap() .get_table("eurosport") .expect("Expecting an eurosport section in the config") .get("url") .expect("Config error, please set the eurosport[url] value") .clone() .into_string() .expect("Config error, please make sure eurosport[url] is a string"); let events = eurosport::get_eurosport_events(url).await; match events { Some(events) => events .iter() .map(|e| Events::EuroSport(e.to_owned())) .collect(), _ => vec![], } } async fn get_viaplay() -> Vec { match viaplay::get_schedule().await { Some(events) => events .iter() .map(|e| Events::Viaplay(e.to_owned())) .collect(), None => vec![], } } async fn get_nfl() -> Vec { match nfl::get_current_schedule().await { Some(events) => events.iter().map(|e| Events::NFL(e.to_owned())).collect(), None => vec![], } } async fn get_cmore() -> Vec { match cmore::get_schedule().await { Some(events) => events.iter().map(|e| Events::Cmore(e.to_owned())).collect(), None => vec![], } } #[cached(time = 3600)] async fn get_events() -> Vec { let mut events: Vec = vec![]; events.extend(get_euro().await); events.extend(get_viaplay().await); events.extend(get_nfl().await); events.extend(get_cmore().await); events.sort_unstable_by_key(|event| (event.get_key())); events } // All events filtered (Eurosport, NFL, Viaplay) #[poise::command(slash_command)] pub async fn all( ctx: Context<'_>, #[description = "Filter sessions for when they are/were happening"] timeframe: Timeframe, #[description = "Content to filter on"] filter: Option, ) -> Result<(), Error> { let events = get_events().await; match events { events if events.len() == 0 => { ctx.say("No events found. Either it's not among the implemented providers or your search is too stringent").await?; } events => { info!("Found {} events from all events", events.len()); let strings = events .into_iter() .filter(|e| e.comp(&timeframe)) .filter(|e| match &filter { None => true, Some(f) => e.filter(f.as_str()), }) .map(|e| e.to_string()) .collect(); let pages = utils::paginator(strings, 1900, "\n".to_string()); utils::paginate_string(ctx, pages).await?; } } Ok(()) }