iwakuweb/src/main.rs
2025-06-10 16:27:45 +02:00

123 lines
3.1 KiB
Rust

mod logger;
extern crate rocket;
extern crate rocket_dyn_templates;
use rocket::fs::FileServer;
use rocket::serde::{json::Json, Deserialize, Serialize};
use rocket::{build, get, launch, post, routes};
use rocket_dyn_templates::{context, Template};
use chrono::Local;
use std::borrow::Cow;
use std::fs::read_to_string;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use serde_json::{json, Value};
use crate::logger::iwakulog::{log, LogLevel};
const ASSETS_DIR: &str = "./assets";
const GUEST_MESSAGES: &str = "./guests.json";
const DATE_TIME_FORMAT: &str = "%Y-%m-%d | %H:%M";
#[derive(Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
struct GuestMessage<'r> {
name: Cow<'r, str>,
body: Cow<'r, str>,
}
fn check_file(path: &str) -> bool {
Path::new(path).exists()
}
fn read_guest_messages() -> Result<Value, Box<dyn std::error::Error>> {
let file = read_to_string(GUEST_MESSAGES)?;
let json: Value = serde_json::from_str(&file)?;
Ok(json)
}
fn post_guest_message(name: &str, body: &str) {
let mut guest_json = match read_guest_messages() {
Ok(x) => x,
Err(x) => panic!("Error while reading guest messages: {x:?}"),
};
let messages = guest_json["messages"]
.as_array_mut()
.expect("Object is not an array?");
let date = Local::now();
messages.push(json!({
"name": name,
"body": body,
"date": date.timestamp(),
}));
let mut file = File::create(GUEST_MESSAGES).expect("Couldn't read msgs");
file.write_all(guest_json.to_string().as_bytes())
.expect("wah");
}
#[get("/abuse")]
fn abuse() -> Template {
Template::render("abuse", context! {})
}
#[get("/post")]
fn post() -> Template {
Template::render("post", context! {})
}
#[get("/webring")]
fn webring() -> Template {
Template::render("webring", context! {})
}
#[get("/")]
fn index() -> Template {
Template::render("index", context! {})
}
#[post("/post_message", data = "<input>")]
fn post_msg(input: Json<GuestMessage<'_>>) {
post_guest_message(&input.name, &input.body);
return;
}
#[get("/services")]
fn services() -> Template {
Template::render("services", context! {})
}
#[get("/guestbook")]
fn guests() -> Template {
let guest_json = match read_guest_messages() {
Ok(x) => x,
Err(x) => panic!("Error while reading guest messages: {x:?}"),
};
Template::render("guest", &guest_json)
}
#[launch]
fn rocket() -> _ {
if !check_file(GUEST_MESSAGES) {
log(
LogLevel::Warn,
format!(
"Guest messages file ({}) has not been found. Creating a new one.",
GUEST_MESSAGES
)
.as_str(),
);
let mut file = File::create(GUEST_MESSAGES).expect("Failed to create file.");
file.write_all(b"{\"messages\":[]}")
.expect("Failed to write to file.");
}
build()
.mount(
"/",
routes![index, guests, post_msg, webring, post, services, abuse],
)
.mount("/assets", FileServer::from(ASSETS_DIR))
.attach(Template::fairing())
}