Skip to content

Commit

Permalink
feat: add support for absolute datetime and refactor scheduler impl
Browse files Browse the repository at this point in the history
  • Loading branch information
jsonmaf1a committed Dec 11, 2024
1 parent 7dc35c1 commit ecad4c1
Showing 1 changed file with 56 additions and 23 deletions.
79 changes: 56 additions & 23 deletions crates/backend/src/scheduler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use chrono::{DateTime, Utc};
use chrono::{DateTime, Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone, Utc};
use dbus::notification::ScheduledNotification;
use humantime::parse_duration;
use std::cmp::Reverse;
use std::collections::BinaryHeap;

Expand All @@ -14,44 +13,78 @@ impl Scheduler {
queue: BinaryHeap::new(),
}
}

pub fn add(&mut self, notification: ScheduledNotification) {
let time = match Self::parse_time(&notification.time) {
Ok(parsed_time) => parsed_time,
match Self::parse_time(&notification.time) {
Ok(parsed_time) => {
dbg!(&parsed_time);

let scheduled_notification = ScheduledNotification {
time: parsed_time.to_rfc3339(),
data: notification.data,
id: notification.id,
};
self.queue.push(Reverse(scheduled_notification));
}
Err(e) => {
eprintln!("Error parsing time '{}': {}", notification.time, e);
return;
}
};

let scheduled_notification = ScheduledNotification {
time: time.to_rfc3339(),
data: notification.data,
id: notification.id,
};

self.queue.push(Reverse(scheduled_notification));
}
}

fn parse_time(time_str: &str) -> Result<DateTime<Utc>, chrono::ParseError> {
let now = Utc::now();

if let Ok(duration) = parse_duration(time_str) {
Ok(now + chrono::Duration::from_std(duration).unwrap())
} else {
time_str.parse::<DateTime<Utc>>()
if let Ok(duration) = humantime::parse_duration(time_str) {
return Ok(now + chrono::Duration::from_std(duration).unwrap());
}

let datetime_formats = [
"%d.%m.%Y %H:%M", // 01.01.2025 00:00
"%Y-%m-%d %H:%M", // 01-01-2025 00:00
"%d.%m.%Y %I:%M %p", // 01.01.2025 12:00 AM
"%Y-%m-%d %I:%M %p", // 01-01-2025 12:00 AM
];

for format in &datetime_formats {
if let Ok(datetime) = NaiveDateTime::parse_from_str(time_str, format) {
return Ok(Local
.from_local_datetime(&datetime)
.single()
.expect("Ambiguous local time")
.with_timezone(&Utc));
}
}

let time_formats = [
"%H:%M", // 18:45
"%I:%M %p", // 06:45 PM
];

for format in &time_formats {
if let Ok(time) = NaiveTime::parse_from_str(time_str, format) {
let today = Local::now().date_naive();
let datetime = today.and_time(time);
return Ok(Local
.from_local_datetime(&datetime)
.single()
.expect("Ambiguous local time")
.with_timezone(&Utc));
}
}

Ok(time_str.parse::<DateTime<Utc>>()?)
}

pub fn pop_due_notifications(&mut self) -> Vec<ScheduledNotification> {
let now = Utc::now();
let mut due_notifications = Vec::new();

while let Some(Reverse(top)) = self.queue.peek() {
if top.time.parse::<DateTime<Utc>>().unwrap() <= now {
due_notifications.push(self.queue.pop().unwrap().0);
} else {
break;
match top.time.parse::<DateTime<Utc>>() {
Ok(time) if time <= now => {
due_notifications.push(self.queue.pop().unwrap().0);
}
_ => break,
}
}

Expand Down

0 comments on commit ecad4c1

Please sign in to comment.