Add anifty.jp support

This commit is contained in:
nonamethanks
2022-04-18 16:45:17 +02:00
parent a45b18ed36
commit c9227645d9
9 changed files with 222 additions and 1 deletions

View File

@@ -52,6 +52,7 @@ module Source
Source::Extractor::Tinami,
Source::Extractor::Fantia,
Source::Extractor::Booth,
Source::Extractor::Anifty,
]
# Should return true if the extractor is configured correctly. Return false

View File

@@ -0,0 +1,110 @@
# frozen_string_literal: true
# @see Source::URL::Anifty
class Source::Extractor
class Anifty < Source::Extractor
def match?
Source::URL::Anifty === parsed_url
end
def image_urls
if parsed_url.image_url?
[parsed_url.full_image_url].compact
else
[api_response["imageURL"]].compact
end
end
def profile_url
if artist_name.present?
"https://anifty.jp/@#{username}"
else
parsed_url.profile_url || parsed_referer&.profile_url
end
end
def username
api_response.dig("creator", "userName") || artist_api_response["userName"]
end
def artist_name
api_response.dig("creator", "displayName") || artist_api_response.dig("createdTokens", 0, "creatorProfile", "displayNameEN")
end
def other_names
other_names = [username]
if api_response.present?
other_names << api_response.dig("creator", "displayNameJA")
elsif artist_api_response
other_names << artist_api_response.dig("createdTokens", 0, "creatorProfile", "displayNameJP")
end
other_names.compact.uniq
end
def artist_commentary_title
api_response["title"] || api_response["titleJA"]
end
def artist_commentary_desc
api_response["description"] || api_response["descriptionJA"]
end
def tags
# anifty marketplace uses XHR requests to filter by tags, so there's no url to get
api_response["tags"].to_a.map do |tag|
[tag["name"], "https://anifty.jp/marketplace"]
end
end
def page_url
if page_url_from_parsed_urls.present?
page_url_from_parsed_urls
elsif work_id.present?
"https://anifty.jp/creations/#{work_id}"
end
end
def page_url_from_parsed_urls
parsed_url.page_url || parsed_referer&.page_url
end
def work_id
parsed_url.work_id || parsed_referer&.work_id || work_id_from_artist_api
end
def work_id_from_artist_api
# Try to get the work ID from the artist's list of tokens
return nil unless parsed_url.file.present? && parsed_url.work_type == "creation"
artist_api_response["createdTokens"].to_a.map do |token|
if Source::URL.parse(token["imageURL"])&.file == parsed_url.file
return token["creationID"]
end
end
nil
end
def artist_hash
parsed_url.artist_hash || parsed_referer&.artist_hash
end
def api_response
return {} if work_id.blank?
resp = http.cache(1.minute).get("https://asia-northeast1-anifty-59655.cloudfunctions.net/api/v2/creations/#{work_id}")
return {} if resp.code != 200
resp.parse.with_indifferent_access
end
memoize :api_response
def artist_api_response
return {} if artist_hash.blank?
resp = http.cache(1.minute).get("https://asia-northeast1-anifty-59655.cloudfunctions.net/api/users/#{artist_hash}")
return {} if resp.code != 200
resp.parse.with_indifferent_access
end
memoize :artist_api_response
end
end

View File

@@ -47,6 +47,7 @@ module Source
Source::URL::Tumblr,
Source::URL::TwitPic,
Source::URL::Weibo,
Source::URL::Anifty,
]
# Parse a URL into a subclass of Source::URL, or raise an exception if the URL is not a valid HTTP or HTTPS URL.

View File

@@ -0,0 +1,62 @@
# frozen_string_literal: true
class Source::URL::Anifty < Source::URL
attr_reader :username, :artist_hash, :work_id, :file, :work_type
def self.match?(url)
url.domain == "anifty.jp" || url.host == "anifty.imgix.net" || (url.host == "storage.googleapis.com" && url.path.include?("/anifty-media/"))
end
def site_name
"Anifty"
end
def parse
case [host, *path_segments]
# https://anifty.imgix.net/creation/0x961d09077b4a9f7a27f6b7ee78cb4c26f0e72c18/20d5ce5b5163a71258e1d0ee152a0347bf40c7da.png?w=660&h=660&fit=crop&crop=focalpoint&fp-x=0.76&fp-y=0.5&fp-z=1&auto=compress
# https://anifty.imgix.net/creation/0x961d09077b4a9f7a27f6b7ee78cb4c26f0e72c18/48b1409838cf7271413480b8533372844b9f2437.png?w=3840&q=undefined&auto=compress
in "anifty.imgix.net", work_type, /0x\w+/ => artist_hash, file
@artist_hash = artist_hash
@file = file
@work_type = work_type
# https://storage.googleapis.com/anifty-media/creation/0x961d09077b4a9f7a27f6b7ee78cb4c26f0e72c18/20d5ce5b5163a71258e1d0ee152a0347bf40c7da.png
# https://storage.googleapis.com/anifty-media/profile/0x961d09077b4a9f7a27f6b7ee78cb4c26f0e72c18/a6d2c366a3e876ddbf04fc269b63124be18af424.png
in "storage.googleapis.com", "anifty-media", work_type, /0x\w+/ => artist_hash, file
@artist_hash = artist_hash
@file = file
@work_type = work_type
# https://anifty.jp/creations/373
# https://anifty.jp/ja/creations/373
# https://anifty.jp/zh/creations/373
# https://anifty.jp/zh-Hant/creations/373
in ("anifty.jp" | "www.anifty.jp"), *, "creations", /\d+/ => work_id
@work_id = work_id
# https://anifty.jp/@hightree
# https://anifty.jp/ja/@hightree
in ("anifty.jp" | "www.anifty.jp"), *, /@(\w+)/
@username = $1
else
end
end
def image_url?
file.present? && artist_hash.present?
end
def full_image_url
"https://storage.googleapis.com/anifty-media/#{work_type}/#{artist_hash}/#{file}" if image_url?
end
def page_url
"https://anifty.jp/creations/#{work_id}" if work_id.present?
end
def profile_url
"https://anifty.jp/@#{username}" if username.present?
end
end