From b41b67af6c15ef233f93087992ffe70e6be4c397 Mon Sep 17 00:00:00 2001 From: evazion Date: Mon, 31 Oct 2022 22:50:21 -0500 Subject: [PATCH] media assets: add dynamically-generated thumbnails (owner-only). Add ability to dynamically generate thumbnails with: * https://danbooru.donmai.us/media_assets/6961761.jpg?width=180&height=180 This is currently restricted to the Owner-level user because it's slow. --- app/controllers/media_assets_controller.rb | 18 +++++++++++++++++- app/logical/media_file.rb | 9 +++++++-- app/models/media_asset.rb | 5 +++++ config/initializers/mime_types.rb | 4 ++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/app/controllers/media_assets_controller.rb b/app/controllers/media_assets_controller.rb index 9cc05f93b..f7d503ac2 100644 --- a/app/controllers/media_assets_controller.rb +++ b/app/controllers/media_assets_controller.rb @@ -15,6 +15,22 @@ class MediaAssetsController < ApplicationController def show @media_asset = authorize MediaAsset.find(params[:id]) @post = Post.find_by_md5(@media_asset.md5) - respond_with(@media_asset) + + if CurrentUser.is_owner? && request.format.symbol.in?(%i[jpeg webp avif]) + width = params.fetch(:width, @media_asset.image_width).to_i + height = params.fetch(:height, @media_asset.image_height).to_i + quality = params.fetch(:quality, 85).to_i + original_file = @media_asset.variant(:original).open_file + + if width != @media_asset.image_width || height != @media_asset.image_height || request.format != @media_asset.mime_type + media_file = original_file.preview!(width, height, format: request.format.symbol, quality: quality) + else + media_file = original_file + end + + send_file(media_file.path, type: media_file.mime_type, disposition: "inline") + else + respond_with(@media_asset) + end end end diff --git a/app/logical/media_file.rb b/app/logical/media_file.rb index 4c87a9fce..a926aed07 100644 --- a/app/logical/media_file.rb +++ b/app/logical/media_file.rb @@ -147,6 +147,10 @@ class MediaFile ExifTool.new(file).metadata end + def mime_type + Mime::Type.lookup_by_extension(file_ext) + end + # @return [Boolean] True if the file is supported by Danbooru. Certain files may be unsupported because they use features we don't support. def is_supported? true @@ -251,8 +255,9 @@ class MediaFile path: path, width: width, height: height, - file_ext: file_ext, file_size: file_size, + file_ext: file_ext, + mime_type: mime_type, md5: md5, is_corrupt?: is_corrupt?, is_supported?: is_supported?, @@ -276,5 +281,5 @@ class MediaFile end end - memoize :file_ext, :file_size, :md5, :metadata + memoize :file_ext, :file_size, :md5, :metadata, :mime_type end diff --git a/app/models/media_asset.rb b/app/models/media_asset.rb index 58ef91212..2bf9ba858 100644 --- a/app/models/media_asset.rb +++ b/app/models/media_asset.rb @@ -304,6 +304,11 @@ class MediaAsset < ApplicationRecord end end + # @return [Mime::Type] The file's MIME type. + def mime_type + Mime::Type.lookup_by_extension(file_ext) + end + def file=(file_or_path) media_file = file_or_path.is_a?(MediaFile) ? file_or_path : MediaFile.open(file_or_path) diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index 35490377a..285c9e43b 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -3,3 +3,7 @@ # Add new mime types for use in respond_to blocks: # Mime::Type.register "text/richtext", :rtf Mime::Type.register_alias "application/xml", :sitemap + +# XXX remove after upgrading to rack 3.0.0. +Mime::Type.register "image/webp", :webp +Mime::Type.register "image/avif", :avif