diff options
| author | Fuwn <[email protected]> | 2024-01-09 23:34:40 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2024-01-09 23:34:40 -0800 |
| commit | fa9f5f70a5221bb940354f3e4d978d4312af77e4 (patch) | |
| tree | 06a8fd1e6c254fae373459a606bf3b256ccb8efe /src/schedule.rs | |
| download | rin-fa9f5f70a5221bb940354f3e4d978d4312af77e4.tar.xz rin-fa9f5f70a5221bb940354f3e4d978d4312af77e4.zip | |
feat: initial release
Diffstat (limited to 'src/schedule.rs')
| -rw-r--r-- | src/schedule.rs | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/src/schedule.rs b/src/schedule.rs new file mode 100644 index 0000000..c6836cc --- /dev/null +++ b/src/schedule.rs @@ -0,0 +1,175 @@ +use { + crate::week::DAYS_OF_WEEK, + std::collections::HashMap, + thirtyfour::prelude::{ElementQueryable, ElementWaitable}, + tokio::io::AsyncWriteExt, +}; + +pub type MarkdownMap = HashMap<String, Vec<String>>; + +pub async fn to_markdown( + driver: &thirtyfour::WebDriver, +) -> Result<String, thirtyfour::error::WebDriverError> { + let schedule = driver + .query(thirtyfour::By::Id("schedule")) + .first() + .await + .expect("failed to find schedule"); + + schedule + .wait_until() + .displayed() + .await + .expect("failed to wait for schedule to be displayed"); + + let mut markdown = html2md::parse_html( + &schedule.inner_html().await.expect("failed to get schedule inner html"), + ); + + markdown = markdown + .lines() + .map(|mut line| { + if line.contains("<summary>") { + line = line.split("<summary>").collect::<Vec<&str>>()[1]; + line = line.split("</summary>").collect::<Vec<&str>>()[0]; + + format!("# {line}") + } else { + line.to_string() + } + }) + .filter(|line| { + !line.starts_with("<details") && !line.starts_with("</details>") + }) + .collect::<Vec<String>>() + .join("\n"); + + Ok(markdown) +} + +pub async fn print_markdown_pipe_markdown( + markdown: &str, +) -> Result<(), std::io::Error> { + let mut child = tokio::process::Command::new("mdcat") + .env( + "TERM", + std::env::var("TERM").unwrap_or_else(|_| "xterm-256color".to_string()), + ) + .stdin(std::process::Stdio::piped()) + .stdout(std::process::Stdio::piped()) + .spawn() + .expect("failed to spawn mdcat"); + + child + .stdin + .as_mut() + .unwrap() + .write_all(markdown.as_bytes()) + .await + .expect("failed to write to mdcat"); + + let child_output = child.wait_with_output().await.unwrap(); + let output = String::from_utf8_lossy(&child_output.stdout).to_string(); + + println!(); + + for line in output.lines() { + println!(" {line}"); + } + + println!(); + + Ok(()) +} + +pub fn markdown_to_map(markdown: &str) -> MarkdownMap { + let mut schedule = HashMap::new(); + let mut current_day = String::new(); + + for line in markdown.lines() { + if line.starts_with("# ") { + current_day = line.replace("# ", "").to_string(); + + schedule.insert(current_day.clone(), Vec::new()); + } else if !line.is_empty() { + schedule.get_mut(¤t_day).unwrap().push(line.to_string()); + } + } + + schedule +} + +#[allow(clippy::future_not_send)] +pub async fn render_markdown(schedule: &MarkdownMap) { + let mut args = std::env::args(); + + args.next(); + + let mut day = args.next().unwrap_or_default(); + + if !day.is_empty() && !DAYS_OF_WEEK.contains(&day.as_str()) { + let mut closest_match = String::new(); + + for day_of_week in DAYS_OF_WEEK { + if day_of_week.to_lowercase().starts_with(&day.to_lowercase()) { + closest_match = day_of_week.to_string(); + + break; + } + } + + if closest_match.is_empty() { + day = String::new(); + } else { + day = closest_match; + } + } + + let mut days = Vec::new(); + + for (day, media) in schedule { + days.push(crate::week::Day::new(day.to_string(), media.clone())); + } + + days.sort_by(|a, b| { + DAYS_OF_WEEK + .iter() + .position(|&day| day == a.name()) + .unwrap() + .cmp(&DAYS_OF_WEEK.iter().position(|&day| day == b.name()).unwrap()) + }); + + let today = chrono::Local::now().format("%A").to_string(); + + if let Some(index) = days.iter().position(|day| day.name() == today) { + days.rotate_left(index); + } + + days.reverse(); + + if day.is_empty() { + for d in days { + let mut lines = String::new(); + + lines.push_str(&format!("{}\n", d.name())); + + for line in d.media() { + lines.push_str(line); + lines.push('\n'); + } + + print_markdown_pipe_markdown(&lines).await.unwrap(); + } + } else { + let mut lines = String::new(); + + lines.push_str(&format!("{day}\n\n")); + + for line in schedule.get(&day).unwrap() { + lines.push_str(line); + lines.push('\n'); + } + + print_markdown_pipe_markdown(&lines).await.unwrap(); + } +} |