diff --git a/app/controllers/topics_controller.rb b/app/controllers/topics_controller.rb index 2c54ae1507c..75ba7a204e4 100644 --- a/app/controllers/topics_controller.rb +++ b/app/controllers/topics_controller.rb @@ -25,7 +25,12 @@ class TopicsController < ApplicationController caches_action :avatar, cache_path: Proc.new {|c| "#{c.params[:post_number]}-#{c.params[:topic_id]}" } def show - opts = params.slice(:username_filters, :best_of, :page, :post_number, :posts_before, :posts_after, :best) + + # We'd like to migrate the wordpress feed to another url. This keeps up backwards compatibility with + # existing installs. + return wordpress if params[:best].present? + + opts = params.slice(:username_filters, :best_of, :page, :post_number, :posts_before, :posts_after) begin @topic_view = TopicView.new(params[:id] || params[:topic_id], current_user, opts) rescue Discourse::NotFound @@ -34,8 +39,6 @@ class TopicsController < ApplicationController return redirect_to(topic.relative_url) end - raise Discourse::NotFound if @topic_view.posts.blank? && !(opts[:best].to_i > 0) - anonymous_etag(@topic_view.topic) do redirect_to_correct_topic && return if slugs_do_not_match View.create_for(@topic_view.topic, request.remote_ip, current_user) @@ -46,6 +49,21 @@ class TopicsController < ApplicationController canonical_url @topic_view.canonical_path end + def wordpress + params.require(:best) + params.require(:topic_id) + + @topic_view = TopicView.new(params[:topic_id], current_user, best: params[:best].to_i) + + raise Discourse::NotFound if @topic_view.posts.blank? + + anonymous_etag(@topic_view.topic) do + wordpress_serializer = TopicViewWordpressSerializer.new(@topic_view, scope: guardian, root: false) + render_json_dump(wordpress_serializer) + end + + end + def destroy_timings PostTiming.destroy_for(current_user.id, params[:topic_id].to_i) render nothing: true @@ -257,6 +275,7 @@ class TopicsController < ApplicationController def perform_show_response topic_view_serializer = TopicViewSerializer.new(@topic_view, scope: guardian, root: false) + respond_to do |format| format.html do store_preloaded("topic_#{@topic_view.topic.id}", MultiJson.dump(topic_view_serializer)) diff --git a/app/serializers/basic_post_serializer.rb b/app/serializers/basic_post_serializer.rb new file mode 100644 index 00000000000..1fedd6f6f1d --- /dev/null +++ b/app/serializers/basic_post_serializer.rb @@ -0,0 +1,34 @@ +# The most basic attributes of a topic that we need to create a link for it. +class BasicPostSerializer < ApplicationSerializer + attributes :id, + :name, + :username, + :avatar_template, + :created_at, + :cooked + + def name + object.user.name + end + + def username + object.user.username + end + + def avatar_template + object.user.avatar_template + end + + def cooked + if object.hidden && !scope.is_staff? + if scope.current_user && object.user_id == scope.current_user.id + I18n.t('flagging.you_must_edit') + else + I18n.t('flagging.user_must_edit') + end + else + object.filter_quotes(@parent_post) + end + end + +end diff --git a/app/serializers/basic_topic_serializer.rb b/app/serializers/basic_topic_serializer.rb index 22703a9d57d..9a7cfb0baf2 100644 --- a/app/serializers/basic_topic_serializer.rb +++ b/app/serializers/basic_topic_serializer.rb @@ -1,5 +1,3 @@ -require_dependency 'age_words' - # The most basic attributes of a topic that we need to create a link for it. class BasicTopicSerializer < ApplicationSerializer attributes :id, :fancy_title, :slug, :posts_count diff --git a/app/serializers/post_serializer.rb b/app/serializers/post_serializer.rb index 2270642c82d..a54c4d84c71 100644 --- a/app/serializers/post_serializer.rb +++ b/app/serializers/post_serializer.rb @@ -1,4 +1,4 @@ -class PostSerializer < ApplicationSerializer +class PostSerializer < BasicPostSerializer # To pass in additional information we might need attr_accessor :topic_slug @@ -8,10 +8,8 @@ class PostSerializer < ApplicationSerializer attr_accessor :single_post_link_counts attr_accessor :draft_sequence - attributes :id, - :post_number, + attributes :post_number, :post_type, - :created_at, :updated_at, :reply_count, :reply_to_post_number, @@ -29,10 +27,7 @@ class PostSerializer < ApplicationSerializer :can_delete, :can_recover, :link_counts, - :cooked, :read, - :username, - :name, :user_title, :reply_to_user, :bookmarked, @@ -40,7 +35,6 @@ class PostSerializer < ApplicationSerializer :actions_summary, :moderator?, :staff?, - :avatar_template, :user_id, :draft_sequence, :hidden, @@ -57,10 +51,6 @@ class PostSerializer < ApplicationSerializer object.user.staff? end - def avatar_template - object.user.avatar_template - end - def yours scope.user == object.user end @@ -77,6 +67,10 @@ class PostSerializer < ApplicationSerializer scope.can_recover_post?(object) end + def display_username + object.user.name + end + def link_counts return @single_post_link_counts if @single_post_link_counts.present? @@ -93,18 +87,6 @@ class PostSerializer < ApplicationSerializer end end - def cooked - if object.hidden && !scope.is_staff? - if scope.current_user && object.user_id == scope.current_user.id - I18n.t('flagging.you_must_edit') - else - I18n.t('flagging.user_must_edit') - end - else - object.filter_quotes(@parent_post) - end - end - def read @topic_view.read?(object.post_number) end @@ -113,22 +95,10 @@ class PostSerializer < ApplicationSerializer object.score || 0 end - def display_username - object.user.name - end - def version object.cached_version end - def username - object.user.username - end - - def name - object.user.name - end - def user_title object.user.title end diff --git a/app/serializers/topic_view_wordpress_serializer.rb b/app/serializers/topic_view_wordpress_serializer.rb new file mode 100644 index 00000000000..f442fe47bab --- /dev/null +++ b/app/serializers/topic_view_wordpress_serializer.rb @@ -0,0 +1,32 @@ +class TopicViewWordpressSerializer < ApplicationSerializer + + # These attributes will be delegated to the topic + attributes :id, + :posts_count, + :filtered_posts_count, + :posts + + has_many :participants, serializer: BasicUserSerializer, embed: :objects + has_many :posts, serializer: BasicPostSerializer, embed: :objects + + def id + object.topic.id + end + + def posts_count + object.topic.posts_count + end + + def filtered_posts_count + object.filtered_posts_count + end + + def participants + object.participants.values + end + + def posts + object.posts + end + +end diff --git a/config/routes.rb b/config/routes.rb index 1057ceff846..1859950097b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -197,6 +197,8 @@ Discourse::Application.routes.draw do get 'threads/:topic_id/:post_number/avatar' => 'topics#avatar', constraints: {topic_id: /\d+/, post_number: /\d+/} # Topic routes + get 't/:slug/:topic_id/wordpress' => 'topics#wordpress', constraints: {topic_id: /\d+/} + get 't/:topic_id/wordpress' => 'topics#wordpress', constraints: {topic_id: /\d+/} get 't/:slug/:topic_id/best_of' => 'topics#show', defaults: {best_of: true}, constraints: {topic_id: /\d+/, post_number: /\d+/} get 't/:topic_id/best_of' => 'topics#show', constraints: {topic_id: /\d+/, post_number: /\d+/} put 't/:slug/:topic_id' => 'topics#update', constraints: {topic_id: /\d+/} diff --git a/spec/components/avatar_lookup_spec.rb b/spec/components/avatar_lookup_spec.rb index a2a9e719462..257578229d5 100644 --- a/spec/components/avatar_lookup_spec.rb +++ b/spec/components/avatar_lookup_spec.rb @@ -1,7 +1,7 @@ # encoding: utf-8 require 'spec_helper' -require 'avatar_lookup' +require_dependency 'avatar_lookup' describe AvatarLookup do let!(:user){ Fabricate(:user) } diff --git a/spec/controllers/topics_controller_spec.rb b/spec/controllers/topics_controller_spec.rb index d8d08de8100..59088a2c47f 100644 --- a/spec/controllers/topics_controller_spec.rb +++ b/spec/controllers/topics_controller_spec.rb @@ -2,6 +2,46 @@ require 'spec_helper' describe TopicsController do + + context 'wordpress' do + let!(:user) { log_in(:moderator) } + let(:p1) { Fabricate(:post, user: user) } + let(:topic) { p1.topic } + let!(:p2) { Fabricate(:post, topic: topic, user:user )} + + it "returns the JSON in the format our wordpress plugin needs" do + xhr :get, :wordpress, topic_id: topic.id, best: 3 + response.should be_success + json = ::JSON.parse(response.body) + json.should be_present + + # The JSON has the data the wordpress plugin needs + json['id'].should == topic.id + json['posts_count'].should == 2 + json['filtered_posts_count'].should == 2 + + # Posts + json['posts'].size.should == 1 + post = json['posts'][0] + post['id'].should == p2.id + post['username'].should == user.username + post['avatar_template'].should == user.avatar_template + post['name'].should == user.name + post['created_at'].should be_present + post['cooked'].should == p2.cooked + + # Participants + json['participants'].size.should == 1 + participant = json['participants'][0] + participant['id'].should == user.id + participant['username'].should == user.username + participant['avatar_template'].should == user.avatar_template + + + puts json.inspect + end + end + context 'move_posts' do it 'needs you to be logged in' do lambda { xhr :post, :move_posts, topic_id: 111, title: 'blah', post_ids: [1,2,3] }.should raise_error(Discourse::NotLoggedIn)