From ac330a3f7b9d20ad7bb99fd925ca415468ea4e6e Mon Sep 17 00:00:00 2001
From: Dessalines <dessalines@users.noreply.github.com>
Date: Thu, 26 Nov 2020 12:26:31 -0500
Subject: [PATCH] Adding a local RSS feed. Fixes #1279 (#1280)

* Adding a local RSS feed. Fixes #1279

* Shorten get_local_feed and get_all_feed functions

* Making the enum params the same.

Co-authored-by: Felix Ableitner <me@nutomic.com>
---
 lemmy_api/src/post.rs     |  2 +-
 lemmy_db/src/lib.rs       |  2 +-
 lemmy_db/src/post_view.rs | 10 +++----
 src/routes/feeds.rs       | 63 ++++++++++++++++++++++++---------------
 4 files changed, 46 insertions(+), 31 deletions(-)

diff --git a/lemmy_api/src/post.rs b/lemmy_api/src/post.rs
index 707c8335..9aa0b4fa 100644
--- a/lemmy_api/src/post.rs
+++ b/lemmy_api/src/post.rs
@@ -247,7 +247,7 @@ impl Perform for GetPosts {
     let community_name = data.community_name.to_owned();
     let posts = match blocking(context.pool(), move |conn| {
       PostQueryBuilder::create(conn)
-        .listing_type(type_)
+        .listing_type(&type_)
         .sort(&sort)
         .show_nsfw(show_nsfw)
         .for_community_id(community_id)
diff --git a/lemmy_db/src/lib.rs b/lemmy_db/src/lib.rs
index 60863206..bad646d1 100644
--- a/lemmy_db/src/lib.rs
+++ b/lemmy_db/src/lib.rs
@@ -156,7 +156,7 @@ pub enum SortType {
   TopAll,
 }
 
-#[derive(EnumString, ToString, Debug, Serialize, Deserialize)]
+#[derive(EnumString, ToString, Debug, Serialize, Deserialize, Clone)]
 pub enum ListingType {
   All,
   Local,
diff --git a/lemmy_db/src/post_view.rs b/lemmy_db/src/post_view.rs
index 0ec4a979..3fb6d2b0 100644
--- a/lemmy_db/src/post_view.rs
+++ b/lemmy_db/src/post_view.rs
@@ -160,7 +160,7 @@ pub struct PostView {
 pub struct PostQueryBuilder<'a> {
   conn: &'a PgConnection,
   query: BoxedQuery<'a, Pg>,
-  listing_type: ListingType,
+  listing_type: &'a ListingType,
   sort: &'a SortType,
   my_user_id: Option<i32>,
   for_creator_id: Option<i32>,
@@ -184,7 +184,7 @@ impl<'a> PostQueryBuilder<'a> {
     PostQueryBuilder {
       conn,
       query,
-      listing_type: ListingType::All,
+      listing_type: &ListingType::All,
       sort: &SortType::Hot,
       my_user_id: None,
       for_creator_id: None,
@@ -200,7 +200,7 @@ impl<'a> PostQueryBuilder<'a> {
     }
   }
 
-  pub fn listing_type(mut self, listing_type: ListingType) -> Self {
+  pub fn listing_type(mut self, listing_type: &'a ListingType) -> Self {
     self.listing_type = listing_type;
     self
   }
@@ -497,7 +497,7 @@ mod tests {
     };
 
     let read_post_listings_with_user = PostQueryBuilder::create(&conn)
-      .listing_type(ListingType::Community)
+      .listing_type(&ListingType::Community)
       .sort(&SortType::New)
       .for_community_id(inserted_community.id)
       .my_user_id(inserted_user.id)
@@ -505,7 +505,7 @@ mod tests {
       .unwrap();
 
     let read_post_listings_no_user = PostQueryBuilder::create(&conn)
-      .listing_type(ListingType::Community)
+      .listing_type(&ListingType::Community)
       .sort(&SortType::New)
       .for_community_id(inserted_community.id)
       .list()
diff --git a/src/routes/feeds.rs b/src/routes/feeds.rs
index a9454be4..fc4a3137 100644
--- a/src/routes/feeds.rs
+++ b/src/routes/feeds.rs
@@ -42,7 +42,8 @@ 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/all.xml", web::get().to(get_all_feed))
+    .route("/feeds/local.xml", web::get().to(get_local_feed));
 }
 
 lazy_static! {
@@ -61,34 +62,43 @@ async fn get_all_feed(
   context: web::Data<LemmyContext>,
 ) -> Result<HttpResponse, Error> {
   let sort_type = get_sort_type(info).map_err(ErrorBadRequest)?;
-
-  let rss = blocking(context.pool(), move |conn| {
-    get_feed_all_data(conn, &sort_type)
-  })
-  .await?
-  .map_err(ErrorBadRequest)?;
-
-  Ok(
-    HttpResponse::Ok()
-      .content_type("application/rss+xml")
-      .body(rss),
-  )
+  Ok(get_feed_data(&context, ListingType::All, sort_type).await?)
 }
 
-fn get_feed_all_data(conn: &PgConnection, sort_type: &SortType) -> Result<String, LemmyError> {
-  let site_view = SiteView::read(&conn)?;
+async fn get_local_feed(
+  info: web::Query<Params>,
+  context: web::Data<LemmyContext>,
+) -> Result<HttpResponse, Error> {
+  let sort_type = get_sort_type(info).map_err(ErrorBadRequest)?;
+  Ok(get_feed_data(&context, ListingType::Local, sort_type).await?)
+}
 
-  let posts = PostQueryBuilder::create(&conn)
-    .listing_type(ListingType::All)
-    .sort(sort_type)
-    .list()?;
+async fn get_feed_data(
+  context: &LemmyContext,
+  listing_type: ListingType,
+  sort_type: SortType,
+) -> Result<HttpResponse, LemmyError> {
+  let site_view = blocking(context.pool(), move |conn| SiteView::read(&conn)).await??;
+
+  let listing_type_ = listing_type.clone();
+  let posts = blocking(context.pool(), move |conn| {
+    PostQueryBuilder::create(&conn)
+      .listing_type(&listing_type_)
+      .sort(&sort_type)
+      .list()
+  })
+  .await??;
 
   let items = create_post_items(posts)?;
 
   let mut channel_builder = ChannelBuilder::default();
   channel_builder
     .namespaces(RSS_NAMESPACE.to_owned())
-    .title(&format!("{} - All", site_view.name))
+    .title(&format!(
+      "{} - {}",
+      site_view.name,
+      listing_type.to_string()
+    ))
     .link(Settings::get().get_protocol_and_hostname())
     .items(items);
 
@@ -96,7 +106,12 @@ fn get_feed_all_data(conn: &PgConnection, sort_type: &SortType) -> Result<String
     channel_builder.description(&site_desc);
   }
 
-  Ok(channel_builder.build().map_err(|e| anyhow!(e))?.to_string())
+  let rss = channel_builder.build().map_err(|e| anyhow!(e))?.to_string();
+  Ok(
+    HttpResponse::Ok()
+      .content_type("application/rss+xml")
+      .body(rss),
+  )
 }
 
 async fn get_feed(
@@ -150,7 +165,7 @@ fn get_feed_user(
   let user_url = user.get_profile_url(&Settings::get().hostname);
 
   let posts = PostQueryBuilder::create(&conn)
-    .listing_type(ListingType::All)
+    .listing_type(&ListingType::All)
     .sort(sort_type)
     .for_creator_id(user.id)
     .list()?;
@@ -176,7 +191,7 @@ fn get_feed_community(
   let community = Community::read_from_name(&conn, &community_name)?;
 
   let posts = PostQueryBuilder::create(&conn)
-    .listing_type(ListingType::All)
+    .listing_type(&ListingType::All)
     .sort(sort_type)
     .for_community_id(community.id)
     .list()?;
@@ -206,7 +221,7 @@ fn get_feed_front(
   let user_id = Claims::decode(&jwt)?.claims.id;
 
   let posts = PostQueryBuilder::create(&conn)
-    .listing_type(ListingType::Subscribed)
+    .listing_type(&ListingType::Subscribed)
     .sort(sort_type)
     .my_user_id(user_id)
     .list()?;
-- 
2.44.1