sources: factor out Source::URL::PixivSketch.
Add upload support for Pixiv Sketch. Fetch tags, commentary, and artist, and rewrite sample images to full images. Authentication isn't required. R18 images are hidden in the browser but visible in the API.
This commit is contained in:
@@ -28,6 +28,7 @@ module Source
|
||||
Source::URL::Moebooru,
|
||||
Source::URL::Nijie,
|
||||
Source::URL::Newgrounds,
|
||||
Source::URL::PixivSketch,
|
||||
Source::URL::Plurk,
|
||||
Source::URL::Skeb,
|
||||
Source::URL::TwitPic,
|
||||
|
||||
47
app/logical/source/url/pixiv_sketch.rb
Normal file
47
app/logical/source/url/pixiv_sketch.rb
Normal file
@@ -0,0 +1,47 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Source
|
||||
class URL::PixivSketch < Source::URL
|
||||
attr_reader :work_id, :username, :full_image_url
|
||||
|
||||
def self.match?(url)
|
||||
url.host.in?(%w[sketch.pixiv.net img-sketch.pixiv.net img-sketch.pximg.net])
|
||||
end
|
||||
|
||||
def parse
|
||||
case [host, *path_segments]
|
||||
|
||||
# https://sketch.pixiv.net/items/5835314698645024323
|
||||
in "sketch.pixiv.net", "items", work_id
|
||||
@work_id = work_id
|
||||
|
||||
# https://img-sketch.pixiv.net/uploads/medium/file/4463372/8906921629213362989.jpg (page: https://sketch.pixiv.net/items/5835314698645024323)
|
||||
# https://img-sketch.pximg.net/c!/w=540,f=webp:jpeg/uploads/medium/file/4463372/8906921629213362989.jpg
|
||||
# https://img-sketch.pixiv.net/c/f_540/uploads/medium/file/9986983/8431631593768139653.jpg
|
||||
in *, "uploads", "medium", "file", dir, file if image_url?
|
||||
@full_image_url = "https://img-sketch.pixiv.net/uploads/medium/file/#{dir}/#{file}"
|
||||
|
||||
# https://sketch.pixiv.net/@user_ejkv8372
|
||||
# https://sketch.pixiv.net/@user_ejkv8372/followings
|
||||
in "sketch.pixiv.net", /^@/ => username, *rest
|
||||
@username = username.delete_prefix("@")
|
||||
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
def image_url?
|
||||
url.host.in?(%w[img-sketch.pixiv.net img-sketch.pximg.net])
|
||||
end
|
||||
|
||||
def page_url
|
||||
# https://sketch.pixiv.net/items/5835314698645024323
|
||||
"https://sketch.pixiv.net/items/#{work_id}" if work_id.present?
|
||||
end
|
||||
|
||||
def api_url
|
||||
# https://sketch.pixiv.net/api/items/5835314698645024323.json (won't work in the browser; use curl)
|
||||
"https://sketch.pixiv.net/api/items/#{work_id}.json" if work_id.present?
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -16,6 +16,7 @@ module Sources
|
||||
Strategies::HentaiFoundry,
|
||||
Strategies::Fanbox,
|
||||
Strategies::Mastodon,
|
||||
Strategies::PixivSketch,
|
||||
Strategies::Weibo,
|
||||
Strategies::Newgrounds,
|
||||
Strategies::Skeb,
|
||||
|
||||
@@ -88,16 +88,12 @@ module Sources
|
||||
def match?
|
||||
return false if parsed_url.nil?
|
||||
return false if url.include? "/fanbox/"
|
||||
return false if Source::URL::PixivSketch === parsed_url
|
||||
parsed_url.domain.in?(domains) || parsed_url.host == "tc-pximg01.techorus-cdn.com"
|
||||
end
|
||||
|
||||
def site_name
|
||||
# XXX pixiv sketch should be in a separate strategy
|
||||
if parsed_url.host.in?(%w[sketch.pixiv.net img-sketch.pixiv.net img-sketch.pximg.net])
|
||||
"Pixiv Sketch"
|
||||
else
|
||||
"Pixiv"
|
||||
end
|
||||
"Pixiv"
|
||||
end
|
||||
|
||||
def image_urls
|
||||
|
||||
88
app/logical/sources/strategies/pixiv_sketch.rb
Normal file
88
app/logical/sources/strategies/pixiv_sketch.rb
Normal file
@@ -0,0 +1,88 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# @see Source::URL::PixivSketch
|
||||
module Sources
|
||||
module Strategies
|
||||
class PixivSketch < Base
|
||||
extend Memoist
|
||||
|
||||
def match?
|
||||
Source::URL::PixivSketch === parsed_url
|
||||
end
|
||||
|
||||
def site_name
|
||||
parsed_url.site_name
|
||||
end
|
||||
|
||||
def image_urls
|
||||
if parsed_url.image_url?
|
||||
[parsed_url.full_image_url]
|
||||
else
|
||||
image_urls_from_api
|
||||
end
|
||||
end
|
||||
|
||||
def image_urls_from_api
|
||||
api_response.dig("data", "media").to_a.pluck("photo").pluck("original").pluck("url2x")
|
||||
end
|
||||
|
||||
def profile_url
|
||||
"https://sketch.pixiv.net/@#{artist_name}" if artist_name.present?
|
||||
end
|
||||
|
||||
def artist_name
|
||||
api_response.dig("data", "user", "unique_name")
|
||||
end
|
||||
|
||||
def other_names
|
||||
[artist_name, display_name].compact
|
||||
end
|
||||
|
||||
def profile_urls
|
||||
[profile_url, pixiv_profile_url].compact
|
||||
end
|
||||
|
||||
def artist_commentary_desc
|
||||
api_response.dig("data", "text")
|
||||
end
|
||||
|
||||
def tags
|
||||
api_response.dig("data", "tags").to_a.map do |tag|
|
||||
[tag, "https://sketch.pixiv.net/tags/#{tag}"]
|
||||
end
|
||||
end
|
||||
|
||||
def display_name
|
||||
api_response.dig("data", "user", "name")
|
||||
end
|
||||
|
||||
def pixiv_profile_url
|
||||
"https://www.pixiv.net/users/#{pixiv_user_id}" if pixiv_user_id.present?
|
||||
end
|
||||
|
||||
def pixiv_user_id
|
||||
api_response.dig("data", "user", "pixiv_user_id")
|
||||
end
|
||||
|
||||
# curl https://sketch.pixiv.net/api/items/5835314698645024323.json | jq
|
||||
def api_response
|
||||
return {} if api_url.blank?
|
||||
|
||||
response = http.cache(1.minute).get(api_url)
|
||||
return {} if response.status == 404
|
||||
|
||||
response.parse
|
||||
end
|
||||
|
||||
def page_url
|
||||
parsed_url.page_url || parsed_referer&.page_url
|
||||
end
|
||||
|
||||
def api_url
|
||||
parsed_url.api_url || parsed_referer&.api_url
|
||||
end
|
||||
|
||||
memoize :api_response
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user