From 8341e64dfdcca906798bfc2d00c94974091177ad Mon Sep 17 00:00:00 2001
From: Awstin
Date: Thu, 19 Dec 2024 07:32:10 -0500
Subject: [PATCH] Added the new link form and processing
---
Cargo.lock | 149 ++++++++++++++++++++++++++++++++++++++--
Cargo.toml | 8 +--
src/auth.rs | 9 ++-
src/database/article.rs | 9 ++-
src/database/link.rs | 10 ++-
src/html/admin.rs | 60 +++++++++++++---
src/html/garden.rs | 3 +-
src/html/mod.rs | 9 +++
src/html/root.rs | 13 ++--
templates/admin.html | 34 +++++++--
templates/signup.html | 2 +-
11 files changed, 261 insertions(+), 45 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 0abd391..56b07b5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -9,6 +9,7 @@ dependencies = [
"askama",
"axum",
"bb8",
+ "chrono",
"clap",
"cookie",
"futures-util",
@@ -18,7 +19,6 @@ dependencies = [
"rand_core",
"serde",
"sqlx",
- "time",
"tokio",
"tower",
"tower-http",
@@ -69,6 +69,21 @@ version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
[[package]]
name = "anstream"
version = "0.6.14"
@@ -310,6 +325,12 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "bumpalo"
+version = "3.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+
[[package]]
name = "byteorder"
version = "1.5.0"
@@ -334,6 +355,21 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+[[package]]
+name = "chrono"
+version = "0.4.39"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "js-sys",
+ "num-traits",
+ "serde",
+ "wasm-bindgen",
+ "windows-targets 0.52.5",
+]
+
[[package]]
name = "clap"
version = "4.5.13"
@@ -396,6 +432,12 @@ dependencies = [
"version_check",
]
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
+
[[package]]
name = "cpufeatures"
version = "0.2.12"
@@ -463,7 +505,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
- "serde",
]
[[package]]
@@ -821,6 +862,29 @@ dependencies = [
"want",
]
+[[package]]
+name = "iana-time-zone"
+version = "0.1.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
[[package]]
name = "idna"
version = "0.5.0"
@@ -862,6 +926,16 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
+[[package]]
+name = "js-sys"
+version = "0.3.76"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
+dependencies = [
+ "once_cell",
+ "wasm-bindgen",
+]
+
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -1640,6 +1714,7 @@ dependencies = [
"atoi",
"byteorder",
"bytes",
+ "chrono",
"crc",
"crossbeam-queue",
"either",
@@ -1665,7 +1740,6 @@ dependencies = [
"smallvec",
"sqlformat",
"thiserror",
- "time",
"tokio",
"tokio-stream",
"tracing",
@@ -1723,6 +1797,7 @@ dependencies = [
"bitflags 2.5.0",
"byteorder",
"bytes",
+ "chrono",
"crc",
"digest",
"dotenvy",
@@ -1750,7 +1825,6 @@ dependencies = [
"sqlx-core",
"stringprep",
"thiserror",
- "time",
"tracing",
"whoami",
]
@@ -1765,6 +1839,7 @@ dependencies = [
"base64",
"bitflags 2.5.0",
"byteorder",
+ "chrono",
"crc",
"dotenvy",
"etcetera",
@@ -1789,7 +1864,6 @@ dependencies = [
"sqlx-core",
"stringprep",
"thiserror",
- "time",
"tracing",
"whoami",
]
@@ -1801,6 +1875,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
dependencies = [
"atoi",
+ "chrono",
"flume",
"futures-channel",
"futures-core",
@@ -1812,7 +1887,6 @@ dependencies = [
"percent-encoding",
"serde",
"sqlx-core",
- "time",
"tracing",
"url",
"urlencoding",
@@ -2248,6 +2322,60 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
+dependencies = [
+ "bumpalo",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.99"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
+
[[package]]
name = "webpki-roots"
version = "0.25.4"
@@ -2286,6 +2414,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+[[package]]
+name = "windows-core"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+dependencies = [
+ "windows-targets 0.52.5",
+]
+
[[package]]
name = "windows-sys"
version = "0.48.0"
diff --git a/Cargo.toml b/Cargo.toml
index a4c4e2d..b2b3f96 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,6 +9,7 @@ edition = "2021"
askama = "0.12.1"
axum = "0.6"
bb8 = "0.8.3"
+chrono = { version = "0.4.38", features = ["alloc", "serde"] }
clap = { version = "4.5.13", features = ["derive"] }
cookie = "0.18.1"
futures-util = "0.3.30"
@@ -18,12 +19,11 @@ rand_chacha = "0.3.1"
rand_core = "0.6.4"
serde = { version = "1.0.197", features = ["derive"] }
sqlx = { version = "0.7.4", features = [
- "runtime-tokio-rustls",
- "postgres",
- "time",
+ "chrono",
"macros",
+ "postgres",
+ "runtime-tokio-rustls",
] }
-time = { version = "0.3.36", features = ["macros", "serde"] }
tokio = { version = "1.35.0", features = ["full"] }
tower = "0.4.13"
tower-http = { version = "0.4.4", features = ["fs"] }
diff --git a/src/auth.rs b/src/auth.rs
index f3e1bf3..6847b53 100644
--- a/src/auth.rs
+++ b/src/auth.rs
@@ -79,10 +79,7 @@ impl AuthState {
.unwrap();
if let Some((id, admin)) = user {
- *store = Some(UserInfo {
- user_id: id,
- admin
- });
+ *store = Some(UserInfo { user_id: id, admin });
}
}
store.as_ref()
@@ -141,7 +138,9 @@ pub async fn post_signup(
return Err(error_page(&SignupError::PasswordsDoNotMatch));
}
- let user_id = create_user(&signup.username, &signup.password, &pool).await.unwrap();
+ let user_id = create_user(&signup.username, &signup.password, &pool)
+ .await
+ .unwrap();
let session_token = new_session(&pool, random, user_id).await;
diff --git a/src/database/article.rs b/src/database/article.rs
index cc0b158..11f17c6 100644
--- a/src/database/article.rs
+++ b/src/database/article.rs
@@ -7,7 +7,7 @@ use std::{
fs::{self, metadata},
path::PathBuf,
};
-use time::{macros::format_description, Date};
+use chrono::NaiveDate;
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
pub struct Article {
@@ -17,7 +17,7 @@ pub struct Article {
pub content: String,
pub previous: Option,
pub next: Option,
- pub date: Date,
+ pub date: NaiveDate,
pub description: Option,
}
@@ -30,7 +30,7 @@ impl Article {
let mut title: Option = None;
let mut previous: Option = None;
let mut next: Option = None;
- let mut date: Option = None;
+ let mut date: Option = None;
let mut description: Option = None;
let mut lines: Vec = super::read_lines(file_name);
lines.reverse();
@@ -45,9 +45,8 @@ impl Article {
} else if line.contains("next: ") {
next = Some(line.clone().replace("next: ", ""));
} else if line.contains("date: ") {
- let format = format_description!("[year]-[month]-[day]");
date = Some(
- Date::parse(&line.clone().replace("date: ", ""), format).expect("not a date"),
+ NaiveDate::parse_from_str(&line.clone().replace("date: ", ""), "%Y-%m-%d").expect("not a date"),
);
} else if line.contains("description: ") {
description = Some(line.clone().replace("description: ", ""));
diff --git a/src/database/link.rs b/src/database/link.rs
index 5b9f971..4f4bae6 100644
--- a/src/database/link.rs
+++ b/src/database/link.rs
@@ -1,9 +1,9 @@
use crate::database::PsqlData;
+use chrono::NaiveDate;
use futures_util::TryStreamExt;
use serde::{Deserialize, Serialize};
use sqlx::{self, postgres::PgPool, Pool, Postgres};
use std::{error::Error, path::Path};
-use time::{macros::format_description, Date};
#[derive(Debug, Serialize, Deserialize, PartialEq, PartialOrd, Clone, sqlx::Type)]
#[sqlx(type_name = "link_type", rename_all = "lowercase")]
@@ -20,7 +20,7 @@ pub struct Link {
pub title: String,
pub author: String,
pub link_type: LinkType,
- pub date_added: Date,
+ pub date_added: NaiveDate,
}
impl Link {
@@ -30,7 +30,7 @@ impl Link {
let mut title: Option = None;
let mut author: Option = None;
let mut link_type: Option = None;
- let mut date_added: Option = None;
+ let mut date_added: Option = None;
while lines.len() > 0 {
let line: String = lines.pop().expect("Something went terribly wrong here");
if line.contains("url: ") {
@@ -45,10 +45,8 @@ impl Link {
_ => LinkType::ARTICLE,
});
} else if line.contains("date_added: ") {
- let format = format_description!("[year]-[month]-[day]");
date_added = Some(
- Date::parse(&line.clone().replace("date_added: ", ""), format)
- .expect("not a date"),
+ NaiveDate::parse_from_str(&line.clone().replace("date: ", ""), "%Y-%m-%d").expect("not a date"),
);
} else if line.contains("description: ") {
description = Some(line.clone().replace("description: ", ""));
diff --git a/src/html/admin.rs b/src/html/admin.rs
index 0925320..6870eee 100644
--- a/src/html/admin.rs
+++ b/src/html/admin.rs
@@ -1,20 +1,33 @@
+use core::panic;
+
use axum::{
response::{IntoResponse, Redirect, Response},
- routing::{get, Router},
- Extension,
+ routing::{get, post, Router},
+ Extension, Form,
+};
+use chrono::Local;
+use sqlx::PgPool;
+
+use crate::{
+ auth::{AuthState, UserInfo},
+ database::{
+ link::{Link, LinkType},
+ PsqlData,
+ },
};
-use crate::auth::{AuthState, UserInfo};
-
-use super::templates::{AdminTemplate, HtmlTemplate};
+use super::{
+ templates::{AdminTemplate, HtmlTemplate},
+ NewLink,
+};
pub fn get_router() -> Router {
- Router::new().route("/", get(get_admin))
+ Router::new()
+ .route("/", get(get_admin))
+ .route("/new_link", post(new_link))
}
-pub async fn get_admin(
- Extension(mut current_user): Extension,
-) -> Response {
+pub async fn get_admin(Extension(mut current_user): Extension) -> Response {
let user_info: UserInfo = current_user.get_user().await.unwrap().clone();
if !user_info.admin {
return Redirect::to("/").into_response();
@@ -22,6 +35,35 @@ pub async fn get_admin(
HtmlTemplate(AdminTemplate {}).into_response()
}
+pub async fn new_link(
+ Extension(mut current_user): Extension,
+ Extension(pool): Extension,
+ Form(new_item): Form,
+) -> Response {
+ let user_info: UserInfo = current_user.get_user().await.unwrap().clone();
+ if !user_info.admin {
+ return Redirect::to("/").into_response();
+ }
+
+ let new_link: Link = Link {
+ id: 0,
+ url: new_item.url,
+ title: new_item.title,
+ author: new_item.author,
+ link_type: match &*new_item.link_type {
+ "article" => LinkType::ARTICLE,
+ "blog" => LinkType::BLOG,
+ _ => panic!("Not a proper link type"),
+ },
+ description: get_trimmed_string(new_item.description),
+ date_added: Local::now().date_naive(),
+ };
+
+ let _ = new_link.insert(&pool).await;
+
+ Redirect::to("/admin").into_response()
+}
+
fn get_trimmed_string(input: String) -> Option {
if input.trim().is_empty() {
None
diff --git a/src/html/garden.rs b/src/html/garden.rs
index a89c2f1..3542d15 100644
--- a/src/html/garden.rs
+++ b/src/html/garden.rs
@@ -4,7 +4,8 @@ use axum::{
};
use super::templates::{
- ArchServerTemplate, BooksTemplate, CookingTemplate, CreationTemplate, EdgeDetectionTemplate, GardenTemplate, HtmlTemplate, TakTemplate, TechnologyTemplate, TimeTemplate
+ ArchServerTemplate, BooksTemplate, CookingTemplate, CreationTemplate, EdgeDetectionTemplate,
+ GardenTemplate, HtmlTemplate, TakTemplate, TechnologyTemplate, TimeTemplate,
};
pub fn get_router() -> Router {
diff --git a/src/html/mod.rs b/src/html/mod.rs
index c8b2e78..753a20e 100644
--- a/src/html/mod.rs
+++ b/src/html/mod.rs
@@ -18,3 +18,12 @@ pub struct Signup {
pub password: String,
pub confirm_password: String,
}
+
+#[derive(Deserialize)]
+pub struct NewLink {
+ pub url: String,
+ pub description: String,
+ pub title: String,
+ pub author: String,
+ pub link_type: String,
+}
diff --git a/src/html/root.rs b/src/html/root.rs
index 2495bf9..e66e79c 100644
--- a/src/html/root.rs
+++ b/src/html/root.rs
@@ -1,4 +1,4 @@
-use std:: sync::{Arc, Mutex};
+use std::sync::{Arc, Mutex};
use axum::{
http::{Response, StatusCode},
@@ -22,9 +22,14 @@ use crate::{
};
use super::{
- admin, blog::{self, get_articles_date_sorted}, garden, templates::{
- AboutTemplate, AiTemplate, BlogrollTemplate, ContactTemplate, GiftsTemplate, HomeTemplate, HtmlTemplate, InterestsTemplate, LinksPageTemplate, LoginTemplate, NowTemplate, ResumeTemplate, SignupTemplate, UsesTemplate, WorkTemplate
- }
+ admin,
+ blog::{self, get_articles_date_sorted},
+ garden,
+ templates::{
+ AboutTemplate, AiTemplate, BlogrollTemplate, ContactTemplate, GiftsTemplate, HomeTemplate,
+ HtmlTemplate, InterestsTemplate, LinksPageTemplate, LoginTemplate, NowTemplate,
+ ResumeTemplate, SignupTemplate, UsesTemplate, WorkTemplate,
+ },
};
pub fn get_router(pool: PgPool) -> Router {
diff --git a/templates/admin.html b/templates/admin.html
index e5b804f..7b6c19b 100644
--- a/templates/admin.html
+++ b/templates/admin.html
@@ -4,9 +4,35 @@
{% block content %}
Admin
+New Link
+
-
- My admin page
-
{% endblock %}
diff --git a/templates/signup.html b/templates/signup.html
index 136ef2d..c5fdc92 100644
--- a/templates/signup.html
+++ b/templates/signup.html
@@ -23,7 +23,7 @@
-
+