Post inline images when syndicating

This commit is contained in:
2024-03-09 17:57:58 +11:00
parent 160cd3dd31
commit ce18d419c8
4 changed files with 24 additions and 7 deletions

View File

@@ -1,5 +1,6 @@
require "dry/monads" require "dry/monads"
require "httparty" require "httparty"
require "nokogiri"
module Adamantium module Adamantium
module Syndication module Syndication
@@ -8,9 +9,12 @@ module Adamantium
include Deps[mastodon_client: "clients.mastodon"] include Deps[mastodon_client: "clients.mastodon"]
def call(post:) 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) mastodon_client.upload_media(photo: photo)
end&.compact end.compact
response = mastodon_client.create_post(post: post, media_ids: media_ids) response = mastodon_client.create_post(post: post, media_ids: media_ids)
@@ -30,6 +34,13 @@ module Adamantium
Failure(:failed_to_de_syndicate) Failure(:failed_to_de_syndicate)
end end
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 end
end end

View File

@@ -44,9 +44,12 @@ module Main
return photos.first["url"] return photos.first["url"]
end end
inline_images.first[1] if inline_images
end
def inline_images
doc = Nokogiri::HTML(content) doc = Nokogiri::HTML(content)
images = doc.at("//img") doc.at("//img")
images.first[1] if images
end end
def prefix_emoji def prefix_emoji

View File

@@ -36,7 +36,8 @@ module Micropub
if req_entity && verify_scope(req: req, scope: :create) if req_entity && verify_scope(req: req, scope: :create)
Dry::Matcher::ResultMatcher.call(create_entry.call(req_entity: req_entity)) do |m| Dry::Matcher::ResultMatcher.call(create_entry.call(req_entity: req_entity)) do |m|
m.success do |post| 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 res.status = 201
end end

View File

@@ -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(:settings) { double("settings", mastodon_server: "https://mastodon.example/@tester", blue_sky_url: "https://bluesky.app") }
let(:mastodon_client) { double("Adamantium::Client::Mastodon") } let(:mastodon_client) { double("Adamantium::Client::Mastodon") }
let(:mastodon_syndicator) { Adamantium::Syndication::Mastodon.new(mastodon_client: mastodon_client) } 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: "<p>Some cool post <img src='https://picsum.photos/200' /> <img src='https://picsum.photos/100' /></p>", syndicate_to: ["https://mastodon.example", "https://bsky.app"], category: []} }
let(:add_post_syndication_source) { spy(Micropub::Commands::Posts::AddSyndicationSource) } let(:add_post_syndication_source) { spy(Micropub::Commands::Posts::AddSyndicationSource) }
subject { subject {
@@ -17,7 +17,9 @@ RSpec.describe Micropub::Commands::Posts::Syndicate do
} }
before 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 end
it "syndicates a post to Mastodon" do it "syndicates a post to Mastodon" do