discord: fix tag search commands being limited to 2 tags.
This commit is contained in:
@@ -102,7 +102,7 @@ class ApplicationController < ActionController::Base
|
||||
render_error_page(406, exception, message: "#{request.format} is not a supported format for this page")
|
||||
when PaginationExtension::PaginationError
|
||||
render_error_page(410, exception, template: "static/pagination_error", message: "You cannot go beyond page #{CurrentUser.user.page_limit}.")
|
||||
when Post::SearchError
|
||||
when PostQueryBuilder::TagLimitError
|
||||
render_error_page(422, exception, template: "static/tag_limit_error", message: "You cannot search for more than #{CurrentUser.tag_query_limit} tags at a time.")
|
||||
when RateLimiter::RateLimitError
|
||||
render_error_page(429, exception)
|
||||
|
||||
@@ -4,7 +4,7 @@ class CountsController < ApplicationController
|
||||
def posts
|
||||
estimate_count = params.fetch(:estimate_count, "true").truthy?
|
||||
skip_cache = params.fetch(:skip_cache, "false").truthy?
|
||||
@count = PostQueryBuilder.new(params[:tags], CurrentUser.user).normalized_query.fast_count(timeout: CurrentUser.statement_timeout, estimate_count: estimate_count, skip_cache: skip_cache)
|
||||
@count = PostQueryBuilder.new(params[:tags], CurrentUser.user, tag_limit: CurrentUser.user.tag_query_limit).normalized_query.fast_count(timeout: CurrentUser.statement_timeout, estimate_count: estimate_count, skip_cache: skip_cache)
|
||||
|
||||
if request.format.xml?
|
||||
respond_with({ posts: @count }, root: "counts")
|
||||
|
||||
@@ -19,7 +19,7 @@ class DiscordSlashCommand
|
||||
|
||||
def call
|
||||
tags = params[:tags]
|
||||
query = PostQueryBuilder.new(tags, User.anonymous).normalized_query
|
||||
query = PostQueryBuilder.new(tags, User.anonymous, tag_limit: nil).normalized_query
|
||||
count = query.fast_count(estimate_count: true, skip_cache: true)
|
||||
|
||||
respond_with("`#{tags}`: #{count} posts")
|
||||
|
||||
@@ -28,7 +28,7 @@ class DiscordSlashCommand
|
||||
def call
|
||||
tags = params[:tags]
|
||||
limit = params.fetch(:limit, 3).clamp(1, 10)
|
||||
posts = Post.user_tag_match(tags, User.anonymous).limit(limit)
|
||||
posts = Post.user_tag_match(tags, User.anonymous, tag_limit: nil).limit(limit)
|
||||
|
||||
respond_with(posts: posts)
|
||||
end
|
||||
|
||||
@@ -26,7 +26,7 @@ class DiscordSlashCommand
|
||||
def call
|
||||
tags = params[:tags]
|
||||
limit = params.fetch(:limit, 1).clamp(1, 10)
|
||||
posts = Post.user_tag_match(tags, User.anonymous).random(limit)
|
||||
posts = Post.user_tag_match(tags, User.anonymous, tag_limit: nil).random(limit)
|
||||
|
||||
respond_with(posts: posts)
|
||||
end
|
||||
|
||||
@@ -3,6 +3,8 @@ require "strscan"
|
||||
class PostQueryBuilder
|
||||
extend Memoist
|
||||
|
||||
class TagLimitError < StandardError; end
|
||||
|
||||
# How many tags a `blah*` search should match.
|
||||
MAX_WILDCARD_TAGS = 100
|
||||
|
||||
@@ -58,13 +60,14 @@ class PostQueryBuilder
|
||||
|
||||
UNLIMITED_METATAGS = %w[status rating limit]
|
||||
|
||||
attr_reader :query_string, :current_user, :safe_mode, :hide_deleted_posts
|
||||
attr_reader :query_string, :current_user, :tag_limit, :safe_mode, :hide_deleted_posts
|
||||
alias_method :safe_mode?, :safe_mode
|
||||
alias_method :hide_deleted_posts?, :hide_deleted_posts
|
||||
|
||||
def initialize(query_string, current_user = User.anonymous, safe_mode: false, hide_deleted_posts: false)
|
||||
def initialize(query_string, current_user = User.anonymous, tag_limit: nil, safe_mode: false, hide_deleted_posts: false)
|
||||
@query_string = query_string
|
||||
@current_user = current_user
|
||||
@tag_limit = tag_limit
|
||||
@safe_mode = safe_mode
|
||||
@hide_deleted_posts = hide_deleted_posts
|
||||
end
|
||||
@@ -468,15 +471,8 @@ class PostQueryBuilder
|
||||
relation
|
||||
end
|
||||
|
||||
def self.is_unlimited_tag?(term)
|
||||
term.type == :metatag && term.name.in?(UNLIMITED_METATAGS)
|
||||
end
|
||||
|
||||
def build
|
||||
tag_count = terms.count { |term| !PostQueryBuilder.is_unlimited_tag?(term) }
|
||||
if tag_count > current_user.tag_query_limit
|
||||
raise ::Post::SearchError
|
||||
end
|
||||
validate!
|
||||
|
||||
relation = Post.all
|
||||
relation = add_joins(relation)
|
||||
@@ -642,6 +638,18 @@ class PostQueryBuilder
|
||||
relation.find_ordered(ids)
|
||||
end
|
||||
|
||||
def validate!
|
||||
tag_count = terms.count { |term| !is_unlimited_tag?(term) }
|
||||
|
||||
if tag_limit.present? && tag_count > tag_limit
|
||||
raise TagLimitError
|
||||
end
|
||||
end
|
||||
|
||||
def is_unlimited_tag?(term)
|
||||
term.type == :metatag && term.name.in?(UNLIMITED_METATAGS)
|
||||
end
|
||||
|
||||
concerning :ParseMethods do
|
||||
def scan_query
|
||||
terms = []
|
||||
|
||||
@@ -6,7 +6,7 @@ module PostSets
|
||||
attr_reader :page, :random, :post_count, :format, :tag_string, :query, :normalized_query
|
||||
|
||||
def initialize(tags, page = 1, per_page = nil, user: CurrentUser.user, random: false, format: "html")
|
||||
@query = PostQueryBuilder.new(tags, user, safe_mode: CurrentUser.safe_mode?, hide_deleted_posts: user.hide_deleted_posts?)
|
||||
@query = PostQueryBuilder.new(tags, user, tag_limit: user.tag_query_limit, safe_mode: CurrentUser.safe_mode?, hide_deleted_posts: user.hide_deleted_posts?)
|
||||
@normalized_query = query.normalized_query
|
||||
@tag_string = tags
|
||||
@page = page
|
||||
|
||||
@@ -1265,11 +1265,11 @@ class Post < ApplicationRecord
|
||||
end
|
||||
|
||||
def system_tag_match(query)
|
||||
user_tag_match(query, User.system, safe_mode: false, hide_deleted_posts: false)
|
||||
user_tag_match(query, User.system, tag_limit: nil, safe_mode: false, hide_deleted_posts: false)
|
||||
end
|
||||
|
||||
def user_tag_match(query, user = CurrentUser.user, safe_mode: CurrentUser.safe_mode?, hide_deleted_posts: user.hide_deleted_posts?)
|
||||
post_query = PostQueryBuilder.new(query, user, safe_mode: safe_mode, hide_deleted_posts: hide_deleted_posts)
|
||||
def user_tag_match(query, user = CurrentUser.user, tag_limit: user.tag_query_limit, safe_mode: CurrentUser.safe_mode?, hide_deleted_posts: user.hide_deleted_posts?)
|
||||
post_query = PostQueryBuilder.new(query, user, tag_limit: tag_limit, safe_mode: safe_mode, hide_deleted_posts: hide_deleted_posts)
|
||||
post_query.normalized_query.build
|
||||
end
|
||||
|
||||
|
||||
@@ -1045,7 +1045,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
|
||||
should "fail for more than 6 tags" do
|
||||
post1 = create(:post, rating: "s")
|
||||
|
||||
assert_raise(::Post::SearchError) do
|
||||
assert_raise(PostQueryBuilder::TagLimitError) do
|
||||
Post.user_tag_match("a b c rating:s width:10 height:10 user:bob")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -82,7 +82,7 @@ module PostSets
|
||||
should "fail" do
|
||||
@set = PostSets::Post.new("a b c", user: create(:user))
|
||||
|
||||
assert_raises(::Post::SearchError) do
|
||||
assert_raises(PostQueryBuilder::TagLimitError) do
|
||||
@set.posts
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user