summaryrefslogtreecommitdiff
path: root/src/works
diff options
context:
space:
mode:
Diffstat (limited to 'src/works')
-rw-r--r--src/works/mod.rs63
-rw-r--r--src/works/stories.rs143
2 files changed, 0 insertions, 206 deletions
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,
-}