Experiment; weather forecast rendering
This commit is contained in:
parent
bf7b3a28e1
commit
0000312bae
|
|
@ -1,6 +1,7 @@
|
||||||
use poise::serenity_prelude::utils::Colour;
|
use poise::serenity_prelude::utils::Colour;
|
||||||
use d20::roll_range;
|
use d20::roll_range;
|
||||||
use poise::ReplyHandle;
|
use poise::ReplyHandle;
|
||||||
|
use poise::serenity_prelude::CreateEmbed;
|
||||||
use crate::{ManifoldCommand, ManifoldContext};
|
use crate::{ManifoldCommand, ManifoldContext};
|
||||||
|
|
||||||
use crate::models::weather::{Weather, WeatherForecastRequestResponse};
|
use crate::models::weather::{Weather, WeatherForecastRequestResponse};
|
||||||
|
|
@ -15,17 +16,15 @@ async fn weather(ctx: ManifoldContext<'_>, #[rest] #[description="Location to lo
|
||||||
|
|
||||||
let responses = &ctx.data().responses;
|
let responses = &ctx.data().responses;
|
||||||
|
|
||||||
my_message.edit(ctx, |m| {
|
let mut pages = Vec::<CreateEmbed>::new();
|
||||||
m.content("");
|
|
||||||
m.embed(|e| {
|
|
||||||
|
|
||||||
let card_colour = Colour::from_rgb(roll_range(0, 255).unwrap_or(0) as u8, roll_range(0, 255).unwrap_or(0) as u8, roll_range(0, 255).unwrap_or(0) as u8);
|
let card_colour = Colour::from_rgb(roll_range(0, 255).unwrap_or(0) as u8, roll_range(0, 255).unwrap_or(0) as u8, roll_range(0, 255).unwrap_or(0) as u8);
|
||||||
|
pages.push(CreateEmbed::default()
|
||||||
e.colour(card_colour);
|
.colour(card_colour)
|
||||||
e.title(format!("Current weather at {}, {}, {}", weather_forecast.location.name, weather_forecast.location.region, weather_forecast.location.country));
|
.title(format!("Current weather at {}, {}, {}", weather_forecast.location.name, weather_forecast.location.region, weather_forecast.location.country))
|
||||||
e.description(format!("Observations recorded at {}.", weather_forecast.current.last_updated));
|
.description(format!("Observations recorded at {}.", weather_forecast.current.last_updated))
|
||||||
e.image(format!("https:{}", weather_forecast.current.condition.icon));
|
.image(format!("https:{}", weather_forecast.current.condition.icon))
|
||||||
e.fields(vec![
|
.fields(vec![
|
||||||
("Temperature (Dewpoint)", format!("{}°C/{}°F ({:.1}°C/{:.1}°F)", weather_forecast.current.temp_c, weather_forecast.current.temp_f, weather_forecast.current.dewpoint_c.unwrap_or(0.0), weather_forecast.current.dewpoint_f.unwrap_or(0.0)), true),
|
("Temperature (Dewpoint)", format!("{}°C/{}°F ({:.1}°C/{:.1}°F)", weather_forecast.current.temp_c, weather_forecast.current.temp_f, weather_forecast.current.dewpoint_c.unwrap_or(0.0), weather_forecast.current.dewpoint_f.unwrap_or(0.0)), true),
|
||||||
("Feels like", format!("{}°C/{}°F", weather_forecast.current.feelslike_c, weather_forecast.current.feelslike_f), true),
|
("Feels like", format!("{}°C/{}°F", weather_forecast.current.feelslike_c, weather_forecast.current.feelslike_f), true),
|
||||||
("Condition", format!("{}", weather_forecast.current.condition.text), true),
|
("Condition", format!("{}", weather_forecast.current.condition.text), true),
|
||||||
|
|
@ -35,64 +34,47 @@ async fn weather(ctx: ManifoldContext<'_>, #[rest] #[description="Location to lo
|
||||||
("Cloud coverage", format!("{}%", weather_forecast.current.cloud), true),
|
("Cloud coverage", format!("{}%", weather_forecast.current.cloud), true),
|
||||||
("UV index", format!("{}", weather_forecast.current.uv), true),
|
("UV index", format!("{}", weather_forecast.current.uv), true),
|
||||||
("Coordinates", format!("Lat: {} Lon: {}", weather_forecast.location.lat, weather_forecast.location.lon), true),
|
("Coordinates", format!("Lat: {} Lon: {}", weather_forecast.location.lat, weather_forecast.location.lon), true),
|
||||||
]);
|
])
|
||||||
e.field("Wind", format!("{}mph/{}kph from the {} ({} degrees), gusting to {}mph/{}kph", weather_forecast.current.wind_mph, weather_forecast.current.wind_kph, weather_forecast.current.wind_dir, weather_forecast.current.wind_degree, weather_forecast.current.gust_mph, weather_forecast.current.gust_kph), false);
|
.field("Wind", format!("{}mph/{}kph from the {} ({} degrees), gusting to {}mph/{}kph", weather_forecast.current.wind_mph, weather_forecast.current.wind_kph, weather_forecast.current.wind_dir, weather_forecast.current.wind_degree, weather_forecast.current.gust_mph, weather_forecast.current.gust_kph), false)
|
||||||
e.footer(|f| {
|
.footer(|f| {
|
||||||
f.text(format!("{}", responses.get_response(&"weather card footer".to_string()).unwrap_or(&"Weather Powered By Deez Nutz".to_string())));
|
f.text(format!("{}", responses.get_response(&"weather card footer".to_string()).unwrap_or(&"Weather Powered By Deez Nutz".to_string())));
|
||||||
f
|
f
|
||||||
});
|
}).to_owned()
|
||||||
e
|
);
|
||||||
});
|
|
||||||
m
|
|
||||||
}).await?;
|
|
||||||
|
|
||||||
Ok(())
|
if let Some(f) = weather_forecast.forecast.forecastday.first() {
|
||||||
|
f.hour.iter().for_each(|f| {
|
||||||
|
pages.push(CreateEmbed::default()
|
||||||
|
.colour(card_colour)
|
||||||
|
.title(format!("Current weather at {}, {}, {}", weather_forecast.location.name, weather_forecast.location.region, weather_forecast.location.country))
|
||||||
|
.description(format!("Forecast for {} made at {}.", f.time, weather_forecast.current.last_updated))
|
||||||
|
.image(format!("https:{}", f.condition.icon))
|
||||||
|
.fields(vec![
|
||||||
|
("Temperature (Dewpoint)", format!("{}°C/{}°F ({:.1}°C/{:.1}°F)", f.temp_c, f.temp_f, f.dewpoint_c, f.dewpoint_f), true),
|
||||||
|
("Feels like", format!("{}°C/{}°F", f.feelslike_c, f.feelslike_f), true),
|
||||||
|
("Condition", format!("{}", f.condition.text), true),
|
||||||
|
("Pressure", format!("{}mb/{}in", f.pressure_mb, f.pressure_in), true),
|
||||||
|
("Precipitation", format!("{}mm/{}in", f.precip_mm, f.precip_in), true),
|
||||||
|
("Humidity", format!("{}%", f.humidity), true),
|
||||||
|
("Cloud coverage", format!("{}%", f.cloud), true),
|
||||||
|
("Coordinates", format!("Lat: {} Lon: {}", weather_forecast.location.lat, weather_forecast.location.lon), true),
|
||||||
|
])
|
||||||
|
.field("Wind", format!("{}mph/{}kph from the {} ({} degrees), gusting to {}mph/{}kph", f.wind_mph, f.wind_kph, f.wind_dir, f.wind_degree, f.gust_mph, f.gust_kph), false)
|
||||||
|
.footer(|f| {
|
||||||
|
f.text(format!("{}", responses.get_response(&"weather card footer".to_string()).unwrap_or(&"Weather Powered By Deez Nutz".to_string())));
|
||||||
|
f
|
||||||
|
}).to_owned());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
my_message.edit(ctx, |m| {
|
||||||
#[command]
|
|
||||||
#[aliases("wf")]
|
|
||||||
pub async fn weather_forecast(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|
||||||
|
|
||||||
let mut my_message = msg.reply_ping(&ctx, "Retrieving weather, be patient").await?;
|
|
||||||
|
|
||||||
let weather_forecast = _get_weather(ctx, msg, args, Some(3)).await?;
|
|
||||||
|
|
||||||
let forecast_index: usize = (chrono::NaiveDateTime::parse_from_str(&*weather_forecast.location.localtime, "%Y-%m-%d %H:%M").unwrap().hour() as usize) + 1;
|
|
||||||
|
|
||||||
debug!("{:?}", weather_forecast);
|
|
||||||
|
|
||||||
my_message.edit(&ctx, |m| {
|
|
||||||
m.content("");
|
m.content("");
|
||||||
|
m.embeds.extend(pages);
|
||||||
for day in &weather_forecast.forecast.forecastday {
|
|
||||||
m.add_embed(|e| {
|
|
||||||
|
|
||||||
let this_forecast = &day.hour[forecast_index];
|
|
||||||
let card_colour = Colour::from_rgb(roll_range(0, 255).unwrap_or(0) as u8, roll_range(0, 255).unwrap_or(0) as u8, roll_range(0, 255).unwrap_or(0) as u8);
|
|
||||||
|
|
||||||
e.colour(card_colour);
|
|
||||||
e.title(format!("Weather for {} at {}, {}, {}", this_forecast.time, weather_forecast.location.name, weather_forecast.location.region, weather_forecast.location.country));
|
|
||||||
e.description(format!("Observations recorded at {}.", weather_forecast.current.last_updated));
|
|
||||||
e.fields(vec![
|
|
||||||
("Temperature (Dewpoint)", format!("{}°C/{}°F ({:.1}°C/{:.1}°F)", this_forecast.temp_c, this_forecast.temp_f, this_forecast.dewpoint_c, this_forecast.dewpoint_f), true),
|
|
||||||
("Feels like", format!("{}°C/{}°F", this_forecast.feelslike_c, this_forecast.feelslike_f), true),
|
|
||||||
("Condition", format!("{}", this_forecast.condition.text), true),
|
|
||||||
("Pressure", format!("{}mb/{}in", this_forecast.pressure_mb, this_forecast.pressure_in), true),
|
|
||||||
("Precipitation", format!("{}mm/{}in", this_forecast.precip_mm, this_forecast.precip_in), true),
|
|
||||||
("Humidity", format!("{}%", this_forecast.humidity), true),
|
|
||||||
]);
|
|
||||||
e.field("Wind", format!("{}mph/{}kph from the {} ({} degrees), gusting to {}mph/{}kph", this_forecast.wind_mph, this_forecast.wind_kph, this_forecast.wind_dir, this_forecast.wind_degree, this_forecast.gust_mph, this_forecast.gust_kph), false);
|
|
||||||
e
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
m
|
m
|
||||||
}).await?;
|
}).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#[poise::command(slash_command, prefix_command, aliases("wl"))]
|
#[poise::command(slash_command, prefix_command, aliases("wl"))]
|
||||||
pub async fn save_weather_location(ctx: ManifoldContext<'_>, #[rest] #[description="Your default weather location"] location: String) -> ManifoldResult<()> {
|
pub async fn save_weather_location(ctx: ManifoldContext<'_>, #[rest] #[description="Your default weather location"] location: String) -> ManifoldResult<()> {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
use crate::error::ManifoldResult;
|
||||||
|
use crate::ManifoldContext;
|
||||||
|
use poise::serenity_prelude;
|
||||||
|
|
||||||
|
pub async fn paginate(ctx: ManifoldContext<'_>, pages: &[&str]) -> ManifoldResult<()> {
|
||||||
|
// Define some unique identifiers for the navigation buttons
|
||||||
|
let ctx_id = ctx.id();
|
||||||
|
let prev_button_id = format!("{}prev", ctx.id());
|
||||||
|
let next_button_id = format!("{}next", ctx.id());
|
||||||
|
|
||||||
|
// Send the embed with the first page as content
|
||||||
|
let mut current_page = 0;
|
||||||
|
ctx.send(|b| {
|
||||||
|
b.embed(|b| b.description(pages[current_page]))
|
||||||
|
.components(|b| {
|
||||||
|
b.create_action_row(|b| {
|
||||||
|
b.create_button(|b| b.custom_id(&prev_button_id).emoji('◀'))
|
||||||
|
.create_button(|b| b.custom_id(&next_button_id).emoji('▶'))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Loop through incoming interactions with the navigation buttons
|
||||||
|
while let Some(press) = serenity_prelude::CollectComponentInteraction::new(ctx)
|
||||||
|
// We defined our button IDs to start with `ctx_id`. If they don't, some other command's
|
||||||
|
// button was pressed
|
||||||
|
.filter(move |press| press.data.custom_id.starts_with(&ctx_id.to_string()))
|
||||||
|
// Timeout when no navigation button has been pressed for 24 hours
|
||||||
|
.timeout(std::time::Duration::from_secs(3600 * 24))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
// Depending on which button was pressed, go to next or previous page
|
||||||
|
if press.data.custom_id == next_button_id {
|
||||||
|
current_page += 1;
|
||||||
|
if current_page >= pages.len() {
|
||||||
|
current_page = 0;
|
||||||
|
}
|
||||||
|
} else if press.data.custom_id == prev_button_id {
|
||||||
|
current_page = current_page.checked_sub(1).unwrap_or(pages.len() - 1);
|
||||||
|
} else {
|
||||||
|
// This is an unrelated button interaction
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the message with the new page contents
|
||||||
|
press
|
||||||
|
.create_interaction_response(ctx, |b| {
|
||||||
|
b.kind(serenity_prelude::InteractionResponseType::UpdateMessage)
|
||||||
|
.interaction_response_data(|b| b.embed(|b| b.description(pages[current_page])))
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -21,7 +21,7 @@ use crate::models::user::{ManifoldUserInfo, UserInfo};
|
||||||
use crate::models::fueltank::FuelTank;
|
use crate::models::fueltank::FuelTank;
|
||||||
use crate::responses::Responses;
|
use crate::responses::Responses;
|
||||||
|
|
||||||
pub mod autocomplete_helpers;
|
pub mod helpers;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue