Implement a way for admins to introduce new weeks and set them as the last active one. The last active week is the last one that is accessible to players, and will also prevent the graph from being displayed. Implement arrows for navigating between the weeks in the HTML.
212 lines
7.7 KiB
Rust
212 lines
7.7 KiB
Rust
use pulldown_cmark::{Options, Parser};
|
|
use rocket::fairing::AdHoc;
|
|
use rocket::form::Form;
|
|
use rocket::http::CookieJar;
|
|
use rocket::response::Redirect;
|
|
|
|
use rocket_db_pools::{sqlx, Connection};
|
|
use rocket_dyn_templates::{context, Template};
|
|
use sqlx::{Acquire, Executor};
|
|
use crate::auth;
|
|
use crate::auth::User;
|
|
use crate::database::Db;
|
|
use crate::database_records::{DisplayTruth, Player, Truth, Week};
|
|
|
|
#[get("/<week_number>")]
|
|
pub async fn week(week_number: u8, mut db: Connection<Db>, cookies: &CookieJar<'_>) -> Template {
|
|
let user: User = auth::get_user(week_number, &mut db, cookies).await;
|
|
|
|
let other_players = if user.logged_in {
|
|
match sqlx::query_as("SELECT id, name FROM Players WHERE id <> $1 AND is_admin == 0 ORDER BY name")
|
|
.bind(user.id)
|
|
.fetch_all(&mut **db).await {
|
|
Ok(v) => v,
|
|
Err(error) => {
|
|
println!("Some error while getting players : {error}");
|
|
Vec::<Player>::new()
|
|
}
|
|
}
|
|
} else {
|
|
Vec::<Player>::new()
|
|
};
|
|
|
|
let week_data: Week = match sqlx::query_as("SELECT number, is_last_week, rendered_text, raw_text FROM Weeks WHERE number == $1")
|
|
.bind(week_number)
|
|
.fetch_one(&mut **db)
|
|
.await {
|
|
Ok(week) => week,
|
|
Err(error) => {
|
|
error!("Error while retrieving week data : {error}");
|
|
Week {number: 0, is_last_week: true, rendered_text: "".to_string(), raw_text: "".to_string() }
|
|
}
|
|
};
|
|
|
|
// FIXME : This is fucking *trash* but fucking hell mate
|
|
if user.is_admin {
|
|
let truths: Vec<Truth> = match sqlx::query_as("SELECT * FROM Truths WHERE week == $1 ORDER BY number")
|
|
.bind(week_number)
|
|
.fetch_all(&mut **db).await {
|
|
Ok(v) => v,
|
|
Err(error) => {
|
|
error!("Error while getting truths : {error}");
|
|
Vec::<Truth>::new()
|
|
}
|
|
};
|
|
|
|
Template::render("index", context! {
|
|
week_data: week_data,
|
|
truths: truths,
|
|
user: user,
|
|
other_players: other_players,
|
|
})
|
|
} else {
|
|
let truths: Vec<DisplayTruth> = match sqlx::query_as("SELECT id, number, author_id, rendered_text FROM Truths WHERE week == $1 ORDER BY number")
|
|
.bind(week_number)
|
|
.fetch_all(&mut **db).await {
|
|
Ok(v) => v,
|
|
Err(error) => {
|
|
error!("Error while getting truths : {error}");
|
|
Vec::<DisplayTruth>::new()
|
|
}
|
|
};
|
|
|
|
Template::render("index", context! {
|
|
week_data: week_data,
|
|
truths: truths,
|
|
user: user,
|
|
other_players: other_players,
|
|
})
|
|
}
|
|
}
|
|
|
|
#[post("/<week>/edit", data="<raw_intro>")]
|
|
pub async fn update_week(week: u8, raw_intro: Form<String>,
|
|
mut db: Connection<Db>, cookies: &CookieJar<'_>) -> Redirect {
|
|
let user = auth::get_user(week, &mut db, cookies).await;
|
|
if !user.is_admin {
|
|
cookies.add(("toast_error", "Vous n'avez pas la permission de changer la semaine."));
|
|
return Redirect::to(uri!("/"));
|
|
}
|
|
|
|
let mut options = Options::empty();
|
|
options.insert(Options::ENABLE_STRIKETHROUGH);
|
|
options.insert(Options::ENABLE_FOOTNOTES);
|
|
options.insert(Options::ENABLE_MATH);
|
|
options.insert(Options::ENABLE_TABLES);
|
|
let markdown_parser = Parser::new_ext(raw_intro.as_str(), options);
|
|
|
|
let mut rendered_markdown = String::new();
|
|
pulldown_cmark::html::push_html(&mut rendered_markdown, markdown_parser);
|
|
|
|
match sqlx::query("UPDATE Weeks SET raw_text = $1, rendered_text = $2 WHERE number == $3;")
|
|
.bind(&raw_intro.as_str())
|
|
.bind(rendered_markdown)
|
|
.bind(week)
|
|
.fetch_optional(&mut **db)
|
|
.await {
|
|
Ok(_) => {
|
|
debug!("Week successfully updated")
|
|
}
|
|
Err(error) => {
|
|
error!("Error while updating week {week} data : {error}");
|
|
cookies.add(("toast_error", "Il y a eu un problème lors du changement de la semaine"));
|
|
}
|
|
};
|
|
|
|
Redirect::to(uri!("/"))
|
|
}
|
|
|
|
#[post("/<week>/set_last")]
|
|
pub async fn set_last_week(week: u8, mut db: Connection<Db>, cookies: &CookieJar<'_>) -> Redirect {
|
|
let user = auth::get_user(week, &mut db, cookies).await;
|
|
if !user.is_admin {
|
|
cookies.add(("toast_error", "Vous n'avez pas la permission de changer la semaine."));
|
|
return Redirect::to(uri!(week(week)));
|
|
}
|
|
|
|
let add_error_cookie = ||
|
|
cookies.add(("toast_error", "Erreur lors du changement d'état de la semaine."));
|
|
|
|
let db_transaction_connection = db.begin().await;
|
|
if db_transaction_connection.is_err() {
|
|
error!("Could not start database transaction for last week change : {:?}", db_transaction_connection.unwrap_err());
|
|
add_error_cookie();
|
|
return Redirect::to(uri!(week(week)));
|
|
}
|
|
let mut db_transaction = db_transaction_connection.unwrap();
|
|
|
|
// Remove the last flag from other weeks, if set.
|
|
match db_transaction.execute("UPDATE Weeks SET is_last_week = 0 WHERE is_last_week == 1;")
|
|
.await {
|
|
Ok(_) => debug!("Succesfully cleared is_last_week"),
|
|
Err(error) => {
|
|
error!("Failed to clear last week status : {error}");
|
|
add_error_cookie();
|
|
return Redirect::to(uri!(week(week)));
|
|
}
|
|
};
|
|
|
|
// We should set one week, if not there's something wrong : rollback.
|
|
if match sqlx::query("UPDATE Weeks SET is_last_week = 1 WHERE number == $1;")
|
|
.bind(week)
|
|
.execute(&mut *db_transaction)
|
|
.await {
|
|
Ok(result) => result.rows_affected(),
|
|
Err(error) => {
|
|
error!("Error while setting last week status : {error}");
|
|
0
|
|
}
|
|
} == 1 {
|
|
db_transaction.commit().await.unwrap_or_else(|error| {
|
|
error!("Error while committing week is last transaction : {error}");
|
|
add_error_cookie();
|
|
})
|
|
} else {
|
|
db_transaction.rollback().await.unwrap_or_else(|error| {
|
|
error!("Error while rolling back week is last transaction : {error}");
|
|
add_error_cookie();
|
|
})
|
|
}
|
|
|
|
Redirect::to(uri!(week(week)))
|
|
}
|
|
|
|
#[get("/<week>/create")]
|
|
pub async fn create_week(week: u8, mut db: Connection<Db>, cookies: &CookieJar<'_>) -> Redirect {
|
|
let user = auth::get_user(week, &mut db, cookies).await;
|
|
if !user.is_admin {
|
|
cookies.add(("toast_error", "Vous n'avez pas la permission de changer la semaine."));
|
|
return Redirect::to(uri!(week(week - 1)));
|
|
}
|
|
|
|
let week_check: Result<Option<u8>, sqlx::Error> = sqlx::query_scalar("SELECT number from Weeks WHERE number == $1;")
|
|
.bind(week)
|
|
.fetch_optional(&mut **db)
|
|
.await;
|
|
|
|
if week_check.is_err() {
|
|
error!("Error while checking week existence : {:?}", week_check.unwrap_err());
|
|
cookies.add(("toast_error", "Erreur en vérifiant que la semaine n'existe pas déjà"));
|
|
return Redirect::to(uri!(week(week - 1)));
|
|
}
|
|
|
|
if week_check.unwrap().is_some() {
|
|
debug!("Week {week} already exists, not creating.");
|
|
return Redirect::to(uri!(week(week)));
|
|
}
|
|
|
|
match sqlx::query("INSERT INTO Weeks (number, is_last_week, rendered_text, raw_text) VALUES ($1, 0, \"\", \"\");")
|
|
.bind(week)
|
|
.execute(&mut **db)
|
|
.await {
|
|
Ok(_) => {
|
|
debug!("Succesfully created new week {week}");
|
|
Redirect::to(uri!(week(week)))
|
|
},
|
|
Err(error) => {
|
|
error!("Error while creating new week {week} : {error}");
|
|
cookies.add(("toast_error", "Erreur en créant la nouvelle selmaine."));
|
|
Redirect::to(uri!(week(week - 1)))
|
|
}
|
|
}
|
|
}
|