From 993e4fd62f2d2563d1fde32773edc2eafe4a99ae Mon Sep 17 00:00:00 2001 From: evazion Date: Sat, 10 Dec 2022 18:22:24 -0600 Subject: [PATCH] Fix #5366: Baraag broken. * Use fixed access tokens instead of fetching an access token with the OAuth flow. This assumes access tokens won't expire, which seems to be true for the default app-level access token, unless you manually regenerate it. Fixes the OAuth flow not working on Baraag for some reason. * Eliminate the MastodonApiClient class. Just inline it in the extractor instead. Downstream users will need to update their configs to set the `pawoo_access_token` and `baraag_access_token` config options. --- app/logical/mastodon_api_client.rb | 89 ------------------------ app/logical/source/extractor/mastodon.rb | 68 +++++++++++------- config/danbooru_default_config.rb | 12 +--- test/unit/sources/mastodon_test.rb | 13 ++-- 4 files changed, 54 insertions(+), 128 deletions(-) delete mode 100644 app/logical/mastodon_api_client.rb diff --git a/app/logical/mastodon_api_client.rb b/app/logical/mastodon_api_client.rb deleted file mode 100644 index ed26a1da7..000000000 --- a/app/logical/mastodon_api_client.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -# An API client for Mastodon. -# -# @see https://docs.joinmastodon.org/api -class MastodonApiClient - extend Memoist - attr_reader :json, :id - - def initialize(site_name, id) - @site_name = site_name - @id = id - end - - def json - return {} if id.blank? || access_token.blank? - JSON.parse(access_token.get("/api/v1/statuses/#{id}").body) - rescue - {} - 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&.dig("media_attachments").to_a.map {|x| x["url"]} - end - - def tags - json&.dig("tags").to_a.map { |tag| [tag["name"], tag["url"]] } - end - - def commentary - commentary = "".dup - commentary << "

#{json["spoiler_text"]}

" if json["spoiler_text"].present? - commentary << json["content"] if json["content"].present? - 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, :json -end diff --git a/app/logical/source/extractor/mastodon.rb b/app/logical/source/extractor/mastodon.rb index a65ee8cff..02c7a3188 100644 --- a/app/logical/source/extractor/mastodon.rb +++ b/app/logical/source/extractor/mastodon.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true # @see Source::URL::Mastodon +# @see https://docs.joinmastodon.org/api class Source::Extractor class Mastodon < Source::Extractor def match? @@ -18,80 +19,99 @@ class Source::Extractor if parsed_url.image_url? [parsed_url.full_image_url] else - api_response.image_urls + api_response.dig("media_attachments").to_a.pluck("url") end end def page_url - artist_name = artist_name_from_url - status_id = status_id_from_url - return if status_id.blank? - - if artist_name.present? - "https://#{domain}/@#{artist_name}/#{status_id}" - else + if username.present? && status_id.present? + "https://#{domain}/@#{username}/#{status_id}" + elsif status_id.present? "https://#{domain}/web/statuses/#{status_id}" end end def profile_url - if artist_name_from_url.present? - "https://#{domain}/@#{artist_name_from_url}" - elsif api_response.present? && api_response.profile_url.present? - api_response.profile_url + if username.present? + "https://#{domain}/@#{username}" + else + api_response.dig("account", "url") end end def account_url - return if account_id.blank? - "https://#{domain}/web/accounts/#{account_id}" + "https://#{domain}/web/accounts/#{account_id}" if account_id.present? end def profile_urls [profile_url, account_url].compact end - def artist_name - api_response.account_name || artist_name_from_url + def username + api_response.dig("account", "username") || artist_name_from_url + end + + def tag_name + username end def artist_name_from_url parsed_url.username || parsed_referer&.username end - def other_names - [api_response.display_name].compact + def artist_name + api_response.dig("account", "display_name").presence end def account_id - parsed_url.user_id || parsed_referer&.user_id || api_response.account_id + parsed_url.user_id || parsed_referer&.user_id || api_response.dig("account", "id") end - def status_id_from_url + def status_id parsed_url.work_id || parsed_referer&.work_id end def artist_commentary_desc - api_response.commentary + commentary = "".dup + commentary << "

