mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Separate registry content type and content disposition
This commit is contained in:
		| @@ -2,7 +2,6 @@ require 'linguist/language' | ||||
| require 'linguist/mime' | ||||
| require 'linguist/pathname' | ||||
|  | ||||
| require 'escape_utils' | ||||
| require 'yaml' | ||||
|  | ||||
| module Linguist | ||||
| @@ -63,12 +62,7 @@ module Linguist | ||||
|     # | ||||
|     # Returns a content disposition String. | ||||
|     def disposition | ||||
|       case content_type | ||||
|       when 'application/octet-stream', 'application/java-archive' | ||||
|         "attachment; filename=#{EscapeUtils.escape_url(pathname.basename)}" | ||||
|       else | ||||
|         'inline' | ||||
|       end | ||||
|       pathname.disposition | ||||
|     end | ||||
|  | ||||
|     # Public: Is the blob text? | ||||
|   | ||||
| @@ -1,7 +1,11 @@ | ||||
| # MIME types and extensions to override when the raw blob is served | ||||
|  | ||||
| # mime types | ||||
| application/javascript: text/plain | ||||
| application/perl: text/plain | ||||
| application/python: text/plain | ||||
| application/rdf+xml: text/plain | ||||
| application/ruby: text/plain | ||||
| application/sh: text/plain | ||||
| application/tex: text/plain | ||||
| application/xhtml+xml: text/plain | ||||
|   | ||||
| @@ -1,11 +1,42 @@ | ||||
| require 'mime/types' | ||||
| require 'yaml' | ||||
|  | ||||
| module MIME | ||||
|   class Type | ||||
|     attr_accessor :binary | ||||
|  | ||||
|     undef_method :binary? | ||||
|     def binary? | ||||
|       if defined? @binary | ||||
|         @binary | ||||
|       else | ||||
|         @encoding == 'base64' | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     attr_accessor :attachment | ||||
|  | ||||
|     def attachment? | ||||
|       if defined? @attachment | ||||
|         @attachment | ||||
|       else | ||||
|         binary? | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | ||||
| # Register additional mime type extensions | ||||
| mime_extensions = YAML.load_file(File.expand_path("../mimes.yml", __FILE__)) | ||||
| mime_extensions.each do |mime_type, exts| | ||||
| mime_extensions.each do |mime_type, options| | ||||
|   mime = MIME::Types[mime_type].first || MIME::Type.new(mime_type) | ||||
|   exts.each { |ext| mime.extensions << ext } | ||||
|  | ||||
|   (options['extensions'] || []).each { |ext| mime.extensions << ext } | ||||
|  | ||||
|   mime.binary     = options['binary']     if options.key?('binary') | ||||
|   mime.attachment = options['attachment'] if options.key?('attachment') | ||||
|  | ||||
|   MIME::Types.add_type_variant(mime) | ||||
|   MIME::Types.index_extensions(mime) | ||||
| end | ||||
|  | ||||
| @@ -59,5 +90,49 @@ module Linguist | ||||
|  | ||||
|       type | ||||
|     end | ||||
|  | ||||
|     # Internal: Determine if extension or mime type is binary. | ||||
|     # | ||||
|     # ext_or_mime_type - A file extension ".txt" or mime type "text/plain". | ||||
|     # | ||||
|     # Returns true or false | ||||
|     def self.binary?(ext_or_mime_type) | ||||
|       mime_type = lookup_mime_type_for(ext_or_mime_type) | ||||
|       mime_type.nil? || mime_type.binary? | ||||
|     end | ||||
|  | ||||
|     # Internal: Determine if extension or mime type is an attachment. | ||||
|     # | ||||
|     # ext_or_mime_type - A file extension ".txt" or mime type "text/plain". | ||||
|     # | ||||
|     # Attachments are files that should be downloaded rather than be | ||||
|     # displayed in the browser. | ||||
|     # | ||||
|     # This is used to set our Content-Disposition headers. | ||||
|     # | ||||
|     # Attachment files should generally binary files but non- | ||||
|     # attachments do not imply plain text. For an example Images are | ||||
|     # not treated as attachments. | ||||
|     # | ||||
|     # Returns true or false | ||||
|     def self.attachment?(ext_or_mime_type) | ||||
|       mime_type = lookup_mime_type_for(ext_or_mime_type) | ||||
|       mime_type.nil? || mime_type.attachment? | ||||
|     end | ||||
|  | ||||
|     # Internal: Lookup mime type for extension or mime type | ||||
|     # | ||||
|     # Returns a MIME::Type | ||||
|     def self.lookup_mime_type_for(ext_or_mime_type) | ||||
|       ext_or_mime_type ||= '' | ||||
|  | ||||
|       if ext_or_mime_type =~ /\w+\/\w+/ | ||||
|         guesses = ::MIME::Types[ext_or_mime_type] | ||||
|       else | ||||
|         guesses = ::MIME::Types.type_for(ext_or_mime_type) | ||||
|       end | ||||
|  | ||||
|       guesses.first | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -2,13 +2,75 @@ | ||||
| # | ||||
| # Review this list if we ever upgrade from mime-types 1.15 to 1.16 | ||||
|  | ||||
| application/atom+xml: | ||||
|   binary: false | ||||
|  | ||||
| application/javascript: | ||||
|   binary: false | ||||
|   extensions: | ||||
|   - js | ||||
|  | ||||
| application/json: | ||||
|   binary: false | ||||
|   extensions: | ||||
|   - json | ||||
|  | ||||
| application/rdf+xml: | ||||
|   binary: false | ||||
|  | ||||
| application/sh: | ||||
|   binary: false | ||||
|  | ||||
| application/x-troff-ms: | ||||
|   binary: false | ||||
|  | ||||
| application/netcdf: | ||||
|   binary: false | ||||
|  | ||||
| application/x-perl: | ||||
|   binary: false | ||||
|   extensions: | ||||
|   - pl | ||||
|   - pm | ||||
|  | ||||
| application/x-python: | ||||
|   binary: false | ||||
|   extensions: | ||||
|   - py | ||||
|  | ||||
| application/x-ruby: | ||||
|   binary: false | ||||
|   extensions: | ||||
|   - rb | ||||
|  | ||||
| application/x-wais-source: | ||||
|   binary: false | ||||
|  | ||||
| application/vnd.mozilla.xul+xml: | ||||
|   binary: false | ||||
|  | ||||
| application/octet-stream: | ||||
| - dmg | ||||
| - dll | ||||
|   binary: true | ||||
|   extensions: | ||||
|   - dmg | ||||
|   - dll | ||||
|  | ||||
| application/java-archive: | ||||
| - ear | ||||
| - war | ||||
|   binary: true | ||||
|   extensions: | ||||
|   - ear | ||||
|   - war | ||||
|  | ||||
| application/x-shockwave-flash: | ||||
| - swf | ||||
|   binary: true | ||||
|   extensions: | ||||
|   - swf | ||||
|  | ||||
| image/gif: | ||||
|   attachment: false | ||||
|  | ||||
| image/jpeg: | ||||
|   attachment: false | ||||
|  | ||||
| image/png: | ||||
|   attachment: false | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| require 'linguist/language' | ||||
| require 'linguist/mime' | ||||
|  | ||||
| require 'escape_utils' | ||||
|  | ||||
| module Linguist | ||||
|   # Similar to ::Pathname, Linguist::Pathname wraps a path string and | ||||
|   # provides helpful query methods. Its useful when you only have a | ||||
| @@ -99,6 +101,30 @@ module Linguist | ||||
|       @content_type ||= Mime.content_type_for(extname) | ||||
|     end | ||||
|  | ||||
|     # Public: Determine if the Pathname should be served as an | ||||
|     # attachment. | ||||
|     # | ||||
|     # Returns true or false. | ||||
|     def attachment? | ||||
|       @attachment ||= Mime.attachment?(extname) | ||||
|     end | ||||
|  | ||||
|     # Public: Get the Content-Disposition header value | ||||
|     # | ||||
|     # This value is used when serving raw blobs. | ||||
|     # | ||||
|     #   # => "attachment; filename=file.tar" | ||||
|     #   # => "inline" | ||||
|     # | ||||
|     # Returns a content disposition String. | ||||
|     def disposition | ||||
|       if attachment? | ||||
|         "attachment; filename=#{EscapeUtils.escape_url(basename)}" | ||||
|       else | ||||
|         'inline' | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     def to_s | ||||
|       @path.dup | ||||
|     end | ||||
|   | ||||
| @@ -23,7 +23,7 @@ class TestBlob < Test::Unit::TestCase | ||||
|   end | ||||
|  | ||||
|   def test_mime_type | ||||
|     assert_equal "text/plain", blob("grit.rb").mime_type | ||||
|     assert_equal "application/ruby", 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 | ||||
| @@ -31,6 +31,7 @@ class TestBlob < Test::Unit::TestCase | ||||
|  | ||||
|   def test_content_type | ||||
|     assert_equal "text/plain; charset=utf-8", blob("grit.rb").content_type | ||||
|     assert_equal "text/plain; charset=utf-8", blob("foo.pl").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 | ||||
| @@ -69,7 +70,9 @@ class TestBlob < Test::Unit::TestCase | ||||
|     assert blob("git.deb").binary? | ||||
|     assert blob("git.exe").binary? | ||||
|     assert !blob("file.txt").binary? | ||||
|     assert !blob("foo.rb").binary? | ||||
|     assert !blob("octocat.png").binary? | ||||
|     assert !blob("script.pl").binary? | ||||
|   end | ||||
|  | ||||
|   def test_text | ||||
| @@ -88,6 +91,7 @@ class TestBlob < Test::Unit::TestCase | ||||
|  | ||||
|   def test_viewable | ||||
|     assert blob("foo.rb").viewable? | ||||
|     assert blob("script.pl").viewable? | ||||
|     assert !blob("octocat.png").viewable? | ||||
|     assert !blob("linguist.gem").viewable? | ||||
|   end | ||||
|   | ||||
| @@ -8,9 +8,9 @@ class TestMime < Test::Unit::TestCase | ||||
|   def test_mime | ||||
|     assert_equal 'text/plain', Mime.mime_for(nil) | ||||
|  | ||||
|     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 'application/ruby', Mime.mime_for(".rb") | ||||
|     assert_equal 'application/javascript', Mime.mime_for(".js") | ||||
|     assert_equal 'application/python', Mime.mime_for(".py") | ||||
|  | ||||
|     assert_equal 'text/plain', Mime.mime_for(".kt") | ||||
|     assert_equal 'text/html', Mime.mime_for(".html") | ||||
| @@ -49,4 +49,116 @@ class TestMime < Test::Unit::TestCase | ||||
|     assert_equal 'application/java-archive', Mime.content_type_for(".ear") | ||||
|     assert_equal 'application/java-archive', Mime.content_type_for(".war") | ||||
|   end | ||||
|  | ||||
|   def test_binary | ||||
|     assert Mime.binary?("application/octet-stream") | ||||
|     assert !Mime.binary?("text/plain") | ||||
|  | ||||
|     assert Mime.binary?("image/gif") | ||||
|     assert Mime.binary?("image/jpeg") | ||||
|     assert Mime.binary?("image/png") | ||||
|     assert Mime.binary?("java-archive") | ||||
|     assert Mime.binary?("x-shockwave-flash") | ||||
|  | ||||
|     assert !Mime.binary?("application/atom+xml") | ||||
|     assert !Mime.binary?("application/javascript") | ||||
|     assert !Mime.binary?("application/json") | ||||
|     assert !Mime.binary?("application/rdf+xml") | ||||
|     assert !Mime.binary?("application/sh") | ||||
|     assert !Mime.binary?("application/x-perl") | ||||
|     assert !Mime.binary?("application/x-python") | ||||
|     assert !Mime.binary?("application/x-ruby") | ||||
|  | ||||
|     assert !Mime.binary?(".ms") | ||||
|     assert !Mime.binary?(".nc") | ||||
|     assert !Mime.binary?(".src") | ||||
|     assert !Mime.binary?(".xul") | ||||
|   end | ||||
|  | ||||
|   def test_attachment | ||||
|     assert Mime.attachment?("application/octet-stream") | ||||
|     assert !Mime.attachment?("text/plain") | ||||
|  | ||||
|     assert Mime.attachment?("application/java-archive") | ||||
|     assert Mime.attachment?("application/ogg") | ||||
|     assert Mime.attachment?("application/pdf") | ||||
|     assert Mime.attachment?("application/x-gzip") | ||||
|     assert Mime.attachment?("application/zip") | ||||
|     assert Mime.attachment?("audio/mp4") | ||||
|  | ||||
|     assert Mime.attachment?(".a") | ||||
|     assert Mime.attachment?(".air") | ||||
|     assert Mime.attachment?(".blend") | ||||
|     assert Mime.attachment?(".crx") | ||||
|     assert Mime.attachment?(".deb") | ||||
|     assert Mime.attachment?(".dmg") | ||||
|     assert Mime.attachment?(".exe") | ||||
|     assert Mime.attachment?(".gem") | ||||
|     assert Mime.attachment?(".graffle") | ||||
|     assert Mime.attachment?(".gz") | ||||
|     assert Mime.attachment?(".icns") | ||||
|     assert Mime.attachment?(".ipa") | ||||
|     assert Mime.attachment?(".lib") | ||||
|     assert Mime.attachment?(".mcz") | ||||
|     assert Mime.attachment?(".mov") | ||||
|     assert Mime.attachment?(".mp3") | ||||
|     assert Mime.attachment?(".nib") | ||||
|     assert Mime.attachment?(".o") | ||||
|     assert Mime.attachment?(".odp") | ||||
|     assert Mime.attachment?(".ods") | ||||
|     assert Mime.attachment?(".odt") | ||||
|     assert Mime.attachment?(".ogg") | ||||
|     assert Mime.attachment?(".ogv") | ||||
|     assert Mime.attachment?(".otf") | ||||
|     assert Mime.attachment?(".pfx") | ||||
|     assert Mime.attachment?(".pigx") | ||||
|     assert Mime.attachment?(".plgx") | ||||
|     assert Mime.attachment?(".pptx") | ||||
|     assert Mime.attachment?(".psd") | ||||
|     assert Mime.attachment?(".sib") | ||||
|     assert Mime.attachment?(".so") | ||||
|     assert Mime.attachment?(".spl") | ||||
|     assert Mime.attachment?(".sqlite3") | ||||
|     assert Mime.attachment?(".swc") | ||||
|     assert Mime.attachment?(".swf") | ||||
|     assert Mime.attachment?(".tar") | ||||
|     assert Mime.attachment?(".ucode") | ||||
|     assert Mime.attachment?(".xpi") | ||||
|     assert Mime.attachment?(".zip") | ||||
|  | ||||
|     assert !Mime.attachment?("application/atom+xml") | ||||
|     assert !Mime.attachment?("application/javascript") | ||||
|     assert !Mime.attachment?("application/json") | ||||
|     assert !Mime.attachment?("application/rdf+xml") | ||||
|     assert !Mime.attachment?("application/sh") | ||||
|     assert !Mime.attachment?("application/xhtml+xml") | ||||
|     assert !Mime.attachment?("application/xml") | ||||
|     assert !Mime.attachment?("image/gif") | ||||
|     assert !Mime.attachment?("image/jpeg") | ||||
|     assert !Mime.attachment?("image/png") | ||||
|     assert !Mime.attachment?("text/css") | ||||
|     assert !Mime.attachment?("text/csv") | ||||
|     assert !Mime.attachment?("text/html") | ||||
|     assert !Mime.attachment?("text/javascript") | ||||
|     assert !Mime.attachment?("text/plain") | ||||
|  | ||||
|     assert !Mime.attachment?(".gif") | ||||
|     assert !Mime.attachment?(".jpeg") | ||||
|     assert !Mime.attachment?(".jpg") | ||||
|     assert !Mime.attachment?(".js") | ||||
|     assert !Mime.attachment?(".latex") | ||||
|     assert !Mime.attachment?(".ms") | ||||
|     assert !Mime.attachment?(".nc") | ||||
|     assert !Mime.attachment?(".pl") | ||||
|     assert !Mime.attachment?(".png") | ||||
|     assert !Mime.attachment?(".ps") | ||||
|     assert !Mime.attachment?(".py") | ||||
|     assert !Mime.attachment?(".rb") | ||||
|     assert !Mime.attachment?(".sh") | ||||
|     assert !Mime.attachment?(".src") | ||||
|     assert !Mime.attachment?(".tcl") | ||||
|     assert !Mime.attachment?(".texi") | ||||
|     assert !Mime.attachment?(".texinfo") | ||||
|     assert !Mime.attachment?(".xul") | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -52,9 +52,9 @@ class TestPathname < Test::Unit::TestCase | ||||
|   end | ||||
|  | ||||
|   def test_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 'application/ruby', Pathname.new("file.rb").mime_type | ||||
|     assert_equal 'application/javascript', Pathname.new("file.js").mime_type | ||||
|     assert_equal 'application/python', Pathname.new("itty.py").mime_type | ||||
|     assert_equal 'text/plain', Pathname.new("defun.kt").mime_type | ||||
|   end | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user