title is now also part of the whole process

This commit is contained in:
2026-03-03 12:58:45 +01:00
parent cf67c980a2
commit 37b8fe5e56
7 changed files with 64 additions and 17 deletions

Binary file not shown.

View File

@@ -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<C: ConnectionTrait>(
db: &C,
title: &str,
title: String,
time: DateTime<Utc>,
) -> Result<alarm::Model, DbErr> {
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()

View File

@@ -55,7 +55,7 @@ async fn app_state() -> AppState {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let app_state = app_state().await;
app_state.scheduler.start();
app_state.scheduler.start().await;
start_axum_server(app_state).await;
Ok(())

View File

@@ -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<Utc>,
}
@@ -39,7 +39,7 @@ pub struct RequestQuery {
impl From<Alarm> for OkResponse {
fn from(value: Alarm) -> Self {
Self {
name: value.time.to_string(),
title: value.title,
enabled: value.enabled,
time: value.time,
}

View File

@@ -12,12 +12,14 @@ use crate::types::Alarm;
#[derive(Debug, Deserialize, ToSchema)]
pub struct RequestBody {
title: String,
time: DateTime<Utc>,
}
#[derive(ToSchema, Serialize)]
pub struct OkResponseBody {
time: DateTime<Utc>,
title: String,
enabled: bool,
}
@@ -41,7 +43,7 @@ impl IntoResponse for Responses {
impl From<Alarm> 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<Alarm> for OkResponseBody {
)]
#[debug_handler]
pub async fn post_handler(State(AppState { scheduler, ..}): State<AppState>, Json(body): Json<RequestBody>) -> Responses {
let result = scheduler.add_alarm(body.time).await;
let result = scheduler.add_alarm(body.time, body.title).await;
match result {
Ok(alarm) => {

View File

@@ -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<Utc>) -> Result<Alarm, String> {
let cron_schedule = format!("{} {} {} * * *", "*", time.minute(), time.hour());
let alarm = Alarm::new(true, time);
pub async fn add_alarm(&self, time: DateTime<Utc>, title: String) -> Result<Alarm, String> {
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<Alarm>) {
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<Utc>) -> String {
let time = time.with_timezone(&Local);
format!("{} {} {} * * *", "*", time.minute(), time.hour())
}
}

View File

@@ -7,11 +7,16 @@ use crate::model;
pub struct Alarm {
pub enabled: bool,
pub time: DateTime<Utc>,
pub title: String,
}
impl Alarm {
pub fn new(enabled: bool, time: DateTime<Utc>) -> Self {
Self { enabled, time }
pub fn new(enabled: bool, time: DateTime<Utc>, title: String) -> Self {
Self {
enabled,
time,
title,
}
}
}
@@ -20,6 +25,7 @@ impl From<model::alarm::Model> for Alarm {
Self {
enabled: value.enabled,
time: DateTime::from_utc(value.time, Utc),
title: value.title,
}
}
}