Fix #4917: Add down_score/up_score orders and metasearches.

Add `upvotes:N`, `downvotes:N`, `order:upvotes`, `order:downvotes`,
`order:upvotes_asc`, `order:downvotes_asc` metatags.

In the API, the field is called up_score / down_score. Here it's called
`upvotes` and `downvotes` because this should be easier to understand
for end users.

Note that internally, `down_score` is negative. A post that matches
`downvotes:>5` will have down_score < -5 internally.
This commit is contained in:
evazion
2021-11-16 03:52:38 -06:00
parent b561ca49f2
commit 43c2870664
2 changed files with 50 additions and 1 deletions

View File

@@ -37,7 +37,7 @@ class PostQueryBuilder
flagger appealer upvote downvote fav ordfav favgroup ordfavgroup pool
ordpool note comment commentary id rating source status filetype
disapproved parent child search embedded md5 width height mpixels ratio
score favcount filesize date age order limit tagcount pixiv_id pixiv
score upvotes downvotes favcount filesize date age order limit tagcount pixiv_id pixiv
unaliased exif duration
] + COUNT_METATAGS + COUNT_METATAG_SYNONYMS + CATEGORY_COUNT_METATAGS
@@ -45,6 +45,8 @@ class PostQueryBuilder
id id_desc
md5 md5_asc
score score_asc
upvotes upvotes_asc
downvotes downvotes_asc
favcount favcount_asc
created_at created_at_asc
change change_asc
@@ -138,6 +140,10 @@ class PostQueryBuilder
attribute_matches(value, "ROUND(1.0 * posts.image_width / GREATEST(1, posts.image_height), 2)", :ratio)
when "score"
attribute_matches(value, :score)
when "upvotes"
attribute_matches(value, :up_score)
when "downvotes"
attribute_matches(value, "ABS(posts.down_score)")
when "favcount"
attribute_matches(value, :fav_count)
when "filesize"
@@ -572,6 +578,19 @@ class PostQueryBuilder
when "score_asc"
relation = relation.order("posts.score ASC, posts.id ASC")
when "upvotes", "upvotes_desc"
relation = relation.order("posts.up_score DESC, posts.id DESC")
when "upvotes_asc"
relation = relation.order("posts.up_score ASC, posts.id ASC")
# XXX down_score is negative so order:downvotes sorts lowest-to-highest so that most downvoted is first.
when "downvotes", "downvotes_desc"
relation = relation.order("posts.down_score ASC, posts.id ASC")
when "downvotes_asc"
relation = relation.order("posts.down_score DESC, posts.id DESC")
when "favcount"
relation = relation.order("posts.fav_count DESC, posts.id DESC")

View File

@@ -235,6 +235,30 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match([posts[1]], "id:>#{posts[0].id} id:<#{posts[2].id}")
end
should "return posts for the score:<N> metatag" do
post1 = create(:post, score: 5)
post2 = create(:post, score: 0)
assert_tag_match([post1], "score:5")
assert_tag_match([post2], "score:0")
end
should "return posts for the upvotes:<N> metatag" do
post1 = create(:post, up_score: 5)
post2 = create(:post, up_score: 0)
assert_tag_match([post1], "upvotes:5")
assert_tag_match([post2], "upvotes:0")
end
should "return posts for the downvotes:<N> metatag" do
post1 = create(:post, down_score: -5)
post2 = create(:post, down_score: 0)
assert_tag_match([post1], "downvotes:5")
assert_tag_match([post2], "downvotes:0")
end
should "return posts for the fav:<name> metatag" do
user1 = create(:user)
user2 = create(:user)
@@ -1013,6 +1037,8 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
p = create(
:post,
score: n,
up_score: n,
down_score: -n,
md5: n.to_s,
fav_count: n,
file_size: 1.megabyte * n,
@@ -1033,6 +1059,8 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match(posts.reverse, "order:id_desc")
assert_tag_match(posts.reverse, "order:score")
assert_tag_match(posts.reverse, "order:upvotes")
assert_tag_match(posts.reverse, "order:downvotes")
assert_tag_match(posts.reverse, "order:favcount")
assert_tag_match(posts.reverse, "order:change")
assert_tag_match(posts.reverse, "order:comment")
@@ -1058,6 +1086,8 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match(posts, "order:id_asc")
assert_tag_match(posts, "order:score_asc")
assert_tag_match(posts, "order:upvotes_asc")
assert_tag_match(posts, "order:downvotes_asc")
assert_tag_match(posts, "order:favcount_asc")
assert_tag_match(posts, "order:change_asc")
assert_tag_match(posts, "order:comment_asc")