diff --git a/lib/paperclip.rb b/lib/paperclip.rb index 3fe6fdb3d..6effec6e7 100644 --- a/lib/paperclip.rb +++ b/lib/paperclip.rb @@ -58,6 +58,8 @@ require 'mime/types' require 'logger' require 'cocaine' +require 'mimemagic' +require 'mimemagic/overlay' require 'paperclip/railtie' if defined?(Rails) diff --git a/lib/paperclip/attachment.rb b/lib/paperclip/attachment.rb index 47e95f0ce..2913ec68b 100644 --- a/lib/paperclip/attachment.rb +++ b/lib/paperclip/attachment.rb @@ -147,7 +147,8 @@ def url(style_name = default_style, options = {}) def default_options { :timestamp => @options[:use_timestamp], - :escape => @options[:escape_url] + :escape => @options[:escape_url], + :url_filter => Paperclip.options[:url_filter] } end diff --git a/lib/paperclip/content_type_detector.rb b/lib/paperclip/content_type_detector.rb index ff286213b..ccab48774 100644 --- a/lib/paperclip/content_type_detector.rb +++ b/lib/paperclip/content_type_detector.rb @@ -33,7 +33,7 @@ def detect elsif calculated_type_matches.any? calculated_type_matches.first else - type_from_file_command || SENSIBLE_DEFAULT + type_from_file_contents || SENSIBLE_DEFAULT end.to_s end @@ -54,11 +54,26 @@ def possible_types end def calculated_type_matches - possible_types.select{|content_type| content_type == type_from_file_command } + possible_types.select do |content_type| + content_type == type_from_file_contents + end + end + + def type_from_file_contents + type_from_mime_magic || type_from_file_command + rescue Errno::ENOENT => e + Paperclip.log("Error while determining content type: #{e}") + SENSIBLE_DEFAULT end def type_from_file_command - @type_from_file_command ||= FileCommandContentTypeDetector.new(@filename).detect + @type_from_file_command ||= + FileCommandContentTypeDetector.new(@filename).detect + end + + def type_from_mime_magic + @type_from_mime_magic ||= + MimeMagic.by_magic(File.open(@filename)).try(:type) end end end diff --git a/lib/paperclip/file_command_content_type_detector.rb b/lib/paperclip/file_command_content_type_detector.rb index a711597fe..6623484c2 100644 --- a/lib/paperclip/file_command_content_type_detector.rb +++ b/lib/paperclip/file_command_content_type_detector.rb @@ -13,20 +13,18 @@ def detect private def type_from_file_command + # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist. type = begin - # On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist. - Paperclip.run("file", "-b --mime :file", :file => @filename) - rescue Cocaine::CommandLineError => e - Paperclip.log("Error while determining content type: #{e}") - SENSIBLE_DEFAULT - end + Paperclip.run("file", "-b --mime :file", file: @filename) + rescue Cocaine::CommandLineError => e + Paperclip.log("Error while determining content type: #{e}") + SENSIBLE_DEFAULT + end if type.nil? || type.match(/\(.*?\)/) type = SENSIBLE_DEFAULT end type.split(/[:;\s]+/)[0] end - end end - diff --git a/lib/paperclip/interpolations.rb b/lib/paperclip/interpolations.rb index 210886a38..62d5bf60b 100644 --- a/lib/paperclip/interpolations.rb +++ b/lib/paperclip/interpolations.rb @@ -51,7 +51,7 @@ def filename attachment, style_name RIGHT_HERE = "#{__FILE__.gsub(%r{\A\./}, "")}:#{__LINE__ + 3}" def url attachment, style_name raise Errors::InfiniteInterpolationError if caller.any?{|b| b.index(RIGHT_HERE) } - attachment.url(style_name, :timestamp => false, :escape => false) + attachment.url(style_name, :timestamp => false, :escape => false, :signing_validity => :internal) end # Returns the timestamp as defined by the _updated_at field diff --git a/lib/paperclip/url_generator.rb b/lib/paperclip/url_generator.rb index 31e0fd40b..c8075d3e2 100644 --- a/lib/paperclip/url_generator.rb +++ b/lib/paperclip/url_generator.rb @@ -8,15 +8,22 @@ def initialize(attachment, attachment_options) end def for(style_name, options) - escape_url_as_needed( - timestamp_as_needed( - @attachment_options[:interpolator].interpolate(most_appropriate_url, @attachment, style_name), - options - ), options) + run_filter( + escape_url_as_needed( + timestamp_as_needed( + @attachment_options[:interpolator].interpolate(most_appropriate_url, @attachment, style_name), + options + ), options + ), options + ) end private + def run_filter(url, options) + return url if @attachment.original_filename.nil? + options[:url_filter].call(url, options) + end # This method is all over the place. def default_url if @attachment_options[:default_url].respond_to?(:call) diff --git a/paperclip.gemspec b/paperclip.gemspec index ed6a0d429..673d6dfb6 100644 --- a/paperclip.gemspec +++ b/paperclip.gemspec @@ -26,6 +26,7 @@ Gem::Specification.new do |s| s.add_dependency('activesupport', '>= 3.0.0') s.add_dependency('cocaine', '~> 0.5.3') s.add_dependency('mime-types') + s.add_dependency('mimemagic', '0.3.3') s.add_development_dependency('activerecord', '>= 3.0.0') s.add_development_dependency('shoulda')