Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
Commit bd8bd674 authored by Pierre Jarriges's avatar Pierre Jarriges
Browse files

get page add page

parent ca03f043
No related branches found
No related tags found
No related merge requests found
......@@ -4,7 +4,9 @@
"metadata": {
"title": "Hello Krustcea !",
"description": "An example website",
"image": "https://example.com/images/ex_pic.png",
"image": [
"https://example.com/images/ex_pic.png"
],
"css": [],
"js": [],
"url_slug": "",
......
......@@ -58,7 +58,9 @@ async fn main() -> std::io::Result<()> {
.service(
web::scope("/auth")
.wrap(AuthService {})
.service(service::admin_workspace),
.service(service::admin_workspace)
.service(service::add_page)
.service(service::get_page_data),
),
)
.service(service::files::favicon)
......
use crate::website::{Page, WebSite};
use crate::AppState;
use actix_web::{
get, post,
web::{Data, Form},
HttpRequest, HttpResponse, Responder,
web::{Data, Form, Json},
HttpRequest, HttpResponse,
};
use std::sync::RwLock;
#[get("/workspace")]
async fn admin_workspace() -> impl Responder {
async fn admin_workspace() -> HttpResponse {
// TODO return admin static web view with js application
actix_web::HttpResponse::Ok().body("Welcome Admin")
}
......@@ -23,7 +24,7 @@ async fn admin_authenticate(
credentials: Form<Credentials>,
app_state: Data<RwLock<AppState>>,
req: HttpRequest,
) -> impl Responder {
) -> HttpResponse {
let (admin_username, admin_pwd, cookie_name) = {
let app_state = app_state
.read()
......@@ -57,7 +58,7 @@ async fn admin_authenticate(
}
#[get("/login")]
pub async fn admin_login() -> impl Responder {
pub async fn admin_login() -> HttpResponse {
// TODO create a module with built-in admin static views
HttpResponse::Ok().body(
"
......@@ -88,3 +89,42 @@ pub async fn admin_login() -> impl Responder {
",
)
}
#[derive(serde::Deserialize, Clone)]
pub struct AddPageData {
parent_page_id: usize,
new_page: Page,
}
#[post("/add-page")]
pub async fn add_page(
website: Data<RwLock<WebSite>>,
add_page_data: Json<AddPageData>,
) -> HttpResponse {
match website
.write()
.expect("Couldn't acquire website write lock")
.add_page(add_page_data.parent_page_id, add_page_data.new_page.clone())
{
Ok(()) => HttpResponse::Ok().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)),
}
}
......@@ -318,6 +318,10 @@ impl Page {
map
}
pub fn add_sub_page(&mut self, page: Page) {
self.sub_pages.push(page);
}
}
#[cfg(test)]
......
......@@ -115,47 +115,38 @@ impl WebSite {
Ok(self.clone())
}
fn init_last_generated_page_id(&mut self) {
let mut ids = vec![self.root_page.get_id()];
fn collect_ids(p: &Page, ids: &mut Vec<usize>) {
for sp in p.sub_pages.iter() {
ids.push(sp.get_id());
collect_ids(sp, ids);
pub fn get_all_pages_as_vec(&self) -> Vec<&Page> {
let mut pages = Vec::new();
fn collect_pages<'a>(root: &'a Page, vec: &mut Vec<&'a Page>) {
vec.push(root);
for p in root.sub_pages.iter() {
collect_pages(p, vec);
}
}
collect_ids(&self.root_page, &mut ids);
self.last_generated_page_id = *ids.iter().max().unwrap();
collect_pages(&self.root_page, &mut pages);
pages
}
fn generate_pages_ids(&mut self) {
self.init_last_generated_page_id();
fn max_page_id(&self) -> usize {
self.get_all_pages_as_vec()
.iter()
.map(|p| p.get_id())
.max()
.unwrap()
}
fn generate_page_id(page: &mut Page, last_generated_page_id: &mut usize) {
if page.get_id() == 0 {
*last_generated_page_id += 1;
page.set_id(*last_generated_page_id);
}
}
fn generate_pages_ids<'a>(&'a mut self) {
self.last_generated_page_id = self.max_page_id();
fn rec_gen_ids(
p: &mut Page,
gen_id: fn(&mut Page, &mut usize),
last_generated_page_id: &mut usize,
) {
gen_id(p, last_generated_page_id);
for sp in p.sub_pages.iter_mut() {
rec_gen_ids(sp, gen_id, last_generated_page_id)
fn process_page(page: &mut Page, id: &mut usize) {
*id += 1;
page.set_id(*id);
for sp in page.sub_pages.iter_mut() {
process_page(sp, id);
}
}
rec_gen_ids(
&mut self.root_page,
generate_page_id,
&mut self.last_generated_page_id,
);
process_page(&mut self.root_page, &mut self.last_generated_page_id);
}
pub fn save(&self, config: &AppConfig) -> std::io::Result<()> {
......@@ -172,4 +163,131 @@ impl WebSite {
Ok(())
}
fn find_page(page: &Page, match_id: usize) -> Option<&Page> {
if page.get_id() == match_id {
return Some(page);
}
for sp in page.sub_pages.iter() {
if let Some(page) = Self::find_page(sp, match_id) {
return Some(page);
};
}
None
}
fn find_page_mut(page: &mut Page, match_id: usize) -> Option<&mut Page> {
if page.get_id() == match_id {
return Some(page);
}
for sp in page.sub_pages.iter_mut() {
if let Some(p) = Self::find_page_mut(sp, match_id) {
return Some(p);
};
}
None
}
pub fn get_page(&self, id: usize) -> Option<&Page> {
Self::find_page(&self.root_page, id)
}
pub fn add_page(&mut self, parent_page_id: usize, page: Page) -> Result<(), String> {
let id = self.last_generated_page_id + 1;
let parent_page = Self::find_page_mut(&mut self.root_page, parent_page_id);
match parent_page {
Some(pp) => {
let mut page = page;
page.set_id(id);
pp.add_sub_page(page);
}
None => {
return Err(format!(
"Parent page with id {} was not found",
parent_page_id
))
}
}
self.last_generated_page_id = id;
Ok(())
}
}
#[cfg(test)]
mod test_website {
use super::*;
fn test_website(pth: &PathBuf) -> WebSite {
WebSiteBuilder::testing(pth).build().unwrap()
}
fn remove_test_dir(pth: &PathBuf) {
let _ = std::fs::remove_dir_all(pth);
}
#[test]
fn test_pages_id() {
let test_dir = &PathBuf::from("./test");
let ws = test_website(&test_dir);
assert_eq!(ws.last_generated_page_id, 3);
assert_eq!(ws.max_page_id(), 3);
assert!(!ws.get_all_pages_as_vec().iter().any(|p| p.get_id() == 0));
remove_test_dir(&test_dir);
}
#[test]
fn test_get_page() {
let test_dir = &PathBuf::from("./test");
let ws = test_website(&test_dir);
let page = ws.get_page(1);
assert!(page.is_some());
let page = ws.get_page(2);
assert!(page.is_some());
let page = ws.get_page(3);
assert!(page.is_some());
let page = ws.get_page(4);
assert!(page.is_none());
remove_test_dir(&test_dir);
}
#[test]
fn test_add_page() {
let test_dir = &PathBuf::from("./test");
let mut ws = test_website(&test_dir);
let test_new_page: &'static str = "
{
\"template_name\": \"TEST TEMPLATE\",
\"metadata\": {
\"title\": \"Added page\",
\"description\": \"Added page descr\",
\"image\": [\"https://example.com/images/ex_pic.png\"],
\"css\": [],
\"js\": [],
\"url_slug\": \"\",
\"lang\": \"en\"
},
\"body\": [
{
\"tag\": \"h1\",
\"text\": \"Added page\"
}
],
\"sub_pages\": []
}
";
let new_page: Page = serde_json::from_str(test_new_page).unwrap();
let added = ws.add_page(1, new_page);
assert!(added.is_ok());
let retrieved = ws.get_page(4);
assert!(retrieved.is_some());
let retrieved = retrieved.unwrap();
assert_eq!(retrieved.metadata.title, "Added page");
remove_test_dir(&test_dir);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment