Add all and cmore commands. And some small updates to others to integrate better for all
This commit is contained in:
parent
8ac7702d8c
commit
12b934fcb4
|
@ -74,11 +74,11 @@ fn sky(input: &str) -> String {
|
|||
|
||||
fn sky_open(input: &str) -> Option<(String, String)> {
|
||||
match input.rsplit_once('{') {
|
||||
None => (return None),
|
||||
None => return None,
|
||||
Some((left, end)) => {
|
||||
if left.ends_with('\\') {
|
||||
match sky_open(left) {
|
||||
None => (return None),
|
||||
None => return None,
|
||||
Some((left, right)) => {
|
||||
let mut end: String = end.to_string();
|
||||
end.push('{');
|
||||
|
@ -95,11 +95,11 @@ fn sky_open(input: &str) -> Option<(String, String)> {
|
|||
|
||||
fn sky_closed(input: &str) -> Option<(String, String)> {
|
||||
match input.split_once('}') {
|
||||
None => (return None),
|
||||
None => return None,
|
||||
Some((left, end)) => {
|
||||
if left.ends_with('\\') {
|
||||
match sky_closed(end) {
|
||||
None => (return None),
|
||||
None => return None,
|
||||
Some((mid, right)) => {
|
||||
let mut start: String = left.to_string();
|
||||
start.push('}');
|
||||
|
|
148
src/commands/links/all.rs
Normal file
148
src/commands/links/all.rs
Normal file
|
@ -0,0 +1,148 @@
|
|||
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<Utc>, 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<Events> {
|
||||
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<Events> {
|
||||
match viaplay::get_schedule().await {
|
||||
Some(events) => events
|
||||
.iter()
|
||||
.map(|e| Events::Viaplay(e.to_owned()))
|
||||
.collect(),
|
||||
None => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_nfl() -> Vec<Events> {
|
||||
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<Events> {
|
||||
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<Events> {
|
||||
let mut events: Vec<Events> = 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<String>,
|
||||
) -> 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(())
|
||||
}
|
188
src/commands/links/cmore.rs
Normal file
188
src/commands/links/cmore.rs
Normal file
|
@ -0,0 +1,188 @@
|
|||
use crate::{commands::utils, Context, Error};
|
||||
use cached::proc_macro::cached;
|
||||
use chrono::{DateTime, Utc};
|
||||
use log::{info, warn};
|
||||
use reqwest::header::AUTHORIZATION;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::Timeframe;
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
pub struct CmoreEvent {
|
||||
#[serde(rename = "assetId")]
|
||||
id: u32,
|
||||
#[serde(rename = "asset")]
|
||||
data: CmoreData,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
pub struct CmoreData {
|
||||
#[serde(default)]
|
||||
description: String,
|
||||
title: String,
|
||||
subtitle: String,
|
||||
duration: i64,
|
||||
// #[serde(rename = "humanDuration")]
|
||||
// hduration: String,
|
||||
#[serde(rename = "liveBroadcastTime")]
|
||||
#[serde(with = "cmore_date")]
|
||||
start: DateTime<Utc>,
|
||||
// #[serde(rename = "mainCategoryTitle")]
|
||||
// category: String,
|
||||
}
|
||||
|
||||
impl CmoreEvent {
|
||||
pub fn filter(&self, filter: &str) -> bool {
|
||||
if filter.is_empty() {
|
||||
return true;
|
||||
};
|
||||
if self.data.description.contains(filter) {
|
||||
return true;
|
||||
}
|
||||
if self.data.title.contains(filter) {
|
||||
return true;
|
||||
}
|
||||
if self.data.subtitle.contains(filter) {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn comp(&self, when: &Timeframe) -> bool {
|
||||
let now = Utc::now();
|
||||
match when {
|
||||
Timeframe::Everything => true,
|
||||
Timeframe::Current => {
|
||||
self.data.start <= now
|
||||
&& self.data.start + chrono::Duration::seconds(self.data.duration) >= now
|
||||
}
|
||||
Timeframe::Future => {
|
||||
self.data.start + chrono::Duration::seconds(self.data.duration) >= now
|
||||
}
|
||||
Timeframe::Past => {
|
||||
self.data.start + chrono::Duration::seconds(self.data.duration) <= now
|
||||
} // _ => self.data.times.end >= now,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
format!(
|
||||
"```md\n[{title}]({subtitle})```(<t:{start}:R>-<t:{end}:R>) https://tom.al/ms/cm/{id}",
|
||||
title = self.data.title,
|
||||
subtitle = self.data.subtitle,
|
||||
start = self.data.start.timestamp(),
|
||||
end = self.data.start.timestamp() + self.data.duration,
|
||||
id = self.id
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_key(&self) -> (DateTime<Utc>, String) {
|
||||
(self.data.start, self.data.description.clone())
|
||||
}
|
||||
}
|
||||
|
||||
mod cmore_date {
|
||||
use chrono::{DateTime, TimeZone, Utc};
|
||||
use serde::{self, Deserialize, Deserializer};
|
||||
|
||||
const FORMAT: &'static str = "%Y-%m-%dT%H:%M:%SZ";
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
Utc.datetime_from_str(&s, FORMAT)
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
#[cached(time = 3600)]
|
||||
pub async fn get_schedule() -> Option<Vec<CmoreEvent>> {
|
||||
let token = super::super::super::SETTINGS
|
||||
.read()
|
||||
.unwrap()
|
||||
.get_table("morningstreams")
|
||||
.unwrap()
|
||||
.get("token")
|
||||
.expect("Config error, please set the morningstreams[token] value")
|
||||
.clone()
|
||||
.into_string()
|
||||
.expect("Config error, please make sure morningstreams[token] is a string");
|
||||
let client = reqwest::Client::new();
|
||||
let req = client
|
||||
.get(format!(
|
||||
"https://api.morningstreams.com/api/hightier/cmore/schedule"
|
||||
))
|
||||
.header(AUTHORIZATION, token)
|
||||
.send()
|
||||
.await;
|
||||
|
||||
let result: Option<Vec<CmoreEvent>> = match req {
|
||||
Err(e) => {
|
||||
warn!("Error getting Cmore schedule {}", e);
|
||||
None
|
||||
}
|
||||
Ok(req) if req.status().as_u16() == 404 => {
|
||||
warn!("404 on getting cmore events");
|
||||
None
|
||||
}
|
||||
Ok(req) if req.status().as_u16() == 200 => {
|
||||
let data = req.json::<Vec<CmoreEvent>>().await;
|
||||
match data {
|
||||
Ok(d) => {
|
||||
Some(d) // .iter().map(|e| e.asset.clone()).collect())
|
||||
}
|
||||
|
||||
Err(e) => {
|
||||
warn!("Error getting Cmore schedule {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(req) => {
|
||||
warn!(
|
||||
"Unhandled status when parsing Cmore request {}",
|
||||
req.status()
|
||||
);
|
||||
None
|
||||
}
|
||||
};
|
||||
result
|
||||
}
|
||||
|
||||
//Cmore events listing
|
||||
#[poise::command(slash_command)]
|
||||
pub async fn cmore(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Filter sessions for when they are/were happening, defaults to future"]
|
||||
timeframe: Option<super::Timeframe>,
|
||||
#[description = "Content to filter on"] filter: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
let tf = match timeframe {
|
||||
None => Timeframe::Future,
|
||||
Some(tf) => tf,
|
||||
};
|
||||
let events: Option<Vec<CmoreEvent>> = get_schedule().await;
|
||||
match events {
|
||||
None => {
|
||||
ctx.say("Unable to get the events, try again later (it's cached so wait a bit...)")
|
||||
.await?;
|
||||
}
|
||||
Some(evs) => {
|
||||
info!("Found {} events from cmore", evs.len());
|
||||
let filtered: Vec<String> = evs
|
||||
.into_iter()
|
||||
.filter(|e| e.comp(&tf))
|
||||
.filter(|e| match &filter {
|
||||
None => true,
|
||||
Some(f) => e.filter(f.as_str()),
|
||||
})
|
||||
.map(|e| e.to_string())
|
||||
.collect();
|
||||
let pages = utils::paginator(filtered, 1900, "\n".to_string());
|
||||
utils::paginate_string(ctx, pages).await?;
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
|
@ -108,7 +108,7 @@ struct Eurosport {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct ESEvents {
|
||||
pub struct ESEvents {
|
||||
id: String,
|
||||
sport: Option<String>,
|
||||
name: String,
|
||||
|
@ -119,7 +119,7 @@ struct ESEvents {
|
|||
}
|
||||
|
||||
impl ESEvents {
|
||||
fn filter(&self, filter: &str) -> bool {
|
||||
pub fn filter(&self, filter: &str) -> bool {
|
||||
if self.name.to_lowercase().contains(filter) {
|
||||
return true;
|
||||
};
|
||||
|
@ -137,18 +137,18 @@ impl ESEvents {
|
|||
return false;
|
||||
}
|
||||
|
||||
fn comp(&self, when: &Option<Timeframe>) -> bool {
|
||||
pub fn comp(&self, when: &Timeframe) -> bool {
|
||||
let now = Utc::now();
|
||||
match when {
|
||||
Some(Timeframe::Everything) => true,
|
||||
Some(Timeframe::Current) => self.start <= now && self.end >= now,
|
||||
Some(Timeframe::Future) => self.end >= now,
|
||||
Some(Timeframe::Past) => self.end <= now,
|
||||
_ => self.end >= now,
|
||||
Timeframe::Everything => true,
|
||||
Timeframe::Current => self.start <= now && self.end >= now,
|
||||
Timeframe::Future => self.end >= now,
|
||||
Timeframe::Past => self.end <= now,
|
||||
// _ => self.end >= now,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_string(&self) -> String {
|
||||
pub fn to_string(&self) -> String {
|
||||
match &self.sport {
|
||||
// None => format!("```md\n({}) {}```\n", self.name, self.secondary),
|
||||
None => format!(
|
||||
|
@ -172,6 +172,10 @@ impl ESEvents {
|
|||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_key(&self) -> (DateTime<Utc>, String) {
|
||||
(self.start, self.name.clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn get_events(v: Eurosport) -> Result<Vec<ESEvents>, serde_json::Error> {
|
||||
|
@ -233,7 +237,7 @@ fn get_events(v: Eurosport) -> Result<Vec<ESEvents>, serde_json::Error> {
|
|||
|
||||
#[cached(time = 3600)]
|
||||
#[allow(dead_code)]
|
||||
async fn get_eurosport_events(url: String) -> Option<Vec<ESEvents>> {
|
||||
pub async fn get_eurosport_events(url: String) -> Option<Vec<ESEvents>> {
|
||||
let cookie = super::super::super::SETTINGS
|
||||
.read()
|
||||
.unwrap()
|
||||
|
@ -282,7 +286,13 @@ async fn get_eurosport_events(url: String) -> Option<Vec<ESEvents>> {
|
|||
}
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
Ok(req) => {
|
||||
warn!(
|
||||
"Eurosport Unhandled request result {}",
|
||||
req.status().as_u16()
|
||||
);
|
||||
None
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
@ -295,6 +305,11 @@ pub async fn eurosport(
|
|||
timeframe: Option<Timeframe>,
|
||||
#[description = "Content to filter on"] filter: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
let tf = match timeframe {
|
||||
None => Timeframe::Future,
|
||||
Some(tf) => tf,
|
||||
};
|
||||
|
||||
let url = super::super::super::SETTINGS
|
||||
.read()
|
||||
.unwrap()
|
||||
|
@ -314,7 +329,7 @@ pub async fn eurosport(
|
|||
info!("Found {} events from eurosport", evs.len());
|
||||
let strings = evs
|
||||
.into_iter()
|
||||
.filter(|e| e.comp(&timeframe))
|
||||
.filter(|e| e.comp(&tf))
|
||||
.filter(|e| match &filter {
|
||||
None => true,
|
||||
Some(f) => e.filter(f.as_str()),
|
||||
|
@ -336,6 +351,10 @@ pub async fn proc_olympics(
|
|||
timeframe: Option<Timeframe>,
|
||||
filter: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
let tf = match timeframe {
|
||||
None => Timeframe::Future,
|
||||
Some(tf) => tf,
|
||||
};
|
||||
let url = super::super::super::SETTINGS
|
||||
.read()
|
||||
.unwrap()
|
||||
|
@ -355,7 +374,7 @@ pub async fn proc_olympics(
|
|||
info!("Found {} events from eurosport olympics ", evs.len());
|
||||
let strings = evs
|
||||
.into_iter()
|
||||
.filter(|e| e.comp(&timeframe))
|
||||
.filter(|e| e.comp(&tf))
|
||||
.filter(|e| match &filter {
|
||||
None => true,
|
||||
Some(f) => e.filter(f.as_str()),
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::{Context, Error};
|
||||
|
||||
mod all;
|
||||
mod cmore;
|
||||
mod eurosport;
|
||||
mod f1;
|
||||
mod nfl;
|
||||
|
@ -60,7 +62,15 @@ pub enum Timeframe {
|
|||
|
||||
#[poise::command(
|
||||
slash_command,
|
||||
subcommands("viaplay::viaplay", "eurosport::eurosport", "wrc::wrc", "f1::f1", "nfl::nfl")
|
||||
subcommands(
|
||||
"viaplay::viaplay",
|
||||
"eurosport::eurosport",
|
||||
"wrc::wrc",
|
||||
"f1::f1",
|
||||
"nfl::nfl",
|
||||
"cmore::cmore",
|
||||
"all::all"
|
||||
)
|
||||
)]
|
||||
pub async fn links(ctx: Context<'_>) -> Result<(), Error> {
|
||||
ctx.say("Hello there!").await?;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::{commands::utils, Context, Error};
|
||||
use cached::proc_macro::cached;
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use log::{warn, info};
|
||||
use log::{info, warn};
|
||||
use reqwest::header::AUTHORIZATION;
|
||||
use serde::Deserialize;
|
||||
use crate::{commands::utils, Context, Error};
|
||||
|
||||
use super::Timeframe;
|
||||
|
||||
|
@ -46,7 +46,7 @@ struct NFLContext {
|
|||
|
||||
#[derive(Deserialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct NFLEvent {
|
||||
pub struct NFLEvent {
|
||||
home_nick_name: String,
|
||||
visitor_nick_name: String,
|
||||
// game_id: String,
|
||||
|
@ -65,7 +65,7 @@ struct NFLVideo {
|
|||
}
|
||||
|
||||
impl NFLEvent {
|
||||
fn filter(&self, filter: &str) -> bool {
|
||||
pub fn filter(&self, filter: &str) -> bool {
|
||||
if filter.is_empty() {
|
||||
return true;
|
||||
};
|
||||
|
@ -75,29 +75,34 @@ impl NFLEvent {
|
|||
false
|
||||
}
|
||||
|
||||
fn comp(&self, when: &Option<Timeframe>) -> bool {
|
||||
pub fn comp(&self, when: &Timeframe) -> bool {
|
||||
let now = Utc::now();
|
||||
match when {
|
||||
Some(Timeframe::Everything) => true,
|
||||
Some(Timeframe::Current) => {
|
||||
self.game_date_time_utc <= now && (self.game_date_time_utc + Duration::minutes(240)) >= now
|
||||
Timeframe::Everything => true,
|
||||
Timeframe::Current => {
|
||||
self.game_date_time_utc <= now
|
||||
&& (self.game_date_time_utc + Duration::minutes(240)) >= now
|
||||
}
|
||||
Some(Timeframe::Future) => (self.game_date_time_utc + Duration::minutes(240)) >= now,
|
||||
Some(Timeframe::Past) => self.game_date_time_utc <= now,
|
||||
_ => (self.game_date_time_utc + Duration::minutes(240)) >= now,
|
||||
Timeframe::Future => (self.game_date_time_utc + Duration::minutes(240)) >= now,
|
||||
Timeframe::Past => self.game_date_time_utc <= now,
|
||||
// _ => (self.game_date_time_utc + Duration::minutes(240)) >= now,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_string(&self) -> String {
|
||||
pub fn to_string(&self) -> String {
|
||||
format!(
|
||||
"```fix\n{home}-{away} ||{title}```<t:{time}:R> https://tom.al/ms/nfl/{id}",
|
||||
title = self.video.title,
|
||||
id = self.video.video_id,
|
||||
time = self.game_date_time_utc.timestamp(),
|
||||
home= self.home_nick_name,
|
||||
home = self.home_nick_name,
|
||||
away = self.visitor_nick_name,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_key(&self) -> (DateTime<Utc>, String) {
|
||||
(self.game_date_time_utc, self.video.title.to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
#[cached(time = 3600)]
|
||||
|
@ -134,6 +139,13 @@ async fn get_week() -> Option<NFLContext> {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn get_current_schedule() -> Option<Vec<NFLEvent>> {
|
||||
match get_week().await {
|
||||
None => return None,
|
||||
Some(w) => return get_schedule(w.current_week).await,
|
||||
}
|
||||
}
|
||||
|
||||
#[cached(time = 3600)]
|
||||
async fn get_schedule(week: u8) -> Option<Vec<NFLEvent>> {
|
||||
let token = super::super::super::SETTINGS
|
||||
|
@ -183,7 +195,6 @@ async fn get_schedule(week: u8) -> Option<Vec<NFLEvent>> {
|
|||
result
|
||||
}
|
||||
|
||||
|
||||
//NFL events listing
|
||||
#[poise::command(slash_command)]
|
||||
pub async fn nfl(
|
||||
|
@ -191,17 +202,23 @@ pub async fn nfl(
|
|||
#[description = "Filter sessions for when they are/were happening, defaults to future"]
|
||||
timeframe: Option<super::Timeframe>,
|
||||
#[description = "Content to filter on"] filter: Option<String>,
|
||||
#[description = "Which game week? (Defaults to current)"]
|
||||
week: Option<u8>,
|
||||
#[description = "Which game week? (Defaults to current)"] week: Option<u8>,
|
||||
) -> Result<(), Error> {
|
||||
let get_week: u8 = match week{
|
||||
let tf = match timeframe {
|
||||
None => Timeframe::Future,
|
||||
Some(tf) => tf,
|
||||
};
|
||||
|
||||
let get_week: u8 = match week {
|
||||
Some(w) => w,
|
||||
None => {
|
||||
match get_week().await {
|
||||
None => { ctx.say("Error getting current week data, try setting one manually").await?; return Ok(())},
|
||||
Some(w) => w.current_week,
|
||||
None => match get_week().await {
|
||||
None => {
|
||||
ctx.say("Error getting current week data, try setting one manually")
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Some(w) => w.current_week,
|
||||
},
|
||||
};
|
||||
|
||||
let events: Option<Vec<NFLEvent>> = get_schedule(get_week).await;
|
||||
|
@ -214,7 +231,7 @@ pub async fn nfl(
|
|||
info!("Found {} events from NFL", evs.len());
|
||||
let filtered: Vec<String> = evs
|
||||
.into_iter()
|
||||
.filter(|e| e.comp(&timeframe))
|
||||
.filter(|e| e.comp(&tf))
|
||||
.filter(|e| match &filter {
|
||||
None => true,
|
||||
Some(f) => e.filter(f.as_str()),
|
||||
|
|
|
@ -24,7 +24,7 @@ use super::Timeframe;
|
|||
// }
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct ViaplayEvent {
|
||||
pub struct ViaplayEvent {
|
||||
content: Content,
|
||||
#[serde(rename = "epg")]
|
||||
times: EPG,
|
||||
|
@ -32,28 +32,37 @@ struct ViaplayEvent {
|
|||
}
|
||||
|
||||
impl ViaplayEvent {
|
||||
fn filter(&self, filter: &str) -> bool {
|
||||
pub fn filter(&self, filter: &str) -> bool {
|
||||
if filter.is_empty() {
|
||||
return true;
|
||||
};
|
||||
if self.content.format.sport.contains(filter) {
|
||||
return true;
|
||||
}
|
||||
if self.content.description.contains(filter) {
|
||||
return true;
|
||||
}
|
||||
if self.content.title.contains(filter) {
|
||||
return true;
|
||||
}
|
||||
if self.content.synopsis.contains(filter) {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn comp(&self, when: &Option<Timeframe>) -> bool {
|
||||
pub fn comp(&self, when: &Timeframe) -> bool {
|
||||
let now = Utc::now();
|
||||
match when {
|
||||
Some(Timeframe::Everything) => true,
|
||||
Some(Timeframe::Current) => self.times.start <= now && self.times.end >= now,
|
||||
Some(Timeframe::Future) => self.times.end >= now,
|
||||
Some(Timeframe::Past) => self.times.end <= now,
|
||||
_ => self.times.end >= now,
|
||||
Timeframe::Everything => true,
|
||||
Timeframe::Current => self.times.start <= now && self.times.end >= now,
|
||||
Timeframe::Future => self.times.end >= now,
|
||||
Timeframe::Past => self.times.end <= now,
|
||||
// _ => self.times.end >= now,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_string(&self) -> String {
|
||||
pub fn to_string(&self) -> String {
|
||||
format!("```md\n[{sport}]({title}) {synopsis}```(<t:{start}:R>-<t:{end}:R>) {desc}\nhttps://tom.al/ms/vp/{id}", sport=self.content.format.sport, title=self.content.title, synopsis=self.content.synopsis, start=self.times.start.timestamp(), end=self.times.end.timestamp(), desc=self.content.description, id=self.system.product_key)
|
||||
}
|
||||
|
||||
|
@ -63,6 +72,10 @@ impl ViaplayEvent {
|
|||
Some(s) => self.content.format.sport.contains(s),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_key(&self) -> (DateTime<Utc>, String) {
|
||||
(self.times.start, self.content.title.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ViaplayEvent {
|
||||
|
@ -74,7 +87,7 @@ impl fmt::Display for ViaplayEvent {
|
|||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct Content {
|
||||
pub struct Content {
|
||||
format: Format,
|
||||
title: String,
|
||||
#[serde(rename = "originalTitle")]
|
||||
|
@ -96,7 +109,7 @@ struct Format {
|
|||
sport: String,
|
||||
}
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct EPG {
|
||||
pub struct EPG {
|
||||
#[serde(with = "viaplay_date")]
|
||||
start: DateTime<Utc>,
|
||||
#[serde(with = "viaplay_date")]
|
||||
|
@ -145,7 +158,7 @@ mod viaplay_sport {
|
|||
}
|
||||
|
||||
#[cached(time = 3600)]
|
||||
async fn get_schedule() -> Option<Vec<ViaplayEvent>> {
|
||||
pub async fn get_schedule() -> Option<Vec<ViaplayEvent>> {
|
||||
let token = super::super::super::SETTINGS
|
||||
.read()
|
||||
.unwrap()
|
||||
|
@ -238,6 +251,10 @@ pub async fn viaplay(
|
|||
#[autocomplete = "autocomplete_sport"]
|
||||
sport: Option<String>,
|
||||
) -> Result<(), Error> {
|
||||
let tf = match timeframe {
|
||||
None => Timeframe::Future,
|
||||
Some(tf) => tf,
|
||||
};
|
||||
let events: Option<Vec<ViaplayEvent>> = get_schedule().await;
|
||||
match events {
|
||||
None => {
|
||||
|
@ -248,7 +265,7 @@ pub async fn viaplay(
|
|||
info!("Found {} events from viaplay", evs.len());
|
||||
let filtered: Vec<String> = evs
|
||||
.into_iter()
|
||||
.filter(|e| e.comp(&timeframe))
|
||||
.filter(|e| e.comp(&tf))
|
||||
.filter(|e| e.check_sport(&sport))
|
||||
.filter(|e| match &filter {
|
||||
None => true,
|
||||
|
|
Loading…
Reference in a new issue