195 lines
6.9 KiB
Rust
195 lines
6.9 KiB
Rust
use crate::{config, pages};
|
|
use actix_web::http::header;
|
|
use actix_web::web::Form;
|
|
use actix_web::{get, post, web, Error, HttpRequest, HttpResponse, Responder, Result};
|
|
use maud::{html, PreEscaped};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
pub struct MessageForm {
|
|
msg_name: String,
|
|
message: String,
|
|
}
|
|
|
|
#[post("/message")]
|
|
pub async fn message_post(r: HttpRequest, f: Form<MessageForm>) -> impl Responder {
|
|
let config: &web::Data<config::Config> = r.app_data().expect("get config failed");
|
|
crate::msg::save_message(&f.message, &f.msg_name.to_string());
|
|
crate::notification::notify(&f.message, &f.msg_name, config.clone()).await;
|
|
web_base::func::redirect("/message")
|
|
}
|
|
|
|
#[get("/message")]
|
|
pub async fn message_page(r: HttpRequest) -> impl Responder {
|
|
let config: &web::Data<config::Config> = r.app_data().expect("get config failed");
|
|
|
|
let resp = html! {
|
|
div class="container" style="margin-top: 25px" {
|
|
h1 { "Message" };
|
|
br;
|
|
|
|
form action=(web_base::func::get_full_url(&r)) method="post" autocomplete="off" {
|
|
input value="" type="text" required name="msg_name" placeholder="Name" class="form-control bg-dark text-white" style="margin-bottom: 15px";
|
|
textarea placeholder="Message" required name="message" cols="10" rows="10" class="form-control bg-dark text-white" style="margin-bottom: 15px;" {};
|
|
input value="Send Message" type="submit" required name="submit" class="btn btn-danger text-white text-decoration-none";
|
|
}
|
|
}
|
|
};
|
|
|
|
pages::html_fn::build_site(resp.into_string(), "Message", false, true, config, &r).await
|
|
}
|
|
|
|
#[get("/mirrors.txt")]
|
|
pub async fn mirrors(r: HttpRequest) -> Result<impl Responder, Error> {
|
|
let config: &web::Data<config::Config> = r.app_data().expect("get config failed");
|
|
if let Ok(mirror_file) = std::fs::File::open("./config/mirrors.txt") {
|
|
let content = std::io::read_to_string(mirror_file).expect("could not read file");
|
|
if web_base::func::is_browser(&r) {
|
|
let resp = html! {
|
|
div style="margin: 25px;" {
|
|
pre {
|
|
(content)
|
|
};
|
|
}
|
|
};
|
|
return Ok(pages::html_fn::build_site(
|
|
resp.into_string(),
|
|
"Mirrors",
|
|
false,
|
|
true,
|
|
config,
|
|
&r,
|
|
)
|
|
.await);
|
|
}
|
|
return HttpResponse::Ok().message_body(content);
|
|
}
|
|
HttpResponse::NotFound().message_body(String::new())
|
|
}
|
|
|
|
#[get("/public_key")]
|
|
pub async fn public_key(r: HttpRequest) -> Result<impl Responder, Error> {
|
|
if web_base::func::is_browser(&r) {
|
|
let config: &web::Data<config::Config> = r.app_data().expect("get config failed");
|
|
let host = format!("http://{}", web_base::func::get_host(&r));
|
|
let key = std::io::read_to_string(
|
|
std::fs::File::open("./config/pub.key").expect("key could not be opened"),
|
|
)
|
|
.expect("could not read key");
|
|
|
|
let pgp = gnupg_rs::GnuPG::new().expect("no gpg");
|
|
let key_name = pgp.import_key(&key).expect("key not valid").name;
|
|
let key = key.replace('\n', "<br>");
|
|
|
|
let resp = html! {
|
|
div class="container" style="margin-top: 25px" {
|
|
div class="alert alert-info" {
|
|
b { "To Import: " };
|
|
span style="display: block;font-family: monospace,monospace;margin-top: 10px; font-size: 20px;overflow-wrap: break-word;" { (format!("curl -sL \"{host}/public_key\"|gpg --import")) };
|
|
};
|
|
h4 class="container card" style="padding-top: 10px; padding-bottom: 10px; background: black; margin-bottom: 15px;" { (key_name) };
|
|
};
|
|
div class="container card bg-primary" {
|
|
p { (PreEscaped(key)) }
|
|
}
|
|
};
|
|
|
|
return Ok(pages::html_fn::build_site(
|
|
resp.into_string(),
|
|
"Public Key",
|
|
true,
|
|
false,
|
|
config,
|
|
&r,
|
|
)
|
|
.await);
|
|
}
|
|
if let Ok(key_f) = std::fs::File::open("./config/pub.key") {
|
|
if let Ok(key_data) = std::io::read_to_string(key_f) {
|
|
return HttpResponse::Ok()
|
|
.insert_header(header::ContentType::plaintext())
|
|
.message_body(key_data);
|
|
}
|
|
}
|
|
|
|
HttpResponse::NotFound().message_body(String::new())
|
|
}
|
|
|
|
fn build_information_block(conf: &web::Data<config::Config>) -> String {
|
|
let name = conf.name().expect("no name found");
|
|
html! {
|
|
div class="container border-dark" style="margin-top: 20px" {
|
|
img src="/assets/me" height="200" width="200" alt="Me" class="rounded";
|
|
br;br;
|
|
h1 { (name) };
|
|
hr;
|
|
}
|
|
}
|
|
.into_string()
|
|
}
|
|
|
|
fn build_contact_block(conf: &web::Data<config::Config>) -> String {
|
|
conf.email().map_or_else(String::new, |email| {
|
|
let pgp_key_message = if std::path::Path::new("./config/pub.key").exists() {
|
|
html! {
|
|
a href="/public_key" { "My PGP Key" };
|
|
br;
|
|
a href="/message" { "Write a message" };
|
|
br;br;
|
|
}
|
|
.into_string()
|
|
} else {
|
|
String::new()
|
|
};
|
|
|
|
html! {
|
|
div class="container border-dark" {
|
|
h1 {
|
|
span class="bi bi-person-lines-fill" style="vertical-align: middle;";
|
|
span { "Contact" };
|
|
};
|
|
hr;
|
|
(PreEscaped(pgp_key_message));
|
|
a href=(format!("mailto:{email}")) { (email) };
|
|
hr;
|
|
}
|
|
}
|
|
.into_string()
|
|
})
|
|
}
|
|
|
|
fn build_donation_block(conf: &web::Data<config::Config>) -> String {
|
|
conf.xmr_address().map_or_else(String::new, |xmr_addr| {
|
|
html! {
|
|
div class="container" style="margin-top: 20px" {
|
|
h1 {
|
|
span class="bi bi-cash-coin";
|
|
span { "Donation" };
|
|
};
|
|
hr;
|
|
p {
|
|
b { "Monero: " };
|
|
span style="color: orange;overflow-wrap: break-word;" { (xmr_addr) };
|
|
}
|
|
}
|
|
}
|
|
.into_string()
|
|
})
|
|
}
|
|
|
|
#[get("/")]
|
|
pub(crate) async fn index(conf: web::Data<config::Config>, r: HttpRequest) -> impl Responder {
|
|
let information_block = build_information_block(&conf);
|
|
let contact_block = build_contact_block(&conf);
|
|
let donation_block = build_donation_block(&conf);
|
|
let own_index = std::fs::read_to_string("./config/index.html").unwrap_or_default();
|
|
let content = format!(
|
|
"
|
|
{information_block}
|
|
{contact_block}
|
|
{own_index}
|
|
{donation_block}
|
|
"
|
|
);
|
|
crate::pages::html_fn::build_site(content, "About Me", false, true, &conf, &r).await
|
|
}
|