diff options
author | Santo Cariotti <santo@dcariotti.me> | 2021-08-05 20:33:14 +0200 |
---|---|---|
committer | Santo Cariotti <santo@dcariotti.me> | 2021-08-05 20:33:14 +0200 |
commit | 5ddacf8e8131bacbcbd360b24c4c45b5380678ee (patch) | |
tree | 7ffb5aeb9adca95aaf344ae68d810c9456f01a4c | |
parent | 0ef059378e3b10c0eebcbb4e5abc0e033f06cd25 (diff) |
feat: get spaces of a faculty
-rw-r--r-- | src/browser/mod.rs | 11 | ||||
-rw-r--r-- | src/browser/web_browser.rs | 32 | ||||
-rw-r--r-- | src/callbacks.rs | 48 | ||||
-rw-r--r-- | src/main.rs | 2 |
4 files changed, 86 insertions, 7 deletions
diff --git a/src/browser/mod.rs b/src/browser/mod.rs index 1675595..1f44493 100644 --- a/src/browser/mod.rs +++ b/src/browser/mod.rs @@ -35,6 +35,17 @@ pub async unsafe fn get_faculties() -> WebDriverResult<Option<HashMap<String, St Ok(None) } +/// Get the spaces (rooms) available to book +pub async unsafe fn get_spaces() -> WebDriverResult<Option<HashMap<String, String>>> { + if let Some(driver) = &WEB_BROWSER { + if let Some(spaces) = driver.spaces().await? { + return Ok(Some(spaces)); + } + } + + Ok(None) +} + pub async unsafe fn select_option( klass: &str, property_name: &str, diff --git a/src/browser/web_browser.rs b/src/browser/web_browser.rs index ffbdc13..f799866 100644 --- a/src/browser/web_browser.rs +++ b/src/browser/web_browser.rs @@ -115,6 +115,38 @@ impl Browser { Ok(None) } + /// Get all spaces for booking and return an `HashMap<key, value>` when `key` is the + /// key for that space inside the `select` tag and `value` is just the text of the option. + pub async fn spaces(&self) -> WebDriverResult<Option<HashMap<String, String>>> { + if let Some(_d) = &self.driver { + thread::sleep(time::Duration::from_millis(1000)); + + _d.find_element(By::Css( + "span[aria-labelledby='select2-spaceSelector-container']", + )) + .await? + .click() + .await?; + + let list_elements = _d + .find_elements(By::Css("#select2-spaceSelector-results li")) + .await?; + + let mut spaces_ids = HashMap::<String, String>::new(); + + for i in list_elements { + spaces_ids.insert( + i.get_attribute("data-select2-id").await.unwrap().unwrap(), + i.text().await.unwrap(), + ); + } + + return Ok(Some(spaces_ids)); + } + + Ok(None) + } + /// Select an option from a list of select elements pub async fn select_option_from_list( &self, diff --git a/src/callbacks.rs b/src/callbacks.rs index c670884..a82d5e9 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -1,18 +1,54 @@ use crate::browser; +use crate::keyboard::make_inline_keyboard; +use std::error::Error; +use teloxide::{ + payloads::EditMessageReplyMarkupSetters, + prelude::{AutoSend, Bot, CallbackQuery, Requester, UpdateWithCx}, +}; /// Handle the string of callback data -pub async fn handler(text: &String) { +pub async fn handler( + cx: &UpdateWithCx<AutoSend<Bot>, CallbackQuery>, + text: &String, +) -> Result<bool, Box<dyn Error + Send + Sync>> { let call: Vec<&str> = text.split("_").collect(); + let chat_id = call[0]; // First part of `_` string is the type of callback we want to handle - let type_ = call[0]; + let type_ = call[1]; match type_ { "faculty" => unsafe { // Select the faculty - let _ = - browser::select_option("select2-results__option", "data-select2-id", call[1]).await; + match browser::select_option("select2-results__option", "data-select2-id", call[2]) + .await + { + Ok(result) => { + if result { + let spaces = browser::get_spaces().await.unwrap(); + let keyboard = + make_inline_keyboard(&spaces, "space", chat_id.parse::<i64>().unwrap()) + .await; + + // Edit the previous faculties message with spaces' buttons + cx.requester + .edit_message_reply_markup( + chat_id.to_string(), + cx.update.message.clone().unwrap().id, + ) + .reply_markup(keyboard) + .await?; + + return Ok(true); + } else { + return Ok(false); + } + } + Err(_) => { + return Ok(false); + } + } }, - _ => {} - }; + _ => Ok(false), + } } diff --git a/src/main.rs b/src/main.rs index 92e661e..6b85559 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,7 +44,7 @@ async fn main() -> Result<(), Box<dyn Error>> { UnboundedReceiverStream::new(rx).for_each_concurrent(None, |cx| async move { let data = &cx.update.data; if let Some(text) = data { - callbacks::handler(text).await; + let _ = callbacks::handler(&cx, text).await; } }) }) |