Add email comments to posts

This commit is contained in:
2024-03-10 13:21:06 +11:00
parent c52e7fe87f
commit 273be35a61
12 changed files with 129 additions and 32 deletions

1
.gitignore vendored
View File

@@ -18,6 +18,7 @@ Capfile
config/deploy.rb
config/deploy/production.rb
config/systemd/que.service.erb
config/mail_room.yaml
script/deploy
tmp/*
public/media

View File

@@ -44,7 +44,8 @@ gem "babosa"
gem "bskyrb"
gem "ogpr"
gem "ruby-filemagic", git: "https://github.com/dnitza/ruby-filemagic", branch: "master"
gem "webmention"
gem "mail_room", github: "dNitza/mail_room", branch: "master"
gem "charlock_holmes"
gem "sanitize"
gem "time_math2", require: "time_math"
gem "jwt"

View File

@@ -1,3 +1,13 @@
GIT
remote: https://github.com/dNitza/mail_room.git
revision: e36e9b457e61227f7b631246e63d35fb17d921fa
branch: master
specs:
mail_room (0.11.1)
jwt (>= 2.0)
net-imap (>= 0.2.1)
oauth2 (>= 1.4.4, < 3)
GIT
remote: https://github.com/dNitza/scraperd.git
revision: a8fc96f56e64a13e70490ded1dd73345dc7bc9f2
@@ -63,6 +73,7 @@ GEM
sshkit (~> 1.3)
capistrano-systemd-multiservice (0.1.0.beta13)
capistrano (~> 3.7)
charlock_holmes (0.7.7)
chronic (0.10.2)
coderay (1.1.3)
concurrent-ruby (1.2.3)
@@ -147,10 +158,11 @@ GEM
ed25519 (1.3.0)
faker (3.2.3)
i18n (>= 1.8.11, < 2)
faraday (2.9.0)
faraday-net_http (>= 2.0, < 3.2)
faraday-net_http (3.1.0)
net-http
ffi (1.16.3)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
rake
formatador (1.1.0)
georuby (2.5.2)
gnuplot (2.6.2)
@@ -226,16 +238,9 @@ GEM
zeitwerk (~> 2.6)
hansi (0.2.1)
hashie (2.1.2)
http (5.2.0)
addressable (~> 2.8)
base64 (~> 0.1)
http-cookie (~> 1.0)
http-form_data (~> 2.2)
llhttp-ffi (~> 0.5.0)
http-accept (1.7.0)
http-cookie (1.0.5)
domain_name (~> 0.5)
http-form_data (2.3.0)
httparty (0.21.0)
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
@@ -245,10 +250,6 @@ GEM
image_processing (1.12.2)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
indieweb-endpoints (8.0.0)
http (~> 5.0)
link-header-parser (~> 5.0)
nokogiri (>= 1.13)
io-console (0.7.2)
irb (1.11.2)
rdoc
@@ -260,14 +261,10 @@ GEM
lastfm (1.27.4)
httparty
xml-simple
link-header-parser (5.1.1)
lint_roller (1.1.0)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
llhttp-ffi (0.5.0)
ffi-compiler (~> 1.0)
rake (~> 13.0)
lumberjack (1.2.10)
mail (2.8.1)
mini_mime (>= 0.1.1)
@@ -290,6 +287,8 @@ GEM
mustermann (= 3.0.0)
mutex_m (0.2.0)
nenv (0.3.0)
net-http (0.4.1)
uri
net-imap (0.4.10)
date
net-protocol
@@ -315,6 +314,13 @@ GEM
notiffany (0.1.3)
nenv (~> 0.1)
shellany (~> 0.0)
oauth2 (2.0.9)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
multi_xml (~> 0.5)
rack (>= 1.2, < 4)
snaky_hash (~> 2.0)
version_gem (~> 1.1)
ogpr (1.1.0)
nokogiri (~> 1.8)
rest-client (~> 2.1.0)
@@ -449,6 +455,9 @@ GEM
slim (5.2.1)
temple (~> 0.10.0)
tilt (>= 2.1.0)
snaky_hash (2.0.1)
hashie
version_gem (~> 1.1, >= 1.1.1)
sshkit (1.22.0)
mutex_m
net-scp (>= 1.1.2)
@@ -479,11 +488,9 @@ GEM
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)
uri (0.13.0)
version_gem (1.1.3)
warning (1.3.0)
webmention (7.0.0)
http (~> 5.0)
indieweb-endpoints (~> 8.0)
nokogiri (>= 1.13)
whenever (1.0.0)
chronic (>= 0.6.3)
xml-simple (1.1.9)
@@ -510,6 +517,7 @@ DEPENDENCIES
capistrano-rbenv (~> 2.2)
capistrano-systemd-multiservice
capistrano3-puma!
charlock_holmes
connection_pool
csv
database_cleaner-sequel
@@ -537,6 +545,7 @@ DEPENDENCIES
jwt
lastfm (~> 1.27)
mail
mail_room!
matrix
mini_magick
ogpr
@@ -565,7 +574,6 @@ DEPENDENCIES
time_math2
timecop
warning
webmention
whenever
RUBY VERSION

View File

@@ -0,0 +1,13 @@
[Unit]
Description = blog mail_room worker
[Service]
Type=simple
Environment = PWD=/home/blog/current
WorkingDirectory = /home/blog/current
ExecStart = /home/deployer/.rbenv/shims/bundle exec mail_room -c config/mail_room.yaml
Restart=always
User=deployer
[Install]
WantedBy = multi-user.target

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
ROM::SQL.migration do
change do
alter_table :posts do
add_column :commentable, :boolean, default: false
end
end
end

View File

@@ -7,7 +7,7 @@ module Adamantium
def run
webmention_repo = Admin::Container["repos.webmention_repo"]
webmentions = webmention_repo.list_all
webmentions = webmention_repo.list_all_for_check
webmentions.each do |webmention|
code = HTTParty.get(webmention.source_url, follow_redirects: false).code

View File

@@ -0,0 +1,38 @@
require "que"
module Adamantium
module Jobs
class SaveEmailReply < Que::Job
def run(message)
webmentions_repo = Micropub::Container["repos.webmentions_repo"]
post_repo = Micropub::Container["repos.post_repo"]
settings = Micropub::Container["settings"]
renderer = Micropub::Container["renderers.markdown"]
mail = Mail::Message.new(message)
return unless mail.subject == "About that post of yours"
reply_content, in_reply_to = mail.body.decoded.split("---")
post_url = URI.join(settings.micropub_site_url, in_reply_to.match(URI::DEFAULT_PARSER.make_regexp)[7]&.gsub(")", "")).to_s
slug = post_url.split("/").last
post = post_repo.fetch!(slug)
return unless post.commentable
reply = {}
reply[:type] = "reply"
reply[:author_name] = mail.from.first
reply[:published_at] = nil
reply[:content_html] = renderer.call(content: reply_content)
reply[:content_text] = reply_content
reply[:source_url] = "email"
reply[:target_url] = post_url
reply[:post_id] = post.id
webmentions_repo.create(reply)
end
end
end
end

View File

@@ -10,6 +10,7 @@ module Admin
def call(params:)
attrs_to_replace = {}
attrs_to_replace[:content] = markdown.call(content: params[:body]) if params[:body]
attrs_to_replace[:commentable] = params[:commentable]
tags = params[:tags].split(",").map(&:strip)

View File

@@ -3,6 +3,13 @@ module Admin
class WebmentionRepo < Adamantium::Repo[:webmentions]
commands update: :by_pk
def list_all_for_check
webmentions
.exclude(source_url: "email")
.order(:id)
.to_a
end
def list_all
webmentions
.order(:id)

View File

@@ -30,6 +30,9 @@ article class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 d
form action="/admin/post/#{post.id}/update" method="POST"
textarea name="body" class="text-gray-800 w-full border-blue-200 border-2 rounded p-2 mb-4" x-data="{ resize: () => { $el.style.height = '5px'; $el.style.height = $el.scrollHeight + 'px' } }" x-init="resize()" @input="resize()"
== markdown_body
fieldset class="mb-4 flex"
label for="commentable" class="mr-2" Commentable?
input class="mt-2" type="checkbox" value="true" id="commentable" name="commentable" switch="switch" checked=post.commentable
fieldset class="mb-4 flex"
label for="tags" class="mr-2" Tags:
input type="text" name="tags" id="tags" class="w-full px-1 border rounded" value="#{post.tags.map(&:label).join(", ")}"

View File

@@ -32,7 +32,10 @@ div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:
span
== webmention.content_html
td
a href="#{webmention.source_url}" Source
- if webmention.source_url == "email"
= "email"
- else
a href="#{webmention.source_url}" Source
td
a href="#{webmention.target_url}" Target
td

View File

@@ -50,19 +50,32 @@ article class="h-entry"
- if post.location
img loading="lazy" class="shadow-solid shadow-pink-100 dark:shadow-pink-200 rounded mb-4" src=post.large_map
-if post.webmentions && post.webmentions.count > 0
- if post.webmentions && post.webmentions.count == 0 && post.commentable
a href="mailto:blog@dnitza.com?subject=About that post of yours&body=%0A%0A---%0A(In reply to #{post.permalink})" Reply
- if post.webmentions && post.webmentions.count > 0
div class="mt-12"
h3 #{post.webmentions.count} Comment#{post.webmentions.count != 1 ? "s" : ""}
h3
= "#{post.webmentions.count} Comment#{post.webmentions.count != 1 ? "s" : ""}"
- if post.commentable
== " &middot; "
a href="mailto:blog@dnitza.com?subject=About that post of yours&body=%0A%0A---%0A(In reply to #{post.permalink})" reply
- post.webmentions.each do |mention|
div class="prose-p:m-1 mb-6 p-8 bg-orange-100 dark:bg-indigo-900 squircle"
div class="flex h-8"
img loading="lazy" class="w-8 rounded-full m-0 mr-2" src=mention.author_photo
a class="block text-orange-700 dark:text-violet-300 no-underline hover:underline" href=mention.author_url
= mention.author_name
- if mention.author_photo != ""
img loading="lazy" class="w-8 rounded-full m-0 mr-2" src=mention.author_photo
- if mention.author_url == ""
= "From #{mention.author_name}"
- else
a class="block text-orange-700 dark:text-violet-300 no-underline hover:underline" href=mention.author_url
= mention.author_name
div class="prose dark:prose-invert dark:text-indigo-250 prose-a:text-orange-700 dark:prose-a:text-violet-300 prose-a:no-underline hover:prose-a:underline"
== mention.content_html
div class="text-sm"
a class="no-underline hover:underline text-orange-900 dark:text-violet-400" href=mention.source_url
- if mention.source_url != "email"
a class="no-underline hover:underline text-orange-900 dark:text-violet-400" href=mention.source_url
= mention.published_at.strftime("%e %B, %Y")
- else
= mention.published_at.strftime("%e %B, %Y")
div class="mb-12"
- if trip