Restructure the code to be more readable and better organized

Moreover, the overall navigation structure is finished but database handling is still missing
Also there still needs to be proper styling for all the html files and proper organization
This commit is contained in:
2021-09-01 21:13:26 +02:00
parent 96260d18ce
commit a4372c6872
7 changed files with 163 additions and 51 deletions

10
Cargo.lock generated
View File

@@ -997,6 +997,7 @@ dependencies = [
"actix-web", "actix-web",
"reqwest", "reqwest",
"tera", "tera",
"uuid",
] ]
[[package]] [[package]]
@@ -2404,6 +2405,15 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "uuid"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [
"getrandom 0.2.3",
]
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.15" version = "0.2.15"

View File

@@ -7,5 +7,6 @@ edition = "2018"
[dependencies] [dependencies]
actix-web = "3" actix-web = "3"
uuid = { version = "0.8.2", features = ["v4"] }
reqwest = { version = "0.11", features = ["blocking"] } reqwest = { version = "0.11", features = ["blocking"] }
tera = "1.12.1" tera = "1.12.1"

View File

@@ -2,12 +2,16 @@ use std::collections::HashMap;
use actix_web::{error, web, App, Error, HttpRequest, HttpResponse, HttpServer, Responder, Result}; use actix_web::{error, web, App, Error, HttpRequest, HttpResponse, HttpServer, Responder, Result};
use tera::Tera; use tera::Tera;
use uuid::Uuid;
const REDIRECT_TIMEOUT_S: i32 = 2;
async fn make_ics_request(req: HttpRequest) -> impl Responder { async fn make_ics_request(req: HttpRequest) -> impl Responder {
let id = req.match_info().get("id").unwrap_or("World"); let id = req.match_info().get("id").unwrap_or("");
let body = match id { let body = match id {
"1" => { "1" => {
// TODO: load url based on id from database and make request
let res = match reqwest::blocking::get("https://cloud.timeedit.net/uu/web/schema/ri6QX6089X8061QQ88Z4758Z08y37424838828461554904Y684XX09894Q8721784ZnX6503.ics") { let res = match reqwest::blocking::get("https://cloud.timeedit.net/uu/web/schema/ri6QX6089X8061QQ88Z4758Z08y37424838828461554904Y684XX09894Q8721784ZnX6503.ics") {
Ok(r) => match r.text() { Ok(r) => match r.text() {
Ok(res) => res, Ok(res) => res,
@@ -23,52 +27,143 @@ async fn make_ics_request(req: HttpRequest) -> impl Responder {
HttpResponse::Ok().content_type("text/calendar").body(body) HttpResponse::Ok().content_type("text/calendar").body(body)
} }
async fn edit( fn error_page(tmpl: web::Data<tera::Tera>, msg: String) -> Result<HttpResponse, Error> {
tmpl: web::Data<tera::Tera>,
query: web::Query<HashMap<String, String>>,
) -> Result<HttpResponse, Error> {
let mut s = "".to_string();
if query.get("create").is_some() {
if let Some(link) = query.get("link") {
// submitted form
let proxy_link = &"Insert link here".to_owned();
let mut ctx = tera::Context::new(); let mut ctx = tera::Context::new();
ctx.insert("link", &link.to_owned()); ctx.insert("message", &msg);
ctx.insert("proxy_link", proxy_link); let s = tmpl
s = tmpl .render("error.html", &ctx)
.render("edit.html", &ctx)
.map_err(|_| error::ErrorInternalServerError("Template error"))?; .map_err(|_| error::ErrorInternalServerError("Template error"))?;
}
// create new link
} else if query.get("edit").is_some() {
if let Some(link) = query.get("link") {
// submitted form
let proxy_link = &"Insert link here".to_owned();
let mut ctx = tera::Context::new();
ctx.insert("link", &link.to_owned());
ctx.insert("proxy_link", proxy_link);
s = tmpl
.render("edit.html", &ctx)
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
}
// edit existing link
} else if query.get("replace").is_some() {
// replace link
s = "Replace".to_string();
} else {
s = tmpl
.render("error.html", &tera::Context::new())
.map_err(|_| error::ErrorInternalServerError("Template error"))?
}
Ok(HttpResponse::Ok().content_type("text/html").body(s)) Ok(HttpResponse::Ok().content_type("text/html").body(s))
} }
// This is the new edit page:
async fn edit_page(
tmpl: web::Data<tera::Tera>,
query: web::Query<HashMap<String, String>>,
) -> Result<HttpResponse, Error> {
// one uuid: 9228c1a4-8956-4f1c-8b5f-53cc575bd78
if let Some(uuid_str) = query.get("uuid") {
// TODO: based on uuid get link from database
let link = "this is the link from the db".to_string();
match Uuid::parse_str(uuid_str) {
Ok(uuid) => {
let mut ctx = tera::Context::new();
ctx.insert("link", &link);
ctx.insert("uuid", &uuid.to_string());
let s = tmpl
.render("edit.html", &ctx)
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(s))
}
Err(err) => error_page(tmpl, format!("uuid parsing error: {}", err.to_string())),
}
} else {
error_page(tmpl, "uuid parameter missing".to_string())
}
}
fn redirect_to_page(
tmpl: web::Data<tera::Tera>,
message: String,
link: String,
time_s: i32,
) -> Result<HttpResponse, Error> {
let mut ctx = tera::Context::new();
ctx.insert("message", &message);
ctx.insert("link", &link);
ctx.insert("time", &time_s);
let s = tmpl
.render("redirect.html", &ctx)
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(s))
}
fn redirect_to_edit_page(
tmpl: web::Data<tera::Tera>,
message: String,
uuid: Uuid,
time_s: i32,
) -> Result<HttpResponse, Error> {
let mut ctx = tera::Context::new();
ctx.insert("message", &message);
let link = format!("/edit?uuid={}", uuid.to_string());
ctx.insert("time", &time_s);
redirect_to_page(tmpl, message, link, time_s)
}
/*
fn redirect_to_index_page(
tmpl: web::Data<tera::Tera>,
query: web::Query<HashMap<String, String>>,
message: String,
uuid: Uuid,
time_s: i32,
) -> Result<HttpResponse, Error> {
// TODO: add option to prefill link
}
*/
async fn edit_process(
tmpl: web::Data<tera::Tera>,
query: web::Query<HashMap<String, String>>,
) -> Result<HttpResponse, Error> {
// TODO: implement handling
if let Some(uuid_str) = query.get("uuid") {
if let Some(link) = query.get("link") {
match Uuid::parse_str(uuid_str) {
Ok(uuid) => {
// TODO: actually save entry in database
redirect_to_edit_page(
tmpl,
"Edit successful!".to_string(),
uuid,
REDIRECT_TIMEOUT_S,
)
}
Err(err) => error_page(tmpl, format!("uuid parsing error: {}", err.to_string())),
}
} else {
error_page(tmpl, "link parameter missing".to_string())
}
} else {
error_page(tmpl, "uuid parameter missing".to_string())
}
}
async fn index_process(
tmpl: web::Data<tera::Tera>,
query: web::Query<HashMap<String, String>>,
) -> Result<HttpResponse, Error> {
if query.get("create").is_some() {
let uuid = Uuid::nil();
// TODO: add actuall logic and use proper uuid
redirect_to_edit_page(
tmpl,
"Create was successful".to_string(),
uuid,
REDIRECT_TIMEOUT_S,
)
} else if query.get("edit").is_some() {
let uuid = Uuid::nil();
// TODO: add actuall logic and use proper uuid
redirect_to_edit_page(
tmpl,
"Entry found in database!".to_string(),
uuid,
REDIRECT_TIMEOUT_S,
)
} else {
error_page(tmpl, "missing create or edit form submission!".to_string())
}
}
// store tera template in application state // store tera template in application state
async fn index(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> { async fn index(tmpl: web::Data<tera::Tera>) -> Result<HttpResponse, Error> {
// TODO: add option to prefill link with parameter
let s = tmpl let s = tmpl
.render("index.html", &tera::Context::new()) .render("index.html", &tera::Context::new())
.map_err(|_| error::ErrorInternalServerError("Template error"))?; .map_err(|_| error::ErrorInternalServerError("Template error"))?;
@@ -87,7 +182,9 @@ async fn main() -> std::io::Result<()> {
.data(tera) .data(tera)
.route("/{id}/events.ics", web::get().to(make_ics_request)) .route("/{id}/events.ics", web::get().to(make_ics_request))
.service(web::resource("/").route(web::get().to(index))) .service(web::resource("/").route(web::get().to(index)))
.service(web::resource("/edit").route(web::get().to(edit))) .service(web::resource("/edit").route(web::get().to(edit_page)))
.service(web::resource("/index_process").route(web::get().to(index_process)))
.service(web::resource("/edit_process").route(web::get().to(edit_process)))
}) })
.bind("127.0.0.1:8080")? .bind("127.0.0.1:8080")?
.run() .run()

View File

@@ -7,11 +7,12 @@
</head> </head>
<body> <body>
<h1>Hi, your link is {{ proxy_link }}!</h1> <h1>Hi, your link is <a href="/{{ uuid }}/events.ics"">/{{ uuid }}/events.ics</a>!</h1>
it takes the data from redirects to it takes the data from
<p> <p>
<form> <form action=" edit_process">
<input type="text" value="{{ link }}"> <input name="uuid" type="hidden" value="{{ uuid }}">
<input name="link" type="text" value="{{ link }}">
<input value="Replace" name="replace" type="submit"> <input value="Replace" name="replace" type="submit">
</form> </form>
</p> </p>

View File

@@ -1 +1 @@
Something went wrong {{ message }}

View File

@@ -9,7 +9,7 @@
<body> <body>
<h1>Welcome!</h1> <h1>Welcome!</h1>
<p> <p>
<form action="edit"> <form action="index_process">
<label for="link"">Link: </label> <label for="link"">Link: </label>
<input id=" link" type="text" name="link" /><br /> <input id=" link" type="text" name="link" /><br />
<input value="Create proxy link" name="create" type="submit"> <input value="Create proxy link" name="create" type="submit">

3
templates/redirect.html Normal file
View File

@@ -0,0 +1,3 @@
<p>{{ message }}</p>
<p>Please wait to be redirected or click <a href="{{ link }}">here!</a></p>
<meta http-equiv="Refresh" content="{{ time }}; url='{{ link }}'" />