diff --git a/snooze-pal.db b/snooze-pal.db index f101f50..276a418 100644 Binary files a/snooze-pal.db and b/snooze-pal.db differ diff --git a/src/dao/alarm.rs b/src/dao/alarm.rs index 2e30978..0ee9aaf 100644 --- a/src/dao/alarm.rs +++ b/src/dao/alarm.rs @@ -1,4 +1,4 @@ -use chrono::{DateTime, Local, Utc}; +use chrono::{DateTime, Utc}; use sea_orm::{ ActiveModelTrait, ActiveValue::Set, ColumnTrait, ConnectionTrait, DbErr, EntityTrait, QueryFilter }; @@ -7,11 +7,11 @@ use crate::model::{self, alarm}; pub async fn create_alarm( db: &C, - title: &str, + title: String, time: DateTime, ) -> Result { let alarm_to_create = model::alarm::ActiveModel { - title: Set(title.to_string()), + title: Set(title), time: Set(time.naive_utc()), enabled: Set(true), ..Default::default() diff --git a/src/main.rs b/src/main.rs index ff0df41..4459259 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,7 +55,7 @@ async fn app_state() -> AppState { #[tokio::main] async fn main() -> Result<(), Box> { let app_state = app_state().await; - app_state.scheduler.start(); + app_state.scheduler.start().await; start_axum_server(app_state).await; Ok(()) diff --git a/src/resources/alarm/get.rs b/src/resources/alarm/get.rs index 3df5946..61f6e63 100644 --- a/src/resources/alarm/get.rs +++ b/src/resources/alarm/get.rs @@ -1,5 +1,5 @@ use axum::{Json, debug_handler, extract::{Query, State}, http::StatusCode, response::IntoResponse}; -use chrono::{DateTime, Local, Utc}; +use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use utoipa::{IntoParams, IntoResponses, ToSchema}; @@ -7,7 +7,7 @@ use crate::{AppState, types::Alarm}; #[derive(ToSchema, Serialize)] pub struct OkResponse { - name: String, + title: String, enabled: bool, time: DateTime, } @@ -39,7 +39,7 @@ pub struct RequestQuery { impl From for OkResponse { fn from(value: Alarm) -> Self { Self { - name: value.time.to_string(), + title: value.title, enabled: value.enabled, time: value.time, } diff --git a/src/resources/alarm/post.rs b/src/resources/alarm/post.rs index d1eb6e9..9f4ec1a 100644 --- a/src/resources/alarm/post.rs +++ b/src/resources/alarm/post.rs @@ -12,12 +12,14 @@ use crate::types::Alarm; #[derive(Debug, Deserialize, ToSchema)] pub struct RequestBody { + title: String, time: DateTime, } #[derive(ToSchema, Serialize)] pub struct OkResponseBody { time: DateTime, + title: String, enabled: bool, } @@ -41,7 +43,7 @@ impl IntoResponse for Responses { impl From for OkResponseBody { fn from(value: Alarm) -> Self { - OkResponseBody { time: value.time, enabled: value.enabled } + OkResponseBody { time: value.time, enabled: value.enabled, title: value.title } } } @@ -54,7 +56,7 @@ impl From for OkResponseBody { )] #[debug_handler] pub async fn post_handler(State(AppState { scheduler, ..}): State, Json(body): Json) -> Responses { - let result = scheduler.add_alarm(body.time).await; + let result = scheduler.add_alarm(body.time, body.title).await; match result { Ok(alarm) => { diff --git a/src/scheduler.rs b/src/scheduler.rs index 1d1ae66..0908567 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -4,7 +4,7 @@ use chrono::{DateTime, Local, Timelike, Utc}; use cron_tab::Cron; use sea_orm::{DatabaseConnection, DbErr}; -use crate::dao::alarm::{self, create_alarm, get_alarms}; +use crate::dao::alarm::{create_alarm, get_alarms}; use crate::ringer::Ringer; use crate::types::Alarm; @@ -48,11 +48,11 @@ impl Scheduler { Ok(()) } - pub async fn add_alarm(&self, time: DateTime) -> Result { - let cron_schedule = format!("{} {} {} * * *", "*", time.minute(), time.hour()); - let alarm = Alarm::new(true, time); + pub async fn add_alarm(&self, time: DateTime, title: String) -> Result { + let cron_schedule = self.construct_cron_schedule(time); + let alarm = Alarm::new(true, time, title.clone()); - create_alarm(&*self.db, "something", time) + create_alarm(&*self.db, title, time) .await .map_err(|e| e.to_string())?; @@ -71,7 +71,46 @@ impl Scheduler { ) } - pub fn start(&self) { + pub async fn start(&self) { self.cron.lock().expect("Failed to lock cron").start(); + self.register_existing_alarms().await; } + + async fn register_existing_alarms(&self) { + let alarmsResult = self.get_alarms(Some(true)).await; + + match alarmsResult { + Ok(alarms) => { + self.register_alarms(alarms); + }, + Err(e) => { + println!("Failed to get alarms: {}", e); + } + } + } + + fn register_alarms(&self, alarms: Vec) { + alarms.into_iter().for_each(|a| { + self.register_alarm(a); + }); + } + + fn register_alarm(&self, alarm: Alarm) { + let cron_schedule = self.construct_cron_schedule(alarm.time); + let scheduling_result = self.schedule(&cron_schedule); + + match scheduling_result { + Ok(_) => { + println!("Registered alarm {}", cron_schedule); + }, + Err(e) => { + println!("Failed to register alarm {}: {}", cron_schedule, e); + } + } + } + + fn construct_cron_schedule(&self, time: DateTime) -> String { + let time = time.with_timezone(&Local); + format!("{} {} {} * * *", "*", time.minute(), time.hour()) + } } diff --git a/src/types.rs b/src/types.rs index 1dd34cb..f1e0aa7 100644 --- a/src/types.rs +++ b/src/types.rs @@ -7,11 +7,16 @@ use crate::model; pub struct Alarm { pub enabled: bool, pub time: DateTime, + pub title: String, } impl Alarm { - pub fn new(enabled: bool, time: DateTime) -> Self { - Self { enabled, time } + pub fn new(enabled: bool, time: DateTime, title: String) -> Self { + Self { + enabled, + time, + title, + } } } @@ -20,6 +25,7 @@ impl From for Alarm { Self { enabled: value.enabled, time: DateTime::from_utc(value.time, Utc), + title: value.title, } } }