diff --git a/lib/adamantium/geo/gpx_parser.rb b/lib/adamantium/geo/gpx_parser.rb index 0c1e056..839de33 100644 --- a/lib/adamantium/geo/gpx_parser.rb +++ b/lib/adamantium/geo/gpx_parser.rb @@ -25,20 +25,22 @@ module Adamantium latdiff = maxlat - minlat londiff = maxlon - minlon - svg = Gnuplot.open do |gp| - Gnuplot::Plot.new(gp) do |plot| - plot.arbitrary_lines << "unset border" - plot.arbitrary_lines << "unset xtics" - plot.arbitrary_lines << "unset ytics" - plot.arbitrary_lines << "set size ratio -1" - plot.arbitrary_lines << "set yrange [#{minlat}:#{maxlat}]" if latdiff >= londiff # portrait - plot.arbitrary_lines << "set xrange [#{minlon}:#{maxlon}]" if latdiff < londiff # landscape - plot.arbitrary_lines << "set term svg" - plot.data << Gnuplot::DataSet.new([x, y]) do |ds| - ds.with = "lines" - ds.linewidth = 4 - ds.linecolor = 'rgb "#84cc16"' - ds.notitle + svg = with_silent_output do + Gnuplot.open do |gp| + Gnuplot::Plot.new(gp) do |plot| + plot.arbitrary_lines << "unset border" + plot.arbitrary_lines << "unset xtics" + plot.arbitrary_lines << "unset ytics" + plot.arbitrary_lines << "set size ratio -1" + plot.arbitrary_lines << "set yrange [#{minlat}:#{maxlat}]" if latdiff >= londiff # portrait + plot.arbitrary_lines << "set xrange [#{minlon}:#{maxlon}]" if latdiff < londiff # landscape + plot.arbitrary_lines << "set term svg" + plot.data << Gnuplot::DataSet.new([x, y]) do |ds| + ds.with = "lines" + ds.linewidth = 4 + ds.linecolor = 'rgb "#84cc16"' + ds.notitle + end end end end @@ -47,6 +49,16 @@ module Adamantium Success({svg: svg, distance: gpx.distance(units: "kilometers"), duration: gpx.duration}) end + + private + + define_method(:with_silent_output) do |&block| + orig_verbose = $VERBOSE + $VERBOSE = nil + result = block.call + $VERBOSE = orig_verbose + result + end end end end diff --git a/slices/micropub/actions/posts/handle.rb b/slices/micropub/actions/posts/handle.rb index faf9d78..c3dc6af 100644 --- a/slices/micropub/actions/posts/handle.rb +++ b/slices/micropub/actions/posts/handle.rb @@ -6,10 +6,8 @@ module Micropub include Deps[ "settings", - "post_utilities.slugify", - "repos.post_repo", + "commands.posts.create_entry", post_param_parser: "param_parser.micropub_post", - create_resolver: "commands.posts.creation_resolver", delete_post: "commands.posts.delete", undelete_post: "commands.posts.undelete", update_post: "commands.posts.update", @@ -18,52 +16,46 @@ module Micropub def handle(req, res) req_entity = post_param_parser.call(params: req.params.to_h) - action = req.params[:action] + action_type = req.params[:action] # delete, undelete, update - if action - perform_action(req: req, res: res, action: action) - elsif req_entity # create - create_entry(req: req, res: res, req_entity: req_entity) + if action_type + case resolve_command(req: req, action_type: action_type) + in Success[command] + command.call(params: req.params.to_h) + res.status = 200 + in Failure[:not_permitted] + halt 401 + end + end + + # create + if req_entity && verify_scope(req: req, scope: :create) + create_entry.call(req_entity: req_entity) do |m| + m.success do |post| + res.status = 201 + res.headers["Location"] = "#{settings.micropub_site_url}/#{post.post_type}/#{post.slug}" + end + + m.failure do |validation| + res.body = {error: validation.errors.to_h}.to_json + res.status = 422 + end + end end end private - def create_entry(req:, res:, req_entity:) - halt 401 unless verify_scope(req: req, scope: :create) + def resolve_command(req:, action_type:) + command, permission_check = commands(action_type) - command, contract = create_resolver.call(entry_type: req_entity).values_at(:command, :validation) - post_params = prepare_params(req_entity.to_h) - validation = contract.call(post_params) + return Failure(:not_permitted) unless permission_check.call(req) - if validation.success? - command.call(validation.to_h).bind do |post| - res.status = 201 - res.headers["Location"] = "#{settings.micropub_site_url}/#{post.post_type}/#{post.slug}" - end - else - res.body = {error: validation.errors.to_h}.to_json - res.status = 422 - end + Success(command) end - def perform_action(req:, res:, action:) - operation, permission_check = resolve_operation(action) - - halt 401 unless permission_check.call(req) - - operation.call(params: req.params.to_h) - res.status = 200 - end - - def prepare_params(post_params) - post = post_params.to_h - post[:slug] = post[:slug].empty? ? slugify.call(text: post[:name], checker: post_repo.method(:slug_exists?)) : post[:slug] - post - end - - def resolve_operation(action) + def commands(action) case action when "delete" [delete_post, ->(req) { verify_scope(req: req, scope: :delete) }] diff --git a/slices/micropub/commands/posts/create_entry.rb b/slices/micropub/commands/posts/create_entry.rb index 1a4f0bc..2eb63b3 100644 --- a/slices/micropub/commands/posts/create_entry.rb +++ b/slices/micropub/commands/posts/create_entry.rb @@ -1,41 +1,32 @@ -require "dry/monads" - module Micropub module Commands module Posts class CreateEntry < Adamantium::Command - include Deps["repos.post_repo", + include Deps[ "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", - ] + "repos.post_repo", + create_resolver: "commands.posts.creation_resolver" + ] - include Dry::Monads[:result] + def call(req_entity:) + command, contract = create_resolver.call(entry_type: req_entity).values_at(:command, :validation) + post_params = prepare_params(req_entity.to_h) + validation = contract.call(post_params) - 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) + if validation.success? + post = command.call(validation.to_h) + Success(post) + else + Failure(validation) + end end private - def prepare_params(params:) - attrs = params.to_h - attrs[:content] = renderer.call(content: attrs[:content]) - attrs + def prepare_params(post_params) + post = post_params.to_h + post[:slug] = post[:slug].empty? ? slugify.call(text: post[:name], checker: post_repo.method(:slug_exists?)) : post[:slug] + post end end end diff --git a/slices/micropub/commands/posts/create_post.rb b/slices/micropub/commands/posts/create_post.rb new file mode 100644 index 0000000..915e145 --- /dev/null +++ b/slices/micropub/commands/posts/create_post.rb @@ -0,0 +1,42 @@ +require "dry/monads" + +module Micropub + module Commands + module Posts + class CreatePost < Adamantium::Command + include Deps["repos.post_repo", + 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 diff --git a/slices/micropub/commands/posts/creation_resolver.rb b/slices/micropub/commands/posts/creation_resolver.rb index 91e2167..6510573 100644 --- a/slices/micropub/commands/posts/creation_resolver.rb +++ b/slices/micropub/commands/posts/creation_resolver.rb @@ -7,7 +7,7 @@ module Micropub "validation.posts.bookmark_contract", "validation.posts.checkin_contract", "validation.posts.book_contract", - "commands.posts.create_entry", + "commands.posts.create_post", "commands.posts.create_bookmark", "commands.posts.create_checkin", "commands.posts.create_book_post" @@ -22,7 +22,7 @@ module Micropub in Entities::BookRequest {command: create_book_post, validation: book_contract} else - {command: create_entry, validation: post_contract} + {command: create_post, validation: post_contract} end end end