From 7553dd31dcfcf92bad82a63a380d969a015deca1 Mon Sep 17 00:00:00 2001 From: Bad Manners Date: Sun, 20 Apr 2025 11:09:58 -0300 Subject: [PATCH] Generate favicon from post --- README.md | 1 - src/error.rs | 3 +++ src/views.rs | 32 ++++++++++++++++++++----- templates/fragments/common_headers.html | 1 + templates/pages/settings.html | 4 ++++ 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index fe36f08..126a955 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,6 @@ Still very much an early WIP. ### Roadmap -- [ ] Favicon from post - [ ] Delete pools - [ ] Logging and improved error handling - [ ] Lossless compression diff --git a/src/error.rs b/src/error.rs index d3bdda0..b1dd47f 100644 --- a/src/error.rs +++ b/src/error.rs @@ -12,6 +12,8 @@ struct NotFoundTemplate; pub enum SameyError { #[error("Integer conversion error: {0}")] IntConversion(#[from] std::num::TryFromIntError), + #[error("Integer parsing error: {0}")] + IntParse(#[from] std::num::ParseIntError), #[error("IO error: {0}")] IO(#[from] std::io::Error), #[error("Task error: {0}")] @@ -41,6 +43,7 @@ impl IntoResponse for SameyError { println!("Server error - {}", &self); match &self { SameyError::IntConversion(_) + | SameyError::IntParse(_) | SameyError::IO(_) | SameyError::Join(_) | SameyError::Render(_) diff --git a/src/views.rs b/src/views.rs index f1378ea..a104748 100644 --- a/src/views.rs +++ b/src/views.rs @@ -17,7 +17,7 @@ use axum_extra::extract::Form; use chrono::Utc; use image::{GenericImageView, ImageFormat, ImageReader}; use itertools::Itertools; -use migration::{Expr, OnConflict}; +use migration::{Expr, OnConflict, Query as MigrationQuery}; use rand::Rng; use sea_orm::{ ActiveValue::Set, ColumnTrait, Condition, EntityTrait, FromQueryResult, IntoSimpleExpr, @@ -1246,7 +1246,7 @@ pub(crate) async fn edit_tag( .one(&db) .await? { - let subquery = migration::Query::select() + let subquery = MigrationQuery::select() .column((SameyTagPost, samey_tag_post::Column::PostId)) .from(SameyTagPost) .and_where(samey_tag_post::Column::TagId.eq(new_tag_db.id)) @@ -1332,11 +1332,17 @@ pub(crate) async fn settings( pub(crate) struct UpdateSettingsForm { application_name: String, base_url: String, + favicon_post_id: String, age_confirmation: Option, } pub(crate) async fn update_settings( - State(AppState { db, app_config, .. }): State, + State(AppState { + db, + app_config, + files_dir, + .. + }): State, auth_session: AuthSession, Form(body): Form, ) -> Result { @@ -1390,6 +1396,21 @@ pub(crate) async fn update_settings( .await?; } + if let Some(favicon_post_id) = body.favicon_post_id.split_whitespace().next() { + match favicon_post_id.parse::() { + Ok(favicon_post_id) => { + let post = SameyPost::find_by_id(favicon_post_id) + .one(&db) + .await? + .ok_or(SameyError::NotFound)?; + ImageReader::open(files_dir.join(post.thumbnail))? + .decode()? + .save_with_format(files_dir.join("favicon.png"), ImageFormat::Png)?; + } + Err(err) => return Err(SameyError::IntParse(err)), + } + } + Ok(Redirect::to("/")) } @@ -1840,9 +1861,8 @@ pub(crate) async fn delete_post( SameyPost::delete_by_id(post.id).exec(&db).await?; tokio::spawn(async move { - let base_path = files_dir.as_ref(); - let _ = std::fs::remove_file(base_path.join(post.media)); - let _ = std::fs::remove_file(base_path.join(post.thumbnail)); + let _ = std::fs::remove_file(files_dir.join(post.media)); + let _ = std::fs::remove_file(files_dir.join(post.thumbnail)); }); Ok(Redirect::to("/")) diff --git a/templates/fragments/common_headers.html b/templates/fragments/common_headers.html index 47eacf4..f02d8a9 100644 --- a/templates/fragments/common_headers.html +++ b/templates/fragments/common_headers.html @@ -1,5 +1,6 @@ + diff --git a/templates/pages/settings.html b/templates/pages/settings.html index 39ff1af..23a764d 100644 --- a/templates/pages/settings.html +++ b/templates/pages/settings.html @@ -24,6 +24,10 @@ +
+ + +