yes this asset is Needed i promise
This commit is contained in:
parent
62afc49675
commit
e316023b37
9 changed files with 258 additions and 199 deletions
BIN
assets/404.gif
Normal file
BIN
assets/404.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 MiB |
|
@ -44,6 +44,16 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
picture.block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
picture.block>img {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0 auto 2em auto;
|
||||
max-width: 700px;
|
||||
|
|
210
src/main.rs
210
src/main.rs
|
@ -2,22 +2,20 @@
|
|||
extern crate rocket;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use db::doll::{self, check_ids, id_exists};
|
||||
use db::migrate::run_migrations;
|
||||
use db::schema::{CreateDollProfile, DollTags, DollTagsDb};
|
||||
use db::schema::DollTags;
|
||||
use regex::Regex;
|
||||
use rng::generate_ids;
|
||||
use rocket::fairing::AdHoc;
|
||||
use rocket::form::{self, Form};
|
||||
use rocket::fs::{relative, FileServer};
|
||||
use rocket::response::Redirect;
|
||||
use rocket_db_pools::Database;
|
||||
use rocket_dyn_templates::tera::try_get_value;
|
||||
use rocket_dyn_templates::{context, Template};
|
||||
use rocket_dyn_templates::Template;
|
||||
use routes::{error_handlers, form, public};
|
||||
use serde_json::{to_value, Value};
|
||||
|
||||
pub mod db;
|
||||
pub mod rng;
|
||||
pub mod routes;
|
||||
|
||||
pub fn id_public_to_db(id: &str) -> Option<i64> {
|
||||
let id_re = Regex::new(r"^\d{6}$").unwrap();
|
||||
|
@ -34,198 +32,6 @@ pub fn id_db_to_public(id: i64) -> String {
|
|||
format!("{:0>3}-{:0>3}", first, second)
|
||||
}
|
||||
|
||||
#[get("/?<miss>&<ident>&<microchip_id>")]
|
||||
fn index(miss: Option<bool>, ident: Option<&str>, microchip_id: Option<&str>) -> Template {
|
||||
Template::render(
|
||||
"index",
|
||||
context! {
|
||||
miss,
|
||||
ident,
|
||||
microchip_id,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[get("/register")]
|
||||
async fn show_register(db: DollTagsDb) -> Template {
|
||||
let mut ids_bundle = generate_ids();
|
||||
let occupied_ids = check_ids(db, &ids_bundle).await.expect("fuck");
|
||||
ids_bundle.retain(|&id| !occupied_ids.contains(&id));
|
||||
let ids = ids_bundle.iter().take(5).collect::<Vec<&i64>>();
|
||||
|
||||
Template::render(
|
||||
"register",
|
||||
context! {
|
||||
ids
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: Validation
|
||||
#[derive(Debug, FromForm)]
|
||||
struct TagForm<'a> {
|
||||
#[field(validate=len(1..=6))]
|
||||
pub ident: &'a str,
|
||||
#[field(validate=len(..32))]
|
||||
pub microchip_id: &'a str,
|
||||
|
||||
#[field(validate=len(..256))]
|
||||
pub name: &'a str,
|
||||
#[field(validate=len(..32))]
|
||||
pub pronoun_subject: &'a str,
|
||||
#[field(validate=len(..32))]
|
||||
pub pronoun_object: &'a str,
|
||||
#[field(validate=len(..32))]
|
||||
pub pronoun_possessive: &'a str,
|
||||
|
||||
#[field(validate=len(..256))]
|
||||
pub handler_name: &'a str,
|
||||
#[field(validate=len(..2048))]
|
||||
pub handler_link: &'a str,
|
||||
|
||||
#[field(validate=len(..256))]
|
||||
pub kind: &'a str,
|
||||
#[field(validate=len(..256))]
|
||||
pub breed: &'a str,
|
||||
#[field(validate=len(..256))]
|
||||
pub behaviour: &'a str,
|
||||
#[field(validate=len(..2048))]
|
||||
pub description: &'a str,
|
||||
|
||||
#[field(validate=validate_chassis(self.chassis_id, self.chassis_color, "chassis_type"))]
|
||||
pub chassis_type: &'a str,
|
||||
#[field(validate=validate_chassis(self.chassis_type, self.chassis_color, "chassis_id"))]
|
||||
pub chassis_id: &'a str,
|
||||
#[field(validate=validate_chassis(self.chassis_type, self.chassis_id, "chassis_color"))]
|
||||
pub chassis_color: &'a str,
|
||||
}
|
||||
|
||||
fn validate_chassis<'v>(a: &str, b: &str, c: &str, field: &str) -> form::Result<'v, ()> {
|
||||
let all_empty = a.len() == 0 && b.len() == 0 && c.len() == 0;
|
||||
let all_full = a.len() != 0
|
||||
&& a.len() < 256
|
||||
&& b.len() != 0
|
||||
&& b.len() < 256
|
||||
&& c.len() != 0
|
||||
&& c.len() < 256;
|
||||
|
||||
if !all_empty && !all_full {
|
||||
Err(form::Error::validation(format!(
|
||||
"missing chassis field {}",
|
||||
field
|
||||
)))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[post("/register", data = "<tag>")]
|
||||
async fn handle_register(mut db: DollTagsDb, tag: Form<TagForm<'_>>) -> Result<Template, Redirect> {
|
||||
println!("register: {:?}", tag);
|
||||
let id = id_public_to_db(&tag.ident).expect("wrong fmt");
|
||||
let pronouns = format!(
|
||||
"{}/{}/{}",
|
||||
tag.pronoun_subject, tag.pronoun_object, tag.pronoun_possessive
|
||||
);
|
||||
let microchip_id = tag.microchip_id.to_lowercase();
|
||||
|
||||
if id_exists(&mut *db, id, µchip_id).await.expect("fuck") {
|
||||
return Err(Redirect::found(uri!("/register")));
|
||||
}
|
||||
|
||||
doll::create(
|
||||
db,
|
||||
CreateDollProfile {
|
||||
id,
|
||||
microchip_id: if microchip_id.len() != 0 {
|
||||
Some(µchip_id)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
name: tag.name,
|
||||
pronouns: pronouns.as_str(),
|
||||
handler_name: tag.handler_name,
|
||||
handler_url: if tag.handler_link.len() != 0 {
|
||||
Some(tag.handler_link)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
kind: if tag.kind.len() != 0 {
|
||||
Some(tag.kind)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
breed: if tag.breed.len() != 0 {
|
||||
Some(tag.breed)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
behaviour: if tag.behaviour.len() != 0 {
|
||||
Some(tag.behaviour)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
description: if tag.description.len() != 0 {
|
||||
Some(tag.description)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
chassis_type: if tag.chassis_type.len() != 0 {
|
||||
Some(tag.chassis_type)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
chassis_id: if tag.chassis_id.len() != 0 {
|
||||
Some(tag.chassis_id)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
chassis_color: if tag.chassis_color.len() != 0 {
|
||||
Some(tag.chassis_color)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
},
|
||||
)
|
||||
.await
|
||||
.expect("fuck");
|
||||
|
||||
Ok(Template::render("register", context! {ids: vec![123456]}))
|
||||
}
|
||||
|
||||
#[get("/profile?<ident>&<microchip_id>")]
|
||||
async fn show_profile(
|
||||
db: DollTagsDb,
|
||||
ident: Option<&str>,
|
||||
microchip_id: Option<&str>,
|
||||
) -> Result<Template, Redirect> {
|
||||
let internal_id = ident.and_then(|v| id_public_to_db(v)).unwrap_or(0);
|
||||
let microchip_id = microchip_id.unwrap_or("");
|
||||
|
||||
let profile = doll::get(db, internal_id, microchip_id)
|
||||
.await
|
||||
.expect("fuck")
|
||||
.ok_or(Redirect::to(uri!(index(
|
||||
Some(true),
|
||||
ident,
|
||||
Some(microchip_id)
|
||||
))))?;
|
||||
let has_notable_traits = profile.has_notable_traits();
|
||||
let has_chassis_info = profile.chassis_id.is_some()
|
||||
&& profile.chassis_type.is_some()
|
||||
&& profile.chassis_color.is_some();
|
||||
|
||||
println!("{:?}", profile);
|
||||
Ok(Template::render(
|
||||
"show_profile",
|
||||
context! {
|
||||
profile,
|
||||
has_notable_traits,
|
||||
has_chassis_info,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[launch]
|
||||
fn rocket() -> _ {
|
||||
rocket::build()
|
||||
|
@ -239,9 +45,15 @@ fn rocket() -> _ {
|
|||
}))
|
||||
.attach(DollTags::init())
|
||||
.attach(AdHoc::try_on_ignite("SQLx migrations", run_migrations))
|
||||
.register("/", catchers![error_handlers::not_found])
|
||||
.mount("/assets", FileServer::from(relative!("/assets")))
|
||||
.mount(
|
||||
"/",
|
||||
routes![index, show_profile, show_register, handle_register],
|
||||
routes![
|
||||
public::index,
|
||||
public::show_profile,
|
||||
form::register_tag::show_register,
|
||||
form::register_tag::handle_register
|
||||
],
|
||||
)
|
||||
}
|
||||
|
|
6
src/routes/error_handlers.rs
Normal file
6
src/routes/error_handlers.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
use rocket_dyn_templates::{context, Template};
|
||||
|
||||
#[catch(404)]
|
||||
pub fn not_found() -> Template {
|
||||
Template::render("error/not-found", context! {})
|
||||
}
|
1
src/routes/form/mod.rs
Normal file
1
src/routes/form/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod register_tag;
|
166
src/routes/form/register_tag.rs
Normal file
166
src/routes/form/register_tag.rs
Normal file
|
@ -0,0 +1,166 @@
|
|||
use rocket::{
|
||||
form::{self, Form},
|
||||
response::Redirect,
|
||||
};
|
||||
use rocket_dyn_templates::{context, Template};
|
||||
|
||||
use crate::{
|
||||
db::{
|
||||
doll,
|
||||
schema::{CreateDollProfile, DollTagsDb},
|
||||
},
|
||||
id_public_to_db,
|
||||
rng::generate_ids,
|
||||
};
|
||||
|
||||
#[get("/register")]
|
||||
pub async fn show_register(db: DollTagsDb) -> Template {
|
||||
let mut ids_bundle = generate_ids();
|
||||
let occupied_ids = doll::check_ids(db, &ids_bundle).await.expect("fuck");
|
||||
ids_bundle.retain(|&id| !occupied_ids.contains(&id));
|
||||
let ids = ids_bundle.iter().take(5).collect::<Vec<&i64>>();
|
||||
|
||||
Template::render(
|
||||
"register",
|
||||
context! {
|
||||
ids
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug, FromForm)]
|
||||
pub struct TagForm<'a> {
|
||||
#[field(validate=len(1..=6))]
|
||||
pub ident: &'a str,
|
||||
#[field(validate=len(..32))]
|
||||
pub microchip_id: &'a str,
|
||||
|
||||
#[field(validate=len(..256))]
|
||||
pub name: &'a str,
|
||||
#[field(validate=len(..32))]
|
||||
pub pronoun_subject: &'a str,
|
||||
#[field(validate=len(..32))]
|
||||
pub pronoun_object: &'a str,
|
||||
#[field(validate=len(..32))]
|
||||
pub pronoun_possessive: &'a str,
|
||||
|
||||
#[field(validate=len(..256))]
|
||||
pub handler_name: &'a str,
|
||||
#[field(validate=len(..2048))]
|
||||
pub handler_link: &'a str,
|
||||
|
||||
#[field(validate=len(..256))]
|
||||
pub kind: &'a str,
|
||||
#[field(validate=len(..256))]
|
||||
pub breed: &'a str,
|
||||
#[field(validate=len(..256))]
|
||||
pub behaviour: &'a str,
|
||||
#[field(validate=len(..2048))]
|
||||
pub description: &'a str,
|
||||
|
||||
#[field(validate=validate_chassis(self.chassis_id, self.chassis_color, "chassis_type"))]
|
||||
pub chassis_type: &'a str,
|
||||
#[field(validate=validate_chassis(self.chassis_type, self.chassis_color, "chassis_id"))]
|
||||
pub chassis_id: &'a str,
|
||||
#[field(validate=validate_chassis(self.chassis_type, self.chassis_id, "chassis_color"))]
|
||||
pub chassis_color: &'a str,
|
||||
}
|
||||
|
||||
fn validate_chassis<'v>(a: &str, b: &str, c: &str, field: &str) -> form::Result<'v, ()> {
|
||||
let all_empty = a.len() == 0 && b.len() == 0 && c.len() == 0;
|
||||
let all_full = a.len() != 0
|
||||
&& a.len() < 256
|
||||
&& b.len() != 0
|
||||
&& b.len() < 256
|
||||
&& c.len() != 0
|
||||
&& c.len() < 256;
|
||||
|
||||
if !all_empty && !all_full {
|
||||
Err(form::Error::validation(format!(
|
||||
"missing chassis field {}",
|
||||
field
|
||||
)))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[post("/register", data = "<tag>")]
|
||||
pub async fn handle_register(
|
||||
mut db: DollTagsDb,
|
||||
tag: Form<TagForm<'_>>,
|
||||
) -> Result<Template, Redirect> {
|
||||
println!("register: {:?}", tag);
|
||||
let id = id_public_to_db(&tag.ident).expect("wrong fmt");
|
||||
let pronouns = format!(
|
||||
"{}/{}/{}",
|
||||
tag.pronoun_subject, tag.pronoun_object, tag.pronoun_possessive
|
||||
);
|
||||
let microchip_id = tag.microchip_id.to_lowercase();
|
||||
|
||||
if doll::id_exists(&mut *db, id, µchip_id)
|
||||
.await
|
||||
.expect("fuck")
|
||||
{
|
||||
return Err(Redirect::found(uri!("/register")));
|
||||
}
|
||||
|
||||
doll::create(
|
||||
db,
|
||||
CreateDollProfile {
|
||||
id,
|
||||
microchip_id: if microchip_id.len() != 0 {
|
||||
Some(µchip_id)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
name: tag.name,
|
||||
pronouns: pronouns.as_str(),
|
||||
handler_name: tag.handler_name,
|
||||
handler_url: if tag.handler_link.len() != 0 {
|
||||
Some(tag.handler_link)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
kind: if tag.kind.len() != 0 {
|
||||
Some(tag.kind)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
breed: if tag.breed.len() != 0 {
|
||||
Some(tag.breed)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
behaviour: if tag.behaviour.len() != 0 {
|
||||
Some(tag.behaviour)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
description: if tag.description.len() != 0 {
|
||||
Some(tag.description)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
chassis_type: if tag.chassis_type.len() != 0 {
|
||||
Some(tag.chassis_type)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
chassis_id: if tag.chassis_id.len() != 0 {
|
||||
Some(tag.chassis_id)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
chassis_color: if tag.chassis_color.len() != 0 {
|
||||
Some(tag.chassis_color)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
},
|
||||
)
|
||||
.await
|
||||
.expect("fuck");
|
||||
|
||||
Ok(Template::render("register", context! {ids: vec![123456]}))
|
||||
}
|
3
src/routes/mod.rs
Normal file
3
src/routes/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub mod error_handlers;
|
||||
pub mod form;
|
||||
pub mod public;
|
52
src/routes/public.rs
Normal file
52
src/routes/public.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
use rocket::response::Redirect;
|
||||
use rocket_dyn_templates::{context, Template};
|
||||
|
||||
use crate::{
|
||||
db::{doll, schema::DollTagsDb},
|
||||
id_public_to_db,
|
||||
};
|
||||
|
||||
#[get("/?<miss>&<ident>&<microchip_id>")]
|
||||
pub fn index(miss: Option<bool>, ident: Option<&str>, microchip_id: Option<&str>) -> Template {
|
||||
Template::render(
|
||||
"index",
|
||||
context! {
|
||||
miss,
|
||||
ident,
|
||||
microchip_id,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[get("/profile?<ident>&<microchip_id>")]
|
||||
pub async fn show_profile(
|
||||
db: DollTagsDb,
|
||||
ident: Option<&str>,
|
||||
microchip_id: Option<&str>,
|
||||
) -> Result<Template, Redirect> {
|
||||
let internal_id = ident.and_then(|v| id_public_to_db(v)).unwrap_or(0);
|
||||
let microchip_id = microchip_id.unwrap_or("");
|
||||
|
||||
let profile = doll::get(db, internal_id, microchip_id)
|
||||
.await
|
||||
.expect("fuck")
|
||||
.ok_or(Redirect::to(uri!(index(
|
||||
Some(true),
|
||||
ident,
|
||||
Some(microchip_id)
|
||||
))))?;
|
||||
let has_notable_traits = profile.has_notable_traits();
|
||||
let has_chassis_info = profile.chassis_id.is_some()
|
||||
&& profile.chassis_type.is_some()
|
||||
&& profile.chassis_color.is_some();
|
||||
|
||||
println!("{:?}", profile);
|
||||
Ok(Template::render(
|
||||
"show_profile",
|
||||
context! {
|
||||
profile,
|
||||
has_notable_traits,
|
||||
has_chassis_info,
|
||||
},
|
||||
))
|
||||
}
|
9
templates/error/not-found.html.tera
Normal file
9
templates/error/not-found.html.tera
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends "base" %}
|
||||
{% block title %}404 Nothing found :c - {% endblock title %}
|
||||
{% block main %}
|
||||
<h1>Sorry, nothing to be found here</h1>
|
||||
<p>i don't know where you found this URL, but it points to nowhere.</p>
|
||||
<picture class="center block">
|
||||
<img src="/assets/404.gif" alt="Maxwell the cat doing the microwave">
|
||||
</picture>
|
||||
{% endblock main %}
|
Loading…
Add table
Reference in a new issue