diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 72122089..912233e0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -19,14 +19,14 @@ jobs: release: ${{ github.base_ref == 'main' }} upload-artifact: true secrets: - SHEET_ID: ${{ vars.SHEET_ID }} + SHEET_ID: ${{ github.base_ref == 'main' && secrets.SHEET_ID_main || secrets.SHEET_ID_dev }} build_flutter_apk: uses: ./.github/workflows/build_flutter_apk.yml with: upload-artifact: true secrets: - SHEET_ID: ${{ vars.SHEET_ID }} + SHEET_ID: ${{ github.base_ref == 'main' && secrets.SHEET_ID_main || secrets.SHEET_ID_dev }} # It should wait untill all checks will pass auto-merge: diff --git a/bot/src/bot/dialogue/commands.rs b/bot/src/bot/dialogue/commands.rs index 36cefa52..12cc8175 100644 --- a/bot/src/bot/dialogue/commands.rs +++ b/bot/src/bot/dialogue/commands.rs @@ -37,7 +37,7 @@ pub async fn commands_handler( dialogue: FADialogue, ) -> anyhow::Result<()> { match cmd { - FACommands::Start => start_endpoint(bot, msg, dialogue).await, + FACommands::Start => start_endpoint(bot, msg, dialogue, Lang::default()).await, } } diff --git a/bot/src/bot/dialogue/endpoints.rs b/bot/src/bot/dialogue/endpoints.rs index 4e8a7467..58d8d0c3 100644 --- a/bot/src/bot/dialogue/endpoints.rs +++ b/bot/src/bot/dialogue/endpoints.rs @@ -7,11 +7,19 @@ use first_aid_bot_core::prelude::*; use rand::random; use teloxide::{requests::Requester, types::Message}; -pub async fn start_endpoint(bot: FABot, msg: Message, dialogue: FADialogue) -> Result<()> { +pub async fn start_endpoint( + bot: FABot, + msg: Message, + dialogue: FADialogue, + lang: Lang, +) -> Result<()> { if is_admin(&msg) && random::() % 50 == 0 { easter_egg(&bot, &msg).await?; } - let ctx = FAContext::default(); + let ctx = FAContext { + lang, + ..FAContext::default() + }; move_to_state(&bot, &msg, &dialogue, &*DATA.get_state(&ctx).await?, ctx).await } @@ -21,13 +29,11 @@ pub async fn transition_endpoint( dialogue: FADialogue, (lang, context): (String, Vec), ) -> Result<()> { - let f = || async { - let lang = lang.as_str().try_into()?; - transition_logic(&bot, &msg, &dialogue, FAContext { lang, context }).await - }; + let lang = lang.as_str().try_into()?; + let f = || async { transition_logic(&bot, &msg, &dialogue, FAContext { lang, context }).await }; if let Err(e) = f().await { - start_endpoint(bot, msg, dialogue).await?; + start_endpoint(bot, msg, dialogue, lang).await?; bail!(e); } Ok(()) @@ -43,7 +49,7 @@ pub async fn broadcast_endpoint( let _ = bot .send_message(msg.chat.id, "WTF you are not an admin bye") .await; - return start_endpoint(bot, msg, dialogue).await; + return start_endpoint(bot, msg, dialogue, Lang::default()).await; } process_broadcast(&bot, &msg, &dialogue, message).await?; Ok(()) diff --git a/bot/src/bot/dialogue/logic/keyboard.rs b/bot/src/bot/dialogue/logic/keyboard.rs index 076d9b0d..5bdae1e0 100644 --- a/bot/src/bot/dialogue/logic/keyboard.rs +++ b/bot/src/bot/dialogue/logic/keyboard.rs @@ -16,16 +16,18 @@ pub fn make_keyboard(keys: &[&str], lang: Lang, depth: usize, is_admin: bool) -> keyboard.push(vec![KeyboardButton::new(lang.details().broadcast)]); } - let special_keys = if depth == 0 { - let f = |lang: Lang| KeyboardButton::new(lang.details().button_lang); - Lang::iter().filter(|&l| l != lang).map(f).collect() - } else { - let mut special_keys = vec![KeyboardButton::new(lang.details().button_back)]; - if depth > 1 { - special_keys.push(KeyboardButton::new(lang.details().button_home)); - }; - special_keys - }; + let ld = lang.details(); + let special_keys = match depth { + 0 => Lang::iter() + .filter(|&l| l != lang) + .map(|l| l.details().button_lang) + .collect(), + 1 => vec![ld.button_back], + 2.. => vec![ld.button_back, ld.button_home], + } + .into_iter() + .map(KeyboardButton::new) + .collect(); keyboard.push(special_keys); ReplyMarkup::Keyboard(KeyboardMarkup::new(keyboard).resize_keyboard(true)) diff --git a/core/src/model/data.rs b/core/src/model/data.rs index 0a4c0cdc..9b4d579b 100644 --- a/core/src/model/data.rs +++ b/core/src/model/data.rs @@ -14,9 +14,10 @@ impl Data { Self { data: None } } pub fn cached() -> Result { - log::info!("Cached data!"); - let data = Some(get_data_from_file("table.csv")?); - Ok(Self { data }) + unimplemented!("There is no multiple language support yet!"); + // log::info!("Cached data!"); + // let data = Some(get_data_from_file("table.csv")?); + // Ok(Self { data }) } pub async fn download() -> Result { log::info!("Downloading data!"); @@ -42,16 +43,20 @@ impl<'a> CowMultLangFsExt<'a> for Cow<'a, MultilangFs> { match self { Cow::Borrowed(v) => { - Ok(Cow::Borrowed(ctx.context.iter().try_fold( - v.get(&ctx.lang).ok_or(err_lang)?, - |fs, key| fs.next_states.get(key).ok_or_else(err_ctx(key)), - )?)) + let init = v.get(&ctx.lang).ok_or(err_lang)?; + Ok(Cow::Borrowed( + ctx.context.iter().try_fold(init, |fs, key| { + fs.next_states.get(key).ok_or_else(err_ctx(key)) + })?, + )) } Cow::Owned(mut v) => { - Ok(Cow::Owned(ctx.context.iter().try_fold( - v.remove(&ctx.lang).ok_or(err_lang)?, - |mut fs, key| fs.next_states.swap_remove(key).ok_or_else(err_ctx(key)), - )?)) + let init = v.remove(&ctx.lang).ok_or(err_lang)?; + Ok(Cow::Owned( + ctx.context.iter().try_fold(init, |mut fs, key| { + fs.next_states.swap_remove(key).ok_or_else(err_ctx(key)) + })?, + )) } } } diff --git a/core/src/model/mod.rs b/core/src/model/mod.rs index 81b0437a..9c9fcdec 100644 --- a/core/src/model/mod.rs +++ b/core/src/model/mod.rs @@ -52,18 +52,19 @@ fn get_finite_state(rdr: Reader, lang: Lang) -> anyhow::Result { Ok(Fs::entry(lang, get_next_states_for_key(&rows, "")?)) } -// This file is only for Ukrainian. If we will want to add more languages, it should be changed -pub fn get_data_from_file(filename: &str) -> anyhow::Result { +pub fn get_data_from_file(_filename: &str) -> anyhow::Result { + unimplemented!("There is no multiple language support yet! There has to be multiple filenames"); // let rdr = Reader::from_reader(BufReader::new(File::open(filename)?)); - let rdr = Reader::from_path(filename)?; - assert!(Lang::iter().count() == 1, "Only one language is supported"); - let lang = Lang::iter().next().unwrap(); - Ok([(lang, get_finite_state(rdr, lang)?)].into()) + // assert!(Lang::iter().count() == 1, "Only one language is supported"); + // let lang = Lang::iter().next().unwrap(); + // Ok([(lang, get_finite_state(rdr, lang)?)].into()) + // Lang::iter() + // .map(|lang| Ok((lang, get_finite_state(Reader::from_path(filename)?, lang)?))) + // .collect() } pub async fn get_data_from_web() -> anyhow::Result { let sheet_id = env!("SHEET_ID"); - // assert!(Lang::iter().count() == 1, "Only one language is supported"); let mut ret = MultilangFs::default(); for lang in Lang::iter() { let url = format!( diff --git a/core/tests/test_data.rs b/core/tests/test_data.rs index 91d35bc2..07dba576 100644 --- a/core/tests/test_data.rs +++ b/core/tests/test_data.rs @@ -77,6 +77,12 @@ pre-formatted fixed-width code block written in the Python programming language assert!(!data.is_empty()); assert!(data.iter().all(|(_, fs)| fs.num_nodes() > 1)); assert!(Lang::iter().all(|lang| data.contains_key(&lang))); + for (lang, fs) in &data { + log::info!("First keys for lang {lang} are: "); + for key in fs.next_states.keys() { + log::info!("{}", key); + } + } data.into_iter() .inspect(|(lang, fs)| log::info!("Testing {lang} with {} nodes", fs.num_nodes())) .try_for_each(|(_, fs)| test_fs(fs))?;