From ce18d419c84380a327bb4e309c6f39ee1eb466b6 Mon Sep 17 00:00:00 2001 From: Daniel Nitsikopoulos Date: Sat, 9 Mar 2024 17:57:58 +1100 Subject: [PATCH] Post inline images when syndicating --- lib/adamantium/syndication/mastodon.rb | 15 +++++++++++++-- slices/main/decorators/posts/decorator.rb | 7 +++++-- slices/micropub/actions/posts/handle.rb | 3 ++- .../unit/commands/posts/syndicate_spec.rb | 6 ++++-- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/lib/adamantium/syndication/mastodon.rb b/lib/adamantium/syndication/mastodon.rb index 0975842..84eb823 100644 --- a/lib/adamantium/syndication/mastodon.rb +++ b/lib/adamantium/syndication/mastodon.rb @@ -1,5 +1,6 @@ require "dry/monads" require "httparty" +require "nokogiri" module Adamantium module Syndication @@ -8,9 +9,12 @@ module Adamantium include Deps[mastodon_client: "clients.mastodon"] def call(post:) - media_ids = post[:photos]&.map do |photo| + inline_images = inline_images(post[:content]).first(4).map { |img| {"value" => img, "alt" => ""} } + images_to_upload = Array(inline_images) + Array(post[:photos]) + + media_ids = images_to_upload.map do |photo| mastodon_client.upload_media(photo: photo) - end&.compact + end.compact response = mastodon_client.create_post(post: post, media_ids: media_ids) @@ -30,6 +34,13 @@ module Adamantium Failure(:failed_to_de_syndicate) end end + + private + + def inline_images(content) + doc = Nokogiri::HTML(content) + doc.search("//img").flat_map { |img| img.attribute_nodes.flat_map(&:value) } + end end end end diff --git a/slices/main/decorators/posts/decorator.rb b/slices/main/decorators/posts/decorator.rb index 27f0752..072a571 100644 --- a/slices/main/decorators/posts/decorator.rb +++ b/slices/main/decorators/posts/decorator.rb @@ -44,9 +44,12 @@ module Main return photos.first["url"] end + inline_images.first[1] if inline_images + end + + def inline_images doc = Nokogiri::HTML(content) - images = doc.at("//img") - images.first[1] if images + doc.at("//img") end def prefix_emoji diff --git a/slices/micropub/actions/posts/handle.rb b/slices/micropub/actions/posts/handle.rb index b3035ab..23961e1 100644 --- a/slices/micropub/actions/posts/handle.rb +++ b/slices/micropub/actions/posts/handle.rb @@ -36,7 +36,8 @@ module Micropub if req_entity && verify_scope(req: req, scope: :create) Dry::Matcher::ResultMatcher.call(create_entry.call(req_entity: req_entity)) do |m| m.success do |post| - res.headers["Location"] = "#{settings.micropub_site_url}/#{post.value!.post_type}/#{post.value!.slug}" + post_type = (post.value!.post_type == :bookmark) ? :bookmark : :post + res.headers["Location"] = "#{settings.micropub_site_url}/#{post_type}/#{post.value!.slug}" res.status = 201 end diff --git a/spec/adamantium/unit/commands/posts/syndicate_spec.rb b/spec/adamantium/unit/commands/posts/syndicate_spec.rb index c73fba6..4ec5fae 100644 --- a/spec/adamantium/unit/commands/posts/syndicate_spec.rb +++ b/spec/adamantium/unit/commands/posts/syndicate_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Micropub::Commands::Posts::Syndicate do let(:settings) { double("settings", mastodon_server: "https://mastodon.example/@tester", blue_sky_url: "https://bluesky.app") } let(:mastodon_client) { double("Adamantium::Client::Mastodon") } let(:mastodon_syndicator) { Adamantium::Syndication::Mastodon.new(mastodon_client: mastodon_client) } - let(:post) { {url: "example.com", syndicate_to: ["https://mastodon.example", "https://bsky.app"], category: []} } + let(:post) { {url: "example.com", content: "

Some cool post

", syndicate_to: ["https://mastodon.example", "https://bsky.app"], category: []} } let(:add_post_syndication_source) { spy(Micropub::Commands::Posts::AddSyndicationSource) } subject { @@ -17,7 +17,9 @@ RSpec.describe Micropub::Commands::Posts::Syndicate do } before do - allow(mastodon_client).to receive(:create_post).with(post: post, media_ids: nil).and_return(Success("http://mastodon.example/post/123")) + allow(mastodon_client).to receive(:upload_media).with(photo: {"alt" => "", "value" => "https://picsum.photos/100"}).and_return("123") + allow(mastodon_client).to receive(:upload_media).with(photo: {"alt" => "", "value" => "https://picsum.photos/200"}).and_return("456") + allow(mastodon_client).to receive(:create_post).with(post: post, media_ids: ["456", "123"]).and_return(Success("http://mastodon.example/post/123")) end it "syndicates a post to Mastodon" do