RSS of a topic via new route
Adds TopicView#recent_posts; Post#by_newest, #with_user, #author_readable; User#readable_name Autodiscovery tag in topic show HTML.
This commit is contained in:
parent
e363950bf5
commit
8855a0bfbe
|
@ -17,7 +17,7 @@ class TopicsController < ApplicationController
|
|||
:move_posts]
|
||||
before_filter :consider_user_for_promotion, only: :show
|
||||
|
||||
skip_before_filter :check_xhr, only: [:avatar, :show]
|
||||
skip_before_filter :check_xhr, only: [:avatar, :show, :feed]
|
||||
caches_action :avatar, :cache_path => Proc.new {|c| "#{c.params[:post_number]}-#{c.params[:topic_id]}" }
|
||||
|
||||
|
||||
|
@ -141,6 +141,11 @@ class TopicsController < ApplicationController
|
|||
render nothing: true
|
||||
end
|
||||
|
||||
def feed
|
||||
@topic_view = TopicView.new(params[:topic_id])
|
||||
render 'topics/show', formats: [:rss]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_topic_view
|
||||
|
|
|
@ -57,6 +57,9 @@ class Post < ActiveRecord::Base
|
|||
TopicUser.auto_track(self.user_id, self.topic_id, TopicUser::NotificationReasons::CREATED_POST)
|
||||
end
|
||||
|
||||
scope :by_newest, order('created_at desc, id desc')
|
||||
scope :with_user, includes(:user)
|
||||
|
||||
def raw_quality
|
||||
|
||||
sentinel = TextSentinel.new(self.raw, min_entropy: SiteSetting.body_min_entropy)
|
||||
|
@ -298,6 +301,10 @@ class Post < ActiveRecord::Base
|
|||
"/t/#{Slug.for(topic.title)}/#{topic.id}/#{post_number}"
|
||||
end
|
||||
|
||||
def author_readable
|
||||
user.readable_name
|
||||
end
|
||||
|
||||
def revise(updated_by, new_raw, opts={})
|
||||
PostRevisor.new(self).revise!(updated_by, new_raw, opts)
|
||||
end
|
||||
|
|
|
@ -458,6 +458,14 @@ class User < ActiveRecord::Base
|
|||
$redis.set(last_seen_key, Time.now.to_f)
|
||||
end
|
||||
|
||||
def readable_name
|
||||
if name.present? && name != username
|
||||
"#{name} (#{username})"
|
||||
else
|
||||
username
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def cook
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
|
||||
<%=csrf_meta_tags%>
|
||||
|
||||
<%= yield :head %>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
@ -21,3 +21,7 @@
|
|||
|
||||
|
||||
<p>Powered by <a href="http://www.discourse.org">Discourse</a>, best viewed with JavaScript enabled</p>
|
||||
|
||||
<% content_for :head do %>
|
||||
<%= auto_discovery_link_tag(@topic_view, {action: :feed, format: :rss}, title: "RSS feed of '#{@topic_view.title}'") %>
|
||||
<% end %>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title><%= @topic_view.title %></title>
|
||||
<link><%= Discourse.base_url %><%= @topic_view.relative_url %></link>
|
||||
<description><%= @topic_view.posts.first.raw %></description>
|
||||
<atom:link href="<%= Discourse.base_url %><%= @topic_view.relative_url %>.rss" rel="self" type="application/rss+xml" />
|
||||
<% @topic_view.recent_posts.each do |post| %>
|
||||
<item>
|
||||
<title><%= @topic_view.title %> at <%= post.created_at %></title>
|
||||
<description><![CDATA[
|
||||
<p><%= post.author_readable %> wrote:</p>
|
||||
<%= post.cooked.html_safe %>
|
||||
]]></description>
|
||||
<link><%= Discourse.base_url %><%= post.url %></link>
|
||||
<pubDate><%= post.created_at.rfc2822 %></pubDate>
|
||||
<guid><%= Discourse.base_url %><%= post.url %></guid>
|
||||
<source url="<%= Discourse.base_url %><%= @topic_view.relative_url %>.rss"><%= @topic_view.title %></source>
|
||||
</item>
|
||||
<% end %>
|
||||
</channel>
|
||||
</rss>
|
|
@ -176,6 +176,7 @@ Discourse::Application.routes.draw do
|
|||
put 't/:topic_id/unmute' => 'topics#unmute', :constraints => {:topic_id => /\d+/}
|
||||
|
||||
get 't/:topic_id/:post_number' => 'topics#show', :constraints => {:topic_id => /\d+/, :post_number => /\d+/}
|
||||
get 't/:slug/:topic_id.rss' => 'topics#feed', :format => :rss, :constraints => {:topic_id => /\d+/}
|
||||
get 't/:slug/:topic_id' => 'topics#show', :constraints => {:topic_id => /\d+/}
|
||||
get 't/:slug/:topic_id/:post_number' => 'topics#show', :constraints => {:topic_id => /\d+/, :post_number => /\d+/}
|
||||
post 't/:topic_id/timings' => 'topics#timings', :constraints => {:topic_id => /\d+/}
|
||||
|
|
|
@ -234,6 +234,10 @@ class TopicView
|
|||
@highest_post_number ||= @all_posts.maximum(:post_number)
|
||||
end
|
||||
|
||||
def recent_posts
|
||||
@all_posts.by_newest.with_user.first(25)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def read_posts_set
|
||||
|
|
|
@ -283,5 +283,24 @@ describe TopicView do
|
|||
|
||||
end
|
||||
|
||||
context '#recent_posts' do
|
||||
before do
|
||||
24.times do # our let()s have already created 3
|
||||
Fabricate(:post, topic: topic, user: first_poster)
|
||||
end
|
||||
end
|
||||
it 'returns at most 25 recent posts ordered newest first' do
|
||||
recent_posts = topic_view.recent_posts
|
||||
|
||||
# count
|
||||
recent_posts.count.should == 25
|
||||
|
||||
# ordering
|
||||
recent_posts.include?(p1).should be_false
|
||||
recent_posts.include?(p3).should be_true
|
||||
recent_posts.first.created_at.should > recent_posts.last.created_at
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -299,6 +299,16 @@ describe TopicsController do
|
|||
|
||||
end
|
||||
|
||||
describe '#feed' do
|
||||
let(:topic) { Fabricate(:post).topic }
|
||||
|
||||
it 'renders rss of the topic' do
|
||||
get :feed, topic_id: topic.id, slug: 'foo', format: :rss
|
||||
response.should be_success
|
||||
response.content_type.should == 'application/rss+xml'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'update' do
|
||||
it "won't allow us to update a topic when we're not logged in" do
|
||||
lambda { xhr :put, :update, topic_id: 1, slug: 'xyz' }.should raise_error(Discourse::NotLoggedIn)
|
||||
|
|
|
@ -23,6 +23,24 @@ describe Post do
|
|||
|
||||
it_behaves_like "a versioned model"
|
||||
|
||||
describe 'scopes' do
|
||||
|
||||
describe '#by_newest' do
|
||||
it 'returns posts ordered by created_at desc' do
|
||||
2.times { Fabricate(:post) }
|
||||
Post.by_newest.first.created_at.should > Post.by_newest.last.created_at
|
||||
end
|
||||
end
|
||||
|
||||
describe '#with_user' do
|
||||
it 'gives you a user' do
|
||||
Fabricate(:post, user: Fabricate(:user))
|
||||
Post.with_user.first.user.should be_a User
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'post uniqueness' do
|
||||
|
||||
context "disabled" do
|
||||
|
@ -760,5 +778,11 @@ describe Post do
|
|||
|
||||
end
|
||||
|
||||
describe '#readable_author' do
|
||||
it 'delegates to the associated user' do
|
||||
User.any_instance.expects(:readable_name)
|
||||
Fabricate(:post).author_readable
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -716,4 +716,22 @@ describe User do
|
|||
|
||||
end
|
||||
|
||||
describe '#readable_name' do
|
||||
context 'when name is missing' do
|
||||
it 'returns just the username' do
|
||||
Fabricate(:user, username: 'foo', name: nil).readable_name.should == 'foo'
|
||||
end
|
||||
end
|
||||
context 'when name and username are identical' do
|
||||
it 'returns just the username' do
|
||||
Fabricate(:user, username: 'foo', name: 'foo').readable_name.should == 'foo'
|
||||
end
|
||||
end
|
||||
context 'when name and username are not identical' do
|
||||
it 'returns the name and username' do
|
||||
Fabricate(:user, username: 'foo', name: 'Bar Baz').readable_name.should == 'Bar Baz (foo)'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue