Add furaffinity support

This commit is contained in:
nonamethanks
2022-04-27 03:42:10 +02:00
parent 47b4e6df2f
commit 8edd5dd810
8 changed files with 179 additions and 1 deletions

View File

@@ -56,6 +56,8 @@ jobs:
DANBOORU_BARAAG_CLIENT_ID: ${{ secrets.DANBOORU_BARAAG_CLIENT_ID }}
DANBOORU_BARAAG_CLIENT_SECRET: ${{ secrets.DANBOORU_BARAAG_CLIENT_SECRET }}
DANBOORU_FANTIA_SESSION_ID: ${{ secrets.DANBOORU_FANTIA_SESSION_ID }}
DANBOORU_FURAFFINITY_COOKIE_A: ${{ secrets.DANBOORU_FURAFFINITY_COOKIE_A }}
DANBOORU_FURAFFINITY_COOKIE_B: ${{ secrets.DANBOORU_FURAFFINITY_COOKIE_B }}
DANBOORU_TINAMI_SESSION_ID: ${{ secrets.DANBOORU_TINAMI_SESSION_ID }}
DANBOORU_DISCORD_WEBHOOK_ID: ${{ secrets.DANBOORU_DISCORD_WEBHOOK_ID }}
DANBOORU_DISCORD_WEBHOOK_SECRET: ${{ secrets.DANBOORU_DISCORD_WEBHOOK_SECRET }}

View File

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

View File

@@ -0,0 +1,73 @@
# frozen_string_literal: true
class Source::Extractor
class Furaffinity < Source::Extractor
def self.enabled?
# https://www.furaffinity.net/controls/settings/
# For this strategy to work properly, in the above settings "Enable Adult Artwork" must be set to "General, Mature, Adult".
Danbooru.config.furaffinity_cookie_a.present? && Danbooru.config.furaffinity_cookie_b.present?
end
def match?
Source::URL::Furaffinity === parsed_url
end
def image_urls
if parsed_url.image_url?
[parsed_url.to_s]
else
download_button = html_response&.css(".submission-content .auto_link .button").to_a.find { |el| el.text == "Download" }
partial_image = download_button&.[]("href")
return [] unless partial_image.present?
[URI.join("https://d.furaffinity.net", partial_image).to_s].compact
end
end
def page_url
parsed_url.page_url || parsed_referer&.page_url
end
def tags
tags = html_response&.css(".tags").to_a.map!(&:text).compact.uniq
tags.map {|tag| [tag, "https://www.furaffinity.net/search/@keywords #{tag}"] }
end
def artist_name
html_response&.at(".submission-id-sub-container a")&.text || parsed_url.username || parsed_referer&.username
end
def profile_url
parsed_url.profile_url || parsed_referer&.profile_url || profile_url_from_page
end
def profile_url_from_page
slug = html_response&.at(".submission-id-avatar a")&.[](:href)
return unless slug.present?
Source::URL.parse(URI.join("https://www.furaffinity.net/", slug)).profile_url
end
def artist_commentary_title
html_response&.at(".submission-title")&.text&.strip
end
def artist_commentary_desc
html_response&.at(".submission-content .section-body")&.to_html
end
def dtext_artist_commentary_desc
DText.from_html(artist_commentary_desc)&.strip
end
def html_response
return nil unless page_url.present?
response = http.cache(1.minute).get(page_url)
return nil unless response.status == 200
response.parse
end
def http
Danbooru::Http.new.cookies(a: Danbooru.config.furaffinity_cookie_a, b: Danbooru.config.furaffinity_cookie_b, sfw: 0)
end
end
end

View File

