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()
 | |
| }
 |