Refactor micropub specific things out to a slice
This commit is contained in:
0
app/commands/.keep
Normal file
0
app/commands/.keep
Normal file
@@ -1,31 +0,0 @@
|
||||
module Adamantium
|
||||
module Commands
|
||||
module AutoTagging
|
||||
class Tag
|
||||
include Dry::Monads[:result]
|
||||
include Deps["repos.post_repo", "repos.auto_tagging_repo"]
|
||||
|
||||
def call(auto_tag_id: nil)
|
||||
auto_taggings = if auto_tag_id
|
||||
auto_tagging_repo.find(auto_tag_id)
|
||||
else
|
||||
auto_tagging_repo.all
|
||||
end
|
||||
|
||||
auto_taggings.each do |auto_tagging|
|
||||
posts = auto_tagging.title_only? ?
|
||||
post_repo.by_title(title_contains: auto_tagging.title_contains) :
|
||||
post_repo.by_content(body_contains: auto_tagging.body_contains)
|
||||
|
||||
posts.each do |post|
|
||||
post_repo.auto_tag_post(post_id: post.id,
|
||||
tag_id: auto_tagging.tag_id)
|
||||
end
|
||||
end
|
||||
|
||||
Success()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,103 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "securerandom"
|
||||
require "dry/monads"
|
||||
require "filemagic"
|
||||
require "image_processing/vips"
|
||||
require "open3"
|
||||
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Media
|
||||
class Upload < Command
|
||||
include Deps["settings"]
|
||||
include Dry::Monads[:result]
|
||||
|
||||
IMAGE_TYPES = %i[jpeg jpg png].freeze
|
||||
VIDEO_TYPES = %i[gif iso].freeze
|
||||
VALID_UPLOAD_TYPES = IMAGE_TYPES + VIDEO_TYPES
|
||||
|
||||
def call(file:)
|
||||
mime = FileMagic.new
|
||||
type = mime.file(file[:tempfile].path, true).to_sym
|
||||
|
||||
return Failure(:invalid_file_type) unless VALID_UPLOAD_TYPES.include? type
|
||||
|
||||
result = save_image(file: file) if IMAGE_TYPES.include? type
|
||||
result = save_video(file: file, type: type) if VIDEO_TYPES.include? type
|
||||
|
||||
if result.success?
|
||||
Success(result.value!)
|
||||
else
|
||||
Failure()
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pathname
|
||||
Time.now.strftime("%m-%Y")
|
||||
end
|
||||
|
||||
def uuid
|
||||
SecureRandom.uuid
|
||||
end
|
||||
|
||||
def save_video(file:, type:)
|
||||
fullsize_filename = "#{uuid}.mp4"
|
||||
|
||||
dirname = File.join("public", "media", pathname)
|
||||
|
||||
unless File.directory?(dirname)
|
||||
FileUtils.mkdir_p(dirname)
|
||||
end
|
||||
|
||||
begin
|
||||
case type
|
||||
when :gif
|
||||
Open3.popen3("ffmpeg -i #{file[:tempfile].path} -movflags faststart -pix_fmt yuv420p -vf 'scale=trunc(iw/2)*2:trunc(ih/2)*2' #{File.join(dirname, fullsize_filename)}")
|
||||
when :iso
|
||||
Open3.popen3("ffmpeg -i #{file[:tempfile].path} -vcodec libx264 -crf 28 #{File.join(dirname, fullsize_filename)}")
|
||||
end
|
||||
rescue Errno::ENOENT, NoMethodError => e
|
||||
return Failure(e.message)
|
||||
end
|
||||
|
||||
upload_path = File.join(settings.micropub_site_url, "/media/", "/#{pathname}/", fullsize_filename).to_s
|
||||
Success(upload_path)
|
||||
end
|
||||
|
||||
def save_image(file:)
|
||||
fullsize_filename = "#{uuid}#{File.extname(file[:filename])}"
|
||||
thumbnail_filename = "#{uuid}-small#{File.extname(file[:filename])}"
|
||||
|
||||
dirname = File.join("public", "media", pathname)
|
||||
|
||||
fullsize_pipeline = ImageProcessing::Vips.source(file[:tempfile])
|
||||
.resize_to_limit(1024, nil)
|
||||
.saver(quality: 100)
|
||||
.call(save: false)
|
||||
|
||||
thumbnail_pipeline = ImageProcessing::Vips.source(file[:tempfile])
|
||||
.resize_to_limit(300, 300, crop: :attention)
|
||||
.saver(quality: 100)
|
||||
.call(save: false)
|
||||
|
||||
unless File.directory?(dirname)
|
||||
FileUtils.mkdir_p(dirname)
|
||||
end
|
||||
|
||||
begin
|
||||
fullsize_pipeline.write_to_file(File.join(dirname, fullsize_filename))
|
||||
thumbnail_pipeline.write_to_file(File.join(dirname, thumbnail_filename))
|
||||
rescue Errno::ENOENT, NoMethodError => e
|
||||
return Failure(e.message)
|
||||
end
|
||||
|
||||
upload_path = File.join(settings.micropub_site_url, "/media/", "/#{pathname}/", fullsize_filename).to_s
|
||||
Success(upload_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,18 +0,0 @@
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class AddSyndicationSource
|
||||
include Deps["repos.post_repo"]
|
||||
|
||||
def call(post_id, source, url)
|
||||
post = post_repo.find!(post_id).to_h
|
||||
syndication_sources = post[:syndication_sources] || {}
|
||||
syndication_sources[source] = url
|
||||
post[:syndication_sources] = syndication_sources
|
||||
|
||||
post_repo.update(post_id, post)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,19 +0,0 @@
|
||||
require "dry/monads"
|
||||
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class CreateBookPost < Command
|
||||
include Deps["repos.post_repo"]
|
||||
|
||||
include Dry::Monads[:result]
|
||||
|
||||
def call(post)
|
||||
created_post = post_repo.create(post)
|
||||
|
||||
Success(created_post)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,32 +0,0 @@
|
||||
require "dry/monads"
|
||||
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class CreateBookmark < Command
|
||||
include Deps["repos.post_repo",
|
||||
"post_utilities.page_cacher",
|
||||
syndicate: "commands.posts.syndicate",
|
||||
raindrop: "syndication.raindrop",
|
||||
]
|
||||
|
||||
include Dry::Monads[:result]
|
||||
|
||||
def call(bookmark)
|
||||
created_bookmark = post_repo.create(bookmark)
|
||||
|
||||
syndicate.call(created_bookmark.id, bookmark)
|
||||
raindrop.call(post: created_bookmark)
|
||||
|
||||
if bookmark[:cache]
|
||||
page_cacher.call(url: created_bookmark.url) do |content|
|
||||
post_repo.update(created_bookmark.id, cached_content: content)
|
||||
end
|
||||
end
|
||||
|
||||
Success(created_bookmark)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,42 +0,0 @@
|
||||
require "dry/monads"
|
||||
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class CreateCheckin < Command
|
||||
include Deps["repos.post_repo",
|
||||
"post_utilities.slugify",
|
||||
"logger",
|
||||
renderer: "renderers.markdown",
|
||||
add_post_syndication_source: "commands.posts.add_syndication_source"
|
||||
]
|
||||
|
||||
include Dry::Monads[:result]
|
||||
|
||||
def call(post)
|
||||
syndication_sources = post.delete(:syndication_sources)
|
||||
post_params = prepare_params(params: post)
|
||||
created_post = post_repo.create(post_params)
|
||||
|
||||
syndication_sources.each do |url|
|
||||
add_post_syndication_source.call(created_post.id, :swarm, url)
|
||||
end
|
||||
|
||||
# decorated_post = Decorators::Posts::Decorator.new(created_post)
|
||||
|
||||
# send_webmentions.call(post_content: attrs[:content], post_url: decorated_post.permalink)
|
||||
|
||||
Success(created_post)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_params(params:)
|
||||
attrs = params.to_h
|
||||
attrs[:content] = renderer.call(content: attrs[:content]) if attrs[:content]
|
||||
attrs
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,43 +0,0 @@
|
||||
require "dry/monads"
|
||||
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class CreateEntry < Command
|
||||
include Deps["repos.post_repo",
|
||||
"post_utilities.slugify",
|
||||
renderer: "renderers.markdown",
|
||||
syndicate: "commands.posts.syndicate",
|
||||
send_to_dayone: "syndication.dayone",
|
||||
send_webmentions: "commands.posts.send_webmentions",
|
||||
auto_tag: "commands.auto_tagging.tag",
|
||||
]
|
||||
|
||||
include Dry::Monads[:result]
|
||||
|
||||
def call(post)
|
||||
post_params = prepare_params(params: post)
|
||||
created_post = post_repo.create(post_params)
|
||||
|
||||
auto_tag.call
|
||||
|
||||
syndicate.call(created_post.id, post)
|
||||
|
||||
decorated_post = Decorators::Posts::Decorator.new(created_post)
|
||||
|
||||
send_webmentions.call(post_content: created_post.content, post_url: decorated_post.permalink)
|
||||
|
||||
Success(created_post)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare_params(params:)
|
||||
attrs = params.to_h
|
||||
attrs[:content] = renderer.call(content: attrs[:content])
|
||||
attrs
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,31 +0,0 @@
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class CreationResolver
|
||||
include Deps[
|
||||
"validation.posts.post_contract",
|
||||
"validation.posts.bookmark_contract",
|
||||
"validation.posts.checkin_contract",
|
||||
"validation.posts.book_contract",
|
||||
"commands.posts.create_entry",
|
||||
"commands.posts.create_bookmark",
|
||||
"commands.posts.create_checkin",
|
||||
"commands.posts.create_book_post"
|
||||
]
|
||||
|
||||
def call(entry_type:)
|
||||
case entry_type
|
||||
in Entities::BookmarkRequest
|
||||
{command: create_bookmark, validation: bookmark_contract}
|
||||
in Entities::CheckinRequest
|
||||
{command: create_checkin, validation: checkin_contract}
|
||||
in Entities::BookRequest
|
||||
{command: create_book_post, validation: book_contract}
|
||||
else
|
||||
{command: create_entry, validation: post_contract}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,14 +0,0 @@
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class Delete < Command
|
||||
include Deps["repos.post_repo"]
|
||||
def call(params:)
|
||||
slug = URI(params[:url]).path.split("/").last
|
||||
|
||||
post_repo.delete!(slug)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,18 +0,0 @@
|
||||
require "httparty"
|
||||
require "que"
|
||||
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class SendWebmentions
|
||||
include Deps["settings", "post_utilities.link_finder"]
|
||||
|
||||
def call(post_content:, post_url:)
|
||||
Que.connection = Adamantium::Container["persistence.db"]
|
||||
|
||||
Adamantium::Jobs::SendWebMentions.enqueue(post_content: post_content, post_url: post_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,51 +0,0 @@
|
||||
require "dry/monads"
|
||||
require "dry/monads/do"
|
||||
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class Syndicate
|
||||
include Dry::Monads[:result]
|
||||
include Dry::Monads::Do.for(:call)
|
||||
|
||||
include Deps["settings",
|
||||
"syndication.mastodon",
|
||||
"syndication.blue_sky",
|
||||
add_post_syndication_source: "commands.posts.add_syndication_source",
|
||||
send_to_dayone: "syndication.dayone",
|
||||
]
|
||||
|
||||
def call(post_id, post)
|
||||
syndicate_to = syndication_targets(post[:syndicate_to])
|
||||
|
||||
if syndicate_to.include? :mastodon
|
||||
res = mastodon.call(post: post)
|
||||
|
||||
add_post_syndication_source.call(post_id, :mastodon, res.value!) if res.success?
|
||||
end
|
||||
|
||||
if syndicate_to.include? :blue_sky
|
||||
res = blue_sky.call(post: post)
|
||||
|
||||
add_post_syndication_source.call(post_id, :blue_sky, res.value!) if res.success?
|
||||
end
|
||||
|
||||
if post[:category].include? "weekly"
|
||||
send_to_dayone.call(name: post[:name], content: post[:content])
|
||||
end
|
||||
|
||||
Success()
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def syndication_targets(syndicate_to)
|
||||
targets = []
|
||||
targets << :mastodon if syndicate_to.any? { |url| settings.mastodon_server.match(/#{url}/) }
|
||||
targets << :blue_sky if syndicate_to.any? { |url| settings.blue_sky_url.match(/#{url}/) }
|
||||
targets
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,14 +0,0 @@
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class Undelete < Command
|
||||
include Deps["repos.post_repo"]
|
||||
def call(params:)
|
||||
slug = URI(params[:url]).path.split("/").last
|
||||
|
||||
post_repo.restore!(slug)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,72 +0,0 @@
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Posts
|
||||
class Update < Command
|
||||
include Deps[
|
||||
"repos.post_repo",
|
||||
"renderers.markdown",
|
||||
"commands.posts.add_syndication_source"
|
||||
]
|
||||
|
||||
def call(params:)
|
||||
slug = URI(params[:url]).path.split("/").last
|
||||
post = post_repo.fetch!(slug)
|
||||
|
||||
if params.key? :replace
|
||||
content = params[:replace].delete(:content).first
|
||||
name = params[:replace].delete(:name)
|
||||
|
||||
attrs_to_replace = {}
|
||||
attrs_to_replace[:name] = name if name
|
||||
attrs_to_replace[:content] = markdown.call(content: content) if content
|
||||
|
||||
post_repo.update(post.id, attrs_to_replace)
|
||||
end
|
||||
|
||||
if params.key? :add
|
||||
attrs_to_add = {}
|
||||
|
||||
syndication = params[:add].delete(:syndication)&.first
|
||||
tags = params[:add].delete(:category)
|
||||
content = params[:add].delete(:content)&.first
|
||||
name = params[:add].delete(:name)
|
||||
|
||||
attrs_to_add[:name] = name if post.name.empty?
|
||||
attrs_to_add[:content] = markdown.call(content: content) if post.content.empty?
|
||||
|
||||
params[:add].keys.each_with_object(attrs_to_add) do |attr, memo|
|
||||
memo[attr] = params[:add][attr].first if post.fetch(attr, nil).nil?
|
||||
end
|
||||
|
||||
post_repo.update(post.id, attrs_to_add) unless attrs_to_add.empty?
|
||||
|
||||
post_repo.tag_post(post_id: post.id, tags: tags) if tags && !tags.empty?
|
||||
add_syndication_source.call(post.id, "", syndication) if syndication && !syndication.empty?
|
||||
end
|
||||
|
||||
if params.key? :delete
|
||||
if params[:delete].is_a? Hash
|
||||
tags = params[:delete][:category]
|
||||
tags&.each do |tag|
|
||||
post_repo.remove_tag(post_id: post.id, tag: tag)
|
||||
end
|
||||
elsif params[:delete].is_a? Array
|
||||
if params[:delete].delete("category")
|
||||
post.tags.each do |tag|
|
||||
post_repo.remove_tag(post_id: post.id, tag: tag.label)
|
||||
end
|
||||
end
|
||||
|
||||
attrs = {}
|
||||
params[:delete].each do |attr|
|
||||
attrs[attr.to_sym] = nil
|
||||
end
|
||||
|
||||
post_repo.update(post.id, attrs) unless attrs.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@@ -1,18 +0,0 @@
|
||||
require "securerandom"
|
||||
require "dry/monads"
|
||||
require "filemagic"
|
||||
|
||||
module Adamantium
|
||||
module Commands
|
||||
module Workouts
|
||||
class Create < Command
|
||||
include Deps["repos.workout_repo"]
|
||||
include Dry::Monads[:result]
|
||||
|
||||
def call(svg:, distance:, duration:)
|
||||
workout_repo.create(path: svg, distance: distance, duration: duration, published_at: Time.now)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user