From f491ed95a3bc82c31c70b0f38ed841408576ec0c Mon Sep 17 00:00:00 2001 From: WriterV2 Date: Sat, 21 Mar 2026 11:56:19 +0100 Subject: Purge + prepare for local website builder --- src/db/story.rs | 129 -------------------------------------------------------- 1 file changed, 129 deletions(-) delete mode 100644 src/db/story.rs (limited to 'src/db/story.rs') diff --git a/src/db/story.rs b/src/db/story.rs deleted file mode 100644 index 1566d22..0000000 --- a/src/db/story.rs +++ /dev/null @@ -1,129 +0,0 @@ -use std::ffi::OsStr; -use std::fs::{read_dir, remove_file}; -use std::io::{BufWriter, Write}; - -use anyhow::Context; -use axum::async_trait; -use maud::html; -use sqlx::SqlitePool; - -use crate::db::product::Product; -use crate::error::AppError; -use crate::handlers::frontend_builder::PageBuilder; - -use super::product::ProductMarker; -use super::ProductDatabaseHandler; - -#[derive(Debug, serde::Serialize, sqlx::FromRow)] -pub struct Story { - pub id: i64, - pub language: String, - pub pdf: Vec, - pub pid: i64, -} - -impl ProductMarker for Story { - fn product_id(&self) -> i64 { - self.pid - } -} - -pub async fn synchronize_story_files(pool: &SqlitePool) -> Result<(), anyhow::Error> { - for entry in read_dir("static").with_context(|| "Failed to read directory")? { - let path = entry.with_context(|| "Failed to get entry")?.path(); - if path.extension().is_some_and(|ext| ext == OsStr::new("pdf")) { - remove_file(path).with_context(|| "Failed to remove file")?; - } - } - let results = - sqlx::query!("SELECT p.name, s.pdf FROM story s INNER JOIN product p ON s.pid = p.id") - .fetch_all(pool) - .await?; - for result in results.iter() { - let pdf_filename = format_filepath(&result.name, "pdf"); - let file = std::fs::File::create_new(&pdf_filename) - .with_context(|| format!("Failed to create {}", &pdf_filename))?; - BufWriter::new(file) - .write_all(&result.pdf.to_vec()) - .with_context(|| format!("Failed to write {}", &pdf_filename))?; - } - Ok(()) -} - -#[async_trait] -impl ProductDatabaseHandler for Story { - async fn get_all(pool: &SqlitePool) -> Result, AppError> - where - Self: Sized, - { - Ok(sqlx::query_as!(Story, "SELECT * FROM story") - .fetch_all(pool) - .await?) - } - - async fn post( - &self, - pool: &SqlitePool, - name: &str, - description: &str, - tags: Vec<&str>, - ) -> Result - where - Self: Sized, - { - let mut tx = pool.begin().await?; - let product = Product::post(&mut tx, name, description, tags).await?; - let story = sqlx::query_as!( - Story, - "INSERT INTO story (language, pdf, pid) VALUES ($1, $2, $3) RETURNING id, language, pdf, pid", - self.language, - self.pdf, - product.id) - .fetch_one(&mut *tx) - .await?; - - tx.commit().await?; - - Ok(story) - } - - async fn delete(pool: &SqlitePool, pid: i64) -> Result<(), AppError> - where - Self: Sized, - { - let mut tx = pool.begin().await?; - sqlx::query!("DELETE FROM story WHERE pid = $1", pid) - .execute(&mut *tx) - .await?; - Product::delete(&mut tx, pid).await?; - tx.commit().await?; - Ok(()) - } -} - -impl<'a> PageBuilder<'a> for Story { - fn page_title() -> &'a str { - "Stories" - } - - // TODO: Add pdf icon - fn product_specific_card_content + ProductMarker>( - &self, - specific_product: &super::product::SpecificProduct, - ) -> maud::Markup { - html!( - div class="flex justify-start mt-5 text-sm" { - span class="mr-10" { (&self.language) } - div class="flex justify-between" { - a href=(format_filepath(&specific_product.product.name, "pdf")) { "PDF" } - } - } - ) - } -} - -pub fn format_filepath(name: &str, extension: &str) -> String { - let mut filename = format!("static/{}.{}", name, extension).to_lowercase(); - filename.retain(|c| !c.is_whitespace()); - filename -} -- cgit v1.2.3