FEATURE: Latest posts endpoint at /posts.json

This commit is contained in:
riking 2015-01-23 21:04:14 -08:00
parent fb72e2665f
commit 1d24d8471e
3 changed files with 50 additions and 7 deletions

View File

@ -5,7 +5,7 @@ require_dependency 'distributed_memoizer'
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, :raw, :cooked]
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]
skip_before_filter :check_xhr, only: [:markdown_id, :markdown_num, :short_link]
@ -25,6 +25,27 @@ class PostsController < ApplicationController
end
end
def latest
posts = Post.order(created_at: :desc)
.where('posts.id > ?', Post.last.id - 50) # last 50 post IDs only, to avoid counting deleted posts in security check
.includes(topic: :category)
.includes(:user)
.limit(50)
# Remove posts the user doesn't have permission to see
# This isn't leaking any information we weren't already through the post ID numbers
posts = posts.reject { |post| !guardian.can_see?(post) }
counts = PostAction.counts_for(posts, current_user)
render_json_dump(serialize_data(posts,
PostSerializer,
scope: guardian,
root: 'latest_posts',
add_raw: true,
all_post_actions: counts)
)
end
def cooked
post = find_post_from_params
render json: {cooked: post.cooked}

View File

@ -1,12 +1,17 @@
class PostSerializer < BasicPostSerializer
# To pass in additional information we might need
attr_accessor :topic_view,
INSTANCE_VARS = [:topic_view,
:parent_post,
:add_raw,
:single_post_link_counts,
:draft_sequence,
:post_actions
:post_actions,
:all_post_actions]
INSTANCE_VARS.each do |v|
self.send(:attr_accessor, v)
end
attributes :post_number,
:post_type,
@ -53,6 +58,15 @@ class PostSerializer < BasicPostSerializer
:static_doc,
:via_email
def initialize(object, opts)
super(object, opts)
PostSerializer::INSTANCE_VARS.each do |name|
if opts.include? name
self.send("#{name}=", opts[name])
end
end
end
def topic_slug
object.try(:topic).try(:slug)
end
@ -154,6 +168,13 @@ class PostSerializer < BasicPostSerializer
scope.is_staff? && object.deleted_by.present?
end
# Helper function to decide between #post_actions and @all_post_actions
def actions
return post_actions if post_actions.present?
return all_post_actions[object.id] if all_post_actions.present?
nil
end
# Summary of the actions taken on this post
def actions_summary
result = []
@ -167,7 +188,7 @@ class PostSerializer < BasicPostSerializer
id: id,
count: count,
hidden: (sym == :vote),
can_act: scope.post_can_act?(object, sym, taken_actions: post_actions)
can_act: scope.post_can_act?(object, sym, taken_actions: actions)
}
if sym == :notify_user && scope.current_user.present? && scope.current_user == object.user
@ -182,9 +203,9 @@ class PostSerializer < BasicPostSerializer
active_flags[id].count > 0
end
if post_actions.present? && post_actions.has_key?(id)
if actions.present? && actions.has_key?(id)
action_summary[:acted] = true
action_summary[:can_undo] = scope.can_delete?(post_actions[id])
action_summary[:can_undo] = scope.can_delete?(actions[id])
end
# only show public data
@ -225,7 +246,7 @@ class PostSerializer < BasicPostSerializer
end
def include_bookmarked?
post_actions.present? && post_actions.keys.include?(PostActionType.types[:bookmark])
actions.present? && actions.keys.include?(PostActionType.types[:bookmark])
end
def include_display_username?

View File

@ -269,6 +269,7 @@ Discourse::Application.routes.draw do
get "uploads/:site/:sha" => "uploads#show", constraints: { site: /\w+/, sha: /[a-z0-9]{40}/}
post "uploads" => "uploads#create"
get "posts" => "posts#latest"
get "posts/by_number/:topic_id/:post_number" => "posts#by_number"
get "posts/:id/reply-history" => "posts#reply_history"
get "posts/:username/deleted" => "posts#deleted_posts", constraints: {username: USERNAME_ROUTE_FORMAT}