From 313257b771bac697d68b5399129cee7bf2fc1113 Mon Sep 17 00:00:00 2001 From: evazion Date: Thu, 16 Sep 2021 02:13:15 -0500 Subject: [PATCH] posts: add `exif:` search metatags. Examples: * https://danbooru.donmai.us/posts?tags=exif:File:ColorComponents * https://danbooru.donmai.us/posts?tags=exif:GIF:GIFVersion * https://danbooru.donmai.us/posts?tags=exif:PNG:ColorType * https://danbooru.donmai.us/posts?tags=exif:PNG:ColorType=RGB * https://danbooru.donmai.us/posts?tags=exif:GIF:GIFVersion=89a * https://danbooru.donmai.us/posts?tags=exif:File:ColorComponents=3 --- app/logical/post_query_builder.rb | 18 +++++++++++++++++- test/unit/post_query_builder_test.rb | 14 ++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/logical/post_query_builder.rb b/app/logical/post_query_builder.rb index 2d7fb99f9..76315f9e3 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 + unaliased exif ] + COUNT_METATAGS + COUNT_METATAG_SYNONYMS + CATEGORY_COUNT_METATAGS ORDER_METATAGS = %w[ @@ -192,6 +192,8 @@ class PostQueryBuilder ordfav_matches(value) when "unaliased" unaliased_matches(value) + when "exif" + exif_matches(value) when "user" user_matches(:uploader, value) when "approver" @@ -242,6 +244,20 @@ class PostQueryBuilder end end + def exif_matches(string) + # string = exif:File:ColorComponents=3 + if string.include?("=") + key, value = string.split(/=/, 2) + hash = { key => value } + metadata = MediaMetadata.joins(:media_asset).where_json_contains(:metadata, hash) + # string = exif:File:ColorComponents + else + metadata = MediaMetadata.joins(:media_asset).where_json_has_key(:metadata, string) + end + + Post.where(md5: metadata.select(:md5)) + end + def attribute_matches(value, field, type = :integer) operator, *args = parse_metatag_value(value, type) Post.where_operator(field, operator, *args) diff --git a/test/unit/post_query_builder_test.rb b/test/unit/post_query_builder_test.rb index bb43a2de8..aa683d84c 100644 --- a/test/unit/post_query_builder_test.rb +++ b/test/unit/post_query_builder_test.rb @@ -901,6 +901,20 @@ class PostQueryBuilderTest < ActiveSupport::TestCase end end + should "return posts for an exif: metatag" do + jpg = create(:post, media_asset: create(:media_asset, file: "test/files/test.jpg")) + gif = create(:post, media_asset: create(:media_asset, file: "test/files/test.gif")) + png = create(:post, media_asset: create(:media_asset, file: "test/files/test.png")) + + assert_tag_match([jpg], "exif:File:ColorComponents") + assert_tag_match([jpg], "exif:File:ColorComponents=3") + assert_tag_match([gif], "exif:GIF:GIFVersion") + assert_tag_match([gif], "exif:GIF:GIFVersion=89a") + assert_tag_match([png], "exif:PNG:ColorType") + assert_tag_match([png], "exif:PNG:ColorType=RGB") + assert_tag_match([], "exif:DNE") + end + should "return posts ordered by a particular attribute" do posts = (1..2).map do |n| tags = ["tagme", "gentag1 gentag2 artist:arttag char:chartag copy:copytag"]