posts: add duration:<x> and order:duration metatags.

Add duration:<x> and order:duration metatags for searching animated
posts by duration.

https://danbooru.donmai.us/posts?tags=animated+duration:<5.0
https://danbooru.donmai.us/posts?tags=animated+duration:>60
https://danbooru.donmai.us/posts?tags=animated+order:duration
This commit is contained in:
evazion
2021-10-07 01:53:23 -05:00
parent 0731b07d27
commit 595e02ab45
2 changed files with 21 additions and 1 deletions

View File

@@ -37,7 +37,7 @@ class PostQueryBuilder
ordpool note comment commentary id rating locked source status filetype ordpool note comment commentary id rating locked source status filetype
disapproved parent child search embedded md5 width height mpixels ratio disapproved parent child search embedded md5 width height mpixels ratio
score favcount filesize date age order limit tagcount pixiv_id pixiv score favcount filesize date age order limit tagcount pixiv_id pixiv
unaliased exif unaliased exif duration
] + COUNT_METATAGS + COUNT_METATAG_SYNONYMS + CATEGORY_COUNT_METATAGS ] + COUNT_METATAGS + COUNT_METATAG_SYNONYMS + CATEGORY_COUNT_METATAGS
ORDER_METATAGS = %w[ ORDER_METATAGS = %w[
@@ -55,6 +55,7 @@ class PostQueryBuilder
portrait landscape portrait landscape
filesize filesize_asc filesize filesize_asc
tagcount tagcount_asc tagcount tagcount_asc
duration duration_asc
rank rank
curated curated
modqueue modqueue
@@ -154,6 +155,8 @@ class PostQueryBuilder
attribute_matches(value, :pixiv_id) attribute_matches(value, :pixiv_id)
when "tagcount" when "tagcount"
attribute_matches(value, :tag_count) attribute_matches(value, :tag_count)
when "duration"
attribute_matches(value, "media_assets.duration", :float).joins(:media_asset)
when "status" when "status"
status_matches(value) status_matches(value)
when "parent" when "parent"
@@ -612,6 +615,12 @@ class PostQueryBuilder
when "tagcount_asc" when "tagcount_asc"
relation = relation.order("posts.tag_count 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)/ when /(#{TagCategory.short_name_regex})tags(?:\Z|_desc)/
relation = relation.order("posts.tag_count_#{TagCategory.short_name_mapping[$1]} DESC") relation = relation.order("posts.tag_count_#{TagCategory.short_name_mapping[$1]} DESC")

View File

@@ -593,6 +593,15 @@ class PostQueryBuilderTest < ActiveSupport::TestCase
assert_tag_match([], "-ratio:2.0") assert_tag_match([], "-ratio:2.0")
end end
should "return posts for the duration:<x> 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:<type> metatag" do should "return posts for the status:<type> metatag" do
pending = create(:post, is_pending: true) pending = create(:post, is_pending: true)
flagged = create(:post, is_flagged: 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:notes_desc")
assert_tag_match(posts.reverse, "order:md5") assert_tag_match(posts.reverse, "order:md5")
assert_tag_match(posts.reverse, "order:md5_desc") 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:id_asc")
assert_tag_match(posts, "order:score_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:note_count_asc")
assert_tag_match(posts, "order:notes_asc") assert_tag_match(posts, "order:notes_asc")
assert_tag_match(posts, "order:md5_asc") assert_tag_match(posts, "order:md5_asc")
assert_tag_match(posts, "order:duration_asc")
# ordering is unpredictable so can't be tested. # ordering is unpredictable so can't be tested.
assert_tag_match([posts.first], "id:#{posts.first.id} order:none") assert_tag_match([posts.first], "id:#{posts.first.id} order:none")