mirror of
https://github.com/discourse/discourse.git
synced 2025-01-31 06:09:30 +08:00
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]
|
:move_posts]
|
||||||
before_filter :consider_user_for_promotion, only: :show
|
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]}" }
|
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
|
render nothing: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def feed
|
||||||
|
@topic_view = TopicView.new(params[:topic_id])
|
||||||
|
render 'topics/show', formats: [:rss]
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def create_topic_view
|
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)
|
TopicUser.auto_track(self.user_id, self.topic_id, TopicUser::NotificationReasons::CREATED_POST)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope :by_newest, order('created_at desc, id desc')
|
||||||
|
scope :with_user, includes(:user)
|
||||||
|
|
||||||
def raw_quality
|
def raw_quality
|
||||||
|
|
||||||
sentinel = TextSentinel.new(self.raw, min_entropy: SiteSetting.body_min_entropy)
|
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}"
|
"/t/#{Slug.for(topic.title)}/#{topic.id}/#{post_number}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def author_readable
|
||||||
|
user.readable_name
|
||||||
|
end
|
||||||
|
|
||||||
def revise(updated_by, new_raw, opts={})
|
def revise(updated_by, new_raw, opts={})
|
||||||
PostRevisor.new(self).revise!(updated_by, new_raw, opts)
|
PostRevisor.new(self).revise!(updated_by, new_raw, opts)
|
||||||
end
|
end
|
||||||
|
|
|
@ -458,6 +458,14 @@ class User < ActiveRecord::Base
|
||||||
$redis.set(last_seen_key, Time.now.to_f)
|
$redis.set(last_seen_key, Time.now.to_f)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def readable_name
|
||||||
|
if name.present? && name != username
|
||||||
|
"#{name} (#{username})"
|
||||||
|
else
|
||||||
|
username
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def cook
|
def cook
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
|
|
||||||
<%=csrf_meta_tags%>
|
<%=csrf_meta_tags%>
|
||||||
|
|
||||||
|
<%= yield :head %>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -21,3 +21,7 @@
|
||||||
|
|
||||||
|
|
||||||
<p>Powered by <a href="http://www.discourse.org">Discourse</a>, best viewed with JavaScript enabled</p>
|
<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 %>
|
||||||
|
|
22
app/views/topics/show.rss.erb
Normal file
22
app/views/topics/show.rss.erb
Normal file
|
@ -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+/}
|
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/: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' => 'topics#show', :constraints => {:topic_id => /\d+/}
|
||||||
get 't/:slug/:topic_id/:post_number' => 'topics#show', :constraints => {:topic_id => /\d+/, :post_number => /\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+/}
|
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)
|
@highest_post_number ||= @all_posts.maximum(:post_number)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def recent_posts
|
||||||
|
@all_posts.by_newest.with_user.first(25)
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def read_posts_set
|
def read_posts_set
|
||||||
|
|
|
@ -283,5 +283,24 @@ describe TopicView do
|
||||||
|
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
|
|
|
@ -299,6 +299,16 @@ describe TopicsController do
|
||||||
|
|
||||||
end
|
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
|
describe 'update' do
|
||||||
it "won't allow us to update a topic when we're not logged in" 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)
|
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"
|
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
|
describe 'post uniqueness' do
|
||||||
|
|
||||||
context "disabled" do
|
context "disabled" do
|
||||||
|
@ -760,5 +778,11 @@ describe Post do
|
||||||
|
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -716,4 +716,22 @@ describe User do
|
||||||
|
|
||||||
end
|
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
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user