Skip to content

Commit d9372a9

Browse files
committed
added url shrtner && moved the whole project to rocket.rs
1 parent 1c29653 commit d9372a9

40 files changed

+980
-62
lines changed

.gitignore

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generated by Cargo
2+
# will have compiled files and executables
3+
/target/
4+
5+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
6+
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
7+
Cargo.lock
8+
9+
# These are backup files generated by rustfmt
10+
**/*.rs.bk
11+
12+
13+
# Added by cargo
14+
15+
/target
16+
17+
.env

404.html

-22
This file was deleted.

Cargo.toml

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "plexx-dev"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
rocket = "0.5.0-rc.2"
10+
rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["tera"] }
11+
sha2 = "*"
12+
hex = "*"
13+
validator = { version = "0.15", features = ["derive"] }
14+
15+
[dependencies.rocket_db_pools]
16+
version = "0.1.0-rc.2"
17+
features = ["sqlx_mysql"]

Dockerfile

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1-
FROM nginx:alpine
1+
FROM rust:latest as builder
2+
WORKDIR /app
3+
COPY . .
4+
RUN cargo install --path .
25

3-
COPY . /usr/share/nginx/html/
6+
7+
FROM debian:buster-slim as runner
8+
WORKDIR /app
9+
COPY --from=builder /usr/local/cargo/bin/plexx-dev /usr/local/bin/plexx-dev
10+
COPY . .
11+
RUN ls
12+
CMD ["plexx-dev"]

JetBrainsMono_var_weight.ttf

-225 KB
Binary file not shown.

LICENSE

+674
Large diffs are not rendered by default.

Rocket.toml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[debug]
2+
port = 5000
3+
4+
[release]
5+
cli_colors = false
6+
port = 80
7+
address = "0.0.0.0"
8+
9+
[global]
10+
min_connections = 64
11+
max_connections = 1024
12+
connect_timeout = 5
13+
idle_timeout = 120
14+
limits = { form = "64 kB", json = "1 MiB" }

index.html

-24
This file was deleted.

src/error.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
pub fn get_error_message(code: u16) -> String {
2+
match code {
3+
300 => "Multiple Choices".to_string(),
4+
301 => "Moved Permanently".to_string(),
5+
304 => "Not Modified".to_string(),
6+
307 => "Temporary Redirect (since HTTP/1.1)".to_string(),
7+
308 => "Permanent Redirect".to_string(),
8+
9+
400 => "Bad Request".to_string(),
10+
401 => "Unauthorized".to_string(),
11+
403 => "Forbidden".to_string(),
12+
404 => "Not found".to_string(),
13+
405 => "Method not allowed".to_string(),
14+
408 => "Request Timeout".to_string(),
15+
418 => "I'm a Teapot".to_string(),
16+
17+
500 => "Internal Server Error".to_string(),
18+
502 => "Bad Gateway".to_string(),
19+
503 => "Service Unavailable".to_string(),
20+
21+
_ => "WIP ERROR CODE".to_string(),
22+
}
23+
}

src/main.rs

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use rocket::*;
2+
use rocket::fs::FileServer;
3+
use rocket::http::Status;
4+
5+
use rocket_dyn_templates::{Template, context};
6+
7+
use rocket_db_pools::Database;
8+
use rocket_db_pools::sqlx;
9+
10+
mod urlshrtner;
11+
mod error;
12+
13+
#[derive(Database)]
14+
#[database("urls")]
15+
pub struct Urls(sqlx::MySqlPool);
16+
17+
#[get("/")]
18+
async fn index() -> Template {
19+
Template::render("index", context! {})
20+
}
21+
22+
#[catch(default)]
23+
async fn default_catcher(status: Status, _: &Request<'_>) -> Template {
24+
Template::render("error", context! {
25+
code: status.code,
26+
message: error::get_error_message(status.code)
27+
})
28+
}
29+
30+
#[launch]
31+
async fn rocket() -> _ {
32+
rocket::build()
33+
.mount("/", routes![
34+
index
35+
])
36+
.mount("/", routes![
37+
urlshrtner::routes::get_url,
38+
urlshrtner::routes::index,
39+
urlshrtner::routes::submit,
40+
])
41+
.mount("/static", FileServer::from("static"))
42+
.register("/", catchers![default_catcher])
43+
.attach(Template::fairing())
44+
.attach(Urls::init())
45+
}

src/urlshrtner/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod routes;
2+
pub mod short;

src/urlshrtner/routes.rs

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
use rocket::*;
2+
3+
use rocket::form::Form;
4+
use rocket::response::Redirect;
5+
use rocket_dyn_templates::{Template, context};
6+
7+
#[allow(unused_imports)]
8+
use rocket_db_pools::{Connection, Database};
9+
use rocket_db_pools::sqlx::{self, Row};
10+
11+
use validator::{Validate, validate_url};
12+
13+
use crate::Urls;
14+
15+
use super::short;
16+
17+
#[get("/<url_hash>")]
18+
pub async fn get_url(mut db: Connection<Urls>, url_hash: String) -> Redirect {
19+
let fallback_url = String::from("https://plexx.dev");
20+
21+
let url: Option<String> = match sqlx::query("SELECT url FROM urls WHERE url_hash = ?")
22+
.bind(&url_hash)
23+
.fetch_one(&mut*db)
24+
.await {
25+
Ok(row) => row,
26+
Err(error) => {
27+
println!("{}", error);
28+
return Redirect::to(fallback_url)
29+
},
30+
}
31+
.try_get(0)
32+
.ok();
33+
34+
let url_str = match url {
35+
Some(url_str) => url_str,
36+
None => {
37+
println!("failed");
38+
fallback_url
39+
},
40+
};
41+
42+
Redirect::to(url_str)
43+
}
44+
45+
#[get("/short")]
46+
pub async fn index() -> Template {
47+
Template::render("urlshrtner/index", context! {})
48+
}
49+
50+
#[derive(FromForm, Debug, Validate)]
51+
pub struct Url {
52+
#[validate(url)]
53+
pub url: String
54+
}
55+
56+
#[allow(unused_assignments)]
57+
#[post("/short", data = "<form>")]
58+
pub async fn submit(mut db: Connection<Urls>, form: Form<Url>) -> Template {
59+
let mut url = form.into_inner().url;
60+
61+
let mut mod_url = String::new();
62+
let is_valid = validate_url(&url);
63+
if !is_valid {
64+
mod_url = "https://".to_string();
65+
mod_url.push_str(url.as_str());
66+
if validate_url(&mod_url) {
67+
url = mod_url;
68+
} else {
69+
return Template::render("urlshrtner/index", context! {
70+
url: "URL is not valid"
71+
});
72+
}
73+
}
74+
75+
let url_hash = short::hash(&url);
76+
77+
sqlx::query("INSERT INTO urls (url, url_hash) VALUES (?, ?)").bind(&url).bind(&url_hash)
78+
.execute(&mut *db)
79+
.await
80+
.ok();
81+
82+
Template::render("urlshrtner/result", context! {
83+
url: format!("plexx.dev/{}", url_hash)
84+
})
85+
}

src/urlshrtner/short.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use sha2::{Sha256, Digest};
2+
3+
pub fn hash(input: &String) -> String {
4+
let mut h = Sha256::new();
5+
h.update(&input);
6+
let hash_u32 = &h.finalize()[..];
7+
8+
format!("{:.6}", hex::encode(hash_u32))
9+
}
192 KB
Binary file not shown.

css/all.min.css static/all.min.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

favicon.ico static/favicon.ico

File renamed without changes.

main.css static/main.css

+16-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
@font-face{
2-
font-family: "JetBrains Mono";
3-
src: url("JetBrainsMono_var_weight.ttf");
4-
src: url("JetBrainsMono_var_weight.ttf") format("ttf"),
5-
url("JetBrainsMono_var_weight.ttf") format("opentype"),
6-
url("JetBrainsMono_var_weight.ttf") format("svg");
2+
font-family: "Source Code Pro";
3+
src: url("SourceCodePro-VariableFont_wght.ttf");
4+
src: url("SourceCodePro-VariableFont_wght.ttf") format("ttf"),
5+
url("SourceCodePro-VariableFont_wght.ttf") format("opentype"),
6+
url("SourceCodePro-VariableFont_wght.ttf") format("svg");
77
}
8-
8+
99
* {
10-
font-family: "JetBrains Mono";
10+
font-family: "Source Code Pro";
1111
}
1212

13-
html {
14-
height: 100%;
15-
}
16-
1713
body {
1814
background-color: rgb(0,0,0);
1915
color: #fff;
@@ -49,7 +45,7 @@ nav {
4945

5046
a {
5147
padding: .75rem;
52-
color: inherit;
48+
color: #fff;
5349
font-weight: 515;
5450
font-size: 1.25rem;
5551
text-decoration: none;
@@ -58,3 +54,11 @@ a {
5854
.link-text {
5955
text-decoration: underline;
6056
}
57+
58+
.form {
59+
vertical-align: baseline;
60+
padding-top: 24vh;
61+
margin: 0 auto 24vh;
62+
max-width: fit-content;
63+
max-height: fit-content;
64+
}

pgp.txt static/pgp.txt

File renamed without changes.

robots.txt static/robots.txt

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

templates/error.html.tera

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{% extends 'layout' %}
2+
{% block content %}
3+
4+
<p class="title">{{ code }}</p>
5+
<p class="text">{{ message }}</p>
6+
<div class="text">
7+
<br>
8+
<a href="/" class="text">
9+
<i class="fas fa-home"></i>
10+
<text class="link-text">Back</text></a>
11+
</div>
12+
13+
{% endblock content %}

templates/index.html.tera

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{% extends 'layout' %}
2+
{% block content %}
3+
4+
<p class="title">plexx</p>
5+
<p class="text">Professional™ Developer</p>
6+
<nav>
7+
<a href="https://github.com/plexx-dev"><i class="fab fa-github"></i> <text class="link-text">Github</text></a>
8+
<a href="mailto:[email protected]"><i class="fas fa-envelope"></i> <text class="link-text">Email</text></a>
9+
<a href="https://steamcommunity.com/id/plexx_dev/"><i class="fab fa-steam"></i> <text class="link-text">Steam</text></a>
10+
<a href="https://status.plexx.dev"><i class="fas fa-server"></i> <text class="link-text">Server-Status</text></a>
11+
<a href="/short"><i class="fas fa-link"></i> <text class="link-text">UrlShrtner</text></a>
12+
<a href="/static/pgp.txt"><i class="fas fa-key"></i> <text class="link-text">PGP-Key</text></a>
13+
<a><i class="fab fa-discord"></i> <text class="link-text">plexx#0928</text></a>
14+
</nav>
15+
16+
{% endblock content %}

templates/layout.html.tera

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<link rel="stylesheet" href="/static/main.css">
6+
<link rel="stylesheet" href="/static/all.min.css">
7+
<title>plexx.dev</title>
8+
<link rel="shortcut icon" href="/static/favicon.ico">
9+
</head>
10+
<body>
11+
<main>
12+
{% block content %}
13+
{% endblock %}
14+
</main>
15+
</body>
16+
</html>

0 commit comments

Comments
 (0)