diff --git a/src/demo.rs b/src/demo.rs index 2be6f81..3330b5b 100644 --- a/src/demo.rs +++ b/src/demo.rs @@ -61,17 +61,20 @@ pub async fn setup_demo_data(pool: &sqlx::SqlitePool) { .await .expect("Failed to create demo user"); - let feeds: Vec = DEMO_FEEDS.iter().map(|demo_feed| { - let mut feed = Feed::new( - demo_feed.name.to_string(), - demo_feed.url.parse().unwrap(), - demo.id, - ); - if let Some(category) = demo_feed.category { - feed.categorization = vec![category.to_string()]; - } - feed - }).collect(); + let feeds: Vec = DEMO_FEEDS + .iter() + .map(|demo_feed| { + let mut feed = Feed::new( + demo_feed.name.to_string(), + demo_feed.url.parse().unwrap(), + demo.id, + ); + if let Some(category) = demo_feed.category { + feed.categorization = vec![category.to_string()]; + } + feed + }) + .collect(); for feed in feeds { feed.write_to_database(pool) @@ -90,6 +93,5 @@ pub async fn setup_demo_data(pool: &sqlx::SqlitePool) { } */ - info!("Successfully set up demo data"); } diff --git a/src/main.rs b/src/main.rs index 3686bfd..b12963d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ mod demo; mod feed_utils; mod feeds; mod poll; +mod poll_utils; mod session_store; mod user; diff --git a/src/poll.rs b/src/poll.rs index 394d338..def2eb7 100644 --- a/src/poll.rs +++ b/src/poll.rs @@ -1,14 +1,13 @@ +use crate::poll_utils::Entry; use crate::user::AuthenticatedUser; -use crate::{feed_utils::fetch_feed, Db}; -use chrono::{DateTime, Duration, Utc}; -use feed_rs::model::Text; +use crate::Db; +use chrono::{Duration, Utc}; use rocket::http::Status; use rocket::serde::uuid::Uuid; use rocket::serde::{self, json::Json, Deserialize, Serialize}; use rocket_db_pools::Connection; use sqlx::{Acquire, SqliteConnection}; use tracing::{error, info}; -use url::Url; const POLLING_INTERVAL: Duration = Duration::minutes(20); const MAX_ENTRIES_PER_FEED: i32 = 30; @@ -21,23 +20,6 @@ pub struct FeedPollResponse { entries: Vec, } -#[derive(Debug, Serialize)] -#[serde(crate = "rocket::serde")] -struct Entry { - /// id is the id from the feed, and is the primary key of entries - id: String, - /// local_id is a UUID generated locally. it is used because we don't have control over the - /// exact format of the id from the feed entry - local_id: Uuid, - title: String, - published: Option>, - updated: Option>, - summary: String, - content: Option, - link: Option, - marked_read: Option>, -} - #[derive(Debug, Deserialize)] #[serde(crate = "rocket::serde")] pub struct EntryStateUpdate { @@ -182,33 +164,6 @@ async fn read_entries(feed_id: &str, db: &mut SqliteConnection) -> Result Result, Status> { - let feed_data = fetch_feed(url).await.map_err(|_| Status::BadGateway)?; - - fn get(item: Option, name: &'static str) -> String { - item.map(|t| t.content.to_string()) - .unwrap_or(format!("")) - } - - let entries: Vec = feed_data - .entries - .into_iter() - .map(|feed_entry| Entry { - id: feed_entry.id, - local_id: Uuid::new_v4(), - title: get(feed_entry.title, "title"), - published: feed_entry.published, - updated: feed_entry.updated, - summary: get(feed_entry.summary, "summary"), - content: feed_entry.content, - link: feed_entry.links.first().map(|l| l.href.clone()), - marked_read: None, - }) - .collect(); - Ok(entries) -} - #[post("/poll/")] pub async fn poll_feed( mut db: Connection, @@ -239,7 +194,7 @@ pub async fn poll_feed( read_entries(&feed_id, &mut db).await? } else { info!("Fetching new entries for feed {}", feed_id); - let entries = fetch_new_entries(&url).await?; + let entries = crate::poll_utils::fetch_new_entries(&url).await?; update_entry_db(&entries, &feed_id, &mut db).await?; entries }; diff --git a/src/poll_utils.rs b/src/poll_utils.rs new file mode 100644 index 0000000..a4b2bfa --- /dev/null +++ b/src/poll_utils.rs @@ -0,0 +1,52 @@ +use crate::feed_utils::fetch_feed; +use chrono::{DateTime, Utc}; +use feed_rs::model::Text; +use rocket::http::Status; +use rocket::serde::uuid::Uuid; +use rocket::serde::Serialize; +use url::Url; + +#[derive(Debug, Serialize)] +#[serde(crate = "rocket::serde")] +pub struct Entry { + /// id is the id from the feed, and is the primary key of entries + pub id: String, + /// local_id is a UUID generated locally. it is used because we don't have control over the + /// exact format of the id from the feed entry + pub local_id: Uuid, + pub title: String, + pub published: Option>, + pub updated: Option>, + pub summary: String, + pub content: Option, + pub link: Option, + pub marked_read: Option>, +} + +/// +/// Perform the request to fetch from the remote feed url +pub async fn fetch_new_entries(url: &Url) -> Result, Status> { + let feed_data = fetch_feed(url).await.map_err(|_| Status::BadGateway)?; + + fn get(item: Option, name: &'static str) -> String { + item.map(|t| t.content.to_string()) + .unwrap_or(format!("")) + } + + let entries: Vec = feed_data + .entries + .into_iter() + .map(|feed_entry| Entry { + id: feed_entry.id, + local_id: Uuid::new_v4(), + title: get(feed_entry.title, "title"), + published: feed_entry.published, + updated: feed_entry.updated, + summary: get(feed_entry.summary, "summary"), + content: feed_entry.content, + link: feed_entry.links.first().map(|l| l.href.clone()), + marked_read: None, + }) + .collect(); + Ok(entries) +}