redirects

This commit is contained in:
Gvidas Juknevičius 2024-03-30 22:33:14 +02:00
parent e289f38192
commit 9770f327b7
Signed by: MCorange
GPG Key ID: 12B1346D720B7FBB
15 changed files with 233 additions and 25 deletions

View File

@ -5,4 +5,8 @@ host="0.0.0.0"
port=8080 port=8080
[database] [database]
url="postgresql://postgres@localhost/mctest" url="postgresql://postgres@localhost/mctest"
[[redirect]]
from="hmm"
to="https://stallman-copypasta.github.io/"

View File

@ -1,19 +1,26 @@
use serde::Deserialize; use serde::Deserialize;
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize, Clone)]
pub struct Config { pub struct Config {
pub debug: bool, pub debug: bool,
pub webserver: ConfigWebserver, pub webserver: ConfigWebserver,
pub database: ConfigDatabase pub database: ConfigDatabase,
pub redirect: Vec<ConfigRedirect>
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize, Clone)]
pub struct ConfigWebserver { pub struct ConfigWebserver {
pub host: String, pub host: String,
pub port: u16, pub port: u16,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize, Clone)]
pub struct ConfigDatabase { pub struct ConfigDatabase {
pub url: String, pub url: String,
}
#[derive(Debug, Deserialize, Clone)]
pub struct ConfigRedirect {
pub from: String,
pub to: String,
} }

View File

@ -26,7 +26,7 @@ async fn main() -> anyhow::Result<()> {
return Ok(()); return Ok(());
} }
if let Err(e) = web::start_actix(config.get_ref(), database).await { if let Err(e) = web::start_actix(config.get_ref().clone(), database).await {
log::error!("Actix had an error: {e}"); log::error!("Actix had an error: {e}");
} }
Ok(()) Ok(())

View File

@ -8,7 +8,7 @@ use actix_files as actix_fs;
use crate::{config::definition::Config, database::Database}; use crate::{config::definition::Config, database::Database};
pub(crate) async fn start_actix(config: &Config, database: Database) -> anyhow::Result<()> { pub(crate) async fn start_actix(config: Config, database: Database) -> anyhow::Result<()> {
let bindip = format!("{}:{}", config.webserver.host, config.webserver.port); let bindip = format!("{}:{}", config.webserver.host, config.webserver.port);
log::info!("Serving an http server at http://{bindip}"); log::info!("Serving an http server at http://{bindip}");
@ -16,7 +16,10 @@ pub(crate) async fn start_actix(config: &Config, database: Database) -> anyhow::
App::new() App::new()
.app_data(actix_web::web::Data::new(Mutex::new(database.clone()))) .app_data(actix_web::web::Data::new(Mutex::new(database.clone())))
.route("/", web::get().to(routes::index)) // index.html .route("/", web::get().to(routes::index)) // index.html
.route("/projects", web::get().to(routes::projects::projects)) // index.html
.route("/contact", web::get().to(routes::contact::contact)) // index.html
.service(routes::api::get_scope()) .service(routes::api::get_scope())
.service(routes::redirect::get_scope(&config))
.service(actix_fs::Files::new("/static", "./static").index_file("index.html")) // static directory .service(actix_fs::Files::new("/static", "./static").index_file("index.html")) // static directory
.service(web::redirect("/favicon.ico", "/static/favicon.ico")) //? special redirect for favicon .service(web::redirect("/favicon.ico", "/static/favicon.ico")) //? special redirect for favicon
}) })

19
src/web/routes/contact.rs Normal file
View File

@ -0,0 +1,19 @@
use std::sync::Mutex;
use actix_web_lab::respond::Html;
use actix_web::{web::Data, Responder, Result};
use askama::Template;
use crate::{database::Database, web::templates::ContactTemplate};
pub async fn contact(_: Data<Mutex<Database>>) -> Result<impl Responder> {
let html = ContactTemplate {
title: String::from("MCorange - Contact me!"),
}.render().expect("Failed to render contacts.html");
Ok(Html(html))
}

View File

@ -1,4 +1,7 @@
pub mod api; pub mod api;
pub mod contact;
pub mod projects;
pub mod redirect;
use std::sync::Mutex; use std::sync::Mutex;
@ -15,24 +18,13 @@ pub async fn index(db: Data<Mutex<Database>>) -> Result<impl Responder> {
let posts = match crate::database::models::posts::Post::get_last_n(&mut db.lock().unwrap(), 10).await { let posts = match crate::database::models::posts::Post::get_last_n(&mut db.lock().unwrap(), 10).await {
Ok(p) => p, Ok(p) => p,
_ => { _ => vec![]
vec![]
}
}; };
let html = IndexTemplate { let html = IndexTemplate {
posts, posts,
title: String::from("Very cool mcoranges website :3"), title: String::from("MCorange - The website :3"),
}.render().expect("Failed to render index.html"); }.render().expect("Failed to render index.html");
Ok(Html(html)) Ok(Html(html))
} }
/*
<div class="post">
<img src="/static/assets/uwu.jpg" alt="post img">
<span>
<h2>Title text</h3>
<p>Description text</p>
</span>
</div>
*/

