diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index a6d8398e7..25af14ede 100644 --- a/app/logical/post_query_builder.rb +++ b/app/logical/post_query_builder.rb @@ -37,7 +37,7 @@ class PostQueryBuilder ordpool note comment commentary id rating locked source status filetype disapproved parent child search embedded md5 width height mpixels ratio score favcount filesize date age order limit tagcount pixiv_id pixiv - unaliased exif + unaliased exif duration ] + COUNT_METATAGS + COUNT_METATAG_SYNONYMS + CATEGORY_COUNT_METATAGS ORDER_METATAGS = %w[ @@ -55,6 +55,7 @@ class PostQueryBuilder portrait landscape filesize filesize_asc tagcount tagcount_asc + duration duration_asc rank curated modqueue @@ -154,6 +155,8 @@ class PostQueryBuilder attribute_matches(value, :pixiv_id) when "tagcount" attribute_matches(value, :tag_count) + when "duration" + attribute_matches(value, "media_assets.duration", :float).joins(:media_asset) when "status" status_matches(value) when "parent" @@ -612,6 +615,12 @@ class PostQueryBuilder when "tagcount_asc" relation = relation.order("posts.tag_count ASC") + when "duration", "duration_desc" + relation = relation.joins(:media_asset).order("media_assets.duration DESC NULLS LAST, posts.id DESC") + + when "duration_asc" + relation = relation.joins(:media_asset).order("media_assets.duration ASC NULLS LAST, posts.id ASC") + when /(#{TagCategory.short_name_regex})tags(?:\Z|_desc)/ relation = relation.order("posts.tag_count_#{TagCategory.short_name_mapping[$1]} DESC") diff --git a/test/unit/post_query_builder_test.rb b/test/unit/post_query_builder_test.rb index cb4149e5b..283de4abc 100644 --- a/test/unit/post_query_builder_test.rb +++ b/test/unit/post_query_builder_test.rb @@ -593,6 +593,15 @@ class PostQueryBuilderTest < ActiveSupport::TestCase assert_tag_match([], "-ratio:2.0") end + should "return posts for the duration: metatag" do + post = create(:post, media_asset: create(:media_asset, file: "test/files/test-512x512.webm")) + + assert_tag_match([post], "duration:0.48") + assert_tag_match([post], "duration:>0.4") + assert_tag_match([post], "duration:<0.5") + assert_tag_match([], "duration:>1") + end + should "return posts for the status: metatag" do pending = create(:post, is_pending: true) flagged = create(:post, is_flagged: true) @@ -941,6 +950,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase assert_tag_match(posts.reverse, "order:notes_desc") assert_tag_match(posts.reverse, "order:md5") assert_tag_match(posts.reverse, "order:md5_desc") + assert_tag_match(posts.reverse, "order:duration_desc") assert_tag_match(posts, "order:id_asc") assert_tag_match(posts, "order:score_asc") @@ -961,6 +971,7 @@ class PostQueryBuilderTest < ActiveSupport::TestCase assert_tag_match(posts, "order:note_count_asc") assert_tag_match(posts, "order:notes_asc") assert_tag_match(posts, "order:md5_asc") + assert_tag_match(posts, "order:duration_asc") # ordering is unpredictable so can't be tested. assert_tag_match([posts.first], "id:#{posts.first.id} order:none")