101 lines
3.1 KiB
Ruby
101 lines
3.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# @see Source::URL::Moebooru
|
|
module Source
|
|
class Extractor
|
|
class Moebooru < Source::Extractor
|
|
delegate :artist_name, :profile_url, :tag_name, :artist_commentary_title, :artist_commentary_desc, :dtext_artist_commentary_title, :dtext_artist_commentary_desc, to: :sub_extractor, allow_nil: true
|
|
delegate :site_name, :domain, to: :parsed_url
|
|
|
|
def match?
|
|
Source::URL::Moebooru === parsed_url
|
|
end
|
|
|
|
def image_urls
|
|
return [] if post_md5.blank? || file_ext.blank?
|
|
[Source::URL::Moebooru.full_image_url(site_name, post_md5, file_ext, post_id)]
|
|
end
|
|
|
|
def page_url
|
|
return nil if post_id.blank?
|
|
"https://#{domain}/post/show/#{post_id}"
|
|
end
|
|
|
|
def tags
|
|
api_response[:tags].to_s.split.map do |tag|
|
|
[tag, "https://#{domain}/post?tags=#{CGI.escape(tag)}"]
|
|
end
|
|
end
|
|
|
|
# XXX the base extractor excludes artist tags from the translated tags; we don't want that for moebooru.
|
|
def translated_tags
|
|
tags.map(&:first).flat_map(&method(:translate_tag)).uniq.sort
|
|
end
|
|
|
|
# Moebooru returns an empty array when doing an md5:<hash> search for a
|
|
# deleted post. Because of this, api_response may be empty in some cases.
|
|
def api_response
|
|
if post_id_from_url.present?
|
|
params = { tags: "id:#{post_id_from_url}" }
|
|
elsif post_md5_from_url.present?
|
|
params = { tags: "md5:#{post_md5_from_url}" }
|
|
else
|
|
return {}
|
|
end
|
|
|
|
response = http.cache(1.minute).get("https://#{domain}/post.json", params: params)
|
|
post = response.parse.first&.with_indifferent_access
|
|
post || {}
|
|
end
|
|
memoize :api_response
|
|
|
|
concerning :HelperMethods do
|
|
def sub_extractor
|
|
@sub_extractor ||= Source::Extractor.find(api_response[:source], default: nil)
|
|
end
|
|
|
|
def file_ext
|
|
if parsed_url.original_file_ext.present?
|
|
parsed_url.original_file_ext
|
|
|
|
# file_ext is not present in konachan's api (only on yande.re)
|
|
elsif api_response[:file_ext].present?
|
|
api_response[:file_ext]
|
|
|
|
# file_url is not present in yande.re's api on deleted posts
|
|
elsif api_response[:file_url].present?
|
|
api_response[:file_url][/\.(jpg|jpeg|png|gif)\z/i, 1]
|
|
|
|
# on yande.re, the file extension doesn't matter, any random string will work. This means we can't guess the true file extension.
|
|
elsif domain == "yande.re"
|
|
"png"
|
|
|
|
# the api_response wasn't available because it's a deleted post.
|
|
elsif post_md5.present?
|
|
%w[jpg png gif].find { |ext| http_exists?("https://#{domain}/image/#{post_md5}.#{ext}") }
|
|
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
|
|
def post_id_from_url
|
|
parsed_url.work_id || parsed_referer&.work_id
|
|
end
|
|
|
|
def post_md5_from_url
|
|
parsed_url.md5 || parsed_referer&.md5
|
|
end
|
|
|
|
def post_id
|
|
post_id_from_url || api_response[:id]
|
|
end
|
|
|
|
def post_md5
|
|
post_md5_from_url || api_response[:md5]
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|