View File

@ -0,0 +1,19 @@
use std::sync::Mutex;
use actix_web_lab::respond::Html;
use actix_web::{web::Data, Responder, Result};
use askama::Template;
use crate::{database::Database, web::templates::ProjectTemplate};
pub async fn projects(_: Data<Mutex<Database>>) -> Result<impl Responder> {
let html = ProjectTemplate {
title: String::from("MCorange - My projects :O"),
}.render().expect("Failed to render projects.html");
Ok(Html(html))
}

View File

@ -0,0 +1,16 @@
use actix_web::{web::{self, redirect}, HttpResponse, Scope};
use crate::config::definition::Config;
pub fn get_scope(config: &Config) -> Scope {
let mut s = Scope::new("/r")
.route("/", web::get().to(HttpResponse::Ok));
for r in config.redirect.clone() {
s = s.service(redirect(r.from, r.to));
}
// .service(
// webhooks::get_scope()
// )
s
}

View File

@ -10,3 +10,16 @@ pub struct IndexTemplate{
} }
#[derive(Debug, Clone, Template)]
#[template(path = "projects.html")]
pub struct ProjectTemplate{
pub title: String,
}
#[derive(Debug, Clone, Template)]
#[template(path = "contact.html")]
pub struct ContactTemplate{
pub title: String,
}

0
static/css/contact.css Normal file
View File

0
static/css/projects.css Normal file
View File

61
templates/contact.html Normal file
View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/static/css/global.css">
<link rel="stylesheet" href="/static/css/contact.css">
</head>
<body>
<input type="checkbox" id="toggle">
<div id="content">
<div class="box titlebar">
<h1>{{title}}</h1>
</div>
<div id="main-pane">
<div class="box" id="sidenav">
<a href="/">Home</a>
<a href="/projects">Projects</a>
<a href="/contact">Contact me</a>
<a href="/r/hmm">???</a>
<label id="login-btn" for="toggle">Login</label>
</div>
<div class="box" id="content-pane">
<h2 style="color: gray;">Nothing here, for now</h2>
</div>
</div>
</div>
<div id="login-modal-container">
<div id="login-modal">
<h1>login <labeL for="toggle">(x)</labeL></h1>
<p>secrets beyond human comprehension lie beneath this unassuming login screen</p>
<div class="container">
<div class="form-group">
<label for="uname"><b>Email:</b></label>
<input type="text" name="uname" required>
</div>
<div class="form-group">
<label for="psw"><b>Password:</b></label>
<input type="password" name="psw" required>
</div>
<br>
<button type="submit">Login</button>
<br>
<label>
<input type="checkbox" checked="checked" name="remember"> Remember me
</label>
</div>
</div>
</div>
</body>
</html>

View File

@ -14,10 +14,10 @@
</div> </div>
<div id="main-pane"> <div id="main-pane">
<div class="box" id="sidenav"> <div class="box" id="sidenav">
<a href="#">Home</a> <a href="/">Home</a>
<a href="#">Home</a> <a href="/projects">Projects</a>
<a href="#">Home</a> <a href="/contact">Contact me</a>
<a href="#">Home</a> <a href="/r/hmm">???</a>
<label id="login-btn" for="toggle">Login</label> <label id="login-btn" for="toggle">Login</label>
</div> </div>
<div class="box" id="content-pane"> <div class="box" id="content-pane">

13
templates/panel.html Normal file
View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/static/css/global.css">
<!-- <link rel="stylesheet" href="/static/css/panel.css"> -->
</head>
<body>
<h1>Nothing in here, for now.</h1>
</body>
</html>

61
templates/projects.html Normal file
View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/static/css/global.css">
<link rel="stylesheet" href="/static/css/projects.css">
</head>
<body>
<input type="checkbox" id="toggle">
<div id="content">
<div class="box titlebar">
<h1>{{title}}</h1>
</div>
<div id="main-pane">
<div class="box" id="sidenav">
<a href="/">Home</a>
<a href="/projects">Projects</a>
<a href="/contact">Contact me</a>
<a href="/r/hmm">???</a>
<label id="login-btn" for="toggle">Login</label>
</div>
<div class="box" id="content-pane">
<h2 style="color: gray;">Nothing here, for now</h2>
</div>
</div>
</div>
<div id="login-modal-container">
<div id="login-modal">
<h1>login <labeL for="toggle">(x)</labeL></h1>
<p>secrets beyond human comprehension lie beneath this unassuming login screen</p>
<div class="container">
<div class="form-group">
<label for="uname"><b>Email:</b></label>
<input type="text" name="uname" required>
</div>
<div class="form-group">
<label for="psw"><b>Password:</b></label>
<input type="password" name="psw" required>
</div>
<br>
<button type="submit">Login</button>
<br>
<label>
<input type="checkbox" checked="checked" name="remember"> Remember me
</label>
</div>
</div>
</div>
</body>
</html>