2017-05-01 17:20:57 +03:00
# frozen_string_literal: true
2019-06-20 11:52:36 +03:00
require 'mime/types/columnar'
2018-04-23 10:16:38 +03:00
2017-05-01 17:20:57 +03:00
module Attachmentable
extend ActiveSupport :: Concern
2018-04-23 10:16:38 +03:00
MAX_MATRIX_LIMIT = 16_777_216 # 4096x4096px or approx. 16MB
2017-05-01 17:20:57 +03:00
included do
before_post_process :set_file_extensions
2018-04-23 10:16:38 +03:00
before_post_process :check_image_dimensions
2019-06-22 17:54:06 +03:00
before_post_process :set_file_content_type
2017-05-01 17:20:57 +03:00
end
private
2019-06-22 17:54:06 +03: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-01 17:20:57 +03:00
def set_file_extensions
self . class . attachment_definitions . each_key do | attachment_name |
attachment = send ( attachment_name )
2018-04-23 10:16:38 +03:00
2017-05-01 17:20:57 +03:00
next if attachment . blank?
2018-04-23 10:16:38 +03: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-03 20:47:09 +03:00
next if attachment . blank? || ! / image.* / . match? ( attachment . content_type ) || attachment . queued_for_write [ :original ] . blank?
2018-04-23 10:16:38 +03:00
width , height = FastImage . size ( attachment . queued_for_write [ :original ] . path )
2019-08-15 21:20:20 +03: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-01 17:20:57 +03:00
end
end
2018-04-23 10:16:38 +03: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-18 18:27:05 +03:00
proper_extension = extensions_for_mime_type . first . to_s
2018-06-24 14:33:06 +03:00
extension = extensions_for_mime_type . include? ( original_extension ) ? original_extension : proper_extension
extension = 'jpeg' if extension == 'jpe'
2018-04-23 10:16:38 +03:00
2018-06-24 14:33:06 +03:00
extension
2018-04-23 10:16:38 +03:00
end
2019-06-22 17:54:06 +03:00
def calculated_content_type ( attachment )
2019-06-30 17:10:43 +03: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-22 17:54:06 +03:00
rescue Terrapin :: CommandLineError
''
end
2017-05-01 17:20:57 +03:00
end