From 043f2fb124bf8994addca18be22f8849c9faf377 Mon Sep 17 00:00:00 2001 From: nonamethanks Date: Mon, 1 Nov 2021 01:37:45 +0100 Subject: [PATCH] Add Foundation support --- app/helpers/icon_helper.rb | 2 + app/logical/artist_finder.rb | 1 + app/logical/sources/strategies.rb | 3 +- app/logical/sources/strategies/foundation.rb | 96 +++++++++++++++++++ app/models/artist_url.rb | 2 +- public/images/foundation-logo.png | Bin 0 -> 470 bytes test/unit/sources/foundation_test.rb | 46 +++++++++ 7 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 app/logical/sources/strategies/foundation.rb create mode 100644 public/images/foundation-logo.png create mode 100644 test/unit/sources/foundation_test.rb diff --git a/app/helpers/icon_helper.rb b/app/helpers/icon_helper.rb index 4b13dea8c..f0af4bb7e 100644 --- a/app/helpers/icon_helper.rb +++ b/app/helpers/icon_helper.rb @@ -202,6 +202,8 @@ module IconHelper image_icon_tag("fantia-logo.png", **options) when "FC2" image_icon_tag("fc2-logo.png", **options) + when "Foundation" + image_icon_tag("foundation-logo.png", **options) when "Gumroad" image_icon_tag("gumroad-logo.png", **options) when "Hentai Foundry" diff --git a/app/logical/artist_finder.rb b/app/logical/artist_finder.rb index b0d423d3a..bfcf6da71 100644 --- a/app/logical/artist_finder.rb +++ b/app/logical/artist_finder.rb @@ -47,6 +47,7 @@ module ArtistFinder "fav.me", # http://fav.me/d9y1njg /blog-imgs-\d+(?:-origin)?\.fc2\.com/i, %r{blog\.fc2\.com(/\w)+/?}i, # http://blog71.fc2.com/a/abk00/file/20080220194219.jpg + "foundation.app", "furaffinity.net", "furaffinity.net/user", # http://www.furaffinity.net/user/achthenuts "gelbooru.com", # http://gelbooru.com/index.php?page=account&s=profile&uname=junou diff --git a/app/logical/sources/strategies.rb b/app/logical/sources/strategies.rb index cd1805c49..b0f5dea41 100644 --- a/app/logical/sources/strategies.rb +++ b/app/logical/sources/strategies.rb @@ -17,7 +17,8 @@ module Sources Strategies::Weibo, Strategies::Newgrounds, Strategies::Skeb, - Strategies::Lofter + Strategies::Lofter, + Strategies::Foundation, ] end diff --git a/app/logical/sources/strategies/foundation.rb b/app/logical/sources/strategies/foundation.rb new file mode 100644 index 000000000..738abbd52 --- /dev/null +++ b/app/logical/sources/strategies/foundation.rb @@ -0,0 +1,96 @@ +# Image URLs +# * https://f8n-ipfs-production.imgix.net/QmX4MotNAAj9Rcyew43KdgGDxU1QtXemMHoUTNacMLLSjQ/nft.png +# +# Page URLs +# +# * https://foundation.app/@mochiiimo/~/97376 +# +# Profile URLs +# +# * https://foundation.app/@mochiiimo + +module Sources + module Strategies + class Foundation < Base + BASE_URL = %r{\Ahttps?://(www\.)?foundation\.app}i + PROFILE_URL = %r{#{BASE_URL}/@(?\w+)}i + PAGE_URL = %r{#{PROFILE_URL}/~/(?\d+)}i + + IMAGE_HOST = /f8n-ipfs-production\.imgix\.net/ + IMAGE_URL = %r{\Ahttps?://#{IMAGE_HOST}/\w+/nft.\w+}i + + def domains + ["foundation.app"] + end + + def match? + return false if parsed_url.nil? + parsed_url.domain.in?(domains) || parsed_url.host =~ IMAGE_HOST + end + + def site_name + "Foundation" + end + + def image_urls + return [url.gsub(/\?.*/, "")] if url =~ IMAGE_URL + page&.search("meta[property='og:image']").map do |img| + img["content"].gsub(/\?.*/, "") + end + end + + def preview_urls + image_urls.map { |img| "#{img}?fit=fill&max-h=600" } + end + + def page_url + urls.select { |url| url[PAGE_URL]}.compact.first + end + + def page + return nil if page_url.blank? + + response = http.cache(1.minute).get(page_url) + return nil unless response.status == 200 + + response.parse + end + + def tags + tags = page&.search("a[href^='/tags/']").to_a + + tags.map do |tag| + [tag.text, URI.join(page_url, tag.attr("href")).to_s] + end + end + + def artist_name + urls.map { |u| u[PROFILE_URL, :artist_name] }.compact.first + end + + def profile_url + return nil if artist_name.blank? + "https://foundation.app/@#{artist_name}" + end + + def artist_commentary_title + return nil if page.blank? + page.at("meta[property='og:title']")["content"].gsub(/ \| Foundation$/, "") + end + + def artist_commentary_desc + header = page&.xpath("//div[text()='Description']")&.first + return nil if header.blank? + header&.parent&.search("div").to_a.fetch(1, nil)&.to_html + end + + def dtext_artist_commentary_desc + DText.from_html(artist_commentary_desc) + end + + def normalize_for_source + page_url + end + end + end +end diff --git a/app/models/artist_url.rb b/app/models/artist_url.rb index f4a0358e2..ed884b47f 100644 --- a/app/models/artist_url.rb +++ b/app/models/artist_url.rb @@ -108,7 +108,7 @@ class ArtistUrl < ApplicationRecord def priority sites = %w[ Pixiv Twitter - ArtStation BCY Deviant\ Art Hentai\ Foundry Nico\ Seiga Nijie pawoo.net Pixiv\ Fanbox Pixiv\ Sketch Tinami Tumblr + ArtStation BCY Deviant\ Art Hentai\ Foundry Foundation Nico\ Seiga Nijie pawoo.net Pixiv\ Fanbox Pixiv\ Sketch Tinami Tumblr Ask.fm Booth.pm Facebook Fantia FC2 Gumroad Instagram Ko-fi Livedoor Lofter Mihuashi Mixi.jp Patreon Piapro.jp Picarto Privatter Sakura.ne.jp Stickam Skeb Twitch Weibo Youtube Amazon Circle.ms DLSite Doujinshi.org Erogamescape Mangaupdates Melonbooks Toranoana Wikipedia ] diff --git a/public/images/foundation-logo.png b/public/images/foundation-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..660fc263a3a84c5d3db9e2e796a1aaa688e3801f GIT binary patch literal 470 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4h9AWhA=@@4F(1VmUKs7M+SzC{oH>NSwWJ? z9znhg3{`3j3=J&|48Ir{7#dzMFq9fFFuY1&V6d9Oz#v{QXIG#N0|Nt7lDE4H!~gdF zGy54B7}!fZeO=j~ax*fBTea=eKFGkpaL?1lF~s6@a)JbF2~*FCn6Q2O=l?S_Ff=wW zFfjP@`}BbW2biV`mfZc++jvpS`TO;QncstL{}~z>7|eh3v-g73|3kAI4}Sdj|NsC0 z?}KALfaw4K-#>IYaeB_b{oWIbxm_0VMKTJzI4&}5cJ7#>*OJ`2MEDh3bBY_=wKwkn zH(Jc;Y;0_7v~{1?*ywovwUo=7AN(b(c?)@XczAjg)#X6Wkcm3ekj6Us&cFR2QJ?b1 zn@j3sXBB;)@*$p$jqTaw`h;&A9diHvZ}nF$TQewQy;T$sYh@Orz?_ooKW z`4|`&R7+eVN>UO_QmvAUQWHy38H@~!40R0+bqx$d3=FJ{jIE4}wG9lc3=EE+H=mE9 cAvZrIGp!Q0hHaDjl|d2a>FVdQ&MBb@06>ba(f|Me literal 0 HcmV?d00001 diff --git a/test/unit/sources/foundation_test.rb b/test/unit/sources/foundation_test.rb new file mode 100644 index 000000000..a126322b1 --- /dev/null +++ b/test/unit/sources/foundation_test.rb @@ -0,0 +1,46 @@ +require "test_helper" + +module Sources + class FoundationTest < ActiveSupport::TestCase + context "The source for a Foundation picture" do + setup do + @post_url = "https://foundation.app/@dadachyo/~/103724" + @image_url = "https://f8n-ipfs-production.imgix.net/QmPhpz6E9TFRpvdVTviM8Hy9o9rxrnPW5Ywj471NnSNkpi/nft.jpg" + @image1 = Sources::Strategies.find(@post_url) + @image2 = Sources::Strategies.find(@image_url) + end + + should "get the artist name" do + assert_equal("dadachyo", @image1.artist_name) + end + + should "get the artist commentary title" do + assert_equal("Rose tea", @image1.artist_commentary_title) + end + + should "get profile url" do + assert_equal("https://foundation.app/@dadachyo", @image1.profile_url) + end + + should "get the image url" do + assert_equal(@image_url, @image1.image_url) + assert_equal(@image_url, @image2.image_url) + end + + should "download an image" do + assert_downloaded(13_908_349, @image1.image_url) + assert_downloaded(13_908_349, @image2.image_url) + end + + should "find the correct artist" do + @artist = FactoryBot.create(:artist, name: "dadachyo", url_string: @image1.profile_url) + assert_equal([@artist], @image1.artists) + end + + should "not raise errors" do + assert_nothing_raised { @image1.to_h } + assert_nothing_raised { @image2.to_h } + end + end + end +end