This commit is contained in:
Pascal Engélibert 2020-11-02 11:41:55 +01:00
parent bcfccd6a0e
commit 11660e7d9d
3 changed files with 91 additions and 57 deletions

View File

@ -2,7 +2,7 @@ use super::{cli, config, db, static_files, templates};
use handlebars::to_json; use handlebars::to_json;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::value::{Map, Value as Json}; use serde_json::value::Value as Json;
use sha2::{Digest, Sha512Trunc256}; use sha2::{Digest, Sha512Trunc256};
use std::{ use std::{
convert::{TryFrom, TryInto}, convert::{TryFrom, TryInto},
@ -43,35 +43,35 @@ pub async fn start_server(
) { ) {
let templates = Arc::new(templates); let templates = Arc::new(templates);
let mut data = Map::<String, Json>::new(); let cache_ads = Arc::new(RwLock::new(to_json(
data.insert("lang".into(), to_json("fr")); dbs.ads
data.insert( .iter()
"ads".into(), .filter_map(|x| {
to_json( let (ad_id, ad) = x.ok()?;
dbs.ads Some(AdWithId {
.iter() id: hex::encode(ad_id.as_ref()),
.filter_map(|x| { ad: bincode::deserialize::<Ad>(&ad).ok()?,
let (ad_id, ad) = x.ok()?;
Some(AdWithId {
id: hex::encode(ad_id.as_ref()),
ad: bincode::deserialize::<Ad>(&ad).ok()?,
})
}) })
.collect::<Vec<AdWithId>>(), })
), .collect::<Vec<AdWithId>>(),
); )));
let data = Arc::new(RwLock::new(data));
let dbs = Arc::new(dbs); let dbs = Arc::new(dbs);
let handle_index = { let handle_index = {
let data = data.clone(); let cache_ads = cache_ads.clone();
move || { move |errors: &[ErrorTemplate]| {
warp::reply::html( warp::reply::html(
templates templates
.hb .hb
.render("index.html", &*data.read().unwrap()) .render(
"index.html",
&IndexTemplate {
lang: "fr",
errors,
ads: &*cache_ads.read().unwrap(),
},
)
.unwrap_or_else(|e| e.to_string()), .unwrap_or_else(|e| e.to_string()),
) )
} }
@ -84,7 +84,7 @@ pub async fn start_server(
let handle_new_ad = { let handle_new_ad = {
let handle_index = handle_index.clone(); let handle_index = handle_index.clone();
let dbs = dbs.clone(); let dbs = dbs.clone();
let data = data.clone(); let cache_ads = cache_ads.clone();
move |query: NewAdQuery| { move |query: NewAdQuery| {
let mut hasher = Sha512Trunc256::new(); let mut hasher = Sha512Trunc256::new();
hasher.update(query.psw); hasher.update(query.psw);
@ -102,22 +102,21 @@ pub async fn start_server(
) )
.unwrap(); .unwrap();
dbs.ads.flush().unwrap(); dbs.ads.flush().unwrap();
data.write().unwrap().insert( let mut cache_ads = cache_ads.write().unwrap();
"ads".into(), *cache_ads = to_json(
to_json( dbs.ads
dbs.ads .iter()
.iter() .filter_map(|x| {
.filter_map(|x| { let (ad_id, ad) = x.ok()?;
let (ad_id, ad) = x.ok()?; Some(AdWithId {
Some(AdWithId { id: hex::encode(ad_id.as_ref()),
id: hex::encode(ad_id.as_ref()), ad: bincode::deserialize::<Ad>(&ad).ok()?,
ad: bincode::deserialize::<Ad>(&ad).ok()?,
})
}) })
.collect::<Vec<AdWithId>>(), })
), .collect::<Vec<AdWithId>>(),
); );
handle_index() drop(cache_ads);
handle_index(&[])
} }
}; };
@ -148,41 +147,56 @@ pub async fn start_server(
dbs.ads.remove(&ad_id).unwrap(); dbs.ads.remove(&ad_id).unwrap();
dbs.ads.flush().unwrap(); dbs.ads.flush().unwrap();
data.write().unwrap().insert( let mut cache_ads = cache_ads.write().unwrap();
"ads".into(), *cache_ads = to_json(
to_json( dbs.ads
dbs.ads .iter()
.iter() .filter_map(|x| {
.filter_map(|x| { let (ad_id, ad) = x.ok()?;
let (ad_id, ad) = x.ok()?; Some(AdWithId {
Some(AdWithId { id: hex::encode(ad_id.as_ref()),
id: hex::encode(ad_id.as_ref()), ad: bincode::deserialize::<Ad>(&ad).ok()?,
ad: bincode::deserialize::<Ad>(&ad).ok()?,
})
}) })
.collect::<Vec<AdWithId>>(), })
), .collect::<Vec<AdWithId>>(),
); );
} else {
return handle_index(&[ErrorTemplate {text: "Le mot de passe de l'annonce est incorrect."}]);
} }
} }
} }
} }
} }
handle_index() handle_index(&[])
} }
}; };
let route_index = warp::path::end().and(warp::get().map(handle_index).or(warp::post().and( let route_index = warp::path::end().and(warp::get().map(move || handle_index(&[])).or(
warp::body::form::<Query>().map(move |query: Query| match query { warp::post().and(
Query::NewAdQuery(query) => handle_new_ad(query), warp::body::form::<Query>().map(move |query: Query| match query {
Query::RmAdQuery(query) => handle_rm_ad(query), Query::NewAdQuery(query) => handle_new_ad(query),
}), Query::RmAdQuery(query) => handle_rm_ad(query),
))); }),
),
));
warp::serve(route_static.or(route_index)) warp::serve(route_static.or(route_index))
.run(config.listen) .run(config.listen)
.await; .await;
} }
#[derive(Serialize)]
struct IndexTemplate<'a> {
lang: &'a str,
errors: &'a [ErrorTemplate<'a>],
ads: &'a Json,
}
#[derive(Serialize)]
struct ErrorTemplate<'a> {
text: &'a str,
}
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
struct NewAdQuery { struct NewAdQuery {
author: String, author: String,

View File

@ -12,6 +12,15 @@ html, body {
width: 200px; width: 200px;
} }
#errors {
padding: 4px;
border: 2px dashed rgba(128, 0, 0, 0.2);
border-radius: 3px;
font-weight: bold;
background-color: rgba(255,0,0,0.2);
color: #800000;
}
.center { .center {
padding: 4px; padding: 4px;
} }

View File

@ -12,6 +12,17 @@
<h1>ĞMarché</h1> <h1>ĞMarché</h1>
{{#if errors}}
<div id="errors">
<span>Oups, il y a un problème&nbsp;:</span>
<ul>
{{#each errors}}
<li>{{this.text}}</li>
{{/each}}
</ul>
</div>
{{/if}}
<p>Ceci est une démo du nouveau site ĞMarché en développement. C'est très moche et il n'y a pas tellement de fonctionnalités mais ça avance. ;)</p> <p>Ceci est une démo du nouveau site ĞMarché en développement. C'est très moche et il n'y a pas tellement de fonctionnalités mais ça avance. ;)</p>
<form method="post"> <form method="post">