Remove the `preview_urls` method from strategies. The only place this was used was when doing IQDB searches, to download the thumbnail image from the source instead of the full image. This wasn't worth it for a few reasons: * Thumbnails on other sites are sometimes not the size we want, which could affect IQDB results. * Grabbing thumbnails is complex for some sites. You can't always just rewrite the image URL. Sometimes it requires extra API calls, which can be slower than just grabbing the full image. * For videos and animations, thumbnails from other sites don't always match our thumbnails. We do smart thumbnail generation to try to avoid blank thumbnails, which means we don't always pick the first frame, which could affect IQDB results. API changes: * /iqdb_queries?search[file_url] now downloads the URL as is without any modification. Before it tried to change thumbnail and sample size image URLs to the full version. * /iqdb_queries?search[url] now returns an error if the URL is for a HTML page that contains multiple images. Before it would grab only the first image and silently ignore the rest.
185 lines
4.6 KiB
Ruby
185 lines
4.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# @see Source::URL::Nijie
|
|
module Sources
|
|
module Strategies
|
|
class Nijie < Base
|
|
def self.enabled?
|
|
Danbooru.config.nijie_login.present? && Danbooru.config.nijie_password.present?
|
|
end
|
|
|
|
def match?
|
|
Source::URL::Nijie === 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_page
|
|
end
|
|
end
|
|
|
|
def image_urls_from_page
|
|
if doujin?
|
|
images = page&.search("#dojin_left .left img").to_a.pluck("src")
|
|
images += page&.search("#dojin_diff img.mozamoza").to_a.pluck("data-original")
|
|
else
|
|
images = page&.search("div#gallery a > .mozamoza").to_a.pluck("src")
|
|
end
|
|
|
|
images.map { |img| Source::URL.parse("https:#{img}").full_image_url }
|
|
end
|
|
|
|
def page_url
|
|
return nil if illust_id.blank?
|
|
"https://nijie.info/view.php?id=#{illust_id}"
|
|
end
|
|
|
|
def profile_url
|
|
return nil if artist_id.blank?
|
|
"https://nijie.info/members.php?id=#{artist_id}"
|
|
end
|
|
|
|
def artist_name
|
|
if doujin?
|
|
page&.at("#dojin_left .right a[href*='members.php?id=']")&.text
|
|
else
|
|
page&.at("a.name")&.text
|
|
end
|
|
end
|
|
|
|
def artist_commentary_title
|
|
if doujin?
|
|
page&.search("#dojin_text p.title")&.text
|
|
else
|
|
page&.search("h2.illust_title")&.text
|
|
end
|
|
end
|
|
|
|
def artist_commentary_desc
|
|
if doujin?
|
|
page&.search("#dojin_text p:not(.title)")&.to_html
|
|
else
|
|
page&.search('#illust_text > p')&.to_html
|
|
end
|
|
end
|
|
|
|
def tags
|
|
links = page&.search("div#view-tag a") || []
|
|
|
|
search_links = links.select do |node|
|
|
node["href"] =~ /search(?:_dojin)?\.php/
|
|
end
|
|
|
|
search_links.map do |node|
|
|
[node.inner_text, "https://nijie.info" + node.attr("href")]
|
|
end
|
|
end
|
|
|
|
def tag_name
|
|
"nijie" + artist_id.to_s
|
|
end
|
|
|
|
def self.to_dtext(text)
|
|
text = text.to_s.gsub(/\r\n|\r/, "<br>")
|
|
|
|
dtext = DText.from_html(text) do |element|
|
|
if element.name == "a" && element["href"]&.start_with?("/jump.php")
|
|
element["href"] = element.text
|
|
end
|
|
end
|
|
|
|
dtext.strip
|
|
end
|
|
|
|
def illust_id
|
|
parsed_url.work_id || parsed_referer&.work_id
|
|
end
|
|
|
|
def artist_id_from_url
|
|
parsed_url.user_id || parsed_referer&.user_id
|
|
end
|
|
|
|
def artist_id_from_page
|
|
page&.search("a.name")&.first&.attr("href")&.match(/members\.php\?id=(\d+)/) { $1.to_i }
|
|
end
|
|
|
|
def artist_id
|
|
artist_id_from_url || artist_id_from_page
|
|
end
|
|
|
|
def normalize_for_source
|
|
return if illust_id.blank?
|
|
|
|
"https://nijie.info/view.php?id=#{illust_id}"
|
|
end
|
|
|
|
def doujin?
|
|
page&.at("#dojin_left").present?
|
|
end
|
|
|
|
def page
|
|
return nil if page_url.blank? || client.blank?
|
|
|
|
response = client.cache(1.minute).get(page_url)
|
|
|
|
if response.status != 200 || response.parse.search("#login_illust").present?
|
|
clear_cached_session_cookie!
|
|
else
|
|
response.parse
|
|
end
|
|
end
|
|
memoize :page
|
|
|
|
def client
|
|
return nil if cached_session_cookie.nil?
|
|
http.cookies(R18: 1, **cached_session_cookie)
|
|
end
|
|
|
|
def http
|
|
super.timeout(60).use(retriable: { max_retries: 20 })
|
|
end
|
|
|
|
# { "NIJIEIJIEID" => "5ca3f816c0c1f3e647940b08b8ab7a45", "nijie_tok" => <long-base64-string> }
|
|
def cached_session_cookie
|
|
Cache.get("nijie-session-cookie", 60.minutes, skip_nil: true) do
|
|
session_cookie
|
|
end
|
|
end
|
|
|
|
def clear_cached_session_cookie!
|
|
flush_cache # clear memoized session cookie
|
|
Cache.delete("nijie-session-cookie")
|
|
end
|
|
|
|
def session_cookie
|
|
login_page = http.get("https://nijie.info/login.php").parse
|
|
|
|
form = {
|
|
email: Danbooru.config.nijie_login,
|
|
password: Danbooru.config.nijie_password,
|
|
url: login_page.at("input[name='url']")&.fetch("value"),
|
|
save: "on",
|
|
ticket: ""
|
|
}
|
|
|
|
response = http.post("https://nijie.info/login_int.php", form: form)
|
|
|
|
if response.status == 200
|
|
response.cookies.cookies.map { |cookie| [cookie.name, cookie.value] }.to_h
|
|
else
|
|
DanbooruLogger.info "Nijie login failed (#{url}, #{response.status})"
|
|
nil
|
|
end
|
|
end
|
|
|
|
memoize :client, :cached_session_cookie
|
|
end
|
|
end
|
|
end
|