Allow chats to choose a locale
This commit is contained in:
1
migrations/2023-01-25-220630_localization/down.sql
Normal file
1
migrations/2023-01-25-220630_localization/down.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE chat DROP locale;
|
||||||
1
migrations/2023-01-25-220630_localization/up.sql
Normal file
1
migrations/2023-01-25-220630_localization/up.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE chat ADD locale TEXT;
|
||||||
52
src/bot.rs
52
src/bot.rs
@@ -31,6 +31,7 @@ use crate::{schema, Database};
|
|||||||
pub enum Command {
|
pub enum Command {
|
||||||
#[command()]
|
#[command()]
|
||||||
SetCalendar,
|
SetCalendar,
|
||||||
|
SetLocale,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn spawn(bot: Throttle<Bot>, db: Database) {
|
pub async fn spawn(bot: Throttle<Bot>, db: Database) {
|
||||||
@@ -43,7 +44,8 @@ pub async fn spawn(bot: Throttle<Bot>, db: Database) {
|
|||||||
|
|
||||||
fn build_handler_chain() -> UpdateHandler<Error> {
|
fn build_handler_chain() -> UpdateHandler<Error> {
|
||||||
let command_handler = teloxide::filter_command::<Command, _>()
|
let command_handler = teloxide::filter_command::<Command, _>()
|
||||||
.branch(case![Command::SetCalendar].endpoint(set_calendar));
|
.branch(case![Command::SetCalendar].endpoint(set_calendar))
|
||||||
|
.branch(case![Command::SetLocale].endpoint(set_locale));
|
||||||
|
|
||||||
let my_chat_member_handler = Update::filter_my_chat_member().endpoint(handle_my_chat_member);
|
let my_chat_member_handler = Update::filter_my_chat_member().endpoint(handle_my_chat_member);
|
||||||
|
|
||||||
@@ -93,6 +95,7 @@ async fn set_calendar(bot: Throttle<Bot>, msg: Message, db: Database) -> Result<
|
|||||||
next_appointment: None,
|
next_appointment: None,
|
||||||
last_reminder: None,
|
last_reminder: None,
|
||||||
pinned_message_id: None,
|
pinned_message_id: None,
|
||||||
|
locale: "de".into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
fetch_and_announce_appointment(&bot, &mut chat_info, &db).await?;
|
fetch_and_announce_appointment(&bot, &mut chat_info, &db).await?;
|
||||||
@@ -100,6 +103,26 @@ async fn set_calendar(bot: Throttle<Bot>, msg: Message, db: Database) -> Result<
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn set_locale(_bot: Throttle<Bot>, msg: Message, db: Database) -> Result<(), Error> {
|
||||||
|
let new_locale = msg.text().map(|text| text.splitn(2, " ").nth(1)).flatten();
|
||||||
|
|
||||||
|
if new_locale.is_none() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let new_locale = new_locale.unwrap();
|
||||||
|
|
||||||
|
db.lock().await.transaction::<_, Error, _>(|db| {
|
||||||
|
use schema::chat::dsl::*;
|
||||||
|
diesel::update(chat)
|
||||||
|
.filter(telegram_id.eq(msg.chat.id.0))
|
||||||
|
.set(locale.eq(new_locale))
|
||||||
|
.execute(db)?;
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn fetch_and_announce_appointment(
|
pub async fn fetch_and_announce_appointment(
|
||||||
bot: &Throttle<Bot>,
|
bot: &Throttle<Bot>,
|
||||||
chat_info: &mut ChatInfo<Utc>,
|
chat_info: &mut ChatInfo<Utc>,
|
||||||
@@ -146,14 +169,22 @@ pub async fn fetch_and_announce_appointment(
|
|||||||
.with_timezone(&Europe::Berlin)
|
.with_timezone(&Europe::Berlin)
|
||||||
.format("%d.%m.%Y %H:%M");
|
.format("%d.%m.%Y %H:%M");
|
||||||
|
|
||||||
let weekday = match appointment.start.weekday() {
|
let weekday = match chat_info.locale.as_str() {
|
||||||
chrono::Weekday::Mon => "Montag",
|
"de" => match appointment.start.weekday() {
|
||||||
chrono::Weekday::Tue => "Dienstag",
|
chrono::Weekday::Mon => "Montag",
|
||||||
chrono::Weekday::Wed => "Mittwoch",
|
chrono::Weekday::Tue => "Dienstag",
|
||||||
chrono::Weekday::Thu => "Donnerstag",
|
chrono::Weekday::Wed => "Mittwoch",
|
||||||
chrono::Weekday::Fri => "Freitag",
|
chrono::Weekday::Thu => "Donnerstag",
|
||||||
chrono::Weekday::Sat => "Samstag",
|
chrono::Weekday::Fri => "Freitag",
|
||||||
chrono::Weekday::Sun => "Sonntag",
|
chrono::Weekday::Sat => "Samstag",
|
||||||
|
chrono::Weekday::Sun => "Sonntag",
|
||||||
|
}
|
||||||
|
.to_owned(),
|
||||||
|
_ => appointment
|
||||||
|
.start
|
||||||
|
.with_timezone(&Europe::Berlin)
|
||||||
|
.format("%A")
|
||||||
|
.to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let announcement = bot
|
let announcement = bot
|
||||||
@@ -161,7 +192,8 @@ pub async fn fetch_and_announce_appointment(
|
|||||||
ChatId(chat_info.id),
|
ChatId(chat_info.id),
|
||||||
t!(
|
t!(
|
||||||
"messages.next_appointment",
|
"messages.next_appointment",
|
||||||
weekday = weekday,
|
locale = &chat_info.locale,
|
||||||
|
weekday = &weekday,
|
||||||
date = &date_str.to_string()
|
date = &date_str.to_string()
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ pub struct DbChat {
|
|||||||
next_appointment_end: Option<i64>,
|
next_appointment_end: Option<i64>,
|
||||||
last_reminder: Option<i64>,
|
last_reminder: Option<i64>,
|
||||||
pinned_message: Option<i32>,
|
pinned_message: Option<i32>,
|
||||||
|
locale: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ChatInfo<Tz: TimeZone> {
|
pub struct ChatInfo<Tz: TimeZone> {
|
||||||
@@ -20,6 +21,7 @@ pub struct ChatInfo<Tz: TimeZone> {
|
|||||||
pub next_appointment: Option<Appointment<Tz>>,
|
pub next_appointment: Option<Appointment<Tz>>,
|
||||||
pub last_reminder: Option<DateTime<Tz>>,
|
pub last_reminder: Option<DateTime<Tz>>,
|
||||||
pub pinned_message_id: Option<i32>,
|
pub pinned_message_id: Option<i32>,
|
||||||
|
pub locale: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DbChat> for ChatInfo<Utc> {
|
impl From<DbChat> for ChatInfo<Utc> {
|
||||||
@@ -42,12 +44,15 @@ impl From<DbChat> for ChatInfo<Utc> {
|
|||||||
.map(|timestamp| NaiveDateTime::from_timestamp(timestamp, 0))
|
.map(|timestamp| NaiveDateTime::from_timestamp(timestamp, 0))
|
||||||
.map(|date_time| DateTime::<Utc>::from_utc(date_time, Utc));
|
.map(|date_time| DateTime::<Utc>::from_utc(date_time, Utc));
|
||||||
|
|
||||||
|
let locale = db_chat.locale.unwrap_or("de".into());
|
||||||
|
|
||||||
ChatInfo {
|
ChatInfo {
|
||||||
id: db_chat.telegram_id,
|
id: db_chat.telegram_id,
|
||||||
calendar: db_chat.calendar,
|
calendar: db_chat.calendar,
|
||||||
next_appointment: next_appointment,
|
next_appointment: next_appointment,
|
||||||
last_reminder,
|
last_reminder,
|
||||||
pinned_message_id: db_chat.pinned_message,
|
pinned_message_id: db_chat.pinned_message,
|
||||||
|
locale,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ async fn check_task(bot: &Throttle<Bot>, reminder_time: NaiveTime, db: &Database
|
|||||||
if now >= appointment.start {
|
if now >= appointment.start {
|
||||||
reminder = Some(Reminder {
|
reminder = Some(Reminder {
|
||||||
time: appointment.start,
|
time: appointment.start,
|
||||||
text: t!("messages.starting_now"),
|
text: t!("messages.starting_now", locale = &chat_info.locale),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
let reminder_date_time = now.date().and_time(reminder_time).unwrap();
|
let reminder_date_time = now.date().and_time(reminder_time).unwrap();
|
||||||
@@ -166,6 +166,7 @@ async fn check_task(bot: &Throttle<Bot>, reminder_time: NaiveTime, db: &Database
|
|||||||
time: reminder_date_time,
|
time: reminder_date_time,
|
||||||
text: t!(
|
text: t!(
|
||||||
"messages.appointment_today",
|
"messages.appointment_today",
|
||||||
|
locale = &chat_info.locale,
|
||||||
start_time = &appointment.start.format("%H:%M").to_string()
|
start_time = &appointment.start.format("%H:%M").to_string()
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,5 +9,6 @@ diesel::table! {
|
|||||||
next_appointment_end -> Nullable<BigInt>,
|
next_appointment_end -> Nullable<BigInt>,
|
||||||
last_reminder -> Nullable<BigInt>,
|
last_reminder -> Nullable<BigInt>,
|
||||||
pinned_message_id -> Nullable<Integer>,
|
pinned_message_id -> Nullable<Integer>,
|
||||||
|
locale -> Nullable<Text>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user