Add strict mode and defaults for GET tagged schedules

This commit is contained in:
Tobias Reisinger 2024-05-06 16:27:42 +02:00
parent f9ad8f9399
commit 3c70ae1da3
Signed by: serguzim
GPG key ID: 13AD60C237A28DFE
4 changed files with 31 additions and 19 deletions

BIN
Cargo.lock generated

Binary file not shown.

View file

@ -209,6 +209,14 @@
"in": "path", "in": "path",
"required": true, "required": true,
"description": "" "description": ""
},
{
"schema": {
"type": "boolean"
},
"name": "strict",
"in": "query",
"description": "Normally on and off will always be included. When strict is set to true, only schedules with the given tag will be returned."
} }
], ],
"get": { "get": {

View file

@ -3,9 +3,7 @@ use actix_web::{delete, get, post, put, web, HttpResponse};
use emgauwa_common::db::{DbController, DbJunctionRelaySchedule, DbSchedule, DbTag}; use emgauwa_common::db::{DbController, DbJunctionRelaySchedule, DbSchedule, DbTag};
use emgauwa_common::errors::{ApiError, DatabaseError, EmgauwaError}; use emgauwa_common::errors::{ApiError, DatabaseError, EmgauwaError};
use emgauwa_common::models::{convert_db_list, FromDbModel, Schedule}; use emgauwa_common::models::{convert_db_list, FromDbModel, Schedule};
use emgauwa_common::types::{ use emgauwa_common::types::{ControllerWsAction, RequestScheduleCreate, RequestScheduleGetTagged, RequestScheduleUpdate, ScheduleUid};
ControllerWsAction, RequestScheduleCreate, RequestScheduleUpdate, ScheduleUid,
};
use itertools::Itertools; use itertools::Itertools;
use sqlx::pool::PoolConnection; use sqlx::pool::PoolConnection;
use sqlx::{Pool, Sqlite}; use sqlx::{Pool, Sqlite};
@ -28,6 +26,7 @@ pub async fn index(pool: web::Data<Pool<Sqlite>>) -> Result<HttpResponse, Emgauw
pub async fn tagged( pub async fn tagged(
pool: web::Data<Pool<Sqlite>>, pool: web::Data<Pool<Sqlite>>,
path: web::Path<(String,)>, path: web::Path<(String,)>,
query: web::Query<RequestScheduleGetTagged>,
) -> Result<HttpResponse, EmgauwaError> { ) -> Result<HttpResponse, EmgauwaError> {
let mut pool_conn = pool.acquire().await?; let mut pool_conn = pool.acquire().await?;
@ -36,7 +35,20 @@ pub async fn tagged(
.await? .await?
.ok_or(DatabaseError::NotFound)?; .ok_or(DatabaseError::NotFound)?;
let db_schedules = DbSchedule::get_by_tag(&mut pool_conn, &tag_db).await?; let mut db_schedules = DbSchedule::get_by_tag(&mut pool_conn, &tag_db).await?;
// only add default schedules if strict is false
if !query.strict.unwrap_or(false) {
if !db_schedules.iter().any(|s| s.uid == ScheduleUid::Off) {
let off = DbSchedule::get_off(&mut pool_conn).await?;
db_schedules.push(off);
}
if !db_schedules.iter().any(|s| s.uid == ScheduleUid::On) {
let on = DbSchedule::get_on(&mut pool_conn).await?;
db_schedules.push(on);
}
}
let schedules: Vec<Schedule> = convert_db_list(&mut pool_conn, db_schedules)?; let schedules: Vec<Schedule> = convert_db_list(&mut pool_conn, db_schedules)?;
Ok(HttpResponse::Ok().json(schedules)) Ok(HttpResponse::Ok().json(schedules))

View file

@ -4,11 +4,12 @@ use actix::{Actor, Arbiter};
use actix_cors::Cors; use actix_cors::Cors;
use actix_web::middleware::TrailingSlash; use actix_web::middleware::TrailingSlash;
use actix_web::{middleware, web, App, HttpServer}; use actix_web::{middleware, web, App, HttpServer};
use serde_json::Value;
use utoipa_swagger_ui::SwaggerUi;
use emgauwa_common::db::DbController; use emgauwa_common::db::DbController;
use emgauwa_common::errors::EmgauwaError; use emgauwa_common::errors::EmgauwaError;
use emgauwa_common::utils::{drop_privileges, init_logging}; use emgauwa_common::utils::{drop_privileges, init_logging};
use serde_json::json;
use utoipa_swagger_ui::SwaggerUi;
use crate::app_state::AppState; use crate::app_state::AppState;
@ -46,6 +47,9 @@ async fn main() -> Result<(), std::io::Error> {
AppState::new(app_state_pool) AppState::new(app_state_pool)
}); });
let api_v1_json: Value =
serde_json::from_str(include_str!("../api.v1.json")).map_err(EmgauwaError::from)?;
log::info!( log::info!(
"Starting server on {}:{}", "Starting server on {}:{}",
settings.server.host, settings.server.host,
@ -63,18 +67,6 @@ async fn main() -> Result<(), std::io::Error> {
}), }),
}; };
let api_default = json!({
"openapi": "3.0.0",
"info": {
"version": "0.0.0",
"title": "Failed to load API documentation",
}
});
let api_v1_json =
serde_json::from_str(include_str!("../api.v1.json")).unwrap_or(api_default.clone());
App::new() App::new()
.wrap(cors) .wrap(cors)
.wrap(middleware::Logger::default()) .wrap(middleware::Logger::default())
@ -83,7 +75,7 @@ async fn main() -> Result<(), std::io::Error> {
.app_data(web::Data::new(app_state.clone())) .app_data(web::Data::new(app_state.clone()))
.service( .service(
SwaggerUi::new("/api/docs/{_:.*}") SwaggerUi::new("/api/docs/{_:.*}")
.external_urls_from_iter_unchecked([("/api/v1.json", api_v1_json)]), .external_urls_from_iter_unchecked([("/api/v1.json", api_v1_json.clone())]),
) )
.service(web::redirect("/api/docs", "/api/docs/")) .service(web::redirect("/api/docs", "/api/docs/"))
.service( .service(