From 6057a8b4f0f8e09744f093555af6b4bb2af8a54a Mon Sep 17 00:00:00 2001 From: Daniel Nitsikopoulos Date: Tue, 4 Jul 2023 22:57:33 +1000 Subject: [PATCH] First pass at webmentions --- app/actions/webmentions/create.rb | 37 +++++++++++++++++++ app/repos/post_repo.rb | 2 +- app/repos/webmentions_repo.rb | 7 ++++ app/templates/posts/show.html.slim | 14 +++++++ config/routes.rb | 2 + .../20230704111528_create_webmentions.rb | 24 ++++++++++++ lib/adamantium/persistence/relations/posts.rb | 2 + .../persistence/relations/webmentions.rb | 21 +++++++++++ 8 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 app/actions/webmentions/create.rb create mode 100644 app/repos/webmentions_repo.rb create mode 100644 db/migrate/20230704111528_create_webmentions.rb create mode 100644 lib/adamantium/persistence/relations/webmentions.rb diff --git a/app/actions/webmentions/create.rb b/app/actions/webmentions/create.rb new file mode 100644 index 0000000..1129f41 --- /dev/null +++ b/app/actions/webmentions/create.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Adamantium + module Actions + module Webmentions + class Create < Adamantium::Action + + include Deps["repos.webmentions_repo", "repos.post_repo"] + + def handle(req, res) + req.params[:children].each do |child| + if child[:"wm-property"] == "in-reply-to" + + slug = child[:"in-reply-to"].split("/").last + post = post_repo.fetch!(slug) + + attrs = { + type: "reply", + author_name: child[:author][:name], + author_photo: child[:author][:photo], + author_url: child[:author][:url], + published_at: child[:published], + content_html: child[:content][:html], + content_text: child[:content][:text], + source_url: child[:url], + target_url: child[:"in-reply-to"], + post_id: post.id + } + + webmentions_repo.create(attrs) + end + end + end + end + end + end +end diff --git a/app/repos/post_repo.rb b/app/repos/post_repo.rb index 23196a2..89b26e7 100644 --- a/app/repos/post_repo.rb +++ b/app/repos/post_repo.rb @@ -216,7 +216,7 @@ module Adamantium def fetch!(slug) posts .published - .combine(:tags, :trips) + .combine(:tags, :trips, :webmentions) .where(slug: slug) .one! end diff --git a/app/repos/webmentions_repo.rb b/app/repos/webmentions_repo.rb new file mode 100644 index 0000000..2efc0e8 --- /dev/null +++ b/app/repos/webmentions_repo.rb @@ -0,0 +1,7 @@ +module Adamantium + module Repos + class WebmentionsRepo < Adamantium::Repo[:webmentions] + commands :create + end + end +end \ No newline at end of file diff --git a/app/templates/posts/show.html.slim b/app/templates/posts/show.html.slim index 0d7e410..7600d08 100644 --- a/app/templates/posts/show.html.slim +++ b/app/templates/posts/show.html.slim @@ -41,6 +41,20 @@ article class="h-entry" - if post.location img class="shadow-solid shadow-pink-100 dark:shadow-pink-200 rounded mb-4" src=post.large_map + -if post.webmentions && post.webmentions.count > 0 + div class="mt-12" + h3 #{post.webmentions.count} Comment(s) + - post.webmentions.each do |mention| + div class="prose-p:m-1" + div class="flex h-6" + img class="w-6 m-0 mr-2" src=mention.author_photo + a class="block" href=mention.author_url + = mention.author_name + div + == mention.content_html + div class="text-sm" + a href=mention.source_url + = mention.published_at.strftime("%e %B, %Y") div class="mb-12" - if trip div class="max-w-prose mx-auto text-gray-600 dark:text-gray-200 flex gap-4" diff --git a/config/routes.rb b/config/routes.rb index e61f042..25daa2d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,6 +19,8 @@ module Adamantium post "/", to: "posts.handle" post "/media", to: "media.create" get "/media", to: "media.show" + + post "/webmentions", to: "webmentions.create" end get "/", to: "site.home" diff --git a/db/migrate/20230704111528_create_webmentions.rb b/db/migrate/20230704111528_create_webmentions.rb new file mode 100644 index 0000000..e8e856f --- /dev/null +++ b/db/migrate/20230704111528_create_webmentions.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +ROM::SQL.migration do + change do + create_table :webmentions do + primary_key :id + column :type, :text, null: false, default: "" + + column :author_name, :text, null: false, default: "" + column :author_photo, :text, null: false, default: "" + column :author_url, :text, default: "" + + column :published_at, :timestamp + + column :content_html, :text, null: false, default: "" + column :content_text, :text, null: false, default: "" + + column :source_url, :text, null: false, default: "" + column :target_url, :text, null: false, default: "" + + foreign_key :post_id, :posts + end + end +end diff --git a/lib/adamantium/persistence/relations/posts.rb b/lib/adamantium/persistence/relations/posts.rb index bcb4ee5..735e895 100644 --- a/lib/adamantium/persistence/relations/posts.rb +++ b/lib/adamantium/persistence/relations/posts.rb @@ -11,6 +11,8 @@ module Adamantium has_many :post_trips has_many :trips, through: :post_trips + + has_many :webmentions end end diff --git a/lib/adamantium/persistence/relations/webmentions.rb b/lib/adamantium/persistence/relations/webmentions.rb new file mode 100644 index 0000000..049cac0 --- /dev/null +++ b/lib/adamantium/persistence/relations/webmentions.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Adamantium + module Persistence + module Relations + class Webmentions < ROM::Relation[:sql] + schema :webmentions, infer: true do + associations do + belongs_to :post + end + end + + auto_struct(true) + + def published + where(self[:published_at] <= Time.now) + end + end + end + end +end