Files
lights/src/configure.rs
Andre Henriques d9e9a33b3d
All checks were successful
continuous-integration/drone/push Build is passing
chore: update configuration
2023-07-09 20:13:25 +01:00

186 lines
5.6 KiB
Rust

use r2d2::PooledConnection;
use r2d2_sqlite::{SqliteConnectionManager, rusqlite::Statement};
use rocket::{serde::{json::{Json, serde_json::json, self}, Deserialize, Serialize}, State};
use crate::{utils::{ApiResponse, get_error_message}, Action, ASender};
use crate::DBPool;
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(crate = "rocket::serde")]
#[serde(rename_all = "camelCase")]
pub struct LightConfiguration {
number: u32,
direction_x: u32,
direction_y: u32,
direction_z: u32,
tags: Option<String>
}
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(crate = "rocket::serde")]
#[serde(rename_all = "camelCase")]
pub struct LightConfigurationRequest {
lights: Vec<LightConfiguration>
}
#[post("/configure", data= "<data>")]
pub async fn configure(data: Json<LightConfigurationRequest>, db: &State<DBPool>, action: &State<ASender<Action>>) -> String {
let conn = get_conn(db);
if let Err(e) = conn {
return e;
}
let conn = conn.unwrap();
let recreate = is_configured(&conn);
if let Err(e) = recreate {
return e;
}
let recreate = recreate.unwrap();
if recreate {
let stmt = conn.execute("DELETE FROM configuration;", ());
if stmt.is_err() || stmt.as_ref().ok().is_none() {
return json!(ApiResponse {code: 500, message: format!("Clould not configure. Err: 4, {:?}", stmt)}).to_string();
}
}
for light in data.lights.iter() {
let mut tags: String = "".to_string();
if light.tags.is_some() {
tags = light.tags.as_ref().unwrap().to_string()
}
let stmt = conn.execute(
"INSERT INTO configuration (ledcount, directionX, directionY, directionZ, tags) VALUES (?1, ?2, ?3, ?4, ?5);",
(light.number, light.direction_x, light.direction_y, light.direction_z, tags));
if stmt.is_err() || stmt.as_ref().ok().is_none() {
return json!(ApiResponse {code: 500, message: format!("Clould not configure. Err: 5, {:?}", stmt)}).to_string();
}
}
let send = action.lock().unwrap().send(Action::Reload);
if send.is_err() || send.ok().is_none() {
return json!(ApiResponse {code: 500, message: "Failed to reload".to_string()}).to_string()
}
let stmt = conn.execute("UPDATE meta set configured=1 where id=1;", ());
if stmt.is_err() || stmt.as_ref().ok().is_none() {
return json!(ApiResponse {code: 500, message: format!("Clould not configure. Err: 5, {:?}", stmt)}).to_string();
}
json!(ApiResponse {code: 200, message: "Configuration was successful".to_string()}).to_string()
}
type Conn = PooledConnection<SqliteConnectionManager>;
fn get_conn(db: &State<DBPool>) -> Result<Conn, String> {
let conn = db.get();
if let Ok(conn) = conn {
return Ok(conn);
}
Err(json!(ApiResponse {code: 500, message: "Clould not conncect to the db.".to_string()}).to_string())
}
fn prepare_statement<'a>(conn: &'a Conn, stat: &str) -> Result<Statement<'a>, String> {
let stmt = conn.prepare(stat);
if stmt.is_err() || stmt.as_ref().ok().is_none() {
return Err(get_error_message("Could not construct statetment"));
}
let stmt: Statement<'a> = stmt.unwrap();
return Ok(stmt);
}
fn is_configured(conn: &Conn) -> Result<bool, String> {
let mut stmt = prepare_statement(conn, "SELECT configured from meta")?;
struct Data {
configured: bool,
}
let version_iter = stmt.query_map([], |row| {
Ok(Data {
configured: row.get(0)?
})
});
if version_iter.is_err() || version_iter.as_ref().ok().is_none() {
return Err(json!(ApiResponse {code: 500, message: "Clould not get data of db".to_string()}).to_string());
}
let mut version_iter = version_iter.ok().unwrap();
if version_iter.by_ref().count() > 1 {
return Err(json!(ApiResponse {code: 500, message: "Change something is very wrong!".to_string()}).to_string());
}
for data in version_iter {
if data.unwrap().configured {
return Ok(true);
}
}
return Ok(false);
}
#[get("/configure")]
pub async fn get_configure(db: &State<DBPool>, action: &State<ASender<Action>>) -> String {
let conn = get_conn(db);
if let Err(e) = conn {
return e;
}
let conn = conn.unwrap();
let configured = is_configured(&conn);
if let Err(e) = configured {
return e;
}
let configured = configured.unwrap();
if !configured {
return get_error_message("Not yet configured");
}
let stmt = prepare_statement(&conn, "SELECT id ledcount directionX directionY directionZ tags from configuration;");
if let Err(e) = stmt {
return e;
}
let mut stmt = stmt.unwrap();
#[derive(Deserialize, Serialize)]
struct Data {
id: u32,
ledcount: u32,
direction_x: u32,
direction_y: u32,
direction_z: u32,
tags: String,
}
let configuration = stmt.query_map([], |row| {
Ok(Data {
id: row.get(0)?,
ledcount: row.get(1)?,
direction_x: row.get(2)?,
direction_y: row.get(3)?,
direction_z: row.get(4)?,
tags: row.get(5)?,
})
});
if configuration.is_err() || configuration.as_ref().ok().is_none() {
return json!(ApiResponse {code: 500, message: "Clould not get data of db".to_string()}).to_string();
}
let configuration = configuration.unwrap();
let data: Vec<Data> = configuration.into_iter().map(|data| {
return data.unwrap();
}).collect();
json!(data).to_string()
}