#{api_response["spoiler_text"]}

" if api_response["spoiler_text"].present? + commentary << api_response["content"] if api_response["content"].present? + commentary end def tags - api_response.tags + api_response.dig("tags").to_a.map do |tag| + [tag["name"], tag["url"]] + end end def dtext_artist_commentary_desc DText.from_html(artist_commentary_desc) do |element| if element.name == "a" # don't include links to the toot itself. - media_urls = api_response.json["media_attachments"].map { |attr| attr["text_url"] } + media_urls = api_response.dig("media_attachments").pluck("text_url") element["href"] = nil if element["href"].in?(media_urls) end end.strip end def api_response - MastodonApiClient.new(domain, status_id_from_url) + return {} if status_id.blank? + resp = http.get("https://#{domain}/api/v1/statuses/#{status_id}") + return {} if resp.status != 200 + resp.parse end + + def http + super.headers(Authorization: "Bearer #{access_token}") + end + + def access_token + case site_name + when "Pawoo" then Danbooru.config.pawoo_access_token + when "Baraag" then Danbooru.config.baraag_access_token + end + end + memoize :api_response end end diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index 1c96ff94a..dee074962 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -381,19 +381,11 @@ module Danbooru end # http://tinysubversions.com/notes/mastodon-bot/ - def pawoo_client_id + def pawoo_access_token nil end - def pawoo_client_secret - nil - end - - def baraag_client_id - nil - end - - def baraag_client_secret + def baraag_access_token nil end diff --git a/test/unit/sources/mastodon_test.rb b/test/unit/sources/mastodon_test.rb index cec38a3b8..c963e02d0 100644 --- a/test/unit/sources/mastodon_test.rb +++ b/test/unit/sources/mastodon_test.rb @@ -12,7 +12,8 @@ module Sources "https://pawoo.net/web/statuses/1202176", image_urls: ["https://img.pawoo.net/media_attachments/files/000/128/953/original/4c0a06087b03343f.png"], profile_url: "https://pawoo.net/@9ed00e924818", - artist_name: "9ed00e924818", + tag_name: "9ed00e924818", + artist_name: nil, dtext_artist_commentary_desc: "a mind forever voyaging through strange seas of thought alone" ) end @@ -37,7 +38,8 @@ module Sources https://img.pawoo.net/media_attachments/files/001/298/084/original/media.mp4 ], profile_urls: %w[https://pawoo.net/@evazion https://pawoo.net/web/accounts/47806], - artist_name: "evazion", + tag_name: "evazion", + artist_name: nil, tags: %w[foo bar baz], dtext_artist_commentary_desc: desc ) @@ -57,7 +59,7 @@ module Sources strategy_should_work( "https://pawoo.net/@nonamethankswashere/12345678901234567890", profile_url: "https://pawoo.net/@nonamethankswashere", - artist_name: "nonamethankswashere", + tag_name: "nonamethankswashere", deleted: true ) end @@ -74,7 +76,8 @@ module Sources image_urls: ["https://baraag.net/system/media_attachments/files/105/732/803/241/495/700/original/556e1eb7f5ca610f.png"], download_size: 573_353, profile_url: "https://baraag.net/@bardbot", - artist_name: "bardbot", + tag_name: "bardbot", + artist_name: "SpicyBardo🔞", dtext_artist_commentary_desc: "🍌" ) end @@ -91,7 +94,7 @@ module Sources strategy_should_work( "https://baraag.net/@nonamethankswashere/12345678901234567890", profile_url: "https://baraag.net/@nonamethankswashere", - artist_name: "nonamethankswashere", + tag_name: "nonamethankswashere", deleted: true ) end