Remove some pubs since not needed and add F1 content to the links command
This commit is contained in:
parent
91e195ddbf
commit
022a1d8991
289
src/commands/links/f1.rs
Normal file
289
src/commands/links/f1.rs
Normal file
|
@ -0,0 +1,289 @@
|
|||
use crate::{Context, Error};
|
||||
use cached::proc_macro::cached;
|
||||
use log::warn;
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::CreateSelectMenuOption;
|
||||
use reqwest::header::AUTHORIZATION;
|
||||
use serde::Deserialize;
|
||||
|
||||
async fn autocomplete_season<'a>(
|
||||
_ctx: Context<'_>,
|
||||
partial: &'a str,
|
||||
) -> impl Iterator<Item = String> + 'a {
|
||||
(1981..2023)
|
||||
.map(|n: u32| n.to_string())
|
||||
.filter(move |e| e.starts_with(&partial))
|
||||
.map(|e| e.to_string())
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct MSReq {
|
||||
containers: Vec<MSEvent>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct MSEvent {
|
||||
id: String,
|
||||
metadata: MSMetadata,
|
||||
}
|
||||
|
||||
impl MSEvent {
|
||||
fn get_title(&self) -> String {
|
||||
let title = &self.metadata.attributes.series.replace("FORMULA", "F");
|
||||
format!("**{}: {}**", title, self.metadata.brief)
|
||||
// format!("", 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)
|
||||
}
|
||||
|
||||
fn get_value(&self) -> String {
|
||||
format!(
|
||||
"[{id}](https://morningstreams.com/hightier/f1/session/{id})\nDuration: {duration}",
|
||||
id = self.id,
|
||||
duration = self.metadata.duration
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct MSMetadata {
|
||||
title: String,
|
||||
#[serde(rename = "emfAttributes")]
|
||||
attributes: EmfAttributes,
|
||||
#[serde(rename = "titleBrief")]
|
||||
brief: String,
|
||||
#[serde(rename = "uiDuration")]
|
||||
duration: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct EmfAttributes {
|
||||
#[serde(rename = "Series")]
|
||||
series: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct Season {
|
||||
#[serde(rename = "containers")]
|
||||
events: Vec<EventData>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct EventData {
|
||||
metadata: SeasonMetadata,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct SeasonMetadata {
|
||||
#[serde(rename = "emfAttributes")]
|
||||
attributes: SeasonAttributes,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
struct SeasonAttributes {
|
||||
#[serde(rename = "MeetingKey")]
|
||||
id: String,
|
||||
#[serde(rename = "Meeting_Official_Name")]
|
||||
name: String,
|
||||
#[serde(rename = "Meeting_Name")]
|
||||
short_name: String,
|
||||
}
|
||||
|
||||
#[cached(time = 18000)]
|
||||
async fn get_event(session: String) -> Option<MSReq> {
|
||||
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/f1/event/{}",
|
||||
session
|
||||
))
|
||||
.header(AUTHORIZATION, token)
|
||||
.send()
|
||||
.await;
|
||||
|
||||
let result: Option<MSReq> = match req {
|
||||
Err(e) => {
|
||||
warn!("Error getting F1TV schedule {}", e);
|
||||
None
|
||||
}
|
||||
Ok(req) if req.status().as_u16() == 404 => {
|
||||
warn!("404 on getting F1TV events");
|
||||
None
|
||||
}
|
||||
Ok(req) if req.status().as_u16() == 200 => {
|
||||
let data = req.json::<MSReq>().await;
|
||||
match data {
|
||||
Ok(d) => Some(d),
|
||||
Err(e) => {
|
||||
warn!("Error getting F1TV schedule {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(req) => {
|
||||
warn!(
|
||||
"Unhandled status when parsing F1TV request {}",
|
||||
req.status()
|
||||
);
|
||||
None
|
||||
}
|
||||
};
|
||||
result
|
||||
}
|
||||
|
||||
#[cached(time = 18000)]
|
||||
async fn get_sessions(season: String) -> Option<Season> {
|
||||
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/f1/season/{}",
|
||||
season
|
||||
))
|
||||
.header(AUTHORIZATION, token)
|
||||
.send()
|
||||
.await;
|
||||
|
||||
let result: Option<Season> = match req {
|
||||
Err(e) => {
|
||||
warn!("Error getting F1TV schedule {}", e);
|
||||
None
|
||||
}
|
||||
Ok(req) if req.status().as_u16() == 404 => {
|
||||
warn!("404 on getting F1TV events");
|
||||
None
|
||||
}
|
||||
Ok(req) if req.status().as_u16() == 200 => {
|
||||
let data = req.json::<Season>().await;
|
||||
match data {
|
||||
Ok(d) => Some(d),
|
||||
Err(e) => {
|
||||
warn!("Error getting F1TV schedule {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(req) => {
|
||||
warn!(
|
||||
"Unhandled status when parsing F1TV request {} text: {}",
|
||||
req.status(),
|
||||
req.text().await.expect(
|
||||
"Whoops not getting the text out of this one, F1TV status error unknown"
|
||||
)
|
||||
);
|
||||
None
|
||||
}
|
||||
};
|
||||
result
|
||||
}
|
||||
|
||||
// F1TV links throughout the seasons
|
||||
#[poise::command(slash_command)]
|
||||
pub async fn f1(
|
||||
ctx: Context<'_>,
|
||||
#[description = "Which season to pull from?"]
|
||||
#[autocomplete = "autocomplete_season"]
|
||||
season: String,
|
||||
) -> Result<(), Error> {
|
||||
let sessions: Option<Season> = get_sessions(season).await;
|
||||
match sessions {
|
||||
None => {
|
||||
ctx.say("Unable to find data for selected season").await?;
|
||||
}
|
||||
Some(ses) if ses.events.len() == 0 => {
|
||||
ctx.say("Found 0 events for this season :(").await?;
|
||||
}
|
||||
Some(sessions) => {
|
||||
let content_id = ctx.id();
|
||||
|
||||
let options: Vec<_> = sessions
|
||||
.events
|
||||
.iter()
|
||||
.map(|e| {
|
||||
CreateSelectMenuOption::default()
|
||||
.label(&e.metadata.attributes.short_name)
|
||||
.description(&e.metadata.attributes.name)
|
||||
.value(&e.metadata.attributes.id)
|
||||
.to_owned()
|
||||
})
|
||||
.collect();
|
||||
|
||||
ctx.send(|m| {
|
||||
m.content("Please select a session").components(|c| {
|
||||
c.create_action_row(|ar| {
|
||||
ar.create_select_menu(|menu| {
|
||||
menu.custom_id(content_id);
|
||||
menu.options(|opt| opt.set_options(options))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.await?;
|
||||
|
||||
while let Some(mci) = serenity::CollectComponentInteraction::new(ctx.discord())
|
||||
.channel_id(ctx.channel_id())
|
||||
.filter(move |mci| mci.data.custom_id == content_id.to_string())
|
||||
.await
|
||||
{
|
||||
println!("Got new interaction event");
|
||||
let session = mci.data.values[0].parse::<String>().unwrap();
|
||||
let ses = get_event(session).await;
|
||||
println!("Now responding to interaction");
|
||||
match mci
|
||||
.create_interaction_response(ctx.discord(), |ir| {
|
||||
ir.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|m| match ses {
|
||||
None => m.content("Unable to get these events :("),
|
||||
Some(evs) if evs.containers.len() == 0 => {
|
||||
m.content("Somehow no sessions found for this event :(")
|
||||
}
|
||||
Some(evs) => {
|
||||
println!("editing message");
|
||||
m.content(evs.containers[0].metadata.title.to_string());
|
||||
m.embed(|e| {
|
||||
e.title(format!(
|
||||
"F1 schedule: {}",
|
||||
evs.containers[0].metadata.title
|
||||
));
|
||||
for event in evs.containers {
|
||||
e.field(event.get_title(), event.get_value(), true);
|
||||
}
|
||||
e
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
.await
|
||||
{
|
||||
Err(e) => {
|
||||
println!("Error on interaction response {}", e);
|
||||
}
|
||||
// Ok(o) => {println!("No error on interaction response, here's what we got back: {}", o);},
|
||||
_ => {
|
||||
();
|
||||
}
|
||||
};
|
||||
println!("Reached end of while loop iteration, going back?");
|
||||
}
|
||||
println!("Exited while loop for F1TV links");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
use crate::{commands::utils, Context, Error};
|
||||
use crate::{Context, Error};
|
||||
|
||||
pub mod eurosport;
|
||||
pub mod viaplay;
|
||||
pub mod wrc;
|
||||
mod eurosport;
|
||||
mod f1;
|
||||
mod viaplay;
|
||||
mod wrc;
|
||||
|
||||
#[derive(Debug, poise::ChoiceParameter)]
|
||||
pub enum Timeframe {
|
||||
|
@ -57,9 +58,8 @@ pub enum Timeframe {
|
|||
// }
|
||||
|
||||
#[poise::command(
|
||||
prefix_command,
|
||||
slash_command,
|
||||
subcommands("viaplay::viaplay", "eurosport::eurosport", "wrc::wrc")
|
||||
subcommands("viaplay::viaplay", "eurosport::eurosport", "wrc::wrc", "f1::f1")
|
||||
)]
|
||||
pub async fn links(ctx: Context<'_>) -> Result<(), Error> {
|
||||
ctx.say("Hello there!").await?;
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{Context, Error};
|
|||
use poise::serenity_prelude as serenity;
|
||||
|
||||
pub mod invites;
|
||||
pub mod links;
|
||||
mod links;
|
||||
// pub mod planning;
|
||||
pub mod schedule;
|
||||
pub mod utils;
|
||||
|
|
Loading…
Reference in a new issue