All checks were successful
continuous-integration/drone/push Build is passing
187 lines
5.5 KiB
Rust
187 lines
5.5 KiB
Rust
use r2d2::PooledConnection;
|
|
use r2d2_sqlite::{SqliteConnectionManager, rusqlite::Statement};
|
|
use rocket::{serde::{json::{Json, serde_json::json}, 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 {
|
|
ledcount: 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.ledcount, 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() {
|
|
println!("stmt: {}", stat);
|
|
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;")?;
|
|
|
|
|
|
#[derive(Debug)]
|
|
struct Data {
|
|
configured: u32,
|
|
}
|
|
|
|
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 version_iter = version_iter.ok().unwrap();
|
|
|
|
for data in version_iter {
|
|
let data = data.unwrap();
|
|
if data.configured == 1 {
|
|
return Ok(true);
|
|
}
|
|
}
|
|
return Ok(false);
|
|
}
|
|
|
|
#[get("/configure")]
|
|
pub async fn get_configure(db: &State<DBPool>) -> 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)]
|
|
#[serde(crate = "rocket::serde")]
|
|
#[serde(rename_all = "camelCase")]
|
|
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()
|
|
}
|