@@ -49,6 +49,7 @@ module Source
Source::URL::TwitPic,
Source::URL::Weibo,
Source::URL::Anifty,
Source::URL::Furaffinity,
]
# 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,45 @@
# frozen_string_literal: true
class Source::URL::Furaffinity < Source::URL
attr_reader :work_id, :username, :filename
def self.match?(url)
url.domain == "furaffinity.net"
end
def parse
case [host, *path_segments]
# https://www.furaffinity.net/view/46821705/
# https://www.furaffinity.net/view/46802202/ (scrap)
in _, "view", /^\d+$/ => work_id
@work_id = work_id
# https://d.furaffinity.net/art/iwbitu/1650222955/1650222955.iwbitu_yubi.jpg
in _, "art", username, subdir, filename
@username = username
@filename = filename
# https://www.furaffinity.net/gallery/iwbitu
# https://www.furaffinity.net/scraps/iwbitu/2/?
# https://www.furaffinity.net/gallery/iwbitu/folder/133763/Regular-commissions
in _, ("gallery" | "user" | "favorites" | "scraps" | "journals"), username, *pages
@username = username
else
nil
end
end
def image_url?
@filename.present?
end
def page_url
"https://www.furaffinity.net/view/#{work_id}" if work_id.present?
end
def profile_url
"https://www.furaffinity.net/user/#{username}" if username.present?
end
end

View File

@@ -95,7 +95,7 @@ class ArtistURL < ApplicationRecord
def priority
sites = %w[
Pixiv Twitter
Anifty ArtStation Baraag BCY Booth Deviant\ Art Hentai\ Foundry Fantia Foundation Lofter Nico\ Seiga Nijie Pawoo Fanbox Pixiv\ Sketch Plurk Tinami Tumblr Weibo
Anifty ArtStation Baraag BCY Booth Deviant\ Art Hentai\ Foundry Fantia Furaffinity Foundation Lofter Nico\ Seiga Nijie Pawoo Fanbox Pixiv\ Sketch Plurk Tinami Tumblr Weibo
Ask.fm Facebook FC2 Gumroad Instagram Ko-fi Livedoor Mihuashi Mixi.jp Patreon Piapro.jp Picarto Privatter Sakura.ne.jp Stickam Skeb Twitch Youtube
Amazon Circle.ms DLSite Doujinshi.org Erogamescape Mangaupdates Melonbooks Toranoana Wikipedia
]

View File

@@ -333,6 +333,17 @@ module Danbooru
def fantia_session_id
end
# Your Furaffinity "a" cookie. Login to Furaffinity then use the
# devtools to find the "a" cookie.
# !!WARNING!! logging out of furaffinity will expire this cookie too!
def furaffinity_cookie_a
end
# Your Furaffinity "b" cookie. Login to Furaffinity then use the
# devtools to find the "b" cookie.
def furaffinity_cookie_b
end
# A list of tags that should be removed when a post is replaced. Regexes allowed.
def post_replacement_tag_removals
%w[replaceme .*_sample resized upscaled downscaled md5_mismatch

View File

@@ -0,0 +1,45 @@
require "test_helper"
module Sources
class FuraffinityTest < ActiveSupport::TestCase
context "A furaffinity post" do
strategy_should_work(
"https://www.furaffinity.net/view/46821705/",
image_urls: ["https://d.furaffinity.net/art/iwbitu/1650222955/1650222955.iwbitu_yubi.jpg"],
profile_url: "https://www.furaffinity.net/user/iwbitu",
page_url: "https://www.furaffinity.net/view/46821705",
artist_name: "iwbitu",
artist_commentary_title: "Yubi",
artist_commentary_desc: /little gift doodle for/
)
end
context "A furaffinity image" do
strategy_should_work(
"https://d.furaffinity.net/art/iwbitu/1650222955/1650222955.iwbitu_yubi.jpg",
image_urls: ["https://d.furaffinity.net/art/iwbitu/1650222955/1650222955.iwbitu_yubi.jpg"],
profile_url: "https://www.furaffinity.net/user/iwbitu",
artist_name: "iwbitu",
page_url: nil,
artist_commentary_title: nil
)
end
context "An adult age-restricted furaffinity post" do
strategy_should_work(
"https://www.furaffinity.net/view/46590097/",
image_urls: ["https://d.furaffinity.net/art/iwbitu/1648803766/1648803766.iwbitu_nyopu_tori.jpg"],
profile_url: "https://www.furaffinity.net/user/iwbitu",
page_url: "https://www.furaffinity.net/view/46590097",
artist_name: "iwbitu",
tags: [],
artist_commentary_title: "Nyopu and Tori",
artist_commentary_desc: /UwU/
)
end
context "A deleted or non-existing furaffinity post" do
strategy_should_work("https://www.furaffinity.net/view/3404111", deleted: true, profile_url: nil)
end
end
end