From 6400b7745c07a80b77ad24e2fa37652e659476f2 Mon Sep 17 00:00:00 2001 From: Tobias Reisinger Date: Thu, 30 Nov 2023 01:43:56 +0100 Subject: [PATCH] Improve controller endpoint and model --- emgauwa-core/src/handlers/v1/controllers.rs | 67 ++++++++++++++++++++- emgauwa-core/src/main.rs | 3 + emgauwa-lib/src/models/mod.rs | 20 +++++- emgauwa-lib/src/types/controller_uid.rs | 9 ++- emgauwa-lib/src/utils.rs | 11 ++++ 5 files changed, 103 insertions(+), 7 deletions(-) diff --git a/emgauwa-core/src/handlers/v1/controllers.rs b/emgauwa-core/src/handlers/v1/controllers.rs index f3fed61..90a0994 100644 --- a/emgauwa-core/src/handlers/v1/controllers.rs +++ b/emgauwa-core/src/handlers/v1/controllers.rs @@ -1,10 +1,18 @@ -use actix_web::{get, web, HttpResponse}; +use actix_web::{delete, get, put, web, HttpResponse}; +use emgauwa_lib::db::errors::DatabaseError; use emgauwa_lib::db::DbController; -use emgauwa_lib::models::{convert_db_list, Controller}; +use emgauwa_lib::models::{convert_db_list, Controller, FromDbModel}; +use emgauwa_lib::types::ControllerUid; +use serde_derive::{Deserialize, Serialize}; use sqlx::{Pool, Sqlite}; use crate::handlers::errors::ApiError; +#[derive(Debug, Serialize, Deserialize)] +pub struct RequestController { + name: String, +} + #[get("/api/v1/controllers")] pub async fn index(pool: web::Data>) -> Result { let mut pool_conn = pool.acquire().await?; @@ -15,3 +23,58 @@ pub async fn index(pool: web::Data>) -> Result>, + path: web::Path<(String,)>, +) -> Result { + let mut pool_conn = pool.acquire().await?; + + let (controller_uid,) = path.into_inner(); + let uid = ControllerUid::try_from(controller_uid.as_str()).or(Err(ApiError::BadUid))?; + + let controller = DbController::get_by_uid(&mut pool_conn, &uid) + .await? + .ok_or(DatabaseError::NotFound)?; + + let return_controller = Controller::from_db_model(&mut pool_conn, controller)?; + Ok(HttpResponse::Ok().json(return_controller)) +} + +#[put("/api/v1/controllers/{controller_id}")] +pub async fn update( + pool: web::Data>, + path: web::Path<(String,)>, + data: web::Json, +) -> Result { + let mut pool_conn = pool.acquire().await?; + + let (controller_uid,) = path.into_inner(); + let uid = ControllerUid::try_from(controller_uid.as_str()).or(Err(ApiError::BadUid))?; + + let controller = DbController::get_by_uid(&mut pool_conn, &uid) + .await? + .ok_or(DatabaseError::NotFound)?; + + let controller = controller + .update(&mut pool_conn, data.name.as_str(), controller.relay_count) + .await?; + + let return_controller = Controller::from_db_model(&mut pool_conn, controller)?; + Ok(HttpResponse::Ok().json(return_controller)) +} + +#[delete("/api/v1/controllers/{controller_id}")] +pub async fn delete( + pool: web::Data>, + path: web::Path<(String,)>, +) -> Result { + let mut pool_conn = pool.acquire().await?; + + let (controller_uid,) = path.into_inner(); + let uid = ControllerUid::try_from(controller_uid.as_str()).or(Err(ApiError::BadUid))?; + + DbController::delete_by_uid(&mut pool_conn, uid).await?; + Ok(HttpResponse::Ok().json("controller got deleted")) +} diff --git a/emgauwa-core/src/main.rs b/emgauwa-core/src/main.rs index b38aa25..d542f5c 100644 --- a/emgauwa-core/src/main.rs +++ b/emgauwa-core/src/main.rs @@ -57,6 +57,9 @@ async fn main() -> std::io::Result<()> { .app_data(web::Data::new(pool.clone())) .app_data(web::Data::new(connected_controllers.clone())) .service(handlers::v1::controllers::index) + .service(handlers::v1::controllers::show) + .service(handlers::v1::controllers::update) + .service(handlers::v1::controllers::delete) .service(handlers::v1::relays::index) .service(handlers::v1::schedules::index) .service(handlers::v1::schedules::tagged) diff --git a/emgauwa-lib/src/models/mod.rs b/emgauwa-lib/src/models/mod.rs index 1846470..187d640 100644 --- a/emgauwa-lib/src/models/mod.rs +++ b/emgauwa-lib/src/models/mod.rs @@ -4,8 +4,9 @@ use sqlx::pool::PoolConnection; use sqlx::Sqlite; use crate::db::errors::DatabaseError; -use crate::db::{DbController, DbRelay, DbSchedule}; -use crate::types::ControllerUid; +use crate::db::{DbController, DbJunctionRelaySchedule, DbRelay, DbSchedule}; +use crate::types::{ControllerUid, Weekday}; +use crate::utils; pub trait FromDbModel { type DbModel: Clone; @@ -40,6 +41,8 @@ pub struct Relay { pub r: DbRelay, pub controller: DbController, pub controller_id: ControllerUid, + pub schedules: Vec, + pub active_schedule: DbSchedule, pub tags: Vec, } @@ -96,10 +99,23 @@ impl FromDbModel for Relay { let tags = executor::block_on(db_model.get_tags(conn))?; let controller_id = cache.uid.clone(); + let schedules = + executor::block_on(DbJunctionRelaySchedule::get_schedules(conn, &db_model))?; + + let weekday = utils::get_weekday(); + let active_schedule = executor::block_on(DbJunctionRelaySchedule::get_schedule( + conn, + &db_model, + weekday as Weekday, + ))? + .ok_or(DatabaseError::NotFound)?; + Ok(Relay { r: db_model, controller: cache, controller_id, + schedules, + active_schedule, tags, }) } diff --git a/emgauwa-lib/src/types/controller_uid.rs b/emgauwa-lib/src/types/controller_uid.rs index 85d8ffd..35793fb 100644 --- a/emgauwa-lib/src/types/controller_uid.rs +++ b/emgauwa-lib/src/types/controller_uid.rs @@ -67,9 +67,12 @@ impl<'r> Decode<'r, Sqlite> for ControllerUid { } } -impl From<&str> for ControllerUid { - fn from(value: &str) -> Self { - Self(Uuid::from_str(value).unwrap()) +impl TryFrom<&str> for ControllerUid { + type Error = uuid::Error; + + fn try_from(value: &str) -> Result { + let uuid = Uuid::from_str(value)?; + Ok(Self(uuid)) } } diff --git a/emgauwa-lib/src/utils.rs b/emgauwa-lib/src/utils.rs index 0d8e6ab..27c253d 100644 --- a/emgauwa-lib/src/utils.rs +++ b/emgauwa-lib/src/utils.rs @@ -1,8 +1,11 @@ use std::str::FromStr; +use chrono::Datelike; use log::LevelFilter; use simple_logger::SimpleLogger; +use crate::types::Weekday; + pub fn load_settings(config_name: &str, env_prefix: &str) -> T where for<'de> T: serde::Deserialize<'de>, @@ -31,3 +34,11 @@ pub fn init_logging(level: &str) { .init() .expect("Error initializing logger."); } + +pub fn get_weekday() -> Weekday { + (chrono::offset::Local::now() + .date_naive() + .weekday() + .number_from_monday() + - 1) as Weekday +}