From 43c2870664e216151ab22bd2a06139c921e55a2d Mon Sep 17 00:00:00 2001 From: evazion Date: Tue, 16 Nov 2021 03:52:38 -0600 Subject: [PATCH] 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. --- app/logical/post_query_builder.rb | 21 ++++++++++++++++++- test/unit/post_query_builder_test.rb | 30 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index e1b0a29b6..56b856411 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -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") diff --git a/test/unit/post_query_builder_test.rb b/test/unit/post_query_builder_test.rb index b2afd8cee..5bd7fcb10 100644 --- a/test/unit/post_query_builder_test.rb +++ b/test/unit/post_query_builder_test.rb @@ -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: 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: 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: 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: 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")