2017-05-02 00:20:57 +10:00
# frozen_string_literal: true
2019-06-20 18:52:36 +10:00
require 'mime/types/columnar'
2018-04-23 17:16:38 +10:00
2017-05-02 00:20:57 +10:00
module Attachmentable
extend ActiveSupport :: Concern
2018-04-23 17:16:38 +10:00
MAX_MATRIX_LIMIT = 16_777_216 # 4096x4096px or approx. 16MB
2017-05-02 00:20:57 +10:00
included do
before_post_process :set_file_extensions
2018-04-23 17:16:38 +10:00
before_post_process :check_image_dimensions
2019-06-23 00:54:06 +10:00
before_post_process :set_file_content_type
2017-05-02 00:20:57 +10:00
end
private
2019-06-23 00:54:06 +10:00
def set_file_content_type
self . class . attachment_definitions . each_key do | attachment_name |
attachment = send ( attachment_name )
next if attachment . blank? || attachment . queued_for_write [ :original ] . blank?
attachment . instance_write :content_type , calculated_content_type ( attachment )
end
end
2017-05-02 00:20:57 +10:00
def set_file_extensions
self . class . attachment_definitions . each_key do | attachment_name |
attachment = send ( attachment_name )
2018-04-23 17:16:38 +10:00
2017-05-02 00:20:57 +10:00
next if attachment . blank?
2018-04-23 17:16:38 +10:00
attachment . instance_write :file_name , [ Paperclip :: Interpolations . basename ( attachment , :original ) , appropriate_extension ( attachment ) ] . delete_if ( & :blank? ) . join ( '.' )
end
end
def check_image_dimensions
self . class . attachment_definitions . each_key do | attachment_name |
attachment = send ( attachment_name )
2018-07-04 03:47:09 +10:00
next if attachment . blank? || ! / image.* / . match? ( attachment . content_type ) || attachment . queued_for_write [ :original ] . blank?
2018-04-23 17:16:38 +10:00
width , height = FastImage . size ( attachment . queued_for_write [ :original ] . path )
2019-08-16 04:20:20 +10:00
raise Mastodon :: DimensionsValidationError , " #{ width } x #{ height } images are not supported, must be below #{ MAX_MATRIX_LIMIT } sqpx " if width . present? && height . present? && ( width * height > = MAX_MATRIX_LIMIT )
2017-05-02 00:20:57 +10:00
end
end
2018-04-23 17:16:38 +10:00
def appropriate_extension ( attachment )
mime_type = MIME :: Types [ attachment . content_type ]
extensions_for_mime_type = mime_type . empty? ? [ ] : mime_type . first . extensions
original_extension = Paperclip :: Interpolations . extension ( attachment , :original )
2018-06-19 01:27:05 +10:00
proper_extension = extensions_for_mime_type . first . to_s
2018-06-24 21:33:06 +10:00
extension = extensions_for_mime_type . include? ( original_extension ) ? original_extension : proper_extension
extension = 'jpeg' if extension == 'jpe'
2018-04-23 17:16:38 +10:00
2018-06-24 21:33:06 +10:00
extension
2018-04-23 17:16:38 +10:00
end
2019-06-23 00:54:06 +10:00
def calculated_content_type ( attachment )
2019-07-01 00:10:43 +10:00
content_type = Paperclip . run ( 'file' , '-b --mime :file' , file : attachment . queued_for_write [ :original ] . path ) . split ( / [:; \ s]+ / ) . first . chomp
content_type = 'video/mp4' if content_type == 'video/x-m4v'
content_type
2019-06-23 00:54:06 +10:00
rescue Terrapin :: CommandLineError
''
end
2017-05-02 00:20:57 +10:00
end