X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Froutes%2Fsrc%2Ffeeds.rs;h=96e718631b392b80f6abeb2ae9bde9f1dcb7c0e4;hb=c8063f3267cf2b3622f1fdc69128c6b55feefbbc;hp=2e4f815db9103b0cc188ddbcca58ee7a40a40e2b;hpb=a610211557a15c00f9591e0515c781d46c26890f;p=lemmy.git diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index 2e4f815d..96e71863 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -13,14 +13,19 @@ use lemmy_db_schema::{ }; use lemmy_db_views::{ post_view::PostQuery, - structs::{PostView, SiteView}, + structs::{LocalUserView, PostView, SiteView}, }; use lemmy_db_views_actor::{ comment_reply_view::CommentReplyQuery, person_mention_view::PersonMentionQuery, structs::{CommentReplyView, PersonMentionView}, }; -use lemmy_utils::{claims::Claims, error::LemmyError, utils::markdown_to_html}; +use lemmy_utils::{ + cache_header::cache_1hour, + claims::Claims, + error::LemmyError, + utils::markdown::markdown_to_html, +}; use once_cell::sync::Lazy; use rss::{ extension::dublincore::DublinCoreExtensionBuilder, @@ -31,13 +36,30 @@ use rss::{ }; use serde::Deserialize; use std::{collections::BTreeMap, str::FromStr}; -use strum::ParseError; const RSS_FETCH_LIMIT: i64 = 20; #[derive(Deserialize)] struct Params { sort: Option, + limit: Option, + page: Option, +} + +impl Params { + fn sort_type(&self) -> Result { + let sort_query = self + .sort + .clone() + .unwrap_or_else(|| SortType::Hot.to_string()); + SortType::from_str(&sort_query).map_err(ErrorBadRequest) + } + fn get_limit(&self) -> i64 { + self.limit.unwrap_or(RSS_FETCH_LIMIT) + } + fn get_page(&self) -> i64 { + self.page.unwrap_or(1) + } } enum RequestType { @@ -48,10 +70,15 @@ enum RequestType { } pub fn config(cfg: &mut web::ServiceConfig) { - cfg - .route("/feeds/{type}/{name}.xml", web::get().to(get_feed)) - .route("/feeds/all.xml", web::get().to(get_all_feed)) - .route("/feeds/local.xml", web::get().to(get_local_feed)); + cfg.service( + web::scope("/feeds") + .route("/{type}/{name}.xml", web::get().to(get_feed)) + .route("/all.xml", web::get().to(get_all_feed).wrap(cache_1hour())) + .route( + "/local.xml", + web::get().to(get_local_feed).wrap(cache_1hour()), + ), + ); } static RSS_NAMESPACE: Lazy> = Lazy::new(|| { @@ -68,8 +95,16 @@ async fn get_all_feed( info: web::Query, context: web::Data, ) -> Result { - let sort_type = get_sort_type(info).map_err(ErrorBadRequest)?; - Ok(get_feed_data(&context, ListingType::All, sort_type).await?) + Ok( + get_feed_data( + &context, + ListingType::All, + info.sort_type()?, + info.get_limit(), + info.get_page(), + ) + .await?, + ) } #[tracing::instrument(skip_all)] @@ -77,8 +112,16 @@ async fn get_local_feed( info: web::Query, context: web::Data, ) -> Result { - let sort_type = get_sort_type(info).map_err(ErrorBadRequest)?; - Ok(get_feed_data(&context, ListingType::Local, sort_type).await?) + Ok( + get_feed_data( + &context, + ListingType::Local, + info.sort_type()?, + info.get_limit(), + info.get_page(), + ) + .await?, + ) } #[tracing::instrument(skip_all)] @@ -86,17 +129,20 @@ async fn get_feed_data( context: &LemmyContext, listing_type: ListingType, sort_type: SortType, + limit: i64, + page: i64, ) -> Result { - let site_view = SiteView::read_local(context.pool()).await?; - - let posts = PostQuery::builder() - .pool(context.pool()) - .listing_type(Some(listing_type)) - .sort(Some(sort_type)) - .limit(Some(RSS_FETCH_LIMIT)) - .build() - .list() - .await?; + let site_view = SiteView::read_local(&mut context.pool()).await?; + + let posts = PostQuery { + listing_type: (Some(listing_type)), + sort: (Some(sort_type)), + limit: (Some(limit)), + page: (Some(page)), + ..Default::default() + } + .list(&mut context.pool()) + .await?; let items = create_post_items(posts, &context.settings().get_protocol_and_hostname())?; @@ -125,8 +171,6 @@ async fn get_feed( info: web::Query, context: web::Data, ) -> Result { - let sort_type = get_sort_type(info).map_err(ErrorBadRequest)?; - let req_type: String = req.match_info().get("type").unwrap_or("none").parse()?; let param: String = req.match_info().get("name").unwrap_or("none").parse()?; @@ -143,23 +187,47 @@ async fn get_feed( let builder = match request_type { RequestType::User => { - get_feed_user(context.pool(), &sort_type, ¶m, &protocol_and_hostname).await + get_feed_user( + &mut context.pool(), + &info.sort_type()?, + &info.get_limit(), + &info.get_page(), + ¶m, + &protocol_and_hostname, + ) + .await } RequestType::Community => { - get_feed_community(context.pool(), &sort_type, ¶m, &protocol_and_hostname).await + get_feed_community( + &mut context.pool(), + &info.sort_type()?, + &info.get_limit(), + &info.get_page(), + ¶m, + &protocol_and_hostname, + ) + .await } RequestType::Front => { get_feed_front( - context.pool(), + &mut context.pool(), &jwt_secret, - &sort_type, + &info.sort_type()?, + &info.get_limit(), + &info.get_page(), ¶m, &protocol_and_hostname, ) .await } RequestType::Inbox => { - get_feed_inbox(context.pool(), &jwt_secret, ¶m, &protocol_and_hostname).await + get_feed_inbox( + &mut context.pool(), + &jwt_secret, + ¶m, + &protocol_and_hostname, + ) + .await } } .map_err(ErrorBadRequest)?; @@ -173,33 +241,28 @@ async fn get_feed( ) } -fn get_sort_type(info: web::Query) -> Result { - let sort_query = info - .sort - .clone() - .unwrap_or_else(|| SortType::Hot.to_string()); - SortType::from_str(&sort_query) -} - #[tracing::instrument(skip_all)] async fn get_feed_user( - pool: &DbPool, + pool: &mut DbPool<'_>, sort_type: &SortType, + limit: &i64, + page: &i64, user_name: &str, protocol_and_hostname: &str, ) -> Result { let site_view = SiteView::read_local(pool).await?; let person = Person::read_from_name(pool, user_name, false).await?; - let posts = PostQuery::builder() - .pool(pool) - .listing_type(Some(ListingType::All)) - .sort(Some(*sort_type)) - .creator_id(Some(person.id)) - .limit(Some(RSS_FETCH_LIMIT)) - .build() - .list() - .await?; + let posts = PostQuery { + listing_type: (Some(ListingType::All)), + sort: (Some(*sort_type)), + creator_id: (Some(person.id)), + limit: (Some(*limit)), + page: (Some(*page)), + ..Default::default() + } + .list(pool) + .await?; let items = create_post_items(posts, protocol_and_hostname)?; @@ -215,22 +278,25 @@ async fn get_feed_user( #[tracing::instrument(skip_all)] async fn get_feed_community( - pool: &DbPool, + pool: &mut DbPool<'_>, sort_type: &SortType, + limit: &i64, + page: &i64, community_name: &str, protocol_and_hostname: &str, ) -> Result { let site_view = SiteView::read_local(pool).await?; let community = Community::read_from_name(pool, community_name, false).await?; - let posts = PostQuery::builder() - .pool(pool) - .sort(Some(*sort_type)) - .community_id(Some(community.id)) - .limit(Some(RSS_FETCH_LIMIT)) - .build() - .list() - .await?; + let posts = PostQuery { + sort: (Some(*sort_type)), + community_id: (Some(community.id)), + limit: (Some(*limit)), + page: (Some(*page)), + ..Default::default() + } + .list(pool) + .await?; let items = create_post_items(posts, protocol_and_hostname)?; @@ -250,25 +316,28 @@ async fn get_feed_community( #[tracing::instrument(skip_all)] async fn get_feed_front( - pool: &DbPool, + pool: &mut DbPool<'_>, jwt_secret: &str, sort_type: &SortType, + limit: &i64, + page: &i64, jwt: &str, protocol_and_hostname: &str, ) -> Result { let site_view = SiteView::read_local(pool).await?; let local_user_id = LocalUserId(Claims::decode(jwt, jwt_secret)?.claims.sub); - let local_user = LocalUser::read(pool, local_user_id).await?; - - let posts = PostQuery::builder() - .pool(pool) - .listing_type(Some(ListingType::Subscribed)) - .local_user(Some(&local_user)) - .sort(Some(*sort_type)) - .limit(Some(RSS_FETCH_LIMIT)) - .build() - .list() - .await?; + let local_user = LocalUserView::read(pool, local_user_id).await?; + + let posts = PostQuery { + listing_type: (Some(ListingType::Subscribed)), + local_user: (Some(&local_user)), + sort: (Some(*sort_type)), + limit: (Some(*limit)), + page: (Some(*page)), + ..Default::default() + } + .list(pool) + .await?; let items = create_post_items(posts, protocol_and_hostname)?; @@ -288,7 +357,7 @@ async fn get_feed_front( #[tracing::instrument(skip_all)] async fn get_feed_inbox( - pool: &DbPool, + pool: &mut DbPool<'_>, jwt_secret: &str, jwt: &str, protocol_and_hostname: &str, @@ -301,27 +370,27 @@ async fn get_feed_inbox( let sort = CommentSortType::New; - let replies = CommentReplyQuery::builder() - .pool(pool) - .recipient_id(Some(person_id)) - .my_person_id(Some(person_id)) - .show_bot_accounts(Some(show_bot_accounts)) - .sort(Some(sort)) - .limit(Some(RSS_FETCH_LIMIT)) - .build() - .list() - .await?; - - let mentions = PersonMentionQuery::builder() - .pool(pool) - .recipient_id(Some(person_id)) - .my_person_id(Some(person_id)) - .show_bot_accounts(Some(show_bot_accounts)) - .sort(Some(sort)) - .limit(Some(RSS_FETCH_LIMIT)) - .build() - .list() - .await?; + let replies = CommentReplyQuery { + recipient_id: (Some(person_id)), + my_person_id: (Some(person_id)), + show_bot_accounts: (show_bot_accounts), + sort: (Some(sort)), + limit: (Some(RSS_FETCH_LIMIT)), + ..Default::default() + } + .list(pool) + .await?; + + let mentions = PersonMentionQuery { + recipient_id: (Some(person_id)), + my_person_id: (Some(person_id)), + show_bot_accounts: (show_bot_accounts), + sort: (Some(sort)), + limit: (Some(RSS_FETCH_LIMIT)), + ..Default::default() + } + .list(pool) + .await?; let items = create_reply_and_mention_items(replies, mentions, protocol_and_hostname)?; @@ -348,10 +417,7 @@ fn create_reply_and_mention_items( let mut reply_items: Vec = replies .iter() .map(|r| { - let reply_url = format!( - "{}/post/{}/comment/{}", - protocol_and_hostname, r.post.id, r.comment.id - ); + let reply_url = format!("{}/comment/{}", protocol_and_hostname, r.comment.id); build_item( &r.creator.name, &r.comment.published, @@ -365,10 +431,7 @@ fn create_reply_and_mention_items( let mut mention_items: Vec = mentions .iter() .map(|m| { - let mention_url = format!( - "{}/post/{}/comment/{}", - protocol_and_hostname, m.post.id, m.comment.id - ); + let mention_url = format!("{}/comment/{}", protocol_and_hostname, m.comment.id); build_item( &m.creator.name, &m.comment.published, @@ -428,7 +491,6 @@ fn create_post_items( i.pub_date(dt.to_rfc2822()); let post_url = format!("{}/post/{}", protocol_and_hostname, p.post.id); - i.link(post_url.clone()); i.comments(post_url.clone()); let guid = GuidBuilder::default() .permalink(true) @@ -452,6 +514,9 @@ fn create_post_items( if let Some(url) = p.post.url { let link_html = format!("
{url}"); description.push_str(&link_html); + i.link(url.to_string()); + } else { + i.link(post_url.clone()); } if let Some(body) = p.post.body {