add posting
This commit is contained in:
parent
e5cb7f3d69
commit
4537fc379c
2 changed files with 58 additions and 9 deletions
|
@ -17,6 +17,7 @@ pub fn header() -> Markup {
|
||||||
a href = "/" { h1 { "Motifs" } }
|
a href = "/" { h1 { "Motifs" } }
|
||||||
a href = "/activity" { "activité" }
|
a href = "/activity" { "activité" }
|
||||||
a href = "/topics" { "sujets" }
|
a href = "/topics" { "sujets" }
|
||||||
|
a href = "/create" { "créer" }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
66
src/main.rs
66
src/main.rs
|
@ -1,12 +1,15 @@
|
||||||
use std::fmt::Write;
|
use std::{
|
||||||
use std::sync::{Arc, RwLock};
|
fmt::Write,
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
response::IntoResponse,
|
http::StatusCode,
|
||||||
|
response::{IntoResponse, Redirect, Response},
|
||||||
routing::get,
|
routing::get,
|
||||||
Json, Router,
|
Form, Json, Router,
|
||||||
};
|
};
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use common::{footer, head, header, style};
|
use common::{footer, head, header, style};
|
||||||
|
@ -33,6 +36,7 @@ async fn main() -> Result<()> {
|
||||||
.route("/style.css", get(style))
|
.route("/style.css", get(style))
|
||||||
.route("/topics", get(topics).post(post))
|
.route("/topics", get(topics).post(post))
|
||||||
.route("/topic/:name", get(topic))
|
.route("/topic/:name", get(topic))
|
||||||
|
.route("/create", get(create))
|
||||||
.route("/activity", get(activity))
|
.route("/activity", get(activity))
|
||||||
.route("/", get(home))
|
.route("/", get(home))
|
||||||
.with_state(state);
|
.with_state(state);
|
||||||
|
@ -147,18 +151,30 @@ struct PostContent {
|
||||||
|
|
||||||
async fn post(
|
async fn post(
|
||||||
State(state): State<MainState>,
|
State(state): State<MainState>,
|
||||||
Json(PostContent {
|
Form(PostContent {
|
||||||
topic,
|
topic,
|
||||||
content,
|
content,
|
||||||
author,
|
author,
|
||||||
}): Json<PostContent>,
|
}): Form<PostContent>,
|
||||||
) -> impl IntoResponse {
|
) -> Response {
|
||||||
let mut store = state.store.write().unwrap();
|
let mut store = state.store.write().unwrap();
|
||||||
let date = Utc::now().format("%d/%m/%Y");
|
let date = Utc::now().format("%d/%m/%Y");
|
||||||
let topic = sanithize_identifier(&topic);
|
let topic = sanithize_identifier(topic.trim());
|
||||||
let content = content.trim();
|
let content = content.trim();
|
||||||
|
|
||||||
|
if content.len() < 10 || content.len() > 10_000 {
|
||||||
|
return (StatusCode::BAD_REQUEST, "Bad content.").into_response();
|
||||||
|
}
|
||||||
|
if author.len() > 2 || author.len() > 32 {
|
||||||
|
return (StatusCode::BAD_REQUEST, "Bad author.").into_response();
|
||||||
|
}
|
||||||
|
if topic.len() > 32 || topic.is_empty() || topic.starts_with('_') || topic.ends_with('_') {
|
||||||
|
return (StatusCode::BAD_REQUEST, "Bad topic.").into_response();
|
||||||
|
}
|
||||||
|
|
||||||
let content = format!("{content}\n\t~{author}, {date}");
|
let content = format!("{content}\n\t~{author}, {date}");
|
||||||
store.insert(&topic, content).unwrap();
|
store.insert(&topic, content).unwrap();
|
||||||
|
Redirect::to("/activity").into_response()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sanithize_identifier(input: &str) -> String {
|
fn sanithize_identifier(input: &str) -> String {
|
||||||
|
@ -177,6 +193,7 @@ fn sanithize_identifier(input: &str) -> String {
|
||||||
('ö', 'o'),
|
('ö', 'o'),
|
||||||
('û', 'u'),
|
('û', 'u'),
|
||||||
('ü', 'u'),
|
('ü', 'u'),
|
||||||
|
(' ', '_'),
|
||||||
];
|
];
|
||||||
text.chars()
|
text.chars()
|
||||||
.map(|c| {
|
.map(|c| {
|
||||||
|
@ -187,10 +204,41 @@ fn sanithize_identifier(input: &str) -> String {
|
||||||
}
|
}
|
||||||
c
|
c
|
||||||
})
|
})
|
||||||
.filter(char::is_ascii)
|
.filter(|c| c.is_ascii_lowercase() || *c == '_')
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn create() -> impl IntoResponse {
|
||||||
|
html!(
|
||||||
|
(head("créer"))
|
||||||
|
body {
|
||||||
|
content {
|
||||||
|
(header())
|
||||||
|
main {
|
||||||
|
h2 { "Créer" }
|
||||||
|
|
||||||
|
form id = "create" action = "/topics" method = "post" {
|
||||||
|
label for = "topic" { "Sujet" }
|
||||||
|
input type = "text" name = "topic";
|
||||||
|
br;
|
||||||
|
|
||||||
|
label for = "author" { "Auteur" }
|
||||||
|
input type = "text" name = "author";
|
||||||
|
br;
|
||||||
|
|
||||||
|
label for = "content" { "Contenu" }
|
||||||
|
textarea form = "create" name = "content" { }
|
||||||
|
br;
|
||||||
|
|
||||||
|
input type = "submit";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(footer())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn error(message: impl ToString) -> Markup {
|
fn error(message: impl ToString) -> Markup {
|
||||||
let message = message.to_string();
|
let message = message.to_string();
|
||||||
html!(
|
html!(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue