From 1ff050a247fb6ce1749dddc282e7f729de8636d8 Mon Sep 17 00:00:00 2001 From: philipp Date: Thu, 2 Nov 2023 12:15:10 +0100 Subject: [PATCH 1/3] add ergo tool --- .gitlab-ci.yml | 4 +- Rocket.toml | 1 + migration.sql | 6 + src/model/rower.rs | 2 +- src/model/user.rs | 51 ++++--- src/tera/admin/user.rs | 18 +-- src/tera/ergo.rs | 191 +++++++++++++++++++++++++++ src/tera/mod.rs | 5 +- templates/admin/user/index.html.tera | 3 + templates/ergo.final.html.tera | 31 +++++ templates/ergo.html.tera | 80 +++++++++++ templates/includes/macros.html.tera | 189 +++++++++++++++++--------- 12 files changed, 486 insertions(+), 95 deletions(-) create mode 100644 src/tera/ergo.rs create mode 100644 templates/ergo.final.html.tera create mode 100644 templates/ergo.html.tera diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3899fda..affa1d3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,7 +42,7 @@ deploy-staging: - scp -r templates $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/ - scp -r svelte $SSH_USER@$SSH_HOST:/home/k004373/rowing-staging/ - ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rotstaging' - - ssh $SSH_USER@$SSH_HOST 'rm /home/k004373/rowing-staging/db.sqlite && cp /home/k004373/rowing/db.sqlite /home/k004373/rowing-staging/db.sqlite && mkdir -p /home/k004373/rowing-staging/svelte/build && sqlite3 /home/k004373/rowing-staging/db.sqlite < /home/k004373/rowing-staging/staging-diff.sql' + - ssh $SSH_USER@$SSH_HOST 'rm /home/k004373/rowing-staging/db.sqlite && cp /home/k004373/rowing/db.sqlite /home/k004373/rowing-staging/db.sqlite && mkdir -p /home/k004373/rowing-staging/svelte/build && mkdir -p /home/k004373/rowing-staging/data-ergo/thirty && mkdir -p /home/k004373/rowing-staging/data-ergo/dozen && && sqlite3 /home/k004373/rowing-staging/db.sqlite < /home/k004373/rowing-staging/staging-diff.sql' - ssh $SSH_USER@$SSH_HOST 'mv /home/k004373/rowing-staging/rot-updating /home/k004373/rowing-staging/rot' - ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rotstaging' only: @@ -62,7 +62,7 @@ deploy-main: - scp -r static $SSH_USER@$SSH_HOST:/home/k004373/rowing/ - scp -r templates $SSH_USER@$SSH_HOST:/home/k004373/rowing/ - scp -r svelte $SSH_USER@$SSH_HOST:/home/k004373/rowing/ - - ssh $SSH_USER@$SSH_HOST 'mkdir -p /home/k004373/rowing/svelte/build' + - ssh $SSH_USER@$SSH_HOST 'mkdir -p /home/k004373/rowing/svelte/build && mkdir -p /home/k004373/rowing-staging/data-ergo/thirty && mkdir -p /home/k004373/rowing-staging/data-ergo/dozen' - ssh $SSH_USER@$SSH_HOST 'sudo systemctl stop rot' - ssh $SSH_USER@$SSH_HOST 'mv /home/k004373/rowing/rot-updating /home/k004373/rowing/rot' - ssh $SSH_USER@$SSH_HOST 'sudo systemctl start rot' diff --git a/Rocket.toml b/Rocket.toml index f774acf..b16f20f 100644 --- a/Rocket.toml +++ b/Rocket.toml @@ -1,3 +1,4 @@ [default] secret_key = "/NtVGizglEoyoxBLzsRDWTy4oAG1qDw4J4O+CWJSv+fypD7W9sam8hUY4j90EZsbZk8wEradS5zBoWtWKi3k8w==" rss_key = "rss-key-for-ci" +limits = { file = "10 MiB"} diff --git a/migration.sql b/migration.sql index f81938d..ca208ad 100644 --- a/migration.sql +++ b/migration.sql @@ -116,3 +116,9 @@ CREATE TABLE IF NOT EXISTS "boat_damage" ( "lock_boat" boolean not null default false -- if true: noone can use the boat ); +-- tmp ergo challenge stuff +ALTER TABLE user ADD COLUMN dob text; +ALTER TABLE user ADD COLUMN weight text; +ALTER TABLE user ADD COLUMN sex text; +ALTER TABLE user ADD COLUMN dirty_thirty text; +ALTER TABLE user ADD COLUMN dirty_dozen text; diff --git a/src/model/rower.rs b/src/model/rower.rs index 707c5d6..c8654cb 100644 --- a/src/model/rower.rs +++ b/src/model/rower.rs @@ -14,7 +14,7 @@ impl Rower { sqlx::query_as!( User, " -SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech +SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech, dob, weight, sex FROM user WHERE id in (SELECT rower_id FROM rower WHERE logbook_id=?) ", diff --git a/src/model/user.rs b/src/model/user.rs index 8a6366d..1c1f1b8 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -14,6 +14,7 @@ use serde::{Deserialize, Serialize}; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; use super::{log::Log, tripdetails::TripDetails, Day}; +use crate::tera::admin::user::UserEditForm; #[derive(FromRow, Debug, Serialize, Deserialize)] pub struct User { @@ -24,6 +25,9 @@ pub struct User { pub is_admin: bool, pub is_guest: bool, pub is_tech: bool, + pub dob: Option, + pub weight: Option, + pub sex: Option, pub deleted: bool, pub last_access: Option, } @@ -92,7 +96,7 @@ impl User { sqlx::query_as!( Self, " -SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech +SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech, dob, weight, sex FROM user WHERE id like ? ", @@ -107,7 +111,7 @@ WHERE id like ? sqlx::query_as!( Self, " -SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech +SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech, dob, weight, sex FROM user WHERE id like ? ", @@ -122,7 +126,7 @@ WHERE id like ? sqlx::query_as!( Self, " -SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech +SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech, dob, weight, sex FROM user WHERE name like ? ", @@ -164,7 +168,7 @@ WHERE name like ? sqlx::query_as!( Self, " -SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech +SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech, dob, weight, sex FROM user WHERE deleted = 0 ORDER BY last_access DESC @@ -175,11 +179,26 @@ ORDER BY last_access DESC .unwrap() } + pub async fn ergo(db: &SqlitePool) -> Vec { + sqlx::query_as!( + Self, + " +SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech, dob, weight, sex +FROM user +WHERE deleted = 0 AND dob is not null and weight is not null and sex is not null +ORDER BY last_access DESC + " + ) + .fetch_all(db) + .await + .unwrap() + } + pub async fn cox(db: &SqlitePool) -> Vec { sqlx::query_as!( Self, " -SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech +SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access, is_tech, dob, weight, sex FROM user WHERE deleted = 0 AND is_cox=true ORDER BY last_access DESC @@ -201,20 +220,16 @@ ORDER BY last_access DESC .is_ok() } - pub async fn update( - &self, - db: &SqlitePool, - is_cox: bool, - is_admin: bool, - is_guest: bool, - is_tech: bool, - ) { + pub async fn update(&self, db: &SqlitePool, data: UserEditForm) { sqlx::query!( - "UPDATE user SET is_cox = ?, is_admin = ?, is_guest = ?, is_tech = ? where id = ?", - is_cox, - is_admin, - is_guest, - is_tech, + "UPDATE user SET is_cox = ?, is_admin = ?, is_guest = ?, is_tech = ?, dob = ?, weight = ?, sex = ? where id = ?", + data.is_cox, + data.is_admin, + data.is_guest, + data.is_tech, + data.dob, + data.weight, + data.sex, self.id ) .execute(db) diff --git a/src/tera/admin/user.rs b/src/tera/admin/user.rs index 7a94196..f0a719c 100644 --- a/src/tera/admin/user.rs +++ b/src/tera/admin/user.rs @@ -58,12 +58,15 @@ async fn delete(db: &State, _admin: AdminUser, user: i32) -> Flash, + pub(crate) weight: Option, + pub(crate) sex: Option, } #[post("/user", data = "")] @@ -80,8 +83,7 @@ async fn update( ); }; - user.update(db, data.is_cox, data.is_admin, data.is_guest, data.is_tech) - .await; + user.update(db, data.into_inner()).await; Flash::success(Redirect::to("/admin/user"), "Successfully updated user") } diff --git a/src/tera/ergo.rs b/src/tera/ergo.rs new file mode 100644 index 0000000..81af3b5 --- /dev/null +++ b/src/tera/ergo.rs @@ -0,0 +1,191 @@ +use std::env; + +use rocket::{ + form::Form, + fs::TempFile, + get, + http::ContentType, + post, + request::FlashMessage, + response::{Flash, Redirect}, + routes, FromForm, Route, State, +}; +use rocket_dyn_templates::{context, Template}; +use serde::Serialize; +use sqlx::SqlitePool; +use tera::Context; + +use crate::model::{ + log::Log, + user::{AdminUser, NonGuestUser, User}, +}; + +#[derive(Serialize)] +struct ErgoStat { + name: String, + dob: Option, + weight: Option, + sex: Option, + result: Option, +} + +#[get("/final")] +async fn send(db: &State, _user: AdminUser) -> Template { + let thirty = sqlx::query_as!( + ErgoStat, + "SELECT name, dirty_thirty as result, dob, weight, sex FROM user WHERE deleted = 0 AND dirty_thirty is not null ORDER BY result DESC" + ) + .fetch_all(db.inner()) + .await + .unwrap(); + + let dozen= sqlx::query_as!( + ErgoStat, + "SELECT name, dirty_dozen as result, dob, weight, sex FROM user WHERE deleted = 0 AND dirty_dozen is not null ORDER BY result DESC" + ) + .fetch_all(db.inner()) + .await + .unwrap(); + + Template::render( + "ergo.final", + context!(loggedin_user: &_user.user, thirty, dozen), + ) +} + +#[get("/reset")] +async fn reset(db: &State, _user: AdminUser) -> Flash { + sqlx::query!("UPDATE user SET dirty_thirty = NULL, dirty_dozen = NULL;") + .execute(db.inner()) + .await + .unwrap(); + + Flash::success( + Redirect::to("/ergo"), + "Erfolgreich zurückgesetzt (Bilder müssen manuell gelöscht werden!)", + ) +} + +#[get("/")] +async fn index( + db: &State, + user: NonGuestUser, + flash: Option>, +) -> Template { + let users = User::ergo(db).await; + + let thirty = sqlx::query_as!( + ErgoStat, + "SELECT name, dirty_thirty as result, dob, weight, sex FROM user WHERE deleted = 0 AND dirty_thirty is not null ORDER BY result DESC" + ) + .fetch_all(db.inner()) + .await + .unwrap(); + + let dozen= sqlx::query_as!( + ErgoStat, + "SELECT name, dirty_dozen as result, dob, weight, sex FROM user WHERE deleted = 0 AND dirty_dozen is not null ORDER BY result DESC" + ) + .fetch_all(db.inner()) + .await + .unwrap(); + + let mut context = Context::new(); + if let Some(msg) = flash { + context.insert("flash", &msg.into_inner()); + } + context.insert("loggedin_user", &user.user); + context.insert("users", &users); + context.insert("thirty", &thirty); + context.insert("dozen", &dozen); + + Template::render("ergo", context.into_json()) +} + +#[derive(FromForm, Debug)] +pub struct ErgoToAdd<'a> { + user: i64, + result: String, + proof: TempFile<'a>, +} + +#[post("/thirty", data = "", format = "multipart/form-data")] +async fn new_thirty( + db: &State, + mut data: Form>, + created_by: NonGuestUser, +) -> Flash { + let user = User::find_by_id(db, data.user as i32).await.unwrap(); + + let extension = if data.proof.content_type() == Some(&ContentType::JPEG) { + "jpg" + } else { + return Flash::error(Redirect::to("/ergo"), "Es werden nur JPG Bilder akzeptiert"); + }; + let base_dir = env::current_dir().unwrap(); + let file_path = base_dir.join(format!("data-ergo/thirty/{}.{extension}", user.name)); + if let Err(e) = data.proof.move_copy_to(file_path).await { + eprintln!("Failed to persist file: {:?}", e); + } + + sqlx::query!( + "UPDATE user SET dirty_thirty = ? where id = ?", + data.result, + data.user + ) + .execute(db.inner()) + .await + .unwrap(); //Okay, because we can only create a User of a valid id + + Log::create( + db, + format!("{created_by:?} created thirty-ergo entry: {data:?}"), + ) + .await; + + Flash::success(Redirect::to("/ergo"), "Erfolgreich eingetragen") +} + +#[post("/dozen", data = "", format = "multipart/form-data")] +async fn new_dozen( + db: &State, + mut data: Form>, + created_by: NonGuestUser, +) -> Flash { + let user = User::find_by_id(db, data.user as i32).await.unwrap(); + + let extension = if data.proof.content_type() == Some(&ContentType::JPEG) { + "jpg" + } else { + return Flash::error(Redirect::to("/ergo"), "Es werden nur JPG Bilder akzeptiert"); + }; + let base_dir = env::current_dir().unwrap(); + let file_path = base_dir.join(format!("data-ergo/dozen/{}.{extension}", user.name)); + if let Err(e) = data.proof.move_copy_to(file_path).await { + eprintln!("Failed to persist file: {:?}", e); + } + + sqlx::query!( + "UPDATE user SET dirty_dozen = ? where id = ?", + data.result, + data.user + ) + .execute(db.inner()) + .await + .unwrap(); //Okay, because we can only create a User of a valid id + + Log::create( + db, + format!("{created_by:?} created dozen-ergo entry: {data:?}"), + ) + .await; + + Flash::success(Redirect::to("/ergo"), "Erfolgreich eingetragen") +} + +pub fn routes() -> Vec { + routes![index, new_thirty, new_dozen, send, reset] +} + +#[cfg(test)] +mod test {} diff --git a/src/tera/mod.rs b/src/tera/mod.rs index 799ae24..8cd4612 100644 --- a/src/tera/mod.rs +++ b/src/tera/mod.rs @@ -20,10 +20,11 @@ use crate::model::{ usertrip::{UserTrip, UserTripDeleteError, UserTripError}, }; -mod admin; +pub(crate) mod admin; mod auth; mod boatdamage; mod cox; +mod ergo; mod log; mod misc; mod stat; @@ -56,6 +57,7 @@ async fn index(db: &State, user: User, flash: Option) -> Rocket { .mount("/auth", auth::routes()) .mount("/wikiauth", routes![wikiauth]) .mount("/log", log::routes()) + .mount("/ergo", ergo::routes()) .mount("/stat", stat::routes()) .mount("/boatdamage", boatdamage::routes()) .mount("/cox", cox::routes()) diff --git a/templates/admin/user/index.html.tera b/templates/admin/user/index.html.tera index bfdd70d..5fbb47b 100644 --- a/templates/admin/user/index.html.tera +++ b/templates/admin/user/index.html.tera @@ -54,6 +54,9 @@ {{ macros::checkbox(label='Steuerberechtigter', name='is_cox', id=loop.index , checked=user.is_cox) }} {{ macros::checkbox(label='Technical', name='is_tech', id=loop.index , checked=user.is_tech) }} {{ macros::checkbox(label='Admin', name='is_admin', id=loop.index , checked=user.is_admin) }} + {{ macros::input(label='DOB', name='dob', id=loop.index, type="text", value=user.dob) }} + {{ macros::input(label='Weight (kg)', name='weight', id=loop.index, type="text", value=user.weight) }} + {{ macros::input(label='Sex', name='sex', id=loop.index, type="text", value=user.sex) }} {% if user.pw %} Passwort zurücksetzen diff --git a/templates/ergo.final.html.tera b/templates/ergo.final.html.tera new file mode 100644 index 0000000..a996e15 --- /dev/null +++ b/templates/ergo.final.html.tera @@ -0,0 +1,31 @@ +{% import "includes/macros" as macros %} + +{% extends "base" %} + +{% block content %} +
+ {% if flash %} + {{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }} + {% endif %} + +

Aktuelle Woche

+
+ Dirty Thirty +

+

{% for stat in thirty %}{{ stat.name }} {{ stat.dob }} {{ stat.weight }} {{ stat.sex }} Donau Linz {{ stat.result }} + {% endfor %} +
+

+
+ +
+ Dirty Dozen +

+

{% for stat in dozen %}{{ stat.name }} {{ stat.dob }} {{ stat.weight }} {{ stat.sex }} Donau Linz {{ stat.result }} + {% endfor %} +
+

+
+
+ +{% endblock content%} diff --git a/templates/ergo.html.tera b/templates/ergo.html.tera new file mode 100644 index 0000000..2ecc90f --- /dev/null +++ b/templates/ergo.html.tera @@ -0,0 +1,80 @@ +{% import "includes/macros" as macros %} + +{% extends "base" %} + +{% block content %} +
+ {% if flash %} + {{ macros::alert(message=flash.1, type=flash.0, class="sm:col-span-2 lg:col-span-3") }} + {% endif %} +

Neuer Eintrag

+
+ Dirty Thirty +

+

+
+ + + {{ macros::input(label="Zeit [(hh:)mm:ss]/Distanz [m]", name="result", required=true, type="text", class="input") }} + + +
+
+

+
+ +
+ Dirty Dozen +

+

+
+ + + {{ macros::input(label="Zeit [(hh:)mm:ss]/Distanz [m]", name="result", required=true, type="text", class="input") }} + + +
+
+

+
+ + + +

Aktuelle Woche

+
+ Dirty Thirty +

+

+
    + {% for stat in thirty %} +
  1. {{ stat.name }}: {{ stat.result }}
  2. + {% endfor %} +
+
+

+
+ +
+ Dirty Dozen +

+

+
    + {% for stat in dozen%} +
  1. {{ stat.name }}: {{ stat.result }}
  2. + {% endfor %} +
+
+

+
+
+ +{% endblock content%} diff --git a/templates/includes/macros.html.tera b/templates/includes/macros.html.tera index 470d734..1781a53 100644 --- a/templates/includes/macros.html.tera +++ b/templates/includes/macros.html.tera @@ -1,70 +1,129 @@ {% macro header(loggedin_user) %} -
-
- - -
- - {% include "includes/question-icon" %} - FAQs - - {% if not loggedin_user.is_guest %} - - {% include "includes/book" %} - Logbuch - - + {% endif %} {% if loggedin_user.is_admin %} + + + + + Userverwaltung + + {% endif %} + + + + + + + Ausloggen + +
+
+
+
{% endmacro header %} {% macro input(label, name, type, required=false, class='rounded-md', value='', min='', hide_label=false, id='', autofocus=false, wrapper_class='') %} From dc3e5555dfeba9ac9ae6d51f11fe599dae6431b5 Mon Sep 17 00:00:00 2001 From: philipp Date: Thu, 2 Nov 2023 12:15:54 +0100 Subject: [PATCH 2/3] push --- staging-diff.sql | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/staging-diff.sql b/staging-diff.sql index f2786a1..59dcf12 100644 --- a/staging-diff.sql +++ b/staging-diff.sql @@ -18,3 +18,13 @@ DROP TABLE logbook; ALTER TABLE logbook_temp RENAME TO logbook; INSERT INTO rower(rower_id, logbook_id) SELECT shipmaster, id FROM logbook; + + + +-- tmp ergo challenge stuff +ALTER TABLE user ADD COLUMN dob text; +ALTER TABLE user ADD COLUMN weight text; +ALTER TABLE user ADD COLUMN sex text; +ALTER TABLE user ADD COLUMN dirty_thirty text; +ALTER TABLE user ADD COLUMN dirty_dozen text; + From e1a7bdae65d14b0c5184097a6a3e3fba61f6bfcc Mon Sep 17 00:00:00 2001 From: philipp Date: Thu, 2 Nov 2023 12:25:13 +0100 Subject: [PATCH 3/3] fix ci --- db.sqlite.bkp | Bin 212992 -> 0 bytes migration.sql | 14 ++++++-------- src/model/logbook.rs | 2 +- src/model/user.rs | 17 +++++++++++++++-- 4 files changed, 22 insertions(+), 11 deletions(-) delete mode 100644 db.sqlite.bkp diff --git a/db.sqlite.bkp b/db.sqlite.bkp deleted file mode 100644 index 0ff20bc532ec78581ff1c71aca5856d1d1ba5f5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212992 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 ate12iJV54tbK`|cA5GnFuD>wpeEL7w`?sS2 diff --git a/migration.sql b/migration.sql index ca208ad..671a644 100644 --- a/migration.sql +++ b/migration.sql @@ -7,7 +7,12 @@ CREATE TABLE IF NOT EXISTS "user" ( "is_guest" boolean NOT NULL DEFAULT TRUE, "is_tech" boolean NOT NULL DEFAULT FALSE, "deleted" boolean NOT NULL DEFAULT FALSE, - "last_access" DATETIME + "last_access" DATETIME, + "dob" text, + "weight" text, + "sex" text, + "dirty_thirty" text, + "dirty_dozen" text ); CREATE TABLE IF NOT EXISTS "trip_type" ( @@ -115,10 +120,3 @@ CREATE TABLE IF NOT EXISTS "boat_damage" ( "verified_at" datetime, "lock_boat" boolean not null default false -- if true: noone can use the boat ); - --- tmp ergo challenge stuff -ALTER TABLE user ADD COLUMN dob text; -ALTER TABLE user ADD COLUMN weight text; -ALTER TABLE user ADD COLUMN sex text; -ALTER TABLE user ADD COLUMN dirty_thirty text; -ALTER TABLE user ADD COLUMN dirty_dozen text; diff --git a/src/model/logbook.rs b/src/model/logbook.rs index 85e4007..f03f209 100644 --- a/src/model/logbook.rs +++ b/src/model/logbook.rs @@ -389,7 +389,7 @@ ORDER BY departure DESC .await .unwrap() .id - .unwrap() + .unwrap() as i32 } pub async fn home( diff --git a/src/model/user.rs b/src/model/user.rs index 1c1f1b8..90061c7 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -530,7 +530,7 @@ impl<'r> FromRequest<'r> for NonGuestUser { #[cfg(test)] mod test { - use crate::testdb; + use crate::{tera::admin::user::UserEditForm, testdb}; use super::User; use sqlx::SqlitePool; @@ -599,7 +599,20 @@ mod test { let pool = testdb!(); let user = User::find_by_id(&pool, 1).await.unwrap(); - user.update(&pool, false, false, false, false).await; + user.update( + &pool, + UserEditForm { + id: 1, + is_guest: false, + is_cox: false, + is_admin: false, + is_tech: false, + dob: None, + weight: None, + sex: None, + }, + ) + .await; let user = User::find_by_id(&pool, 1).await.unwrap(); assert_eq!(user.is_admin, false);