Add a rate limit of 1 request per 2 seconds to the post RSS feed endpoint (/posts.atom). This lets you check your feeds 30 times per minute, or 1800 times per hour. The previous limit was 10 requests per second. This is because there are too many bad RSS feed reader bots constantly checking the same tags over and over again, 24 hours a day, as fast they can.
142 lines
4.7 KiB
Ruby
142 lines
4.7 KiB
Ruby
class PostsController < ApplicationController
|
|
respond_to :html, :xml, :json, :js
|
|
layout "sidebar"
|
|
|
|
rate_limit :index, rate: 1.0/2.seconds, burst: 50, if: -> { request.format.atom? }, key: "posts:index.atom"
|
|
|
|
def index
|
|
if params[:md5].present?
|
|
@post = authorize Post.find_by!(md5: params[:md5])
|
|
respond_with(@post) do |format|
|
|
format.html { redirect_to(@post) }
|
|
end
|
|
elsif params[:random].to_s.truthy?
|
|
post_set = PostSets::Post.new(params[:tags], params[:page], params[:limit], format: request.format.symbol)
|
|
query = "#{post_set.normalized_query.to_s} random:#{post_set.per_page}".strip
|
|
redirect_to posts_path(tags: query, page: params[:page], limit: params[:limit], format: request.format.symbol)
|
|
else
|
|
tag_query = params[:tags] || params.dig(:post, :tags)
|
|
@show_votes = (params[:show_votes].presence || cookies[:post_preview_show_votes].presence || "false").truthy?
|
|
@post_set = PostSets::Post.new(tag_query, params[:page], params[:limit], format: request.format.symbol, show_votes: @show_votes)
|
|
@preview_size = params[:size].presence || cookies[:post_preview_size].presence || PostPreviewComponent::DEFAULT_SIZE
|
|
@posts = authorize @post_set.posts, policy_class: PostPolicy
|
|
@post_set.log!
|
|
respond_with(@posts) do |format|
|
|
format.atom
|
|
end
|
|
end
|
|
end
|
|
|
|
def show
|
|
@post = authorize Post.find(params[:id])
|
|
|
|
if request.format.html?
|
|
include_deleted = @post.is_deleted? || (@post.parent_id.present? && @post.parent.is_deleted?) || CurrentUser.user.show_deleted_children?
|
|
@sibling_posts = @post.parent.present? ? @post.parent.children : Post.none
|
|
@sibling_posts = @sibling_posts.undeleted unless include_deleted
|
|
@sibling_posts = @sibling_posts.includes(:media_asset)
|
|
|
|
@child_posts = @post.children
|
|
@child_posts = @child_posts.undeleted unless include_deleted
|
|
@sibling_posts = @sibling_posts.includes(:media_asset)
|
|
end
|
|
|
|
respond_with(@post) do |format|
|
|
format.html.tooltip { render layout: false }
|
|
end
|
|
end
|
|
|
|
def show_seq
|
|
authorize Post
|
|
context = PostSearchContext.new(params)
|
|
if context.post_id
|
|
redirect_to(post_path(context.post_id, q: params[:q]))
|
|
else
|
|
redirect_to(post_path(params[:id], q: params[:q]))
|
|
end
|
|
end
|
|
|
|
def update
|
|
@post = authorize Post.find(params[:id])
|
|
@post.update(permitted_attributes(@post))
|
|
@show_votes = (params[:show_votes].presence || cookies[:post_preview_show_votes].presence || "false").truthy?
|
|
@preview_size = params[:size].presence || cookies[:post_preview_size].presence || PostPreviewComponent::DEFAULT_SIZE
|
|
respond_with_post_after_update(@post)
|
|
end
|
|
|
|
def destroy
|
|
@post = authorize Post.find(params[:id])
|
|
|
|
if params[:commit] == "Delete"
|
|
move_favorites = params.dig(:post, :move_favorites).to_s.truthy?
|
|
@post.delete!(params.dig(:post, :reason), move_favorites: move_favorites, user: CurrentUser.user)
|
|
flash[:notice] = "Post deleted"
|
|
end
|
|
|
|
respond_with_post_after_update(@post)
|
|
end
|
|
|
|
def revert
|
|
@post = authorize Post.find(params[:id])
|
|
@version = @post.versions.find(params[:version_id])
|
|
@post.revert_to!(@version)
|
|
|
|
respond_with(@post) do |format|
|
|
format.js
|
|
end
|
|
end
|
|
|
|
def copy_notes
|
|
@post = Post.find(params[:id])
|
|
@other_post = authorize Post.find(params[:other_post_id].to_i)
|
|
@post.copy_notes_to(@other_post)
|
|
|
|
if @post.errors.any?
|
|
@error_message = @post.errors.full_messages.join("; ")
|
|
render :json => {:success => false, :reason => @error_message}.to_json, :status => 400
|
|
else
|
|
head 204
|
|
end
|
|
end
|
|
|
|
def random
|
|
@post = Post.user_tag_match(params[:tags]).random(1).take
|
|
raise ActiveRecord::RecordNotFound if @post.nil?
|
|
authorize @post
|
|
respond_with(@post) do |format|
|
|
format.html { redirect_to post_path(@post, :tags => params[:tags]) }
|
|
end
|
|
end
|
|
|
|
def mark_as_translated
|
|
@post = authorize Post.find(params[:id])
|
|
@post.mark_as_translated(params[:post])
|
|
respond_with_post_after_update(@post)
|
|
end
|
|
|
|
private
|
|
|
|
def respond_with_post_after_update(post)
|
|
respond_with(post) do |format|
|
|
format.html do
|
|
if post.warnings.any?
|
|
flash[:notice] = post.warnings.full_messages.join(".\n \n")
|
|
end
|
|
|
|
if post.errors.any?
|
|
@error_message = post.errors.full_messages.join("; ")
|
|
render :template => "static/error", :status => 500
|
|
else
|
|
response_params = {:q => params[:tags_query], :pool_id => params[:pool_id], :favgroup_id => params[:favgroup_id]}
|
|
response_params.reject! {|_key, value| value.blank?}
|
|
redirect_to post_path(post, response_params)
|
|
end
|
|
end
|
|
|
|
format.json do
|
|
render :json => post.to_json
|
|
end
|
|
end
|
|
end
|
|
end
|