Add strict mode and defaults for GET tagged schedules
This commit is contained in:
		
							parent
							
								
									f9ad8f9399
								
							
						
					
					
						commit
						3c70ae1da3
					
				
					 4 changed files with 41 additions and 75 deletions
				
			
		
							
								
								
									
										66
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										66
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -723,9 +723,6 @@ dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "libsqlite3-sys",
 | 
					 "libsqlite3-sys",
 | 
				
			||||||
 "log",
 | 
					 "log",
 | 
				
			||||||
 "rppal 0.17.1",
 | 
					 | 
				
			||||||
 "rppal-mcp23s17",
 | 
					 | 
				
			||||||
 "rppal-pfd",
 | 
					 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_derive",
 | 
					 "serde_derive",
 | 
				
			||||||
 "serde_json",
 | 
					 "serde_json",
 | 
				
			||||||
| 
						 | 
					@ -1703,48 +1700,6 @@ dependencies = [
 | 
				
			||||||
 "serde_derive",
 | 
					 "serde_derive",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "rppal"
 | 
					 | 
				
			||||||
version = "0.14.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "612e1a22e21f08a246657c6433fe52b773ae43d07c9ef88ccfc433cc8683caba"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "rppal"
 | 
					 | 
				
			||||||
version = "0.17.1"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "1dc171bbe325b04172e18d917c58c2cf1fb5adfd9ffabb1d6b3d62ba4c1c1331"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "libc",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "rppal-mcp23s17"
 | 
					 | 
				
			||||||
version = "0.0.3"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "66119979a7ae3d743517c63b26e039080bd8d3b9c782bad5103c06877293b1cf"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "bitflags 1.3.2",
 | 
					 | 
				
			||||||
 "log",
 | 
					 | 
				
			||||||
 "rppal 0.14.1",
 | 
					 | 
				
			||||||
 "thiserror",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "rppal-pfd"
 | 
					 | 
				
			||||||
version = "0.0.5"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "1804948e00d57085912f87c724be9aa4fdb6c00aa54ef8cf1eae40dd76053088"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "log",
 | 
					 | 
				
			||||||
 "rppal 0.14.1",
 | 
					 | 
				
			||||||
 "rppal-mcp23s17",
 | 
					 | 
				
			||||||
 "thiserror",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "rsa"
 | 
					name = "rsa"
 | 
				
			||||||
version = "0.9.6"
 | 
					version = "0.9.6"
 | 
				
			||||||
| 
						 | 
					@ -2382,16 +2337,15 @@ dependencies = [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "tokio-util"
 | 
					name = "tokio-util"
 | 
				
			||||||
version = "0.7.10"
 | 
					version = "0.7.11"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
 | 
					checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "bytes",
 | 
					 "bytes",
 | 
				
			||||||
 "futures-core",
 | 
					 "futures-core",
 | 
				
			||||||
 "futures-sink",
 | 
					 "futures-sink",
 | 
				
			||||||
 "pin-project-lite",
 | 
					 "pin-project-lite",
 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
 "tracing",
 | 
					 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
| 
						 | 
					@ -2533,9 +2487,9 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "utoipa"
 | 
					name = "utoipa"
 | 
				
			||||||
version = "4.2.0"
 | 
					version = "4.2.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "272ebdfbc99111033031d2f10e018836056e4d2c8e2acda76450ec7974269fa7"
 | 
					checksum = "e95b8d4503ee98939fb7024f6da083f7c48ff033cc3cba7521360e1bc6c1470b"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "indexmap",
 | 
					 "indexmap",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
| 
						 | 
					@ -2545,9 +2499,9 @@ dependencies = [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "utoipa-gen"
 | 
					name = "utoipa-gen"
 | 
				
			||||||
version = "4.2.0"
 | 
					version = "4.3.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "d3c9f4d08338c1bfa70dde39412a040a884c6f318b3d09aaaf3437a1e52027fc"
 | 
					checksum = "7bf0e16c02bc4bf5322ab65f10ab1149bdbcaa782cba66dc7057370a3f8190be"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "proc-macro-error",
 | 
					 "proc-macro-error",
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
| 
						 | 
					@ -2856,18 +2810,18 @@ dependencies = [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "zerocopy"
 | 
					name = "zerocopy"
 | 
				
			||||||
version = "0.7.32"
 | 
					version = "0.7.33"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
 | 
					checksum = "087eca3c1eaf8c47b94d02790dd086cd594b912d2043d4de4bfdd466b3befb7c"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "zerocopy-derive",
 | 
					 "zerocopy-derive",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "zerocopy-derive"
 | 
					name = "zerocopy-derive"
 | 
				
			||||||
version = "0.7.32"
 | 
					version = "0.7.33"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
 | 
					checksum = "6f4b6c273f496d8fd4eaf18853e6b448760225dc030ff2c485a786859aea6393"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "proc-macro2",
 | 
					 "proc-macro2",
 | 
				
			||||||
 "quote",
 | 
					 "quote",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								src/main.rs
									
										
									
									
									
								
							| 
						 | 
					@ -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(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue