use std::sync::Arc; use axum::extract::Path; use axum::http::StatusCode; use axum::{extract::State, response::IntoResponse}; use rss::{ChannelBuilder, Item}; use crate::scrapers::fetch_footprints; use crate::{app::AppState, templates::HtmlTemplate}; use super::template::FeedsTemplate; pub async fn feeds(State(state): State>) -> impl IntoResponse { let template = FeedsTemplate { feeds: state.feeds.values().cloned().collect(), }; HtmlTemplate(template) } pub async fn feed( State(state): State>, Path(feed_id): Path, ) -> Result { let feed = state.feeds.get(&feed_id).ok_or(StatusCode::NOT_FOUND)?; let footprints = fetch_footprints(&feed.url) .await .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; let footprints: Vec = footprints .iter() .map(|x| x.clone().into_rss_item(&feed.url)) .collect(); let channel = ChannelBuilder::default() .title(&feed.title) .link(&feed.url) .description(format!("FindPenguins: {}", &feed.title)) .items(footprints) .build(); Ok(( StatusCode::OK, [("Content-Type", "application/rss+xml")], channel.to_string(), )) }