From 41208b99a1e0c1733803e8360d04e18e28af691b Mon Sep 17 00:00:00 2001 From: Arpit Jalan Date: Thu, 31 Mar 2016 18:40:50 +0530 Subject: [PATCH] FEATURE: RSS feed for user posts and topics --- app/controllers/list_controller.rb | 15 ++++++++++++++ app/controllers/posts_controller.rb | 24 +++++++++++++++++++++-- config/locales/server.en.yml | 2 ++ config/routes.rb | 5 +++++ spec/controllers/posts_controller_spec.rb | 18 +++++++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb index 0d96f5dbee7..b52a7a26f5c 100644 --- a/app/controllers/list_controller.rb +++ b/app/controllers/list_controller.rb @@ -35,6 +35,8 @@ class ListController < ApplicationController Discourse.anonymous_filters.map { |f| :"parent_category_category_none_#{f}" }, # category feeds :category_feed, + # user topics feed + :user_topics_feed, # top summaries :top, :category_top, @@ -154,6 +156,19 @@ class ListController < ApplicationController render 'list', formats: [:rss] end + def user_topics_feed + discourse_expires_in 1.minute + target_user = fetch_user_from_params + + @title = "#{SiteSetting.title} - #{I18n.t("rss_description.user_topics", username: target_user.username)}" + @link = "#{Discourse.base_url}/users/#{target_user.username}/activity/topics" + @atom_link = "#{Discourse.base_url}/users/#{target_user.username}/activity/topics.rss" + @description = I18n.t("rss_description.user_topics", username: target_user.username) + @topic_list = TopicQuery.new(nil, order: 'created').send("list_topics_by", target_user) + + render 'list', formats: [:rss] + end + def top(options=nil) options ||= {} period = ListController.best_period_for(current_user.try(:previous_visit_at), options[:category]) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 230eac83236..4e5fe2c4a88 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -7,9 +7,9 @@ require_dependency 'new_post_result_serializer' class PostsController < ApplicationController # Need to be logged in for all actions here - before_filter :ensure_logged_in, except: [:show, :replies, :by_number, :short_link, :reply_history, :revisions, :latest_revision, :expand_embed, :markdown_id, :markdown_num, :cooked, :latest] + before_filter :ensure_logged_in, except: [:show, :replies, :by_number, :short_link, :reply_history, :revisions, :latest_revision, :expand_embed, :markdown_id, :markdown_num, :cooked, :latest, :user_posts_feed] - skip_before_filter :preload_json, :check_xhr, only: [:markdown_id, :markdown_num, :short_link, :latest] + skip_before_filter :preload_json, :check_xhr, only: [:markdown_id, :markdown_num, :short_link, :latest, :user_posts_feed] def markdown_id markdown Post.find(params[:id].to_i) @@ -86,6 +86,26 @@ class PostsController < ApplicationController end end + def user_posts_feed + params.require(:username) + user = fetch_user_from_params + + posts = Post.public_posts + .where(user_id: user.id) + .order(created_at: :desc) + .includes(:user) + .includes(topic: :category) + .limit(50) + + posts = posts.reject { |post| !guardian.can_see?(post) || post.topic.blank? } + + @posts = posts + @title = "#{SiteSetting.title} - #{I18n.t("rss_description.user_posts", username: user.username)}" + @link = "#{Discourse.base_url}/users/#{user.username}/activity" + @description = I18n.t("rss_description.user_posts", username: user.username) + render 'posts/latest', formats: [:rss] + end + def cooked post = find_post_from_params render json: {cooked: post.cooked} diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 88ffe7ee677..70ff7b770c3 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -207,6 +207,8 @@ en: private_posts: "Latest private messages" group_posts: "Latest posts from %{group_name}" group_mentions: "Latest mentions from %{group_name}" + user_posts: "Latest posts by @%{username}" + user_topics: "Latest topics by @%{username}" too_late_to_edit: "That post was created too long ago. It can no longer be edited or deleted." revert_version_same: "The current version is same as the version you are trying to revert to." diff --git a/config/routes.rb b/config/routes.rb index c8de5b65077..48e134e0d59 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -314,6 +314,11 @@ Discourse::Application.routes.draw do get "users/:username/invited/:filter" => "users#invited", constraints: {username: USERNAME_ROUTE_FORMAT} post "users/action/send_activation_email" => "users#send_activation_email" get "users/:username/summary" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} + + # user activity RSS feed + get "users/:username/activity/topics.rss" => "list#user_topics_feed", format: :rss, constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/activity.rss" => "posts#user_posts_feed", format: :rss, constraints: {username: USERNAME_ROUTE_FORMAT} + get "users/:username/activity" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/activity/:filter" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/badges" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 635798e8d9b..da23e399cf1 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -108,6 +108,24 @@ describe PostsController do end end + describe 'user_posts_feed' do + let(:user) { log_in } + let!(:public_topic) { Fabricate(:topic) } + let!(:post) { Fabricate(:post, user: user, topic: public_topic) } + let!(:private_topic) { Fabricate(:topic, archetype: Archetype.private_message, category: nil) } + let!(:private_post) { Fabricate(:post, user: user, topic: private_topic) } + let!(:topicless_post) { Fabricate(:post, user: user, raw: '

Car 54, where are you?

') } + + it 'returns public posts with topic for rss' do + topicless_post.update topic_id: -100 + xhr :get, :user_posts_feed, username: user.username, format: :rss + expect(response).to be_success + expect(assigns(:posts)).to include post + expect(assigns(:posts)).to_not include private_post + expect(assigns(:posts)).to_not include topicless_post + end + end + describe 'cooked' do before do post = Post.new(cooked: 'wat')