pixiv: replace HTTParty with Danbooru::Http.
This commit is contained in:
@@ -1,5 +1,3 @@
|
|||||||
require 'resolv-replace'
|
|
||||||
|
|
||||||
class PixivApiClient
|
class PixivApiClient
|
||||||
extend Memoist
|
extend Memoist
|
||||||
|
|
||||||
@@ -100,21 +98,12 @@ class PixivApiClient
|
|||||||
end
|
end
|
||||||
|
|
||||||
def work(illust_id)
|
def work(illust_id)
|
||||||
headers = Danbooru.config.http_headers.merge(
|
params = { image_sizes: "large", include_stats: "true" }
|
||||||
"Referer" => "http://www.pixiv.net",
|
|
||||||
"Content-Type" => "application/x-www-form-urlencoded",
|
|
||||||
"Authorization" => "Bearer #{access_token}"
|
|
||||||
)
|
|
||||||
params = {
|
|
||||||
"image_sizes" => "large",
|
|
||||||
"include_stats" => "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
url = "https://public-api.secure.pixiv.net/v#{API_VERSION}/works/#{illust_id.to_i}.json"
|
url = "https://public-api.secure.pixiv.net/v#{API_VERSION}/works/#{illust_id.to_i}.json"
|
||||||
response = Danbooru::Http.cache(1.minute).headers(headers).get(url, params: params)
|
response = api_client.cache(1.minute).get(url, params: params)
|
||||||
json = response.parse
|
json = response.parse
|
||||||
|
|
||||||
if response.code == 200
|
if response.status == 200
|
||||||
WorkResponse.new(json["response"][0])
|
WorkResponse.new(json["response"][0])
|
||||||
elsif json["status"] == "failure" && json.dig("errors", "system", "message") =~ /対象のイラストは見つかりませんでした。/
|
elsif json["status"] == "failure" && json.dig("errors", "system", "message") =~ /対象のイラストは見つかりませんでした。/
|
||||||
raise BadIDError.new("Pixiv ##{illust_id} not found: work was deleted, made private, or ID is invalid.")
|
raise BadIDError.new("Pixiv ##{illust_id} not found: work was deleted, made private, or ID is invalid.")
|
||||||
@@ -126,18 +115,11 @@ class PixivApiClient
|
|||||||
end
|
end
|
||||||
|
|
||||||
def novel(novel_id)
|
def novel(novel_id)
|
||||||
headers = Danbooru.config.http_headers.merge(
|
|
||||||
"Referer" => "http://www.pixiv.net",
|
|
||||||
"Content-Type" => "application/x-www-form-urlencoded",
|
|
||||||
"Authorization" => "Bearer #{access_token}"
|
|
||||||
)
|
|
||||||
|
|
||||||
url = "https://public-api.secure.pixiv.net/v#{API_VERSION}/novels/#{novel_id.to_i}.json"
|
url = "https://public-api.secure.pixiv.net/v#{API_VERSION}/novels/#{novel_id.to_i}.json"
|
||||||
resp = HTTParty.get(url, Danbooru.config.httparty_options.deep_merge(headers: headers))
|
resp = api_client.cache(1.minute).get(url)
|
||||||
body = resp.body.force_encoding("utf-8")
|
json = resp.parse
|
||||||
json = JSON.parse(body)
|
|
||||||
|
|
||||||
if resp.success?
|
if resp.status == 200
|
||||||
NovelResponse.new(json["response"][0])
|
NovelResponse.new(json["response"][0])
|
||||||
elsif json["status"] == "failure" && json.dig("errors", "system", "message") =~ /対象のイラストは見つかりませんでした。/
|
elsif json["status"] == "failure" && json.dig("errors", "system", "message") =~ /対象のイラストは見つかりませんでした。/
|
||||||
raise Error.new("Pixiv API call failed (status=#{resp.code} body=#{body})")
|
raise Error.new("Pixiv API call failed (status=#{resp.code} body=#{body})")
|
||||||
@@ -147,37 +129,42 @@ class PixivApiClient
|
|||||||
end
|
end
|
||||||
|
|
||||||
def access_token
|
def access_token
|
||||||
Cache.get("pixiv-papi-access-token", 3000) do
|
# truncate timestamp to 1-hour resolution so that it doesn't break caching.
|
||||||
access_token = nil
|
client_time = Time.zone.now.utc.change(min: 0).rfc3339
|
||||||
|
client_hash = Digest::MD5.hexdigest(client_time + CLIENT_HASH_SALT)
|
||||||
|
|
||||||
client_time = Time.now.rfc3339
|
headers = {
|
||||||
client_hash = Digest::MD5.hexdigest(client_time + CLIENT_HASH_SALT)
|
"Referer": "http://www.pixiv.net",
|
||||||
|
"X-Client-Time": client_time,
|
||||||
|
"X-Client-Hash": client_hash
|
||||||
|
}
|
||||||
|
|
||||||
headers = {
|
params = {
|
||||||
"Referer": "http://www.pixiv.net",
|
username: Danbooru.config.pixiv_login,
|
||||||
"X-Client-Time": client_time,
|
password: Danbooru.config.pixiv_password,
|
||||||
"X-Client-Hash": client_hash
|
grant_type: "password",
|
||||||
}
|
client_id: CLIENT_ID,
|
||||||
params = {
|
client_secret: CLIENT_SECRET
|
||||||
username: Danbooru.config.pixiv_login,
|
}
|
||||||
password: Danbooru.config.pixiv_password,
|
|
||||||
grant_type: "password",
|
|
||||||
client_id: CLIENT_ID,
|
|
||||||
client_secret: CLIENT_SECRET
|
|
||||||
}
|
|
||||||
url = "https://oauth.secure.pixiv.net/auth/token"
|
|
||||||
|
|
||||||
resp = HTTParty.post(url, Danbooru.config.httparty_options.deep_merge(body: params, headers: headers))
|
resp = http.headers(headers).cache(1.hour).post("https://oauth.secure.pixiv.net/auth/token", form: params)
|
||||||
body = resp.body.force_encoding("utf-8")
|
return nil unless resp.status == 200
|
||||||
|
|
||||||
if resp.success?
|
resp.parse.dig("response", "access_token")
|
||||||
json = JSON.parse(body)
|
|
||||||
access_token = json["response"]["access_token"]
|
|
||||||
else
|
|
||||||
raise Error.new("Pixiv API access token call failed (status=#{resp.code} body=#{body})")
|
|
||||||
end
|
|
||||||
|
|
||||||
access_token
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def api_client
|
||||||
|
http.headers(
|
||||||
|
**Danbooru.config.http_headers,
|
||||||
|
"Referer": "http://www.pixiv.net",
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
"Authorization": "Bearer #{access_token}"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def http
|
||||||
|
Danbooru::Http.new
|
||||||
|
end
|
||||||
|
|
||||||
|
memoize :access_token, :api_client, :http
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user