posts: add is: and has: metatags.

Add the following metatags:

* is:parent
* is:child
* is:safe
* is:questionable
* is:explicit
* is:sfw (same as -rating:q,e)
* is:nsfw (same as rating:q,e)
* is:active
* is:deleted
* is:pending
* is:flagged
* is:appealed
* is:banned
* is:modqueue
* is:unmoderated
* is:jpg
* is:png
* is:gif
* is:mp4
* is:webm
* is:swf
* is:zip
* has:parent
* has:children
* has:source
* has:appeals
* has:flags
* has:replacements
* has:comments
* has:commentary
* has:notes
* has:pools

All of these searches were already possible with other metatags, but these might be more convenient.
This commit is contained in:
evazion
2022-05-18 11:44:35 -05:00
parent 141044d352
commit 181639368c
5 changed files with 150 additions and 3 deletions

View File

@@ -3,6 +3,7 @@
class MediaAsset < ApplicationRecord
class Error < StandardError; end
FILE_TYPES = %w[jpg png gif mp4 webm swf zip]
FILE_KEY_LENGTH = 9
VARIANTS = %i[preview 180x180 360x360 720x720 sample original]
MAX_VIDEO_DURATION = Danbooru.config.max_video_duration.to_i
@@ -41,7 +42,7 @@ class MediaAsset < ApplicationRecord
}
validates :md5, uniqueness: { conditions: -> { where(status: [:processing, :active]) } }
validates :file_ext, inclusion: { in: %w[jpg png gif mp4 webm swf zip], message: "File is not an image or video" }
validates :file_ext, inclusion: { in: FILE_TYPES, message: "File is not an image or video" }
validates :file_size, numericality: { less_than_or_equal_to: Danbooru.config.max_file_size, message: ->(asset, _) { "too large (size: #{asset.file_size.to_formatted_s(:human_size)}; max size: #{Danbooru.config.max_file_size.to_formatted_s(:human_size)})" } }
validates :file_key, length: { is: FILE_KEY_LENGTH }, uniqueness: true, if: :file_key_changed?
validates :duration, numericality: { less_than_or_equal_to: MAX_VIDEO_DURATION, message: "must be less than #{MAX_VIDEO_DURATION} seconds", allow_nil: true }, on: :create # XXX should allow admins to bypass

View File

@@ -1058,6 +1058,54 @@ class Post < ApplicationRecord
none
end
def is_matches(value, current_user = User.anonymous)
case value.downcase
when "parent"
where(has_children: true)
when "child"
where.not(parent: nil)
when "sfw"
where.not(rating: ["q", "e"])
when "nsfw"
where(rating: ["q", "e"])
when *AutocompleteService::POST_STATUSES
status_matches(value, current_user)
when *MediaAsset::FILE_TYPES
attribute_matches(value, :file_ext, :enum)
when *Post::RATINGS.values.map(&:downcase)
rating_matches(value)
else
none
end
end
def has_matches(value)
case value.downcase
when "parent"
where.not(parent: nil)
when "child", "children"
where(has_children: true)
when "source"
where.not(source: "")
when "appeals"
where(id: PostAppeal.select(:post_id))
when "flags"
where(id: PostFlag.by_users.select(:post_id))
when "replacements"
where(id: PostReplacement.select(:post_id))
when "comments"
where(id: Comment.undeleted.select(:post_id))
when "commentary"
where(id: ArtistCommentary.undeleted.select(:post_id))
when "notes"
where(id: Note.active.select(:post_id))
when "pools"
where(id: Pool.undeleted.select("unnest(post_ids)"))
else
none
end
end
def status_matches(status, current_user = User.anonymous)
case status.downcase
when "pending"