diff --git a/app/logical/mastodon_api_client.rb b/app/logical/mastodon_api_client.rb
new file mode 100644
index 000000000..0b837d669
--- /dev/null
+++ b/app/logical/mastodon_api_client.rb
@@ -0,0 +1,84 @@
+class MastodonApiClient
+ extend Memoist
+ attr_reader :json
+
+ def initialize(site_name, id)
+ @site_name = site_name
+
+ return if access_token.blank?
+
+ begin
+ @json = JSON.parse(access_token.get("/api/v1/statuses/#{id}").body)
+ rescue StandardError
+ @json = {}
+ end
+ end
+
+ def profile_url
+ json.dig("account", "url")
+ end
+
+ def account_name
+ json.dig("account", "username")
+ end
+
+ def display_name
+ json.dig("account", "display_name")
+ end
+
+ def account_id
+ json.dig("account", "id")
+ end
+
+ def image_url
+ image_urls.first
+ end
+
+ def image_urls
+ json["media_attachments"].to_a.map {|x| x["url"]}
+ end
+
+ def tags
+ json["tags"].to_a.map { |tag| [tag["name"], tag["url"]] }
+ end
+
+ def commentary
+ commentary = ""
+ commentary << "
#{json["spoiler_text"]}
" if json["spoiler_text"].present?
+ commentary << json["content"]
+ commentary
+ end
+
+ def to_h
+ json
+ end
+
+ def fetch_access_token
+ Cache.get("#{@site_name}-token") do
+ result = client.client_credentials.get_token
+ result.token
+ end
+ end
+
+ def access_token
+ return if client.blank?
+ OAuth2::AccessToken.new(client, fetch_access_token)
+ end
+
+ def client
+ case @site_name
+ when "pawoo.net"
+ client_id = Danbooru.config.pawoo_client_id
+ client_secret = Danbooru.config.pawoo_client_secret
+ when "baraag.net"
+ client_id = Danbooru.config.baraag_client_id
+ client_secret = Danbooru.config.baraag_client_secret
+ end
+
+ return unless client_id && client_secret
+
+ OAuth2::Client.new(client_id, client_secret, :site => "https://#{@site_name}")
+ end
+
+ memoize :client
+end
diff --git a/app/logical/pawoo_api_client.rb b/app/logical/pawoo_api_client.rb
deleted file mode 100644
index f74d42e38..000000000
--- a/app/logical/pawoo_api_client.rb
+++ /dev/null
@@ -1,156 +0,0 @@
-class PawooApiClient
- extend Memoist
-
- PROFILE1 = %r!\Ahttps?://pawoo\.net/web/accounts/(\d+)!
- PROFILE2 = %r!\Ahttps?://pawoo\.net/@([^/]+)!
- STATUS1 = %r!\Ahttps?://pawoo\.net/web/statuses/(\d+)!
- STATUS2 = %r!\Ahttps?://pawoo\.net/@.+?/([^/]+)!
-
- class MissingConfigurationError < StandardError; end
-
- class Account
- attr_reader :json
-
- def self.is_match?(url)
- if url =~ PROFILE1
- return $1
- end
-
- if url =~ PROFILE2
- return $1
- end
-
- false
- end
-
- def initialize(json)
- @json = json
- end
-
- def profile_url
- json["url"]
- end
-
- def account_name
- json["username"]
- end
-
- def image_url
- nil
- end
-
- def image_urls
- []
- end
-
- def tags
- []
- end
-
- def commentary
- nil
- end
-
- def to_h
- json
- end
- end
-
- class Status
- attr_reader :json
-
- def self.is_match?(url)
- if url =~ STATUS1
- return $1
- end
-
- if url =~ STATUS2
- return $1
- end
-
- false
- end
-
- def initialize(json)
- @json = json
- end
-
- def profile_url
- json["account"]["url"]
- end
-
- def account_name
- json["account"]["username"]
- end
-
- def image_url
- image_urls.first
- end
-
- def image_urls
- json["media_attachments"].map {|x| x["url"]}
- end
-
- def tags
- json["tags"].map { |tag| [tag["name"], tag["url"]] }
- end
-
- def commentary
- commentary = ""
- commentary << "#{json["spoiler_text"]}
" if json["spoiler_text"].present?
- commentary << json["content"]
- commentary
- end
-
- def to_h
- json
- end
- end
-
- def get(url)
- if id = Status.is_match?(url)
- begin
- data = JSON.parse(access_token.get("/api/v1/statuses/#{id}").body)
- rescue
- data = {
- "account" => {},
- "media_attachments" => [],
- "tags" => [],
- "content" => "",
- }
- end
- return Status.new(data)
- end
-
- if id = Account.is_match?(url)
- begin
- data = JSON.parse(access_token.get("/api/v1/accounts/#{id}").body)
- rescue
- data = {}
- end
- Account.new(data)
- end
- end
-
- private
-
- def fetch_access_token
- raise MissingConfigurationError, "missing pawoo client id" if Danbooru.config.pawoo_client_id.nil?
- raise MissingConfigurationError, "missing pawoo client secret" if Danbooru.config.pawoo_client_secret.nil?
-
- Cache.get("pawoo-token") do
- result = client.client_credentials.get_token
- result.token
- end
- end
-
- def access_token
- OAuth2::AccessToken.new(client, fetch_access_token)
- end
-
- def client
- OAuth2::Client.new(Danbooru.config.pawoo_client_id, Danbooru.config.pawoo_client_secret, :site => "https://pawoo.net")
- end
-
- memoize :client
-end
diff --git a/app/logical/sources/strategies.rb b/app/logical/sources/strategies.rb
index fddc1fdd3..895a9a6bd 100644
--- a/app/logical/sources/strategies.rb
+++ b/app/logical/sources/strategies.rb
@@ -11,7 +11,7 @@ module Sources
Strategies::Tumblr,
Strategies::ArtStation,
Strategies::Nijie,
- Strategies::Pawoo,
+ Strategies::Mastodon,
Strategies::Moebooru,
Strategies::HentaiFoundry,
Strategies::Weibo,
diff --git a/app/logical/sources/strategies/pawoo.rb b/app/logical/sources/strategies/mastodon.rb
similarity index 60%
rename from app/logical/sources/strategies/pawoo.rb
rename to app/logical/sources/strategies/mastodon.rb
index f170eb100..3fef4810e 100644
--- a/app/logical/sources/strategies/pawoo.rb
+++ b/app/logical/sources/strategies/mastodon.rb
@@ -15,25 +15,28 @@
# * https://pawoo.net/oauth_authentications/17230064
module Sources::Strategies
- class Pawoo < Base
- HOST = %r{\Ahttps?://(www\.)?pawoo\.net}i
- IMAGE = %r{\Ahttps?://img\.pawoo\.net/media_attachments/files/(\d+/\d+/\d+)}
+ class Mastodon < Base
+ HOST = %r{\Ahttps?://(?:www\.)?(?pawoo\.net|baraag\.net)}i
+ IMAGE = %r{\Ahttps?://(?:img\.pawoo\.net|baraag\.net)/media_attachments/files/(\d+/\d+/\d+)}
NAMED_PROFILE = %r{#{HOST}/@(?\w+)}i
- ID_PROFILE = %r{#{HOST}/web/accounts/(?\d+)}
+ ID_PROFILE = %r{#{HOST}/web/accounts/(?\d+)}
STATUS1 = %r{\A#{HOST}/web/statuses/(?\d+)}
STATUS2 = %r{\A#{NAMED_PROFILE}/(?\d+)}
- def self.enabled?
- Danbooru.config.pawoo_client_id.present? && Danbooru.config.pawoo_client_secret.present?
- end
-
def domains
- ["pawoo.net"]
+ ["pawoo.net", "baraag.net"]
end
def site_name
- "Pawoo"
+ parsed_url.domain
+ end
+
+ def file_host
+ case site_name
+ when "pawoo.net" then "img.pawoo.net"
+ else site_name
+ end
end
def image_url
@@ -41,49 +44,56 @@ module Sources::Strategies
end
def image_urls
- if url =~ %r{#{IMAGE}/small/([a-z0-9]+\.\w+)\z}i
- ["https://img.pawoo.net/media_attachments/files/#{$1}/original/#{$2}"]
- elsif url =~ %r{#{IMAGE}/original/([a-z0-9]+\.\w+)\z}i
- [url]
+ if url =~ %r{#{IMAGE}/(?:small|original)/([a-z0-9]+\.\w+)\z}i
+ ["https://#{file_host}/media_attachments/files/#{$1}/original/#{$2}"]
else
api_response.image_urls
end
end
def page_url
- [url, referer_url].each do |x|
- if PawooApiClient::Status.is_match?(x)
- return x
- end
- end
+ artist_name = artist_name_from_url
+ status_id = status_id_from_url
+ return if status_id.blank?
- super
+ if artist_name.present?
+ "https://#{site_name}/@#{artist_name}/#{status_id}"
+ else
+ "https://#{site_name}/web/statuses/#{status_id}"
+ end
end
def profile_url
- if url =~ PawooApiClient::PROFILE2
- "https://pawoo.net/@#{$1}"
- elsif api_response.profile_url.blank?
- url
- else
+ if artist_name_from_url.present?
+ "https://#{site_name}/@#{artist_name_from_url}"
+ elsif api_response.present? && api_response.profile_url.present?
api_response.profile_url
end
end
+ def account_url
+ return if account_id.blank?
+ "https://#{site_name}/web/accounts/#{account_id}"
+ end
+
+ def profile_urls
+ [profile_url, account_url].compact
+ end
+
def artist_name
api_response.account_name
end
def artist_name_from_url
- if url =~ NAMED_PROFILE
- url[NAMED_PROFILE, :artist_name]
- end
+ url[NAMED_PROFILE, :artist_name]
end
- def artist_id_from_url
- if url =~ ID_PROFILE
- url[ID_PROFILE, :artist_name]
- end
+ def other_names
+ [api_response.display_name]
+ end
+
+ def account_id
+ url[ID_PROFILE, :account_id] || api_response.account_id
end
def status_id_from_url
@@ -99,15 +109,7 @@ module Sources::Strategies
end
def normalize_for_source
- artist_name = artist_name_from_url
- status_id = status_id_from_url
- return if status_id.blank?
-
- if artist_name.present?
- "https://pawoo.net/@#{artist_name}/#{status_id}"
- else
- "https://pawoo.net/web/statuses/#{status_id}"
- end
+ page_url
end
def dtext_artist_commentary_desc
@@ -121,13 +123,8 @@ module Sources::Strategies
end
def api_response
- [url, referer_url].each do |x|
- if (client = PawooApiClient.new.get(x))
- return client
- end
- end
-
- nil
+ return {} if status_id_from_url.blank?
+ MastodonApiClient.new(site_name, status_id_from_url)
end
memoize :api_response
end
diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb
index 98a4d1710..291d79974 100644
--- a/config/danbooru_default_config.rb
+++ b/config/danbooru_default_config.rb
@@ -330,6 +330,14 @@ module Danbooru
nil
end
+ def baraag_client_id
+ nil
+ end
+
+ def baraag_client_secret
+ nil
+ end
+
# 1. Register app at https://www.tumblr.com/oauth/register.
# 2. Copy "OAuth Consumer Key" from https://www.tumblr.com/oauth/apps.
def tumblr_consumer_key
diff --git a/test/unit/sources/pawoo_test.rb b/test/unit/sources/mastodon_test.rb
similarity index 77%
rename from test/unit/sources/pawoo_test.rb
rename to test/unit/sources/mastodon_test.rb
index a20485085..59d31d0f7 100644
--- a/test/unit/sources/pawoo_test.rb
+++ b/test/unit/sources/mastodon_test.rb
@@ -1,7 +1,7 @@
require 'test_helper'
module Sources
- class PawooTest < ActiveSupport::TestCase
+ class MastodonTest < ActiveSupport::TestCase
context "The source site for a https://pawoo.net/web/status/$id url" do
setup do
skip "Pawoo keys not set" unless Danbooru.config.pawoo_client_id
@@ -38,7 +38,9 @@ module Sources
end
should "get the profile" do
- assert_equal("https://pawoo.net/@evazion", @site.profile_url)
+ profiles = %w[https://pawoo.net/@evazion https://pawoo.net/web/accounts/47806]
+ assert_equal(profiles.first, @site.profile_url)
+ assert_equal(profiles, @site.profile_urls)
end
should "get the artist name" do
@@ -68,7 +70,7 @@ module Sources
end
should "get the dtext-ified commentary" do
- desc = <<-EOS.strip_heredoc.chomp
+ desc = <<-DESC.strip_heredoc.chomp
test post please ignore
blah blah blah
@@ -76,7 +78,7 @@ module Sources
this is a test 🍕
"#foo":[https://pawoo.net/tags/foo] "#bar":[https://pawoo.net/tags/bar] "#baz":[https://pawoo.net/tags/baz]
- EOS
+ DESC
assert_equal(desc, @site.dtext_artist_commentary_desc)
end
@@ -95,21 +97,40 @@ module Sources
end
end
+ context "A baraag url" do
+ setup do
+ skip "Baraag keys not set" unless Danbooru.config.baraag_client_id
+ @url = "https://baraag.net/@bardbot/105732813175612920"
+ @site = Sources::Strategies.find(@url)
+ end
+
+ should "work" do
+ assert_equal("https://baraag.net/@bardbot", @site.profile_url)
+ assert_equal(["https://baraag.net/system/media_attachments/files/105/732/803/241/495/700/original/556e1eb7f5ca610f.png"], @site.image_urls)
+ assert_equal("bardbot", @site.artist_name)
+ assert_equal("🍌", @site.dtext_artist_commentary_desc)
+ end
+ end
+
context "normalizing for source" do
should "normalize correctly" do
source1 = "https://pawoo.net/@evazion/19451018/"
source2 = "https://pawoo.net/web/statuses/19451018/favorites"
+ source3 = "https://baraag.net/@bardbot/105732813175612920/"
assert_equal("https://pawoo.net/@evazion/19451018", Sources::Strategies.normalize_source(source1))
assert_equal("https://pawoo.net/web/statuses/19451018", Sources::Strategies.normalize_source(source2))
+ assert_equal("https://baraag.net/@bardbot/105732813175612920", Sources::Strategies.normalize_source(source3))
end
should "avoid normalizing unnormalizable urls" do
bad_source1 = "https://img.pawoo.net/media_attachments/files/001/297/997/original/c4272a09570757c2.png"
bad_source2 = "https://pawoo.net/@evazion/media"
+ bad_source3 = "https://baraag.net/system/media_attachments/files/105/732/803/241/495/700/original/556e1eb7f5ca610f.png"
assert_equal(bad_source1, Sources::Strategies.normalize_source(bad_source1))
assert_equal(bad_source2, Sources::Strategies.normalize_source(bad_source2))
+ assert_equal(bad_source3, Sources::Strategies.normalize_source(bad_source3))
end
end
end