diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/modules/blog.rs | 22 | ||||
| -rw-r--r-- | src/modules/blog/config.rs | 59 | ||||
| -rw-r--r-- | src/modules/blog/module.rs (renamed from src/modules/multi_blog.rs) | 148 | ||||
| -rw-r--r-- | src/modules/mod.rs | 6 |
4 files changed, 211 insertions, 24 deletions
diff --git a/src/modules/blog.rs b/src/modules/blog.rs new file mode 100644 index 0000000..4672ec2 --- /dev/null +++ b/src/modules/blog.rs @@ -0,0 +1,22 @@ +// This file is part of Locus <https://github.com/gemrest/locus>. +// Copyright (C) 2022-2022 Fuwn <[email protected]> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// Copyright (C) 2022-2022 Fuwn <[email protected]> +// SPDX-License-Identifier: GPL-3.0-only + +mod config; +mod module; + +pub use module::module; diff --git a/src/modules/blog/config.rs b/src/modules/blog/config.rs new file mode 100644 index 0000000..34d9373 --- /dev/null +++ b/src/modules/blog/config.rs @@ -0,0 +1,59 @@ +// This file is part of Locus <https://github.com/gemrest/locus>. +// Copyright (C) 2022-2022 Fuwn <[email protected]> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +// Copyright (C) 2022-2022 Fuwn <[email protected]> +// SPDX-License-Identifier: GPL-3.0-only + +use std::collections::HashMap; + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Clone, Default)] +pub struct Entry { + description: Option<String>, + author: Option<String>, + created: Option<String>, + last_modified: Option<String>, + name: Option<String>, +} +impl Entry { + pub const fn description(&self) -> &Option<String> { &self.description } + + pub const fn author(&self) -> &Option<String> { &self.author } + + pub const fn name(&self) -> &Option<String> { &self.name } + + pub const fn created(&self) -> &Option<String> { &self.created } + + pub const fn last_modified(&self) -> &Option<String> { &self.last_modified } +} + +#[derive(Serialize, Deserialize, Clone, Default)] +pub struct Blog { + name: Option<String>, + description: Option<String>, + posts: Option<HashMap<String, Entry>>, +} +impl Blog { + pub const fn description(&self) -> &Option<String> { &self.description } + + pub const fn name(&self) -> &Option<String> { &self.name } + + pub const fn posts(&self) -> &Option<HashMap<String, Entry>> { &self.posts } + + pub fn from_string(string: &str) -> serde_json::Result<Self> { + serde_json::from_str(string) + } +} diff --git a/src/modules/multi_blog.rs b/src/modules/blog/module.rs index 4dda4b0..c6e904d 100644 --- a/src/modules/multi_blog.rs +++ b/src/modules/blog/module.rs @@ -22,7 +22,7 @@ use std::{ io::Read, }; -use crate::{route::track_mount, success}; +use crate::{modules::blog::config::Blog, route::track_mount, success}; #[allow(clippy::too_many_lines)] pub fn module(router: &mut windmark::Router) { @@ -111,14 +111,38 @@ pub fn module(router: &mut windmark::Router) { blog_clone.len(), blog_clone .iter() - .map(|(title, _)| title.clone()) - .collect::<Vec<_>>() + .map(|(title, entries)| (title.clone(), entries.clone())) + .collect::<Vec<(_, _)>>() .into_iter() - .map(|i| { + .map(|(title, entries)| { + let config: Option<Blog> = + entries.get("blog.json").and_then(|content| { + if let Ok(config) = Blog::from_string(content) { + Some(config) + } else { + None + } + }); + let name = config + .clone() + .unwrap_or_default() + .name() + .clone() + .unwrap_or_else(|| title.clone()); + let description = config + .unwrap_or_default() + .description() + .clone() + .unwrap_or_else(|| "One of Fuwn's blogs".to_string()); + format!( - "=> {} {}", - format_args!("/blog/{}", i.replace(' ', "_").to_lowercase(),), - i + "=> {} {} ― {}", + format_args!( + "/blog/{}", + name.replace(' ', "_").to_lowercase(), + ), + name, + description ) }) .collect::<Vec<_>>() @@ -129,36 +153,75 @@ pub fn module(router: &mut windmark::Router) { }), ); - for (blog, entries) in blogs { + for (blog, mut entries) in blogs { let fixed_blog_name = blog.replace(' ', "_").to_lowercase(); - let entries_clone = entries.clone(); let fixed_blog_name_clone = fixed_blog_name.clone(); - let blog_clone = blog.clone(); + let config: Option<Blog> = + entries.remove_entry("blog.json").and_then(|(_, content)| { + if let Ok(config) = Blog::from_string(&content) { + Some(config) + } else { + None + } + }); + let entries_clone = entries.clone(); + let name = config + .clone() + .unwrap_or_default() + .name() + .clone() + .unwrap_or_else(|| blog.clone()); + let description = config + .clone() + .unwrap_or_default() + .description() + .clone() + .unwrap_or_else(|| "One of Fuwn's blogs".to_string()); + let config_clone = config.clone(); track_mount( router, &format!("/blog/{}", fixed_blog_name), - &format!("{} ― One of Fuwn's blogs", &blog), + &format!("{} ― {}", name, description), Box::new(move |context| { success!( &format!( - "# {} ({})\n\n{}", + "# {} ({})\n\n{}\n\n{}", blog.to_uppercase(), entries_clone.len(), + description, entries_clone .iter() .map(|(title, _)| title.clone()) .collect::<Vec<_>>() .into_iter() - .map(|i| { + .map(|title| { format!( - "=> {} {}", + "=> {} {}{}", format_args!( "/blog/{}/{}", fixed_blog_name_clone, - i.to_lowercase() + title.to_lowercase() ), - i + title, + { + let post = config_clone + .clone() + .unwrap_or_default() + .posts() + .clone() + .and_then(|posts| posts.get(&title).cloned()) + .unwrap_or_default() + .description() + .clone() + .unwrap_or_else(|| "".to_string()); + + if post.is_empty() { + "".to_string() + } else { + format!(" ― {}", post) + } + } ) }) .collect::<Vec<_>>() @@ -170,15 +233,58 @@ pub fn module(router: &mut windmark::Router) { ); for (title, contents) in entries { + let header = if let Ok(header) = construct_header(&config, &title) { + header + } else { + "".to_string() + }; + track_mount( router, &format!("/blog/{}/{}", fixed_blog_name, title.to_lowercase()), - &format!( - "{}, {} ― An entry to one of Fuwn's blogs", - blog_clone, title - ), - Box::new(move |context| success!(contents, context)), + &format!("{}, {} ― An entry to one of Fuwn's blogs", name, title), + Box::new(move |context| { + success!(format!("{}\n{}", header, contents), context) + }), ); } } } + +fn construct_header(config: &Option<Blog>, name: &str) -> Result<String, ()> { + let post = + if let Some(posts) = config.clone().unwrap_or_default().posts().clone() { + if let Some(post) = posts.get(name) { + post.clone() + } else { + return Err(()); + } + } else { + return Err(()); + }; + + Ok(format!( + "# {}\n\n{}{}{}{}", + post.name().clone().unwrap_or_else(|| name.to_string()), + if post.author().is_some() { + format!("Author: {}\n", post.author().clone().unwrap()) + } else { + "".to_string() + }, + if post.created().is_some() { + format!("Created: {}\n", post.created().clone().unwrap()) + } else { + "".to_string() + }, + if post.last_modified().is_some() { + format!("Last Modified: {}\n", post.last_modified().clone().unwrap()) + } else { + "".to_string() + }, + if post.description().is_some() { + format!("\n{}\n", post.description().clone().unwrap()) + } else { + "".to_string() + }, + )) +} diff --git a/src/modules/mod.rs b/src/modules/mod.rs index 4b67961..79025ae 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -16,7 +16,7 @@ // Copyright (C) 2022-2022 Fuwn <[email protected]> // SPDX-License-Identifier: GPL-3.0-only -mod multi_blog; +mod blog; mod random; mod remarks; mod robots; @@ -28,7 +28,7 @@ mod uptime; pub fn module(router: &mut windmark::Router) { crate::statelesses!( - router, uptime, sitemap, search, remarks, multi_blog, random, r#static, - router, robots, + router, uptime, sitemap, search, remarks, blog, random, r#static, router, + robots, ); } |