From 063b900b321333bb57f4e8c0a286402d4046dae3 Mon Sep 17 00:00:00 2001 From: Leonid Kozarin Date: Sat, 28 Oct 2023 04:44:07 +0300 Subject: [PATCH] Fix #10, migration, default locale and inline clicks by another person --- locales/en.yml | 2 ++ locales/ru.yml | 2 ++ migrations/10_create-chats-table.sql | 4 +-- src/handlers/dick.rs | 7 ++-- src/handlers/inline.rs | 53 ++++++++++++++++++++-------- src/main.rs | 2 +- 6 files changed, 49 insertions(+), 21 deletions(-) diff --git a/locales/en.yml b/locales/en.yml index 5246695..f3cf664 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -46,6 +46,8 @@ inline: dick_of_day: "Elect the Dick of a Day" callback: errors: + another_user: "This message was sent by another person." + invalid_data: "Possibly this message was sent via an older version of the bot. Try to resend it again." unknown_data: "Unknown command" no_data: "Something went wrong…" titles: diff --git a/locales/ru.yml b/locales/ru.yml index 0122819..77f4d4b 100644 --- a/locales/ru.yml +++ b/locales/ru.yml @@ -46,6 +46,8 @@ inline: dick_of_day: "Избрание Писюна Дня" callback: errors: + another_user: "Сообщение было отправлено другим человеком." + invalid_data: "Возможно, это сообщение было отправлено через более старую версию бота. Попробуй послать его ещё раз." unknown_data: "Неизвестная команда" no_data: "Что-то пошло не так нет…" titles: diff --git a/migrations/10_create-chats-table.sql b/migrations/10_create-chats-table.sql index 6255fe3..2f03bfc 100644 --- a/migrations/10_create-chats-table.sql +++ b/migrations/10_create-chats-table.sql @@ -29,8 +29,8 @@ DECLARE BEGIN SELECT count(*) INTO c_count FROM Chats; IF NOT c_count = 0 THEN - INSERT INTO Chats (type, chat_id) SELECT 'id', chat_id FROM Dicks; - UPDATE Dicks d SET chat_id = id FROM Chats c WHERE c.chat_id = d.chat_id; + INSERT INTO Chats (type, chat_id) SELECT DISTINCT 'id'::chat_id_type, chat_id FROM Dicks; + UPDATE Dicks d SET bonus_attempts = (bonus_attempts + 1), chat_id = id FROM Chats c WHERE c.chat_id = d.chat_id; UPDATE Dick_of_Day dod SET chat_id = id FROM Chats c WHERE c.chat_id = dod.chat_id; END IF; END $$; diff --git a/src/handlers/dick.rs b/src/handlers/dick.rs index d7ba7ed..a64439f 100644 --- a/src/handlers/dick.rs +++ b/src/handlers/dick.rs @@ -83,14 +83,15 @@ pub(crate) async fn top_impl(repos: &repo::Repositories, config: config::AppConf .await? .iter().enumerate() .map(|(i, d)| { - let name = teloxide::utils::html::escape(&d.owner_name); + let ltr_name = format!("{LTR_MARK}{}", d.owner_name); + let name = teloxide::utils::html::escape(<r_name); let can_grow = chrono::Utc::now().num_days_from_ce() > d.grown_at.num_days_from_ce(); let line = t!("commands.top.line", locale = &lang_code, n = i+1, name = name, length = d.length); if can_grow { - format!("{LTR_MARK}{line} [+]") + format!("{line} [+]") } else { - format!("{LTR_MARK}{line}") + line } }) .collect::>(); diff --git a/src/handlers/inline.rs b/src/handlers/inline.rs index fa35143..7e1cf4d 100644 --- a/src/handlers/inline.rs +++ b/src/handlers/inline.rs @@ -44,6 +44,7 @@ pub async fn inline_handler(bot: Bot, query: InlineQuery, repos: Repositories) - let name = utils::get_full_name(&query.from); repos.users.create_or_update(query.from.id, name).await?; + let uid = query.from.id.0; let lang_code = ensure_lang_code(Some(&query.from)); let btn_label = t!("inline.results.button", locale = &lang_code); let results: Vec = InlineCommand::iter() @@ -56,7 +57,7 @@ pub async fn inline_handler(bot: Bot, query: InlineQuery, repos: Repositories) - key.clone(), title, content ); let buttons = vec![vec![ - InlineKeyboardButton::callback(&btn_label, key) + InlineKeyboardButton::callback(&btn_label, format!("{uid}:{key}")) ]]; article.reply_markup.replace(InlineKeyboardMarkup::new(buttons)); InlineQueryResult::Article(article) @@ -74,6 +75,12 @@ pub async fn inline_chosen_handler() -> HandlerResult { Ok(()) } +enum CallbackDataParseResult { + Ok(InlineCommand), + AnotherUser, + Invalid, +} + pub async fn callback_handler(bot: Bot, query: CallbackQuery, repos: Repositories, config: AppConfig) -> HandlerResult { let lang_code = ensure_lang_code(Some(&query.from)); @@ -82,20 +89,36 @@ pub async fn callback_handler(bot: Bot, query: CallbackQuery, let mut answer = bot.answer_callback_query(&query.id); if let (Some(inline_msg_id), Some(data)) = (query.inline_message_id, query.data) { - match InlineCommand::from_str(&data) { - Ok(cmd) => { - let text = cmd.execute(&repos, config, from_refs).await?; - let mut edit = bot.edit_message_text_inline(inline_msg_id, text); - edit.reply_markup = None; - edit.parse_mode.replace(Html); - edit.await?; - } - Err(e) => { - log::error!("unknown callback data: {e}"); - let text = t!("inline.callback.errors.unknown_data", locale = &lang_code); - answer.text.replace(text); - answer.show_alert.replace(true); - } + let parse_res = data.split_once(":") + .map(|(uid, data)| { + if uid == query.from.id.0.to_string() { + InlineCommand::from_str(&data) + .map(|cmd| CallbackDataParseResult::Ok(cmd)) + } else { + Ok(CallbackDataParseResult::AnotherUser) + } + }) + .unwrap_or(Ok(CallbackDataParseResult::Invalid)); + + if let Ok(CallbackDataParseResult::Ok(cmd)) = parse_res { + let text = cmd.execute(&repos, config, from_refs).await?; + let mut edit = bot.edit_message_text_inline(inline_msg_id, text); + edit.reply_markup = None; + edit.parse_mode.replace(Html); + edit.await?; + } else { + let key = match parse_res { + Ok(CallbackDataParseResult::AnotherUser) => "another_user", + Ok(CallbackDataParseResult::Invalid) => "invalid_data", + Err(e) => { + log::error!("unknown callback data: {e}"); + "unknown_data" + } + Ok(CallbackDataParseResult::Ok(_)) => panic!("unexpected CallbackDataParseResult::Ok(_)") + }; + let text = t!(&format!("inline.callback.errors.{key}"), locale = &lang_code); + answer.text.replace(text); + answer.show_alert.replace(true); } } else { let text = t!("inline.callback.errors.no_data", locale = &lang_code); diff --git a/src/main.rs b/src/main.rs index 7cbef7b..2adbd38 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ use crate::handlers::{DickCommands, DickOfDayCommands, HelpCommands, ImportComma const ENV_WEBHOOK_URL: &str = "WEBHOOK_URL"; -i18n!(); // load localizations with default parameters +i18n!(fallback = "en"); // load localizations with default parameters #[tokio::main] async fn main() -> Result<(), Box> {