From 73ecda59d4934f4e12f3b7e1a04dff1e19cc4bd3 Mon Sep 17 00:00:00 2001 From: selfhoster1312 Date: Tue, 15 Apr 2025 17:11:07 +0200 Subject: [PATCH] feat: add get_feed_config function in templates --- src/feed_store.rs | 3 +-- src/main.rs | 6 +++--- src/template_engine.rs | 31 ++++++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/feed_store.rs b/src/feed_store.rs index 1eec4c7..420191b 100644 --- a/src/feed_store.rs +++ b/src/feed_store.rs @@ -253,8 +253,7 @@ impl FeedStore { let mut feeds: BTreeMap = BTreeMap::new(); for feed_config in feedlist { - let feed_url = Url::parse(&feed_config.url).unwrap(); - feeds.insert(feed_url.clone(), FeedStoreFeed::new(&dir, &feed_url)); + feeds.insert(feed_config.url.clone(), FeedStoreFeed::new(&dir, &feed_config.url)); } Self { _dir: dir, feeds } diff --git a/src/main.rs b/src/main.rs index 65da312..2d11289 100644 --- a/src/main.rs +++ b/src/main.rs @@ -54,7 +54,7 @@ struct Args { } /// Config to be parsed from toml file given as cmdline option -#[derive(Deserialize, Serialize)] +#[derive(Clone, Deserialize, Serialize)] struct Config { /// to be used as part of the fetchers username header bot_name: String, @@ -101,14 +101,14 @@ pub fn to_checked_pathbuf(dir: &Utf8Path) -> Utf8PathBuf { /// /// This is a separate struct in case one wants to configure additional /// information in the future. -#[derive(Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize)] struct FeedConfig { /// short name for the feed name: String, /// homepage URL for the website homepage: Url, /// url of an ATOM, RSS or Json feed - url: String, + url: Url, } fn fetch(config: &Config, feed_store: &mut FeedStore, force_rebuild: bool) -> Result { diff --git a/src/template_engine.rs b/src/template_engine.rs index 06ab50e..38bf41b 100644 --- a/src/template_engine.rs +++ b/src/template_engine.rs @@ -4,9 +4,10 @@ use crate::Config; use anyhow::Result; use camino::Utf8Path; use feed_rs::model::Feed; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::fs::{copy, create_dir_all, File}; use tera::{from_value, Tera}; +use url::Url; pub fn build(config: &Config, feed_store: &mut FeedStore) -> Result<()> { let mut tera = if let Some(theme) = &config.theme { @@ -27,6 +28,9 @@ pub fn build(config: &Config, feed_store: &mut FeedStore) -> Result<()> { context.insert("PKG_NAME", env!("CARGO_PKG_NAME")); context.insert("PKG_VERSION", env!("CARGO_PKG_VERSION")); tera.register_function("get_author", GetAuthorFunction { feeds }); + tera.register_function("get_feed_config", GetFeedConfigFunction { + feeds: config.feeds.iter().map(|feed| (feed.url.clone(), feed.clone())).collect() + }); for name in tera.get_template_names() { debug!("Processing template {name}"); @@ -73,6 +77,31 @@ fn create_tera(templates_dir: &Utf8Path) -> Result { Ok(tera) } +struct GetFeedConfigFunction { + feeds: BTreeMap, +} + +impl tera::Function for GetFeedConfigFunction { + fn call(&self, args: &HashMap) -> Result { + let feed: Url = match args.get("feed") { + None => { + return Err(tera::Error::msg( + "No argument of name 'feed' given to function.", + )) + } + Some(val) => from_value(val.clone())?, + }; + + if let Some(feed_config) = self.feeds.get(&feed) { + Ok(tera::to_value(feed_config)?) + } else { + Err(tera::Error::msg( + format!("Invalid feed URL: {}", feed), + )) + } + } +} + struct GetAuthorFunction { feeds: HashMap, }