diff --git a/lib/linguist/blob_helper.rb b/lib/linguist/blob_helper.rb index f1659da5..ebd95594 100644 --- a/lib/linguist/blob_helper.rb +++ b/lib/linguist/blob_helper.rb @@ -11,18 +11,15 @@ module Linguist end def mime_type - @mime_type ||= begin - guesses = MIME::Types.type_for(pathname.extname) - guesses.first ? guesses.first.simplified : 'text/plain' - end + @mime_type ||= pathname.mime_type end - def special_mime_type - Mime.lookup(pathname.extname) + def content_type + pathname.content_type end def disposition - case special_mime_type + case content_type when 'application/octet-stream', 'application/java-archive' "attachment; filename=#{EscapeUtils.escape_url(pathname.basename)}" else @@ -43,7 +40,7 @@ module Linguist end def binary? - special_mime_type == 'octet-stream' || !(text? || image?) + content_type.include?('octet') || !(text? || image?) end def file? @@ -51,8 +48,7 @@ module Linguist end def text? - pathname.media_type == 'text' || - pathname.mime_type == 'application/json' + content_type[/(text|json)/] end def image? diff --git a/lib/linguist/special_mime_types.yml b/lib/linguist/content_types.yml similarity index 94% rename from lib/linguist/special_mime_types.yml rename to lib/linguist/content_types.yml index 391578a9..2a24546d 100644 --- a/lib/linguist/special_mime_types.yml +++ b/lib/linguist/content_types.yml @@ -12,9 +12,6 @@ air: application/octet-stream blend: application/octet-stream crx: application/octet-stream deb: application/octet-stream -dll: application/octet-stream -dmg: application/octet-stream -exe: application/octet-stream gem: application/octet-stream graffle: application/octet-stream gz: application/octet-stream diff --git a/lib/linguist/mime.rb b/lib/linguist/mime.rb index 26bf2cb1..78266525 100644 --- a/lib/linguist/mime.rb +++ b/lib/linguist/mime.rb @@ -1,5 +1,11 @@ require 'mime/types' +# Register additional binary extensions +binary = MIME::Types['application/octet-stream'].first +binary.extensions << 'dmg' +binary.extensions << 'dll' +MIME::Types.index_extensions(binary) + # Register 'ear' and 'war' as java java = MIME::Types['application/java-archive'].first java.extensions << 'ear' @@ -8,20 +14,19 @@ MIME::Types.index_extensions(java) module Linguist module Mime - Special = YAML.load_file(File.expand_path("../special_mime_types.yml", __FILE__)) + Special = YAML.load_file(File.expand_path("../content_types.yml", __FILE__)) - def self.lookup(ext) + def self.mime_for(ext) ext ||= '' - guesses = ::MIME::Types.type_for(ext) - orginal_type = guesses.first ? guesses.first.simplified : 'text/plain' - - type = Special[orginal_type] || - Special[ext.sub(/^\./, '')] || - orginal_type + guesses.first ? guesses.first.simplified : 'text/plain' + end + def self.content_type_for(ext) + ext ||= '' + type = mime_for(ext) + type = Special[type] || Special[ext.sub(/^\./, '')] || type type += '; charset=utf-8' if type =~ /^text\// - type end end diff --git a/lib/linguist/pathname.rb b/lib/linguist/pathname.rb index 3211246c..32398ee6 100644 --- a/lib/linguist/pathname.rb +++ b/lib/linguist/pathname.rb @@ -34,11 +34,19 @@ module Linguist end def mime_type - @mime_type ||= Mime.lookup(extname) + @mime_type ||= Mime.mime_for(extname) end def media_type - mime_type.split('/').first + mime_type.split('/')[0] + end + + def sub_type + mime_type.split('/')[1] + end + + def content_type + @content_type ||= Mime.content_type_for(extname) end def to_s diff --git a/test/test_blob.rb b/test/test_blob.rb index 0473e828..7453e68c 100644 --- a/test/test_blob.rb +++ b/test/test_blob.rb @@ -41,12 +41,14 @@ class TestBlob < Test::Unit::TestCase assert_equal "text/plain", blob("grit.rb").mime_type assert_equal "application/xml", blob("bar.xml").mime_type assert_equal "text/plain", blob("dog.o").mime_type + assert_equal "application/sh", blob("script.sh").mime_type end - def test_special_mime_type - assert_equal "text/plain; charset=utf-8", blob("grit.rb").special_mime_type - assert_equal "text/plain; charset=utf-8", blob("bar.xml").special_mime_type - assert_equal "application/octet-stream", blob("dog.o").special_mime_type + def test_content_type + assert_equal "text/plain; charset=utf-8", blob("grit.rb").content_type + assert_equal "text/plain; charset=utf-8", blob("bar.xml").content_type + assert_equal "application/octet-stream", blob("dog.o").content_type + assert_equal "text/plain; charset=utf-8", blob("script.sh").content_type end def test_disposition @@ -93,6 +95,7 @@ class TestBlob < Test::Unit::TestCase def test_text assert blob("file.txt").text? assert blob("file.json").text? + assert blob("script.sh").text? end def test_image diff --git a/test/test_mime.rb b/test/test_mime.rb index 1bca8991..1dd08fe2 100644 --- a/test/test_mime.rb +++ b/test/test_mime.rb @@ -5,22 +5,45 @@ require 'test/unit' class TestMime < Test::Unit::TestCase include Linguist - def test_lookup - assert_equal 'text/plain; charset=utf-8', Mime.lookup(nil) + def test_mime + assert_equal 'text/plain', Mime.mime_for(nil) - assert_equal 'text/plain; charset=utf-8', Mime.lookup(".rb") - assert_equal 'text/plain; charset=utf-8', Mime.lookup(".js") - assert_equal 'text/plain; charset=utf-8', Mime.lookup(".py") + assert_equal 'text/plain', Mime.mime_for(".rb") + assert_equal 'text/plain', Mime.mime_for(".js") + assert_equal 'text/plain', Mime.mime_for(".py") - assert_equal 'text/plain; charset=utf-8', Mime.lookup(".kt") - assert_equal 'text/plain; charset=utf-8', Mime.lookup(".html") - assert_equal 'text/plain; charset=utf-8', Mime.lookup(".sh") - assert_equal 'text/plain; charset=utf-8', Mime.lookup(".latex") + assert_equal 'text/plain', Mime.mime_for(".kt") + assert_equal 'text/html', Mime.mime_for(".html") + assert_equal 'application/sh', Mime.mime_for(".sh") + assert_equal 'application/latex', Mime.mime_for(".latex") - assert_equal 'application/octet-stream', Mime.lookup(".dmg") + assert_equal 'application/octet-stream', Mime.mime_for(".dmg") + assert_equal 'application/octet-stream', Mime.mime_for(".exe") + assert_equal 'application/octet-stream', Mime.mime_for(".dll") - assert_equal 'application/java-archive', Mime.lookup(".jar") - assert_equal 'application/java-archive', Mime.lookup(".ear") - assert_equal 'application/java-archive', Mime.lookup(".war") + assert_equal 'application/java-archive', Mime.mime_for(".jar") + assert_equal 'application/java-archive', Mime.mime_for(".ear") + assert_equal 'application/java-archive', Mime.mime_for(".war") + end + + def test_content_type + assert_equal 'text/plain; charset=utf-8', Mime.content_type_for(nil) + + assert_equal 'text/plain; charset=utf-8', Mime.content_type_for(".rb") + assert_equal 'text/plain; charset=utf-8', Mime.content_type_for(".js") + assert_equal 'text/plain; charset=utf-8', Mime.content_type_for(".py") + + assert_equal 'text/plain; charset=utf-8', Mime.content_type_for(".kt") + assert_equal 'text/plain; charset=utf-8', Mime.content_type_for(".html") + assert_equal 'text/plain; charset=utf-8', Mime.content_type_for(".sh") + assert_equal 'text/plain; charset=utf-8', Mime.content_type_for(".latex") + + assert_equal 'application/octet-stream', Mime.content_type_for(".dmg") + assert_equal 'application/octet-stream', Mime.content_type_for(".exe") + assert_equal 'application/octet-stream', Mime.content_type_for(".dll") + + assert_equal 'application/java-archive', Mime.content_type_for(".jar") + assert_equal 'application/java-archive', Mime.content_type_for(".ear") + assert_equal 'application/java-archive', Mime.content_type_for(".war") end end diff --git a/test/test_pathname.rb b/test/test_pathname.rb index 95cfd5ce..ae1281f6 100644 --- a/test/test_pathname.rb +++ b/test/test_pathname.rb @@ -61,10 +61,16 @@ class TestPathname < Test::Unit::TestCase end def test_mime_type - assert_equal 'text/plain; charset=utf-8', Pathname.new("file.rb").mime_type - assert_equal 'text/plain; charset=utf-8', Pathname.new("file.js").mime_type - assert_equal 'text/plain; charset=utf-8', Pathname.new("itty.py").mime_type - assert_equal 'text/plain; charset=utf-8', Pathname.new("defun.kt").mime_type + assert_equal 'text/plain', Pathname.new("file.rb").mime_type + assert_equal 'text/plain', Pathname.new("file.js").mime_type + assert_equal 'text/plain', Pathname.new("itty.py").mime_type + assert_equal 'text/plain', Pathname.new("defun.kt").mime_type + end + + def test_content_type + assert_equal 'text/plain; charset=utf-8', Pathname.new("file.txt").content_type + assert_equal 'text/plain; charset=utf-8', Pathname.new("file.rb").content_type + assert_equal 'image/png', Pathname.new("octocat.png").content_type end def test_media_type