summaryrefslogtreecommitdiff
path: root/src/schedule.rs
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-01-09 23:34:40 -0800
committerFuwn <[email protected]>2024-01-09 23:34:40 -0800
commitfa9f5f70a5221bb940354f3e4d978d4312af77e4 (patch)
tree06a8fd1e6c254fae373459a606bf3b256ccb8efe /src/schedule.rs
downloadrin-fa9f5f70a5221bb940354f3e4d978d4312af77e4.tar.xz
rin-fa9f5f70a5221bb940354f3e4d978d4312af77e4.zip
feat: initial release
Diffstat (limited to 'src/schedule.rs')
-rw-r--r--src/schedule.rs175
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(&current_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();
+ }
+}