fileinfo 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +31 -6
- data/fileinfo.gemspec +3 -2
- data/lib/file_info.rb +36 -18
- data/lib/file_info/version.rb +1 -1
- data/spec/file_info_spec.rb +89 -8
- data/spec/fixtures/bytes +1 -0
- data/spec/fixtures/mockup.psd +0 -0
- metadata +36 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fd22a80c28289631c040bde751eee82a7b51369
|
4
|
+
data.tar.gz: 38320adc6dc77ad1e6e38e6d4d1b4c49052da480
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24f820540d61e3e613b3c511eb3d5e8cebc7663de1c8828d6b4456a7215835ec7c18e1574411315e8961c0a7b1de2c63f7eddf1654b675a45139a0cf0ac8b59c
|
7
|
+
data.tar.gz: 2823c8c4c042db5d8b8aecbfffd38b3c552c7c2b20f1300bbddd4aacf5b08ff8139127339fd20d19043d795e1152dc6c3a88f32195aa86ec8f9d2eaf2f466e54
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
[](https://coveralls.io/r/rafBM/fileinfo?branch=master)
|
7
7
|
[](https://gemnasium.com/rafBM/fileinfo)
|
8
8
|
|
9
|
-
FileInfo detects
|
9
|
+
FileInfo detects file encodings and MIME types using the [wonderful Unix `file` command](http://en.wikipedia.org/wiki/File_\(command\)).
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
@@ -30,18 +30,43 @@ $ gem install fileinfo
|
|
30
30
|
|
31
31
|
## Usage
|
32
32
|
|
33
|
-
|
33
|
+
### Detect encoding
|
34
|
+
|
35
|
+
Use `FileInfo.parse` with a string or `FileInfo.load` with a filename.
|
34
36
|
|
35
37
|
```ruby
|
36
38
|
FileInfo.parse('foo bar baz').encoding # => #<Encoding:US-ASCII>
|
37
39
|
FileInfo.parse('föø bår bàz').encoding # => #<Encoding:UTF-8>
|
40
|
+
|
41
|
+
filename = '/Users/rafbm/Downloads/some_crap_coming_from_windows.csv'
|
42
|
+
FileInfo.load(filename).encoding # => #<Encoding:ISO-8859-1>
|
38
43
|
```
|
39
44
|
|
40
|
-
|
45
|
+
### Detect MIME type
|
46
|
+
|
47
|
+
A bunch of methods are available depending on your needs.
|
41
48
|
|
42
49
|
```ruby
|
43
|
-
|
44
|
-
|
50
|
+
info = FileInfo.load('picture.jpg')
|
51
|
+
info.type # => "image/jpeg"
|
52
|
+
info.media_type # => "image"
|
53
|
+
info.sub_type # => "jpeg"
|
54
|
+
```
|
55
|
+
|
56
|
+
The `#mime_type` method can also return a `MIME::Type` instance.
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
info = FileInfo.parse('Hello world')
|
60
|
+
info.mime_type # => #<MIME::Type:0x007f81a1a36090 @content_type="text/plain" ...>
|
61
|
+
```
|
62
|
+
|
63
|
+
**NOTE:** You must install the `mime-types` gem yourself as it is not a dependency of `fileinfo`.
|
64
|
+
|
65
|
+
Finally, `#content_type` can be used to get the full string returned by `file --mime --brief`.
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
info = FileInfo.parse('Hëllø wõrld')
|
69
|
+
info.content_type # => "text/plain; charset=utf-8"
|
45
70
|
```
|
46
71
|
|
47
72
|
## Contributing
|
@@ -54,4 +79,4 @@ FileInfo.load(filename).encoding # => #<Encoding:ISO-8859-1>
|
|
54
79
|
|
55
80
|
---
|
56
81
|
|
57
|
-
©
|
82
|
+
© 2014 [Rafaël Blais Masson](http://rafbm.com). FileInfo is released under the MIT license.
|
data/fileinfo.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = FileInfo::VERSION
|
9
9
|
spec.authors = ['Rafaël Blais Masson']
|
10
10
|
spec.email = ['rafael@heliom.ca']
|
11
|
-
spec.description = "FileInfo detects
|
12
|
-
spec.summary = "FileInfo detects
|
11
|
+
spec.description = "FileInfo detects file encodings and MIME types using the wonderful Unix `file` command."
|
12
|
+
spec.summary = "FileInfo detects file encodings and MIME types using the wonderful Unix `file` command."
|
13
13
|
spec.homepage = 'http://github.com/rafBM/fileinfo'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
22
|
spec.add_development_dependency 'rake'
|
23
23
|
spec.add_development_dependency 'rspec', '~> 2.14'
|
24
|
+
spec.add_development_dependency 'mime-types'
|
24
25
|
end
|
data/lib/file_info.rb
CHANGED
@@ -6,42 +6,60 @@ require 'tempfile'
|
|
6
6
|
class FileInfo
|
7
7
|
class UnknownEncodingError < StandardError; end
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
MIME_TYPE_REGEX = /^[^;]+/
|
10
|
+
CHARSET_REGEX = /charset=(\S+)/
|
11
|
+
|
12
|
+
MIME_TYPE_ERROR_MESSAGE = 'You must install the "mime-types" gem to use FileInfo#mime_type'
|
13
|
+
|
14
|
+
attr_reader :content_type
|
11
15
|
|
12
16
|
def initialize(output)
|
13
|
-
@
|
17
|
+
@content_type = output.strip
|
18
|
+
end
|
19
|
+
|
20
|
+
def type
|
21
|
+
@type ||= content_type.match(MIME_TYPE_REGEX)[0]
|
22
|
+
end
|
23
|
+
|
24
|
+
def media_type
|
25
|
+
@media_type ||= type.split('/')[0]
|
26
|
+
end
|
27
|
+
|
28
|
+
def sub_type
|
29
|
+
@sub_type ||= type.split('/')[1]
|
30
|
+
end
|
31
|
+
|
32
|
+
def mime_type
|
33
|
+
@mime_type ||= begin
|
34
|
+
require 'mime/types' unless defined? MIME::Types
|
35
|
+
MIME::Types[type][0]
|
36
|
+
rescue LoadError
|
37
|
+
raise LoadError, MIME_TYPE_ERROR_MESSAGE
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def charset
|
42
|
+
@charset ||= content_type.match(CHARSET_REGEX)[1]
|
14
43
|
end
|
15
44
|
|
16
45
|
def encoding
|
17
|
-
@encoding ||= ::Encoding.find(
|
46
|
+
@encoding ||= ::Encoding.find(charset)
|
18
47
|
rescue ArgumentError => e
|
19
48
|
raise UnknownEncodingError, e.message
|
20
49
|
end
|
21
50
|
|
22
51
|
def self.load(filename)
|
23
52
|
raise ArgumentError, "File '#{filename}' does not exist." if !File.exists? filename
|
24
|
-
new `file --mime #{Shellwords.escape(filename)}`
|
53
|
+
new `file --mime --brief #{Shellwords.escape(filename)}`
|
25
54
|
end
|
26
55
|
|
27
56
|
def self.parse(content)
|
28
57
|
file = Tempfile.new(rand.to_s)
|
29
58
|
file.write(content)
|
30
59
|
file.rewind
|
31
|
-
|
60
|
+
new `file --mime --brief #{file.path}`
|
61
|
+
ensure
|
32
62
|
file.close
|
33
63
|
file.unlink
|
34
|
-
|
35
|
-
new output
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def string
|
41
|
-
@string ||= @output.match(STRING_REGEX)[1].strip
|
42
|
-
end
|
43
|
-
|
44
|
-
def encoding_string
|
45
|
-
@encoding_string ||= string.match(ENCODING_REGEX)[1]
|
46
64
|
end
|
47
65
|
end
|
data/lib/file_info/version.rb
CHANGED
data/spec/file_info_spec.rb
CHANGED
@@ -7,15 +7,33 @@ describe FileInfo do
|
|
7
7
|
let(:macroman_file) { fixture('encoding_macroman.csv') }
|
8
8
|
let(:utf8_file) { fixture('encoding_utf8.csv') }
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
let(:photoshop_file) { fixture('mockup.psd') }
|
11
|
+
let(:binary_file) { fixture('bytes') }
|
12
|
+
|
13
|
+
describe '#charset' do
|
14
|
+
it 'returns encoding string' do
|
15
|
+
expect(FileInfo.load(ascii_file.path).charset).to eq 'us-ascii'
|
16
|
+
expect(FileInfo.load(isolatin_file.path).charset).to eq 'iso-8859-1'
|
17
|
+
expect(FileInfo.load(isowindows_file.path).charset).to eq 'iso-8859-1'
|
18
|
+
expect(FileInfo.load(utf8_file.path).charset).to eq 'utf-8'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#encoding' do
|
23
|
+
it 'returns Encoding instance' do
|
12
24
|
expect(FileInfo.load(ascii_file.path).encoding).to eq Encoding::US_ASCII
|
13
25
|
expect(FileInfo.load(isolatin_file.path).encoding).to eq Encoding::ISO_8859_1
|
14
26
|
expect(FileInfo.load(isowindows_file.path).encoding).to eq Encoding::ISO_8859_1
|
15
27
|
expect(FileInfo.load(utf8_file.path).encoding).to eq Encoding::UTF_8
|
16
28
|
end
|
17
29
|
|
18
|
-
it '
|
30
|
+
it 'raises UnknownEncodingError' do
|
31
|
+
expect { FileInfo.load(macroman_file.path).encoding }.to raise_error(FileInfo::UnknownEncodingError)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '.load' do
|
36
|
+
it 'accepts filename with space' do
|
19
37
|
old_filename = fixture('encoding_utf8.csv').path
|
20
38
|
new_filename = old_filename.sub('_', ' ')
|
21
39
|
FileUtils.cp(old_filename, new_filename)
|
@@ -25,7 +43,7 @@ describe FileInfo do
|
|
25
43
|
FileUtils.rm(new_filename)
|
26
44
|
end
|
27
45
|
|
28
|
-
it '
|
46
|
+
it 'accepts filename with space and quote' do
|
29
47
|
old_filename = fixture('encoding_utf8.csv').path
|
30
48
|
new_filename = old_filename.sub('_', ' " ')
|
31
49
|
FileUtils.cp(old_filename, new_filename)
|
@@ -41,7 +59,7 @@ describe FileInfo do
|
|
41
59
|
end
|
42
60
|
|
43
61
|
describe '.parse' do
|
44
|
-
it '
|
62
|
+
it 'accepts a string' do
|
45
63
|
expect(FileInfo.parse(ascii_file.read).encoding).to eq Encoding::US_ASCII
|
46
64
|
expect(FileInfo.parse(isolatin_file.read).encoding).to eq Encoding::ISO_8859_1
|
47
65
|
expect(FileInfo.parse(isowindows_file.read).encoding).to eq Encoding::ISO_8859_1
|
@@ -49,9 +67,72 @@ describe FileInfo do
|
|
49
67
|
end
|
50
68
|
end
|
51
69
|
|
52
|
-
|
53
|
-
|
54
|
-
|
70
|
+
let(:txt) { FileInfo.parse(FileInfo.parse('Hello, world!')) }
|
71
|
+
let(:csv) { FileInfo.load(utf8_file.path) }
|
72
|
+
let(:psd) { FileInfo.load(photoshop_file.path) }
|
73
|
+
let(:empty) { FileInfo.parse('') }
|
74
|
+
let(:bytes) { FileInfo.load(binary_file.path) }
|
75
|
+
|
76
|
+
describe '#content_type' do
|
77
|
+
it 'returns full Content-Type string' do
|
78
|
+
expect(txt.content_type).to eq 'text/plain; charset=us-ascii'
|
79
|
+
expect(csv.content_type).to eq 'text/plain; charset=utf-8'
|
80
|
+
expect(psd.content_type).to eq 'image/vnd.adobe.photoshop; charset=binary'
|
81
|
+
expect(empty.content_type).to eq 'application/x-empty; charset=binary'
|
82
|
+
expect(bytes.content_type).to eq 'application/octet-stream; charset=binary'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#type' do
|
87
|
+
it 'returns MIME type string' do
|
88
|
+
expect(txt.type).to eq 'text/plain'
|
89
|
+
expect(csv.type).to eq 'text/plain'
|
90
|
+
expect(psd.type).to eq 'image/vnd.adobe.photoshop'
|
91
|
+
expect(empty.type).to eq 'application/x-empty'
|
92
|
+
expect(bytes.type).to eq 'application/octet-stream'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#media_type' do
|
97
|
+
it 'returns MIME media type string' do
|
98
|
+
expect(txt.media_type).to eq 'text'
|
99
|
+
expect(csv.media_type).to eq 'text'
|
100
|
+
expect(psd.media_type).to eq 'image'
|
101
|
+
expect(empty.media_type).to eq 'application'
|
102
|
+
expect(bytes.media_type).to eq 'application'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#sub_type' do
|
107
|
+
it 'returns MIME sub type string' do
|
108
|
+
expect(txt.sub_type).to eq 'plain'
|
109
|
+
expect(csv.sub_type).to eq 'plain'
|
110
|
+
expect(psd.sub_type).to eq 'vnd.adobe.photoshop'
|
111
|
+
expect(empty.sub_type).to eq 'x-empty'
|
112
|
+
expect(bytes.sub_type).to eq 'octet-stream'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe '#mime_type' do
|
117
|
+
it 'returns a MIME::Type instance' do
|
118
|
+
[txt, csv, psd, bytes].each do |fileinfo|
|
119
|
+
expect(fileinfo.mime_type).to be_a MIME::Type
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'returns nil for empty file' do
|
124
|
+
expect(empty.mime_type).to eq nil
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'when "mime-types" gem isn’t available' do
|
128
|
+
before do
|
129
|
+
MIME.send(:remove_const, :Types)
|
130
|
+
allow_any_instance_of(FileInfo).to receive(:require).with('mime/types').and_raise(LoadError)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'raises LoadError with custom message' do
|
134
|
+
expect { txt.mime_type }.to raise_error(LoadError, FileInfo::MIME_TYPE_ERROR_MESSAGE)
|
135
|
+
end
|
55
136
|
end
|
56
137
|
end
|
57
138
|
end
|
data/spec/fixtures/bytes
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
�Ɋ���z��S��Q_
|
Binary file
|
metadata
CHANGED
@@ -1,68 +1,82 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fileinfo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafaël Blais Masson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-04-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '2.14'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '2.14'
|
55
|
-
|
56
|
-
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mime-types
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: FileInfo detects file encodings and MIME types using the wonderful Unix
|
70
|
+
`file` command.
|
57
71
|
email:
|
58
72
|
- rafael@heliom.ca
|
59
73
|
executables: []
|
60
74
|
extensions: []
|
61
75
|
extra_rdoc_files: []
|
62
76
|
files:
|
63
|
-
- .gitignore
|
64
|
-
- .rspec
|
65
|
-
- .travis.yml
|
77
|
+
- ".gitignore"
|
78
|
+
- ".rspec"
|
79
|
+
- ".travis.yml"
|
66
80
|
- Gemfile
|
67
81
|
- LICENSE.txt
|
68
82
|
- README.md
|
@@ -72,11 +86,13 @@ files:
|
|
72
86
|
- lib/file_info/version.rb
|
73
87
|
- lib/fileinfo.rb
|
74
88
|
- spec/file_info_spec.rb
|
89
|
+
- spec/fixtures/bytes
|
75
90
|
- spec/fixtures/encoding_ascii.csv
|
76
91
|
- spec/fixtures/encoding_isolatin.csv
|
77
92
|
- spec/fixtures/encoding_isowindows.csv
|
78
93
|
- spec/fixtures/encoding_macroman.csv
|
79
94
|
- spec/fixtures/encoding_utf8.csv
|
95
|
+
- spec/fixtures/mockup.psd
|
80
96
|
- spec/spec_helper.rb
|
81
97
|
homepage: http://github.com/rafBM/fileinfo
|
82
98
|
licenses:
|
@@ -88,26 +104,28 @@ require_paths:
|
|
88
104
|
- lib
|
89
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
90
106
|
requirements:
|
91
|
-
- -
|
107
|
+
- - ">="
|
92
108
|
- !ruby/object:Gem::Version
|
93
109
|
version: '0'
|
94
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
111
|
requirements:
|
96
|
-
- -
|
112
|
+
- - ">="
|
97
113
|
- !ruby/object:Gem::Version
|
98
114
|
version: '0'
|
99
115
|
requirements: []
|
100
116
|
rubyforge_project:
|
101
|
-
rubygems_version: 2.
|
117
|
+
rubygems_version: 2.2.2
|
102
118
|
signing_key:
|
103
119
|
specification_version: 4
|
104
|
-
summary: FileInfo detects
|
105
|
-
|
120
|
+
summary: FileInfo detects file encodings and MIME types using the wonderful Unix `file`
|
121
|
+
command.
|
106
122
|
test_files:
|
107
123
|
- spec/file_info_spec.rb
|
124
|
+
- spec/fixtures/bytes
|
108
125
|
- spec/fixtures/encoding_ascii.csv
|
109
126
|
- spec/fixtures/encoding_isolatin.csv
|
110
127
|
- spec/fixtures/encoding_isowindows.csv
|
111
128
|
- spec/fixtures/encoding_macroman.csv
|
112
129
|
- spec/fixtures/encoding_utf8.csv
|
130
|
+
- spec/fixtures/mockup.psd
|
113
131
|
- spec/spec_helper.rb
|