use crate::website::{Page, PageTemplate, WebSite}; use crate::AppState; use actix_web::{ delete, get, post, put, web::{Data, Json}, HttpResponse, }; use std::sync::RwLock; #[derive(serde::Deserialize, Clone)] pub struct AddPageData { parent_page_id: usize, new_page: Page, } #[post("/add-page")] pub async fn add_page( app_state: Data<RwLock<AppState>>, website: Data<RwLock<WebSite>>, add_page_data: Json<AddPageData>, ) -> HttpResponse { let add_page_data = add_page_data.into_inner(); let mut website = website .write() .expect("Couldn't acquire website write lock"); match website.add_page(add_page_data.parent_page_id, add_page_data.new_page.clone()) { Ok(()) => { if let Err(msg) = website.build() { return HttpResponse::InternalServerError() .body(format!("Error rebuilding Website - {}", msg)); } if let Err(msg) = website.save(&app_state.read().expect("Couldn't read AppState").config) { return HttpResponse::InternalServerError() .body(format!("Error saving website to static file - {}", msg)); }; HttpResponse::Created().finish() } Err(msg) => { HttpResponse::BadRequest().body(format!("Error adding new page to website - {}", msg)) } } } #[get("/page-data/{id}")] pub async fn get_page_data( website: Data<RwLock<WebSite>>, id: actix_web::web::Path<usize>, ) -> HttpResponse { let id = id.into_inner(); match website .read() .expect("Couldn't acquire website read lock") .get_page(id) { Some(page) => HttpResponse::Ok().json(page), None => HttpResponse::NotFound().body(format!("Page with id {} was not found", id)), } } #[put("/update-page/{id}")] pub async fn update_page( id: actix_web::web::Path<usize>, app_state: Data<RwLock<AppState>>, website: Data<RwLock<WebSite>>, updated_page: Json<Page>, ) -> HttpResponse { let id = id.into_inner(); let mut website = website .write() .expect("Couldn't acquire website write lock"); let page = { match website.update_page(id, updated_page.into_inner()) { Ok(page) => page.clone(), Err(msg) => { return HttpResponse::BadRequest() .body(format!("Error updating page with id {} - {:?}", id, msg)); } } }; if let Err(msg) = website.build() { return HttpResponse::InternalServerError() .body(format!("Error rebuilding Website - {}", msg)); } if let Err(msg) = website.save(&app_state.read().expect("Couldn't read AppState").config) { return HttpResponse::InternalServerError() .body(format!("Error saving website to static file - {}", msg)); }; HttpResponse::Ok().json(page) } #[post("/add-template")] pub async fn add_template( app_state: Data<RwLock<AppState>>, website: Data<RwLock<WebSite>>, new_template: Json<PageTemplate>, ) -> HttpResponse { let template = { match website .write() .expect("Couldn't acquire website write lock") .add_template(new_template.into_inner()) { Ok(template) => template.clone(), Err(msg) => { return HttpResponse::BadRequest() .body(format!("Error adding new template {}", msg)) } } }; if let Err(msg) = website .read() .expect("Couldn't read WebSite") .save(&app_state.read().expect("Couldn't read AppState").config) { return HttpResponse::InternalServerError() .body(format!("Error saving website to static file - {}", msg)); }; HttpResponse::Created().json(template) } #[put("/update-template")] pub async fn update_template( app_state: Data<RwLock<AppState>>, website: Data<RwLock<WebSite>>, updated_template: Json<PageTemplate>, ) -> HttpResponse { let mut website = website .write() .expect("Couldn't acquire website write lock"); let updated = { match website.update_template(updated_template.into_inner()) { Ok(template) => template.clone(), Err(msg) => { return HttpResponse::BadRequest().body(format!("Error updating template {}", msg)) } } }; WebSite::update_page_rec_after_template_update(&mut website.root_page, &updated); if let Err(msg) = website.build() { return HttpResponse::InternalServerError() .body(format!("Error rebuilding Website - {}", msg)); } if let Err(msg) = website.save(&app_state.read().expect("Couldn't read AppState").config) { return HttpResponse::InternalServerError() .body(format!("Error saving website to static file - {}", msg)); }; HttpResponse::Ok().json(updated) } #[delete("/remove-page/{id}")] pub async fn remove_page( id: actix_web::web::Path<usize>, app_state: Data<RwLock<AppState>>, website: Data<RwLock<WebSite>>, ) -> HttpResponse { let mut website = website .write() .expect("Couldn't acquire website write lock"); match website.remove_page(id.into_inner()) { Ok(()) => { website .save(&app_state.read().expect("Couldn't read AppState").config) .expect("Error saving website to static file"); HttpResponse::Accepted().finish() } Err(msg) => HttpResponse::BadRequest().body(msg), } } #[delete("remove-template/{name}")] pub async fn remove_template( name: actix_web::web::Path<String>, app_state: Data<RwLock<AppState>>, website: Data<RwLock<WebSite>>, ) -> HttpResponse { let mut website = website .write() .expect("Couldn't acquire website write lock"); match website.remove_template(name.into_inner()) { Ok(()) => { if let Err(msg) = website.save(&app_state.read().expect("Couldn't read AppState").config) { return HttpResponse::InternalServerError() .body(format!("Error saving website to static file {}", msg)); } HttpResponse::Accepted().finish() } Err(msg) => HttpResponse::BadRequest().body(msg), } }