diff options
| author | WriterV2 <primary-v2@protonmail.com> | 2024-08-04 10:07:08 +0200 |
|---|---|---|
| committer | WriterV2 <primary-v2@protonmail.com> | 2024-08-04 10:07:08 +0200 |
| commit | f982a5621bfed646ce71fcf7aeeca71ef4ae55c1 (patch) | |
| tree | 4811e7dbd105b0a17da8725d5f7a9a5536eb5fbc /src | |
| parent | 19c2c05c6f5220f4feedad99a38e0fb4dc57b957 (diff) | |
Purge
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 28 | ||||
| -rw-r--r-- | src/works/mod.rs | 63 | ||||
| -rw-r--r-- | src/works/stories.rs | 143 |
3 files changed, 1 insertions, 233 deletions
diff --git a/src/main.rs b/src/main.rs index 8dddff7..37f1399 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,31 +1,5 @@ -use std::fs::write; - -use anyhow::{Context, Ok, Result}; -use tera::Tera; - -use self::works::stories::Stories; -use self::works::Works; - -mod works; - -const STORY: (&str, &str) = ("stories", "story"); +use anyhow::Result; fn main() -> Result<()> { - // new tera instance - let tera = Tera::new("templates/**/*.html").context("Failed to create new Tera instance")?; - - // render index.html file - let output = tera - .render("index.html", &tera::Context::new()) - .context("Failed to render index.html")?; - write("docs/index.html", output).context("Failed to write index.html")?; - - // render pages for stories - Stories::new_from_file(STORY.0)? - .render_overview_page(&tera, STORY.0) - .context("Failed to render overview page for stories")? - .render_single_pages(&tera, STORY.1) - .context("Failed to render single pages for stories")?; - Ok(()) } diff --git a/src/works/mod.rs b/src/works/mod.rs deleted file mode 100644 index 8cda299..0000000 --- a/src/works/mod.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::fs::{write, File}; -use std::io::BufReader; -use std::path::PathBuf; - -use anyhow::{Context, Ok, Result}; -use serde::{Deserialize, Serialize}; - -pub mod stories; - -// functionality for a group of work, e.g. stories or games -pub trait Works: for<'a> Deserialize<'a> + Serialize { - // create works from the corresponding JSON file, - // e.g. stories from stories.json - fn new_from_file(workname: &str) -> Result<Self> { - let work = serde_json::from_reader(BufReader::new( - &File::open(PathBuf::from(format!("{}.json", workname))) - .with_context(|| format!("Failed to open {}.json", workname))?, - )) - .with_context(|| format!("Failed to create works from {}.json", workname))?; - Ok(work) - } - - // crate tera context from the group of work - // tera context can be accessed in HTML tera templating - fn create_tera_context(&self) -> tera::Context { - let mut context = tera::Context::new(); - context.insert("works", &self); - context - } - - // render page for every work - fn render_single_pages(self, tera_instance: &tera::Tera, template_name: &str) -> Result<Self>; - - // render corresponding overview HTML template - // with its tera context - fn render_overview_page( - self, - tera_instance: &tera::Tera, - filename_without_extension: &str, - ) -> Result<Self> { - write( - format!("docs/{}.html", filename_without_extension).as_str(), - tera_instance - .render( - format!("{}.html", filename_without_extension).as_str(), - &self.create_tera_context(), - ) - .with_context(|| { - format!( - "Failed rendering overview page for {}", - filename_without_extension - ) - })?, - ) - .with_context(|| { - format!( - "Failed to write overview page for {}", - filename_without_extension - ) - })?; - Ok(self) - } -} diff --git a/src/works/stories.rs b/src/works/stories.rs deleted file mode 100644 index 8a6e4dc..0000000 --- a/src/works/stories.rs +++ /dev/null @@ -1,143 +0,0 @@ -use std::fs::{File, write, metadata, read_to_string}; -use std::cmp::max; -use std::io::BufReader; -use std::path::{PathBuf, Path}; -use std::os::linux::fs::MetadataExt; -use anyhow::{Result, Ok, Context}; -use chrono::NaiveDate; -use serde::{Deserialize, Serialize}; - -// stories and their information -// derive from JSON -// process to context for HTML -#[derive(Debug, Deserialize, Serialize)] -pub struct Stories(Vec<Story>); - -#[derive(Debug, Deserialize, Serialize)] -struct Story { - title: String, - description: String, - path_to_document: String, - language: Language, - #[serde(default)] - number_of_pages: u32, - #[serde(default)] - last_update: NaiveDate, -} - -// see src/works/mod.rs for information of Works trait -impl super::Works for Stories { - // render single pages for every story with the extracted text and a download button - fn render_single_pages( - self, - tera_instance: &tera::Tera, - template_name: &str, - ) -> Result<Self> { - let mut result = Vec::new(); - for story in self.0.iter() { - if story.update_available().with_context(|| format!("Failed to check for update for {}", story.title))? { - let mut context = tera::Context::new(); - context.insert("story", story); - context.insert("text", &story.get_text().with_context(|| format!("Failed to get text from {}", story.title))?); - result.push(write( - story.get_html_path().as_str(), - tera_instance.render(format!("{}.html", template_name).as_str(), &context).with_context(|| format!("Failed to render single story page for {}", story.title))?, - )); - } - } - Ok(self) - } - - // create stories from stories.json and add last modification date - fn new_from_file(workname: &str) -> Result<Self> { - let mut stories: Self = serde_json::from_reader(BufReader::new( - &File::open(PathBuf::from(format!("{}.json", workname))) - .with_context(|| format!("Failed to open {}.json", workname))?, - )) - .with_context(|| format!("Failed to create works from {}.json", workname))?; - - for story in stories.0.iter_mut() { - story.get_last_modified().with_context(|| format!("Failed to get last modified date for {}", story.title))?; - story.get_pages_num().with_context(|| format!("Failed to get number of pages from {}'s PDF", story.title))?; - } - Ok(stories) - } -} - -impl Story { - // check if it's necessary to re-compile the html single page - fn update_available(&self) -> Result<bool> { - Ok( - // HTML file doesn't exist yet - !Path::new(&self.get_html_path()).exists() - // pdf document changes - || metadata(self.get_pdf_path()).with_context(|| format!("Failed to get PDF metadata for {}", self.title))?.modified().with_context(|| format!("Failed to get last modified date for {}'s PDF", self.title))? - > metadata(self.get_html_path()).with_context(|| format!("Failed to get HTML metadata for {}", self.title))?.modified().with_context(|| format!("Failed to get last modified date for {}'s HTML", self.title))? - // base template changes - || metadata("templates/base.html").context("Failed to get metadata for base HTML template")?.modified().context("Failed to get last modified date for base HTML template")? - > metadata(self.get_html_path()).with_context(|| format!("Failed to get HTML metadata for {}", self.title))?.modified().with_context(|| format!("Failed to get last modified date for {}'s HTML", self.title))? - // story template changes - ||metadata("templates/story.html").context("Failed to get metadata for story HTML template")?.modified().context("Failed to get last modified date for story HTML template")? > metadata(self.get_html_path()).with_context(|| format!("Failed to get HTML metadata for {}", self.title))?.modified().with_context(|| format!("Failed to get last modified date for {}'s HTML", self.title))?, // add error context - ) - } - - // use story document name for the single page - // e.g. mit_gutem_gewissen.pdf -> mit_gutem_gewissen.html - fn get_html_path(&self) -> String { - format!( - "docs/stories/{}.html", - self.path_to_document.replace(".pdf", "") - ) - } - - // get path to pdf document - fn get_pdf_path(&self) -> String { - format!("docs/stories/{}", &self.path_to_document) - } - - // get path to html file with story content - fn get_content_html_path(&self) -> String { - format!( - "stories_html/{}.html", - self.path_to_document.replace(".pdf", "") - ) - } - - // extract text from pdf document - fn get_text(&self) -> Result<String> { - let text = read_to_string(self.get_content_html_path()).with_context(|| format!("Failed to read {}'s content HTML file", self.title))?; - Ok(text) - } - - // get date of last modification - fn get_last_modified(&mut self) -> Result<chrono::NaiveDate> { - let pdf_last_modification = metadata(self.get_pdf_path()).with_context(|| format!("Failed to get {}'s PDF", self.title))?.st_mtime(); - let html_path = metadata(self.get_html_path()); - let html_last_modification = if let core::result::Result::Ok(file) = html_path { - file.st_mtime() - } else { - 0 - }; - let date = if let Some(d) = chrono::NaiveDateTime::from_timestamp_opt(max(pdf_last_modification, html_last_modification), 0) { - d.date() - } else { - chrono::NaiveDate::default() - }; - self.last_update = date; - Ok(date) - } - - // get number of pages of pdf file - fn get_pages_num(&mut self) -> Result<u32> { - let file = pdf::file::File::open(self.get_pdf_path()).with_context(|| format!("Failed to get {}'s PDF", self.title))?; - self.number_of_pages = file.num_pages(); - Ok(file.num_pages()) - } -} - -// language of story content -#[derive(Deserialize, Serialize, Debug)] -pub enum Language { - German, - English, -} |
