diff --git a/slices/admin/templates/photos/index.html.slim b/slices/admin/templates/photos/index.html.slim index 63f804c..f5cae24 100644 --- a/slices/admin/templates/photos/index.html.slim +++ b/slices/admin/templates/photos/index.html.slim @@ -12,11 +12,21 @@ div class="mb-4 max-w-prose mx-auto prose dark:prose-invert" h2 = year div class="grid grid-cols-3 gap-4" - photos.each_with_index do |photo, idx| - - next if photo.match(/small/) - div class="rounded max-w-xs" x-data="" id="photo-#{idx}" - img loading="lazy" class="rounded object-cover hover:opacity-80 h-48 w-48 mb-2" src="/#{photo.gsub("public/", "")}" - div class="grid grid-cols-2 gap-2" - button class="hover:text-blue-400 p-1 bg-blue-100 rounded text-blue-600 no-underline" @click="$clipboard('#{Hanami.app.settings.micropub_site_url}/#{photo.gsub("public/", "")}')" Copy URL - button class="hover:text-blue-400 p-1 bg-blue-100 rounded text-blue-600 no-underline" @click="$clipboard('![](#{Hanami.app.settings.micropub_site_url}/#{photo.gsub("public/", "")})')" Copy .md - div class="grid grid-cols-1" - button class="text-red-600 p-1 bg-red-50 rounded hover:text-red-400 mt-2" hx-delete="/admin/media/#{photo}" hx-target="#photo-#{idx}" Delete + - if photo.match(/.mp3/) + div class="rounded max-w-xs" x-data="" id="photo-#{idx}" + div class="w-48 mb-2" + audio controls="" src="/#{photo.gsub("public/", "")}" + div class="grid grid-cols-2 gap-2" + button class="hover:text-blue-400 p-1 bg-blue-100 rounded text-blue-600 no-underline" @click="$clipboard('#{Hanami.app.settings.micropub_site_url}/#{photo.gsub("public/", "")}')" Copy URL + button class="hover:text-blue-400 p-1 bg-blue-100 rounded text-blue-600 no-underline" @click="$clipboard('')" Copy .md + div class="grid grid-cols-1" + button class="text-red-600 p-1 bg-red-50 rounded hover:text-red-400 mt-2" hx-delete="/admin/media/#{photo}" hx-target="#photo-#{idx}" Delete + - else + - next if photo.match(/small/) + div class="rounded max-w-xs" x-data="" id="photo-#{idx}" + img loading="lazy" class="rounded object-cover hover:opacity-80 h-48 w-48 mb-2" src="/#{photo.gsub("public/", "")}" + div class="grid grid-cols-2 gap-2" + button class="hover:text-blue-400 p-1 bg-blue-100 rounded text-blue-600 no-underline" @click="$clipboard('#{Hanami.app.settings.micropub_site_url}/#{photo.gsub("public/", "")}')" Copy URL + button class="hover:text-blue-400 p-1 bg-blue-100 rounded text-blue-600 no-underline" @click="$clipboard('![](#{Hanami.app.settings.micropub_site_url}/#{photo.gsub("public/", "")})')" Copy .md + div class="grid grid-cols-1" + button class="text-red-600 p-1 bg-red-50 rounded hover:text-red-400 mt-2" hx-delete="/admin/media/#{photo}" hx-target="#photo-#{idx}" Delete diff --git a/slices/admin/templates/posts/show.html.slim b/slices/admin/templates/posts/show.html.slim index a1af05c..f4b0afa 100644 --- a/slices/admin/templates/posts/show.html.slim +++ b/slices/admin/templates/posts/show.html.slim @@ -26,7 +26,7 @@ div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark: // TODO: Add preview, fix sending to DayOne article class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200 prose-a:text-blue-600 prose-a:no-underline hover:prose-a:underline prose-img:rounded" a href="/post/#{post.slug}" - h1= post.name + h1= post.name || "💬" 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" x-data="{ resize: () => { $el.style.height = '5px'; $el.style.height = $el.scrollHeight + 'px' } }" x-init="resize()" @input="resize()" == markdown_body diff --git a/slices/micropub/commands/media/upload.rb b/slices/micropub/commands/media/upload.rb index 4c58458..8c86a35 100644 --- a/slices/micropub/commands/media/upload.rb +++ b/slices/micropub/commands/media/upload.rb @@ -13,18 +13,20 @@ module Micropub 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 + IMAGE_TYPES = %w[image/jpeg imag/jpg image/png].freeze + VIDEO_TYPES = %w[image/gif video/mp4].freeze + AUDIO_TYPES = %w[audio/mp3 audio/mpeg audio/x-m4a].freeze + VALID_UPLOAD_TYPES = IMAGE_TYPES + VIDEO_TYPES + AUDIO_TYPES def call(file:) mime = FileMagic.new - type = mime.file(file[:tempfile].path, true).to_sym - + mime.flags = [:mime_type] + type = mime.file(file[:tempfile].path) 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 + result = save_audio(file: file, type: type) if AUDIO_TYPES.include? type if result.success? Success(result.value!) @@ -67,6 +69,25 @@ module Micropub Success(upload_path) end + def save_audio(file:, type:) + filename = "#{uuid}.mp3" + + dirname = File.join("public", "media", pathname) + + unless File.directory?(dirname) + FileUtils.mkdir_p(dirname) + end + + begin + Open3.popen3("ffmpeg -i #{file[:tempfile].path} -vn -ar 44100 -ac 2 -b:a 192k #{File.join(dirname, filename)}") + rescue Errno::ENOENT, NoMethodError => e + return Failure(e.message) + end + + upload_path = File.join(settings.micropub_site_url, "/media/", "/#{pathname}/", 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])}"