From 01b683798eeab2abceaf9a36413376afd1e10007 Mon Sep 17 00:00:00 2001 From: evazion Date: Sat, 19 Mar 2022 00:38:19 -0500 Subject: [PATCH] sources: add Tinami support. --- app/logical/source/url.rb | 1 + app/logical/source/url/tinami.rb | 67 +++++++++++++ app/logical/sources/strategies.rb | 1 + app/logical/sources/strategies/tinami.rb | 74 ++++++++++++++ test/functional/uploads_controller_test.rb | 2 + test/unit/sources/tinami_test.rb | 111 +++++++++++++++++++++ 6 files changed, 256 insertions(+) create mode 100644 app/logical/source/url/tinami.rb create mode 100644 app/logical/sources/strategies/tinami.rb create mode 100644 test/unit/sources/tinami_test.rb diff --git a/app/logical/source/url.rb b/app/logical/source/url.rb index ab3fcad3d..7401d890e 100644 --- a/app/logical/source/url.rb +++ b/app/logical/source/url.rb @@ -41,6 +41,7 @@ module Source Source::URL::PixivSketch, Source::URL::Plurk, Source::URL::Skeb, + Source::URL::Tinami, Source::URL::Tumblr, Source::URL::TwitPic, Source::URL::Weibo, diff --git a/app/logical/source/url/tinami.rb b/app/logical/source/url/tinami.rb new file mode 100644 index 000000000..e76fe4ec8 --- /dev/null +++ b/app/logical/source/url/tinami.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +# Unhandled: +# +# http://www.tinami.com/comic/naomao +# http://www.tinami.com/comic/naomao/1 +# http://www.tinami.com/comic/jaga/052.php +# http://www.tinami.com/gallery/img/29aono.jpg +# http://www.tinami.com/today/artworks/t071127_147092.jpg + +class Source::URL::Tinami < Source::URL + attr_reader :user_id, :profile_id, :work_id + + def self.match?(url) + url.domain.in?(%w[tinami.com tinami.jp]) + end + + def parse + case [host, *path_segments] + + # https://img.tinami.com/illust/img/287/497c8a9dc60e6.jpg + # https://img.tinami.com/illust2/img/419/5013fde3406b9.jpg (page: https://www.tinami.com/view/461459) + # https://img.tinami.com/illust2/L/452/622f7aa336bf3.gif (thumbnail) + # https://img.tinami.com/comic/naomao/naomao_001_01.jpg (page: http://www.tinami.com/comic/naomao/1) + # https://img.tinami.com/comic/naomao/naomao_002_01.jpg (page: http://www.tinami.com/comic/naomao/2) + # https://img.tinami.com/comic/naomao/naomao_topillust.gif + in "img.tinami.com", *rest + # pass + + # http://www.tinami.com/creator/profile/1624 + in _, "creator", "profile", user_id + @user_id = user_id + + # https://www.tinami.com/search/list?prof_id=1624 + in _, "search", "list" if params[:prof_id].present? + @user_id = params[:prof_id] + + # The /profile/:id URL is not the same as the /creator/profile/:id URL + # http://www.tinami.com/profile/1182 (creator: http://www.tinami.com/creator/profile/1624) + # http://www.tinami.jp/p/1182 + in _, ("profile" | "p"), profile_id + @profile_id = profile_id + + # https://www.tinami.com/view/461459 + in _, "view", work_id + @work_id = work_id + + # https://www.tinami.com/view/tweet/card/461459 (sample image) + in _, "view", "tweet", "card", work_id + @work_id = work_id + + else + end + end + + def image_url? + host == "img.tinami.com" + end + + def page_url + "https://www.tinami.com/view/#{work_id}" if work_id.present? + end + + def profile_url + "https://www.tinami.com/creator/profile/#{user_id}" if user_id.present? + end +end diff --git a/app/logical/sources/strategies.rb b/app/logical/sources/strategies.rb index 66376d3e8..1d9baafad 100644 --- a/app/logical/sources/strategies.rb +++ b/app/logical/sources/strategies.rb @@ -22,6 +22,7 @@ module Sources Strategies::Lofter, Strategies::Foundation, Strategies::Plurk, + Strategies::Tinami, Strategies::TwitPic, Strategies::Fantia, ] diff --git a/app/logical/sources/strategies/tinami.rb b/app/logical/sources/strategies/tinami.rb new file mode 100644 index 000000000..685adb2bb --- /dev/null +++ b/app/logical/sources/strategies/tinami.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +# @see Source::URL::Tinami +module Sources + module Strategies + class Tinami < Base + + def match? + Source::URL::Tinami === parsed_url + end + + def image_urls + if parsed_url.image_url? + [url] + else + # Page type 1: http://www.tinami.com/view/1087268 + # Page type 2: http://www.tinami.com/view/1087271 + # Page type 3: http://www.tinami.com/view/1087270 + # Page type 4: http://www.tinami.com/view/1087267 (no images, text only) + page&.css(".viewbody img.captify, .viewbody .nv_body img").to_a.map do |img| + # img[:src] == "//img.tinami.com/illust2/img/619/6234b647da609.jpg" + "https:#{img[:src]}" + end + end + end + + def page_url + parsed_url.page_url || parsed_referer&.page_url + end + + def tags + page&.css("#view .tag a[href^='/search/list']").to_a.map do |tag| + [tag.text, "https://www.tinami.com/search/list?keyword=#{CGI.escape(tag.text)}"] + end + end + + def profile_url + "https://www.tinami.com/creator/profile/#{user_id}" if user_id.present? + end + + def tag_name + nil + end + + def artist_name + page&.at("#view .prof > p > a > strong")&.text + end + + def artist_commentary_title + page&.at("#view .viewdata h1")&.text.to_s.strip + end + + def artist_commentary_desc + page&.at("#view .comment .description")&.text.to_s.strip.delete("\t") + end + + def user_id + url = page&.at("#view .prof > p > a")&.attr("href")&.prepend("https://www.tinami.com") + Source::URL.parse(url)&.user_id + 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 + + memoize :page, :user_id + end + end +end diff --git a/test/functional/uploads_controller_test.rb b/test/functional/uploads_controller_test.rb index 03e4bffea..77bfba5cc 100644 --- a/test/functional/uploads_controller_test.rb +++ b/test/functional/uploads_controller_test.rb @@ -358,6 +358,8 @@ class UploadsControllerTest < ActionDispatch::IntegrationTest should_upload_successfully("https://fantia.jp/products/249638") should_upload_successfully("http://wwwew.web.fc2.com/e/405.jpg") + + should_upload_successfully("http://www.tinami.com/view/1087268") end end end diff --git a/test/unit/sources/tinami_test.rb b/test/unit/sources/tinami_test.rb new file mode 100644 index 000000000..c83a5b702 --- /dev/null +++ b/test/unit/sources/tinami_test.rb @@ -0,0 +1,111 @@ +require "test_helper" + +module Sources + class TinamiTest < ActiveSupport::TestCase + context "Tinami:" do + context "A 'http://www.tinami.com/view/:id' post with one image" do + should "work" do + source = Sources::Strategies.find("http://www.tinami.com/view/1087268") + + assert_equal("みぐめ", source.artist_name) + assert_equal("https://www.tinami.com/view/1087268", source.page_url) + assert_equal(["https://img.tinami.com/illust2/img/647/6234fe5588e97.jpg"], source.image_urls) + assert_equal("https://www.tinami.com/creator/profile/66493", source.profile_url) + assert_equal(%w[横顔 アナログ ボールペン SP], source.tags.map(&:first)) + assert_equal("横顔", source.artist_commentary_title) + assert_equal("横顔", source.artist_commentary_desc) + end + end + + context "A 'http://www.tinami.com/view/:id' post with multiple images (type one)" do + should "work" do + source = Sources::Strategies.find("http://www.tinami.com/view/1087271") + + assert_equal("Shimaken", source.artist_name) + assert_equal("https://www.tinami.com/view/1087271", source.page_url) + assert_equal(%w[ + https://img.tinami.com/illust2/img/458/62351d05dc2d1.jpg + https://img.tinami.com/illust2/img/658/62351d0645c67.jpg + https://img.tinami.com/illust2/img/977/62351d06ab068.jpg + ], source.image_urls) + assert_equal("https://www.tinami.com/creator/profile/27790", source.profile_url) + assert_equal(%w[オリジナル 女の子 創作 漫画 マンガ ひとしずく 学園 体操服 ブルマ バドミントン], source.tags.map(&:first)) + assert_equal("「ひとしずく」15話", source.artist_commentary_title) + assert_equal("学園百合漫画「ひとしずく」の15話目です。", source.artist_commentary_desc) + end + end + + context "A 'http://www.tinami.com/view/:id' post with multiple images (type two)" do + should "work" do + source = Sources::Strategies.find("http://www.tinami.com/view/1087270") + + assert_equal("セラ箱", source.artist_name) + assert_equal("https://www.tinami.com/view/1087270", source.page_url) + assert_equal(%w[ + https://img.tinami.com/illust2/img/934/623503bb9891b.jpg + https://img.tinami.com/illust2/img/398/623503bd481bb.jpg + https://img.tinami.com/illust2/img/698/623503bec2105.jpg + https://img.tinami.com/illust2/img/981/623503c029fbf.jpg + https://img.tinami.com/illust2/img/769/623503c187eab.jpg + https://img.tinami.com/illust2/img/847/623503c2dd8d6.jpg + https://img.tinami.com/illust2/img/252/623503c434204.jpg + ], source.image_urls) + assert_equal("https://www.tinami.com/creator/profile/38168", source.profile_url) + assert_equal(%w[Re:ゼロから始める異世界生活 レム リゼロ セラ箱 rizero フィギュア リペイント], source.tags.map(&:first)) + assert_equal("レムのクリアドレス:リゼロ", source.artist_commentary_title) + assert_equal(<<~EOS.chomp, source.artist_commentary_desc) + リゼロのレムのプライズをクリアドレス仕様にリペイント。透け透けキラキラな感じに改装してみたものです。 + + >https://youtu.be/nkjZkEALg94 + + 製作日記的な動画です( ´∀` ) + + 需要ありましたらご笑覧を + EOS + end + end + + context "A Tinami image URL without a referer" do + should "work" do + source = Sources::Strategies.find("https://img.tinami.com/illust2/img/647/6234fe5588e97.jpg") + + assert_nil(source.artist_name) + assert_nil(source.page_url) + assert_equal(["https://img.tinami.com/illust2/img/647/6234fe5588e97.jpg"], source.image_urls) + assert_nil(source.profile_url) + assert_equal(%w[], source.tags.map(&:first)) + assert_equal("", source.artist_commentary_title) + assert_equal("", source.artist_commentary_desc) + end + end + + context "A Tinami image URL with a referer" do + should "work" do + source = Sources::Strategies.find("https://img.tinami.com/illust2/img/647/6234fe5588e97.jpg", "http://www.tinami.com/view/1087268") + + assert_equal("みぐめ", source.artist_name) + assert_equal("https://www.tinami.com/view/1087268", source.page_url) + assert_equal(["https://img.tinami.com/illust2/img/647/6234fe5588e97.jpg"], source.image_urls) + assert_equal("https://www.tinami.com/creator/profile/66493", source.profile_url) + assert_equal(%w[横顔 アナログ ボールペン SP], source.tags.map(&:first)) + assert_equal("横顔", source.artist_commentary_title) + assert_equal("横顔", source.artist_commentary_desc) + end + end + + context "A deleted Tinami post" do + should "work" do + source = Sources::Strategies.find("http://www.tinami.com/view/774077") + + assert_nil(source.artist_name) + assert_equal("https://www.tinami.com/view/774077", source.page_url) + assert_equal([], source.image_urls) + assert_nil(source.profile_url) + assert_equal(%w[], source.tags.map(&:first)) + assert_equal("", source.artist_commentary_title) + assert_equal("", source.artist_commentary_desc) + end + end + end + end +end