From 5aa4c4d20370f7cc62bf2fe8152e002c1f512187 Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Tue, 4 Jul 2023 11:34:05 -0700 Subject: [PATCH] Add user pages --- src/main.rs | 2 +- src/models/database.rs | 36 ++++- src/models/submission/legacy_submission.rs | 3 +- src/models/submission/submission.rs | 3 + src/models/user/mod.rs | 2 +- src/routes/get_challenge.rs | 2 +- src/routes/get_user.rs | 35 +++++ src/routes/mod.rs | 4 + templates/base.html.tera | 72 ++++++++++ templates/challenge.html.tera | 55 +++++++ templates/index.html.tera | 159 --------------------- templates/nav.html.tera | 51 +++++++ templates/user.html.tera | 9 ++ 13 files changed, 269 insertions(+), 164 deletions(-) create mode 100644 src/routes/get_user.rs create mode 100644 templates/base.html.tera create mode 100644 templates/challenge.html.tera delete mode 100644 templates/index.html.tera create mode 100644 templates/nav.html.tera create mode 100644 templates/user.html.tera diff --git a/src/main.rs b/src/main.rs index 0d8d1e3..3472744 100644 --- a/src/main.rs +++ b/src/main.rs @@ -87,7 +87,7 @@ async fn rocket() -> Result, rocket::Error> { .manage(load_database()) .mount( "/", - routes![get_challenge, get_guilds, login, post_login, success, logout, testing], + routes![get_challenge, get_guilds, get_user, login, post_login, success, logout, testing], ) .mount("/css", FileServer::from(relative!("styles/css"))) .mount("/", FileServer::from(relative!("assets")).rank(2)) diff --git a/src/models/database.rs b/src/models/database.rs index 49fb316..2c3522c 100644 --- a/src/models/database.rs +++ b/src/models/database.rs @@ -139,7 +139,7 @@ impl Database { }, }; } - for submission in legacy.parse().unwrap() { + for submission in legacy.parse(n as u32).unwrap() { conn.execute( "INSERT INTO Submission(author_id, timestamp, image, challenge) VALUES (?1, ?2, ?3, ?4)", params![ @@ -181,6 +181,40 @@ impl Database { author_id: row.get(0)?, timestamp: row.get(1)?, image: row.get(2)?, + challenge, + }) + })? + .collect::, rusqlite::Error>>()?) + } + + pub fn get_user_by_name(&self, name: &str) -> Result> { + Ok(self.conn()? + .prepare("SELECT id, discriminator, avatar, deleted FROM User where name = ?1")? + .query_row(params![name], |row| { + Ok(Some(User { + id: row.get(0)?, + name: name.to_owned(), + discriminator: row.get(1)?, + avatar: row.get(2)?, + deleted: row.get(3)?, + })) + })?) + } + + pub fn get_submissions_by_user_name(&self, name: &str) -> Result> { + Ok(self.conn()? + .prepare(" + SELECT author_id, timestamp, image, challenge + FROM Submission s + JOIN User u ON s.author_id = u.id + WHERE u.name = ?1", + )? + .query_map(params![name], |row| { + Ok(Submission { + author_id: row.get(0)?, + timestamp: row.get(1)?, + image: row.get(2)?, + challenge: row.get(3)?, }) })? .collect::, rusqlite::Error>>()?) diff --git a/src/models/submission/legacy_submission.rs b/src/models/submission/legacy_submission.rs index 17b9743..46795a5 100644 --- a/src/models/submission/legacy_submission.rs +++ b/src/models/submission/legacy_submission.rs @@ -26,7 +26,7 @@ pub enum LegacySubmissionParseError { } impl LegacySubmission { - pub fn parse(&self) -> Result, LegacySubmissionParseError> { + pub fn parse(&self, challenge: u32) -> Result, LegacySubmissionParseError> { let author_id = self.id; Ok(self.images .iter() @@ -53,6 +53,7 @@ impl LegacySubmission { })?)() }, image: image.clone(), + challenge, } }) .collect()) diff --git a/src/models/submission/submission.rs b/src/models/submission/submission.rs index 1c1a4c2..df66e36 100644 --- a/src/models/submission/submission.rs +++ b/src/models/submission/submission.rs @@ -15,4 +15,7 @@ pub struct Submission { // Image path relative to submission folder. // Thumbnail image path will be determined from this. pub image: String, + // Not necessary for challenge pages, + // but needed for user profile pages + pub challenge: u32, } \ No newline at end of file diff --git a/src/models/user/mod.rs b/src/models/user/mod.rs index c9da86d..2b7e7ad 100644 --- a/src/models/user/mod.rs +++ b/src/models/user/mod.rs @@ -81,7 +81,7 @@ impl User { "https://cdn.discordapp.com/avatars/{}/{}.{}?size=1024", self.id, avatar, - if avatar.starts_with("a_") { "gif "} else { "webp" } + if avatar.starts_with("a_") { "gif" } else { "webp" } ), // Archived user or user with no avatar, calculate default avatar // https://www.reddit.com/r/discordapp/comments/au6v4e/comment/eh61dm6/ diff --git a/src/routes/get_challenge.rs b/src/routes/get_challenge.rs index b042546..4368c9b 100644 --- a/src/routes/get_challenge.rs +++ b/src/routes/get_challenge.rs @@ -20,7 +20,7 @@ pub async fn get_challenge( ) -> Template { let (submissions, users) = database.get_challenge_user_data(challenge).unwrap(); Template::render( - "index", + "challenge", context! { challenge, submissions, diff --git a/src/routes/get_user.rs b/src/routes/get_user.rs new file mode 100644 index 0000000..64883d4 --- /dev/null +++ b/src/routes/get_user.rs @@ -0,0 +1,35 @@ +use std::ops::Deref; + +use rocket::{http::CookieJar, State}; +use rocket_dyn_templates::{context, Template}; + +use crate::{ + cookies::LANG_COOKIE, + i18n::DEFAULT as DEFAULT_LANG, + models::{Settings, SessionUser, Database}, + utils::AcceptLanguage, +}; + +#[get("/users/")] +pub async fn get_user( + user: String, + cookies: &CookieJar<'_>, + settings: &State, + database: &State, + accept_language: AcceptLanguage, +) -> Template { + Template::render( + "user", + context! { + profile_user: database.get_user_by_name(&user).unwrap(), + submissions: database.get_submissions_by_user_name(&user).unwrap(), + settings: settings.deref(), + lang: cookies + .get(LANG_COOKIE) + .map(|cookie| vec![cookie.value().to_owned()]) + .or(accept_language.0) + .unwrap_or_else(|| vec![DEFAULT_LANG.to_owned()]), + user: SessionUser::get(cookies).await.unwrap(), + }, + ) +} \ No newline at end of file diff --git a/src/routes/mod.rs b/src/routes/mod.rs index ca7164a..b343108 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -6,6 +6,10 @@ pub use _get_challenge::get_challenge; mod _get_guilds; pub use _get_guilds::get_guilds; +#[path = "get_user.rs"] +mod _get_user; +pub use _get_user::get_user; + #[path = "login.rs"] mod _login; pub use _login::login; diff --git a/templates/base.html.tera b/templates/base.html.tera new file mode 100644 index 0000000..b6090a5 --- /dev/null +++ b/templates/base.html.tera @@ -0,0 +1,72 @@ + + + + {% block title %}Tegaki Tuesday{% endblock %} + + + + + + {% block head %}{% endblock head %} + + + {% if user %} + {% include "modal" %} + {% endif %} +
+ +
+
{% block content %}{% endblock %}
+
+ {% block content_copyright %} + Copyright {% include "copyright-years" %} Tegaki Tuesday. All rights reserved. 字ちゃん mascot art by @bellumela. + {% endblock %} +
+
+
+ +
+ {% for submission in submissions %} + {% if users %} + {% set author = users[submission.author_id] %} + {% else %} + {% set author = profile_user %} + {% endif %} +
+ {{ author.username }}'s submission +
+ {% if profile_user %} + #{{ submission.challenge }} + {% else %} + {% if not author.deleted %}{% endif %}{{ author.username }}{% if author.deleted %} (deleted account){% else %}{% endif %} + {% endif %} +
+
+ {% endfor %} +
+ +
+
+ + \ No newline at end of file diff --git a/templates/challenge.html.tera b/templates/challenge.html.tera new file mode 100644 index 0000000..dd4ebb6 --- /dev/null +++ b/templates/challenge.html.tera @@ -0,0 +1,55 @@ +{% extends "base" %} + +{% block content %} +

Welcome to Tegaki Tuesday #{{ challenge }}!

+{% if content.japanese %} +
+ + + {% for line in content.japanese %} + {% for subline in line %} +

+ {%- for word in subline -%} + {%- if word.dictionary -%} + + {%- endif -%} + {% for segment in word.text -%} + {{ segment.kanji }}({{ segment.furigana | safe }}) + {%- endfor -%} + {%- if word.dictionary -%} + + {%- endif -%} + {%- endfor -%} +

+ {% endfor %} + {% endfor %} +
+{% endif %} +{{ content.text | safe }} +{% if content.translation %} +

+ Translation + {% if content.translation.author %}by {{ content.translation.author }}{% endif %} + {% if content.translation.site %} via + {% if content.translation.site.link %} + {{ content.translation.site.name }} + {% else %} + {{ content.translation.site.name }} + {% endif %} + {%- endif -%} +

+{%- endif -%} +{%- if content.suggester -%} +

This challenge was suggested by {{ content.suggester }} using the -h suggest command.

+{%- endif -%} +{% endblock %} \ No newline at end of file diff --git a/templates/index.html.tera b/templates/index.html.tera deleted file mode 100644 index 3837301..0000000 --- a/templates/index.html.tera +++ /dev/null @@ -1,159 +0,0 @@ - - - - Tegaki Tuesday - - - - - - - - {% if user %} - {% include "modal" %} - {% endif %} -
- -
-
-

Welcome to Tegaki Tuesday #{{ challenge }}!

- {% if content.japanese %} -
- - - {% for line in content.japanese %} - {% for subline in line %} -

- {%- for word in subline -%} - {%- if word.dictionary -%} - - {%- endif -%} - {% for segment in word.text -%} - {{ segment.kanji }}({{ segment.furigana | safe }}) - {%- endfor -%} - {%- if word.dictionary -%} - - {%- endif -%} - {%- endfor -%} -

- {% endfor %} - {% endfor %} -
- {% endif %} - {{ content.text | safe }} - {% if content.translation %} -

- Translation - {% if content.translation.author %}by {{ content.translation.author }}{% endif %} - {% if content.translation.site %} via - {% if content.translation.site.link %} - {{ content.translation.site.name }} - {% else %} - {{ content.translation.site.name }} - {% endif %} - {%- endif -%} -

- {%- endif -%} - {%- if content.suggester -%} -

This challenge was suggested by {{ content.suggester }} using the -h suggest command.

- {%- endif -%} -
-
- Copyright {% include "copyright-years" %} Tegaki Tuesday. All rights reserved. 字ちゃん mascot art by @bellumela. -
-
-
- -
- {% for submission in submissions %} - {% set author = users[submission.author_id] %} -
- {{ author.username }}'s submission -
{% if not author.deleted %}{% endif %}{{ author.username }}{% if author.deleted %} (deleted account){% else %}{% endif %}
-
- {% endfor %} -
- -
-
- - \ No newline at end of file diff --git a/templates/nav.html.tera b/templates/nav.html.tera new file mode 100644 index 0000000..b1d2af4 --- /dev/null +++ b/templates/nav.html.tera @@ -0,0 +1,51 @@ +{% if challenge %} + + + +{% endif %} +{% if content.song %} +
+ {% if content.song.japanese %}{{ content.song.japanese | furigana | safe }}{% else %}{{ content.song.english }}{% endif %} +
+{% endif %} +{% if user %} + +{% else%} +Log in +{% endif %} +