yes this asset is Needed i promise

This commit is contained in:
Artemis 2025-01-24 13:35:15 +01:00
parent 62afc49675
commit e316023b37
9 changed files with 258 additions and 199 deletions

BIN
assets/404.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View file

@ -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;

View file

@ -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, &microchip_id).await.expect("fuck") {
return Err(Redirect::found(uri!("/register")));
}
doll::create(
db,
CreateDollProfile {
id,
microchip_id: if microchip_id.len() != 0 {
Some(&microchip_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
],
)
}

View 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
View file

@ -0,0 +1 @@
pub mod register_tag;

View 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, &microchip_id)
.await
.expect("fuck")
{
return Err(Redirect::found(uri!("/register")));
}
doll::create(
db,
CreateDollProfile {
id,
microchip_id: if microchip_id.len() != 0 {
Some(&microchip_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
View file

@ -0,0 +1,3 @@
pub mod error_handlers;
pub mod form;
pub mod public;

52
src/routes/public.rs Normal file
View 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,
},
))
}

View 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 %}