Files
reminder-bot/src/commands/timezone.rs

137 lines
4.8 KiB
Rust

use chrono::Utc;
use chrono_tz::{Tz, TZ_VARIANTS};
use levenshtein::levenshtein;
use poise::{
serenity_prelude::{CreateEmbed, CreateEmbedFooter},
CreateReply,
};
use serde::{Deserialize, Serialize};
use crate::{
commands::autocomplete::timezone_autocomplete,
consts::THEME_COLOR,
models::CtxData,
utils::{Extract, Recordable},
Context, Error,
};
#[derive(Serialize, Deserialize, Extract)]
pub struct Options {
pub timezone: Option<String>,
}
impl Recordable for Options {
async fn run(self, ctx: Context<'_>) -> Result<(), Error> {
let mut user_data = ctx.author_data().await.unwrap();
let footer_text = format!("Current timezone: {}", user_data.timezone);
if let Some(timezone) = self.timezone {
match timezone.parse::<Tz>() {
Ok(tz) => {
user_data.timezone = timezone.clone();
user_data.commit_changes(&ctx.data().database).await;
let now = Utc::now().with_timezone(&tz);
ctx.send(
CreateReply::default().embed(
CreateEmbed::new()
.title("Timezone Set")
.description(format!(
"Timezone has been set to **{}**. Your current time should be `{}`",
timezone,
now.format("%H:%M")
))
.color(*THEME_COLOR),
),
)
.await?;
}
Err(_) => {
let filtered_tz = TZ_VARIANTS
.iter()
.filter(|tz| {
timezone.contains(&tz.to_string())
|| tz.to_string().contains(&timezone)
|| levenshtein(&tz.to_string(), &timezone) < 4
})
.take(25)
.map(|t| t.to_owned())
.collect::<Vec<Tz>>();
let fields = filtered_tz.iter().map(|tz| {
(
tz.to_string(),
format!("🕗 `{}`", Utc::now().with_timezone(tz).format("%H:%M")),
true,
)
});
ctx.send(
CreateReply::default().embed(
CreateEmbed::new()
.title("Timezone Not Recognized")
.description(concat!(
"Possibly you meant one of the following timezones,",
" otherwise click [here](https://gist.github.com/JellyWX/",
"913dfc8b63d45192ad6cb54c829324ee):"
))
.color(*THEME_COLOR)
.fields(fields)
.footer(CreateEmbedFooter::new(footer_text))
.url(
"https://gist.github.com/JellyWX/913dfc8b63d45192ad6cb54c829324ee",
),
),
)
.await?;
}
}
} else {
let popular_timezones_iter = ctx.data().popular_timezones.iter().map(|t| {
(
t.to_string(),
format!("🕗 `{}`", Utc::now().with_timezone(t).format("%H:%M")),
true,
)
});
ctx.send(
CreateReply::default().embed(
CreateEmbed::new()
.title("Timezone Usage")
.description(
"**Usage:**
`/timezone Name`
**Example:**
`/timezone Europe/London`
You may want to use one of the popular timezones below, otherwise click [here](https://gist.github.com/JellyWX/913dfc8b63d45192ad6cb54c829324ee):",
)
.color(*THEME_COLOR)
.fields(popular_timezones_iter)
.footer(CreateEmbedFooter::new(footer_text))
.url("https://gist.github.com/JellyWX/913dfc8b63d45192ad6cb54c829324ee"),
),
)
.await?;
}
Ok(())
}
}
/// Select your timezone
#[poise::command(slash_command, rename = "timezone", identifying_name = "timezone")]
pub async fn command(
ctx: Context<'_>,
#[description = "Timezone to use from this list: https://gist.github.com/JellyWX/913dfc8b63d45192ad6cb54c829324ee"]
#[autocomplete = "timezone_autocomplete"]
timezone: Option<String>,
) -> Result<(), Error> {
(Options { timezone }).run(ctx).await
}