redirects
This commit is contained in:
parent
e289f38192
commit
9770f327b7
|
@ -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/"
|
|
@ -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,
|
||||||
}
|
}
|
|
@ -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(())
|
||||||
|
|
|
@ -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
19
src/web/routes/contact.rs
Normal 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))
|
||||||
|
}
|
|
@ -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>
|
|
||||||
*/
|
|
19
src/web/routes/projects.rs
Normal file
19
src/web/routes/projects.rs
Normal 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))
|
||||||
|
}
|
16
src/web/routes/redirect.rs
Normal file
16
src/web/routes/redirect.rs
Normal 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
|
||||||
|
}
|
|
@ -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
0
static/css/contact.css
Normal file
0
static/css/projects.css
Normal file
0
static/css/projects.css
Normal file
61
templates/contact.html
Normal file
61
templates/contact.html
Normal 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>
|
|
@ -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
13
templates/panel.html
Normal 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
61
templates/projects.html
Normal 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>
|
Loading…
Reference in New Issue
Block a user