refactor to rocket
This commit is contained in:
parent
e1c45d6a45
commit
7507f94141
14 changed files with 1194 additions and 895 deletions
1683
Cargo.lock
generated
1683
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -6,16 +6,14 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-files = "0.6.2"
|
|
||||||
actix-web = "4.2.1"
|
|
||||||
chrono = "0.4.22"
|
chrono = "0.4.22"
|
||||||
env_logger = "0.9.3"
|
env_logger = "0.9.3"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
gnupg-rs = "0.1.0"
|
gnupg-rs = "0.1.0"
|
||||||
web-base = "0.2"
|
|
||||||
serde = {version = "1.0.147", features = ["derive"] }
|
serde = {version = "1.0.147", features = ["derive"] }
|
||||||
serde_json = "1.0.87"
|
serde_json = "1.0.87"
|
||||||
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
reqwest = { version = "0.11", features = ["blocking", "json"] }
|
||||||
maud = "0.24.0"
|
maud = "0.24.0"
|
||||||
tokio = { version = "1", features = ["sync"] }
|
tokio = { version = "1", features = ["sync"] }
|
||||||
|
rocket = "0.5.1"
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ RUN pacman -Syu --noconfirm
|
||||||
RUN pacman -S --noconfirm gnupg ca-certificates openssl-1.1
|
RUN pacman -S --noconfirm gnupg ca-certificates openssl-1.1
|
||||||
|
|
||||||
COPY --from=builder /app/target/release/me-site /me-site
|
COPY --from=builder /app/target/release/me-site /me-site
|
||||||
|
COPY ./rocket.toml /rocket.toml
|
||||||
|
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
## Possible Values to configure:
|
## Possible Values to configure:
|
||||||
- `name` : Personal Name
|
- `name` : Personal Name
|
||||||
- `email` : Personal Mail
|
- `email` : Personal Mail
|
||||||
|
- `base_url` : Base URL of the Site
|
||||||
- `secret_key` : Secret Key for Flask
|
- `secret_key` : Secret Key for Flask
|
||||||
- `xmr_address` : Monero Receive Address
|
- `xmr_address` : Monero Receive Address
|
||||||
- `notify` : Notification Object
|
- `notify` : Notification Object
|
||||||
|
|
3
rocket.toml
Normal file
3
rocket.toml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[default]
|
||||||
|
address = "0.0.0.0"
|
||||||
|
port = 8080
|
|
@ -23,6 +23,15 @@ impl Config {
|
||||||
Self { root: v, color: c }
|
Self { root: v, color: c }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn base_url(&self) -> String {
|
||||||
|
self.root
|
||||||
|
.get("base_url")
|
||||||
|
.unwrap()
|
||||||
|
.as_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_string()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
Option::from(self.root.get("name")?.as_str()?.to_string())
|
Option::from(self.root.get("name")?.as_str()?.to_string())
|
||||||
}
|
}
|
||||||
|
|
55
src/main.rs
55
src/main.rs
|
@ -3,44 +3,35 @@ mod msg;
|
||||||
mod notification;
|
mod notification;
|
||||||
mod pages;
|
mod pages;
|
||||||
|
|
||||||
use actix_web::{web, App};
|
use rocket::{launch, routes};
|
||||||
|
|
||||||
#[actix_web::main]
|
#[launch]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn rocket() -> _ {
|
||||||
std::env::set_var("RUST_LOG", "info");
|
std::env::set_var("RUST_LOG", "info");
|
||||||
std::env::set_var("RUST_BACKTRACE", "1");
|
std::env::set_var("RUST_BACKTRACE", "1");
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
let conf = config::Config::new();
|
let conf = config::Config::new();
|
||||||
web_base::bootstrap::cache_bootstrap().await;
|
pages::bootstrap::cache_bootstrap().await;
|
||||||
|
|
||||||
let manifest = web_base::Manifest::new(&conf.name().unwrap())
|
rocket::build()
|
||||||
.set_short_name(&conf.name().unwrap())
|
.mount(
|
||||||
.set_start_url("/")
|
"/",
|
||||||
.set_background_color(&conf.bg_color().unwrap())
|
routes![
|
||||||
.add_icon("/assets/me.png", "2000x2000", "image/png")
|
pages::assets::wallpaper,
|
||||||
.set_display(web_base::ManifestDisplay::MinimalUI);
|
pages::assets::me_img,
|
||||||
|
pages::assets::me_img_png,
|
||||||
web_base::map!(
|
pages::bootstrap::bootstrap_css,
|
||||||
web_base::Site::new()
|
pages::bootstrap::bootstrap_icons,
|
||||||
.enable_bootstrap(true)
|
pages::bootstrap::bootstrap_js,
|
||||||
.enable_scaling(true)
|
pages::bootstrap::bootstrap_font1,
|
||||||
.enable_favicon("/assets/me".to_string())
|
pages::bootstrap::bootstrap_font2,
|
||||||
.add_manifest(manifest),
|
pages::index::message_post,
|
||||||
|x: App<_>| {
|
pages::index::message_page,
|
||||||
x.app_data(web::Data::new(conf.clone()))
|
pages::index::mirrors,
|
||||||
.service(pages::index::index)
|
pages::index::public_key,
|
||||||
// Assets
|
pages::index::index
|
||||||
.service(pages::assets::wallpaper)
|
],
|
||||||
.service(pages::assets::me_img)
|
|
||||||
.service(pages::assets::me_img_png)
|
|
||||||
.service(pages::index::public_key)
|
|
||||||
.service(pages::index::mirrors)
|
|
||||||
.service(pages::index::message_page)
|
|
||||||
.service(pages::index::message_post)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
.bind(("0.0.0.0", 8080))?
|
.manage(conf)
|
||||||
.run()
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
use crate::config;
|
use crate::config;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use actix_web::web::{self, Data};
|
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
pub async fn notify(msg: &str, title: &str, config: Data<Config>) {
|
pub async fn notify(msg: &str, title: &str, config: &Config) {
|
||||||
if let Some(gotify) = config.gotify_config() {
|
if let Some(gotify) = config.gotify_config() {
|
||||||
gotify_notification(msg, title, gotify).await;
|
gotify_notification(msg, title, gotify).await;
|
||||||
}
|
}
|
||||||
if let Some(webhook) = config.webhook_config() {
|
if let Some(webhook) = config.webhook_config() {
|
||||||
info!("Sending webhook notification");
|
info!("Sending webhook notification");
|
||||||
let request =
|
let request = serde_json::json!({
|
||||||
serde_json::json!({
|
|
||||||
"instance": config.name(),
|
"instance": config.name(),
|
||||||
"title": title,
|
"title": title,
|
||||||
"msg": msg
|
"msg": msg
|
||||||
|
@ -29,7 +27,10 @@ async fn gotify_notification(msg: &str, title: &str, config: config::GotifySetti
|
||||||
info!("Sending gotify notification");
|
info!("Sending gotify notification");
|
||||||
let c = reqwest::Client::new();
|
let c = reqwest::Client::new();
|
||||||
let _ = c
|
let _ = c
|
||||||
.post(format!("https://{}/message?token={}", config.host, config.token))
|
.post(format!(
|
||||||
|
"https://{}/message?token={}",
|
||||||
|
config.host, config.token
|
||||||
|
))
|
||||||
.header("title", title)
|
.header("title", title)
|
||||||
.header("message", msg)
|
.header("message", msg)
|
||||||
.header("priority", 5)
|
.header("priority", 5)
|
||||||
|
|
|
@ -1,19 +1,18 @@
|
||||||
use actix_files::NamedFile;
|
use rocket::{fs::NamedFile, get};
|
||||||
use actix_web::{get, Result};
|
|
||||||
|
|
||||||
// Assets
|
// Assets
|
||||||
|
|
||||||
#[get("/assets/wall")]
|
#[get("/assets/wall")]
|
||||||
pub(crate) async fn wallpaper() -> Result<NamedFile> {
|
pub async fn wallpaper() -> Option<NamedFile> {
|
||||||
Ok(NamedFile::open("./config/wall.avif")?)
|
NamedFile::open("./config/wall.avif").await.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/assets/me")]
|
#[get("/assets/me")]
|
||||||
pub(crate) async fn me_img() -> Result<NamedFile> {
|
pub async fn me_img() -> Option<NamedFile> {
|
||||||
Ok(NamedFile::open("./config/me.avif")?)
|
NamedFile::open("./config/me.avif").await.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/assets/me.png")]
|
#[get("/assets/me.png")]
|
||||||
pub(crate) async fn me_img_png() -> Result<NamedFile> {
|
pub async fn me_img_png() -> Option<NamedFile> {
|
||||||
Ok(NamedFile::open("./config/me.png")?)
|
NamedFile::open("./config/me.png").await.ok()
|
||||||
}
|
}
|
||||||
|
|
67
src/pages/bootstrap.rs
Normal file
67
src/pages/bootstrap.rs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
use rocket::{fs::NamedFile, get};
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
async fn download_file(url: &str, file: &str) {
|
||||||
|
let content = reqwest::get(url).await.expect("couldn't download file");
|
||||||
|
std::fs::File::create(file)
|
||||||
|
.expect("could not create file")
|
||||||
|
.write_all(&content.bytes().await.expect("could not get bytes"))
|
||||||
|
.expect("could not write file");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/bootstrap.min.css")]
|
||||||
|
pub async fn bootstrap_css() -> Option<NamedFile> {
|
||||||
|
NamedFile::open("./cache/bootstrap.mi.await.ok()n.css")
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/bootstrap-icons.css")]
|
||||||
|
pub async fn bootstrap_icons() -> Option<NamedFile> {
|
||||||
|
NamedFile::open("./cache/bootstrap-icon.await.ok()s.css")
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/bootstrap.bundle.min.js")]
|
||||||
|
pub async fn bootstrap_js() -> Option<NamedFile> {
|
||||||
|
NamedFile::open("./cache/bootstrap.b.await.ok()undle.min.js")
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/fonts/bootstrap-icons.woff2")]
|
||||||
|
pub async fn bootstrap_font1() -> Option<NamedFile> {
|
||||||
|
NamedFile::open("./cache/fonts/bootstrap-icons.woff2")
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/fonts/bootstrap-icons.woff")]
|
||||||
|
pub async fn bootstrap_font2() -> Option<NamedFile> {
|
||||||
|
NamedFile::open("./cache/fonts/bootstrap-icons.woff")
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cache Bootstrap files locally
|
||||||
|
pub async fn cache_bootstrap() {
|
||||||
|
std::fs::create_dir_all("./cache/fonts").expect("couldn't create cache dir");
|
||||||
|
download_file(
|
||||||
|
"https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css",
|
||||||
|
"./cache/bootstrap.min.css",
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
download_file(
|
||||||
|
"https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css",
|
||||||
|
"./cache/bootstrap-icons.css",
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
download_file(
|
||||||
|
"https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js",
|
||||||
|
"./cache/bootstrap.bundle.min.js",
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
download_file("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/fonts/bootstrap-icons.woff2?8d200481aa7f02a2d63a331fc782cfaf", "./cache/fonts/bootstrap-icons.woff2").await;
|
||||||
|
download_file("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/fonts/bootstrap-icons.woff?8d200481aa7f02a2d63a331fc782cfaf", "./cache/fonts/bootstrap-icons.woff").await;
|
||||||
|
}
|
92
src/pages/html.rs
Normal file
92
src/pages/html.rs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
use crate::config::Config;
|
||||||
|
use maud::{html, PreEscaped, DOCTYPE};
|
||||||
|
use rocket::request::{FromRequest, Outcome, Request};
|
||||||
|
|
||||||
|
pub enum RequestClient {
|
||||||
|
Browser,
|
||||||
|
Other,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rocket::async_trait]
|
||||||
|
impl<'r> FromRequest<'r> for RequestClient {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
async fn from_request(req: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
|
if is_browser(req) {
|
||||||
|
Outcome::Success(Self::Browser)
|
||||||
|
} else {
|
||||||
|
Outcome::Success(Self::Other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn is_browser(req: &Request) -> bool {
|
||||||
|
let ua = req
|
||||||
|
.headers()
|
||||||
|
.get("usesr-agent")
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.to_lowercase();
|
||||||
|
ua.contains("chrome") || ua.contains("safari") || ua.contains("firefox")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn build_site(
|
||||||
|
content: String,
|
||||||
|
title: &str,
|
||||||
|
disable_color: bool,
|
||||||
|
shadow: bool,
|
||||||
|
config: &Config,
|
||||||
|
) -> String {
|
||||||
|
let mut c_class = "bg-dark text-white justify-content-center text-center".to_string();
|
||||||
|
let mut c_style = String::new();
|
||||||
|
let mut g_style = "a {text-decoration: none; font-weight: bold; color: white}".to_string();
|
||||||
|
if !disable_color {
|
||||||
|
if let (Some(fg), Some(bg)) = (config.fg_color(), config.bg_color()) {
|
||||||
|
c_class = "justify-content-center text-center".to_string();
|
||||||
|
c_style = format!("background: {bg}; color: {fg};");
|
||||||
|
g_style = format!("a {{text-decoration: none; font-weight: bold; color: {fg}}}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if std::path::Path::new("./config/wall.avif").exists() {
|
||||||
|
c_style.push_str("background-image: url('assets/wall');background-size:cover;");
|
||||||
|
}
|
||||||
|
|
||||||
|
if shadow {
|
||||||
|
c_style.push_str("text-shadow: 1px 1px 3px black;");
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = html! {
|
||||||
|
body style=(c_style) class=(c_class) {
|
||||||
|
style { (g_style) };
|
||||||
|
(PreEscaped(content))
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
build_site_from_body(title, &body.into_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_site_from_body(title: &str, body: &str) -> String {
|
||||||
|
html! {
|
||||||
|
(DOCTYPE)
|
||||||
|
html {
|
||||||
|
head {
|
||||||
|
meta charset="UTF-8";
|
||||||
|
title {
|
||||||
|
(title)
|
||||||
|
};
|
||||||
|
link rel="icon" href="/assets/me";
|
||||||
|
meta name="viewport" content="width=device-width, initial-scale=1.0";
|
||||||
|
link href="/bootstrap.min.css" rel="stylesheet";
|
||||||
|
link href="/bootstrap-icons.css" rel="stylesheet";
|
||||||
|
script src="/bootstrap.bundle.min.js" {};
|
||||||
|
link href="/style/global.css" rel="stylesheet";
|
||||||
|
link href="/style/site.css" rel="stylesheet";
|
||||||
|
link href="/style/common.css" rel="stylesheet";
|
||||||
|
};
|
||||||
|
(PreEscaped(body))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
.into_string()
|
||||||
|
}
|
|
@ -1,43 +0,0 @@
|
||||||
use crate::config::Config;
|
|
||||||
use actix_web::HttpResponse;
|
|
||||||
use actix_web::{web::Data, HttpRequest};
|
|
||||||
use maud::{html, PreEscaped};
|
|
||||||
|
|
||||||
pub(crate) async fn build_site(
|
|
||||||
content: String,
|
|
||||||
title: &str,
|
|
||||||
disable_color: bool,
|
|
||||||
shadow: bool,
|
|
||||||
config: &Data<Config>,
|
|
||||||
r: &HttpRequest,
|
|
||||||
) -> HttpResponse<String> {
|
|
||||||
let mut c_class = "bg-dark text-white justify-content-center text-center".to_string();
|
|
||||||
let mut c_style = String::new();
|
|
||||||
let mut g_style = "a {text-decoration: none; font-weight: bold; color: white}".to_string();
|
|
||||||
if !disable_color {
|
|
||||||
if let (Some(fg), Some(bg)) = (config.fg_color(), config.bg_color()) {
|
|
||||||
c_class = "justify-content-center text-center".to_string();
|
|
||||||
c_style = format!("background: {bg}; color: {fg};");
|
|
||||||
g_style = format!("a {{text-decoration: none; font-weight: bold; color: {fg}}}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if std::path::Path::new("./config/wall.avif").exists() {
|
|
||||||
c_style.push_str("background-image: url('assets/wall');background-size:cover;");
|
|
||||||
}
|
|
||||||
if shadow {
|
|
||||||
c_style.push_str("text-shadow: 1px 1px 3px black;");
|
|
||||||
}
|
|
||||||
|
|
||||||
let body = html! {
|
|
||||||
body style=(c_style) class=(c_class) {
|
|
||||||
style { (g_style) };
|
|
||||||
(PreEscaped(content))
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
web_base::func::build_site_from_body(
|
|
||||||
&web_base::Site::from_request(&r),
|
|
||||||
title,
|
|
||||||
&body.into_string(),
|
|
||||||
)
|
|
||||||
}
|
|
|
@ -1,34 +1,33 @@
|
||||||
use crate::{config, pages};
|
use crate::config;
|
||||||
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 maud::{html, PreEscaped};
|
||||||
|
use rocket::{form::Form, get, post, response::Redirect, uri, FromForm, State};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
use super::html::{build_site, RequestClient};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, FromForm)]
|
||||||
pub struct MessageForm {
|
pub struct MessageForm {
|
||||||
msg_name: String,
|
msg_name: String,
|
||||||
message: String,
|
message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/message")]
|
#[post("/message", data = "<msg>")]
|
||||||
pub async fn message_post(r: HttpRequest, f: Form<MessageForm>) -> impl Responder {
|
pub async fn message_post(msg: Form<MessageForm>, config: &State<config::Config>) -> Redirect {
|
||||||
let config: &web::Data<config::Config> = r.app_data().expect("get config failed");
|
crate::msg::save_message(&msg.message, &msg.msg_name.to_string());
|
||||||
crate::msg::save_message(&f.message, &f.msg_name.to_string());
|
crate::notification::notify(&msg.message, &msg.msg_name, config).await;
|
||||||
crate::notification::notify(&f.message, &f.msg_name, config.clone()).await;
|
Redirect::to(uri!(message_page))
|
||||||
web_base::func::redirect("/message")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/message")]
|
#[get("/message")]
|
||||||
pub async fn message_page(r: HttpRequest) -> impl Responder {
|
pub async fn message_page(config: &State<config::Config>) -> String {
|
||||||
let config: &web::Data<config::Config> = r.app_data().expect("get config failed");
|
let post_uri = uri!(message_post).to_string();
|
||||||
|
|
||||||
let resp = html! {
|
let resp = html! {
|
||||||
div class="container" style="margin-top: 25px" {
|
div class="container" style="margin-top: 25px" {
|
||||||
h1 { "Message" };
|
h1 { "Message" };
|
||||||
br;
|
br;
|
||||||
|
|
||||||
form action=(web_base::func::get_full_url(&r)) method="post" autocomplete="off" {
|
form action=(post_uri) 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";
|
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;" {};
|
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";
|
input value="Send Message" type="submit" required name="submit" class="btn btn-danger text-white text-decoration-none";
|
||||||
|
@ -36,15 +35,14 @@ pub async fn message_page(r: HttpRequest) -> impl Responder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pages::html_fn::build_site(resp.into_string(), "Message", false, true, config, &r).await
|
build_site(resp.into_string(), "Message", false, true, config).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/mirrors.txt")]
|
#[get("/mirrors.txt")]
|
||||||
pub async fn mirrors(r: HttpRequest) -> Result<impl Responder, Error> {
|
pub async fn mirrors(r: RequestClient, config: &State<config::Config>) -> Option<String> {
|
||||||
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") {
|
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");
|
let content = std::io::read_to_string(mirror_file).ok()?;
|
||||||
if web_base::func::is_browser(&r) {
|
if matches!(r, RequestClient::Browser) {
|
||||||
let resp = html! {
|
let resp = html! {
|
||||||
div style="margin: 25px;" {
|
div style="margin: 25px;" {
|
||||||
pre {
|
pre {
|
||||||
|
@ -52,26 +50,19 @@ pub async fn mirrors(r: HttpRequest) -> Result<impl Responder, Error> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return Ok(pages::html_fn::build_site(
|
|
||||||
resp.into_string(),
|
return Some(build_site(resp.into_string(), "Mirrors", false, true, config).await);
|
||||||
"Mirrors",
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
config,
|
|
||||||
&r,
|
|
||||||
)
|
|
||||||
.await);
|
|
||||||
}
|
}
|
||||||
return HttpResponse::Ok().message_body(content);
|
return Some(content);
|
||||||
}
|
}
|
||||||
HttpResponse::NotFound().message_body(String::new())
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/public_key")]
|
#[get("/public_key")]
|
||||||
pub async fn public_key(r: HttpRequest) -> Result<impl Responder, Error> {
|
pub async fn public_key(r: RequestClient, config: &State<config::Config>) -> Option<String> {
|
||||||
if web_base::func::is_browser(&r) {
|
if matches!(r, RequestClient::Browser) {
|
||||||
let config: &web::Data<config::Config> = r.app_data().expect("get config failed");
|
let host = config.base_url();
|
||||||
let host = format!("http://{}", web_base::func::get_host(&r));
|
|
||||||
let key = std::io::read_to_string(
|
let key = std::io::read_to_string(
|
||||||
std::fs::File::open("./config/pub.key").expect("key could not be opened"),
|
std::fs::File::open("./config/pub.key").expect("key could not be opened"),
|
||||||
)
|
)
|
||||||
|
@ -94,28 +85,19 @@ pub async fn public_key(r: HttpRequest) -> Result<impl Responder, Error> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(pages::html_fn::build_site(
|
return Some(build_site(resp.into_string(), "Public Key", true, false, config).await);
|
||||||
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_f) = std::fs::File::open("./config/pub.key") {
|
||||||
if let Ok(key_data) = std::io::read_to_string(key_f) {
|
if let Ok(key_data) = std::io::read_to_string(key_f) {
|
||||||
return HttpResponse::Ok()
|
return Some(key_data);
|
||||||
.insert_header(header::ContentType::plaintext())
|
|
||||||
.message_body(key_data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponse::NotFound().message_body(String::new())
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_information_block(conf: &web::Data<config::Config>) -> String {
|
fn build_information_block(conf: &config::Config) -> String {
|
||||||
let name = conf.name().expect("no name found");
|
let name = conf.name().expect("no name found");
|
||||||
html! {
|
html! {
|
||||||
div class="container border-dark" style="margin-top: 20px" {
|
div class="container border-dark" style="margin-top: 20px" {
|
||||||
|
@ -128,7 +110,7 @@ fn build_information_block(conf: &web::Data<config::Config>) -> String {
|
||||||
.into_string()
|
.into_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_contact_block(conf: &web::Data<config::Config>) -> String {
|
fn build_contact_block(conf: &config::Config) -> String {
|
||||||
conf.email().map_or_else(String::new, |email| {
|
conf.email().map_or_else(String::new, |email| {
|
||||||
let pgp_key_message = if std::path::Path::new("./config/pub.key").exists() {
|
let pgp_key_message = if std::path::Path::new("./config/pub.key").exists() {
|
||||||
html! {
|
html! {
|
||||||
|
@ -158,7 +140,7 @@ fn build_contact_block(conf: &web::Data<config::Config>) -> String {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_donation_block(conf: &web::Data<config::Config>) -> String {
|
fn build_donation_block(conf: &config::Config) -> String {
|
||||||
conf.xmr_address().map_or_else(String::new, |xmr_addr| {
|
conf.xmr_address().map_or_else(String::new, |xmr_addr| {
|
||||||
html! {
|
html! {
|
||||||
div class="container" style="margin-top: 20px" {
|
div class="container" style="margin-top: 20px" {
|
||||||
|
@ -178,10 +160,10 @@ fn build_donation_block(conf: &web::Data<config::Config>) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub(crate) async fn index(conf: web::Data<config::Config>, r: HttpRequest) -> impl Responder {
|
pub async fn index(conf: &State<config::Config>) -> String {
|
||||||
let information_block = build_information_block(&conf);
|
let information_block = build_information_block(conf);
|
||||||
let contact_block = build_contact_block(&conf);
|
let contact_block = build_contact_block(conf);
|
||||||
let donation_block = build_donation_block(&conf);
|
let donation_block = build_donation_block(conf);
|
||||||
let own_index = std::fs::read_to_string("./config/index.html").unwrap_or_default();
|
let own_index = std::fs::read_to_string("./config/index.html").unwrap_or_default();
|
||||||
let content = format!(
|
let content = format!(
|
||||||
"
|
"
|
||||||
|
@ -191,5 +173,5 @@ pub(crate) async fn index(conf: web::Data<config::Config>, r: HttpRequest) -> im
|
||||||
{donation_block}
|
{donation_block}
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
crate::pages::html_fn::build_site(content, "About Me", false, true, &conf, &r).await
|
build_site(content, "About Me", false, true, conf).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
pub mod assets;
|
pub mod assets;
|
||||||
pub mod html_fn;
|
pub mod bootstrap;
|
||||||
|
pub mod html;
|
||||||
pub mod index;
|
pub mod index;
|
||||||
|
|
Loading…
Add table
Reference in a new issue