exiftoolr 0.0.9 → 0.1.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.
@@ -1,80 +1,82 @@
1
- ---
2
- :gps_latitude_ref: North
3
- :model: iPhone 4S
4
- :color_space: sRGB
5
- :components_configuration: Y, Cb, Cr, -
6
- :exif_byte_order: Big-endian (Motorola, MM)
7
- :sensing_method: One-chip color area
8
- :create_date: 2011-11-23 09:39:52 -08:00
9
- :bits_per_sample: 8
10
- :date_time_original: 2011-11-23 09:39:52 -08:00
11
- :source_file: test/iPhone 4S.jpg
12
- :gps_img_direction: 121.9838275
13
- :thumbnail_length: 5987
14
- :exif_image_width: 3264
15
- :exposure_program: Program AE
16
- :compression: JPEG (old-style)
17
- :image_size: 3264x2448
1
+ ---
2
+ :source_file: /Users/mrm/Dropbox/code/exiftoolr/test/iPhone 4S.jpg
3
+ :exif_tool_version: 9.31
4
+ :file_name: iPhone 4S.jpg
5
+ :directory: /Users/mrm/Dropbox/code/exiftoolr/test
6
+ :file_size: 1954 kB
7
+ :file_modify_date: 2012-02-23 05:22:18.000000000 +00:00
8
+ :file_access_date: 2013-07-14 20:25:41.000000000 +00:00
9
+ :file_inode_change_date: 2013-02-16 19:21:57.000000000 +00:00
10
+ :file_permissions: rw-r--r--
11
+ :file_type: JPEG
18
12
  :mime_type: image/jpeg
19
- :gps_longitude: -122.47566667
20
- :x_resolution: 72
13
+ :exif_byte_order: Big-endian (Motorola, MM)
14
+ :make: Apple
15
+ :model: iPhone 4S
21
16
  :orientation: Horizontal (normal)
17
+ :x_resolution: 72
18
+ :y_resolution: 72
19
+ :resolution_unit: inches
22
20
  :software: 5.0.1
23
- :thumbnail_offset: 914
24
- :gps_altitude_ref: Above Sea Level
25
- :shutter_speed: !ruby/object:Rational
21
+ :modify_date: 2011-11-23 09:39:52.000000000 +00:00
22
+ :y_cb_cr_positioning: Centered
23
+ :exposure_time: !ruby/object:Rational
26
24
  denominator: 6135
27
25
  numerator: 1
28
- :directory: test
29
- :flashpix_version: "0100"
30
- :y_cb_cr_positioning: Centered
31
- :flash: Auto, Did not fire
32
26
  :f_number: 2.4
33
- :gps_altitude: 14.2 m Above Sea Level
34
- :file_modify_date: 2012-02-19 21:49:48 -08:00
35
- :y_resolution: 72
36
- :encoding_process: Baseline DCT, Huffman coding
37
- :thumbnail_image: (Binary data 5987 bytes)
38
- :exposure_mode: Auto
39
- :white_balance: Auto
40
- :circle_of_confusion: 0.004 mm
41
- :metering_mode: Multi-segment
42
- :gps_latitude: 37.50233333
43
- :color_components: 3
44
- :image_height: 2448
45
- :exif_tool_version: 8.59
46
- :exposure_time: !ruby/object:Rational
27
+ :exposure_program: Program AE
28
+ :iso: 64
29
+ :exif_version: '0221'
30
+ :date_time_original: 2011-11-23 09:39:52.000000000 +00:00
31
+ :create_date: 2011-11-23 09:39:52.000000000 +00:00
32
+ :components_configuration: Y, Cb, Cr, -
33
+ :shutter_speed_value: !ruby/object:Rational
47
34
  denominator: 6135
48
35
  numerator: 1
49
- :gps_longitude_ref: West
50
- :resolution_unit: inches
51
- :scene_capture_type: Standard
52
- :gps_position: 37.50233333 N, 122.47566667 W
53
- :file_name: iPhone 4S.jpg
54
- :hyperfocal_distance: 2.08 m
55
- :focal_length35efl: "4.3 mm (35 mm equivalent: 35.0 mm)"
56
- :y_cb_cr_sub_sampling: YCbCr4:2:0 (2 2)
57
- :aperture: 2.4
58
- :fov: 54.4 deg
59
- :brightness_value: 11.27442702
60
- :file_permissions: rw-r--r--
61
- :gps_img_direction_ref: True North
62
- :exif_version: "0221"
63
- :sharpness: Normal
64
- :gps_time_stamp: "19:03:32"
65
36
  :aperture_value: 2.4
66
- :exif_image_height: 2448
37
+ :brightness_value: 11.27442702
38
+ :metering_mode: Multi-segment
39
+ :flash: Auto, Did not fire
67
40
  :focal_length: 4.3 mm
68
- :light_value: 15.8
69
- :modify_date: 2011-11-23 09:39:52 -08:00
70
- :shutter_speed_value: !ruby/object:Rational
71
- denominator: 6135
72
- numerator: 1
73
- :make: Apple
74
- :file_size: 1954 kB
75
41
  :subject_area: 1631 1223 881 881
42
+ :flashpix_version: '0100'
43
+ :color_space: sRGB
44
+ :exif_image_width: 3264
45
+ :exif_image_height: 2448
46
+ :sensing_method: One-chip color area
47
+ :exposure_mode: Auto
48
+ :white_balance: Auto
76
49
  :focal_length_in35mm_format: 35 mm
50
+ :scene_capture_type: Standard
51
+ :sharpness: Normal
52
+ :gps_latitude_ref: North
53
+ :gps_longitude_ref: West
54
+ :gps_altitude_ref: Above Sea Level
55
+ :gps_time_stamp: '19:03:32'
56
+ :gps_img_direction_ref: True North
57
+ :gps_img_direction: 121.9838275
58
+ :compression: JPEG (old-style)
59
+ :thumbnail_offset: 914
60
+ :thumbnail_length: 5987
77
61
  :image_width: 3264
78
- :file_type: JPEG
62
+ :image_height: 2448
63
+ :encoding_process: Baseline DCT, Huffman coding
64
+ :bits_per_sample: 8
65
+ :color_components: 3
66
+ :y_cb_cr_sub_sampling: YCbCr4:2:0 (2 2)
67
+ :aperture: 2.4
68
+ :gps_altitude: 14.2 m Above Sea Level
69
+ :gps_latitude: 37.50233333
70
+ :gps_longitude: -122.47566667
71
+ :gps_position: 37.50233333 N, 122.47566667 W
72
+ :image_size: 3264x2448
79
73
  :scale_factor35efl: 8.2
80
- :iso: 64
74
+ :shutter_speed: !ruby/object:Rational
75
+ denominator: 6135
76
+ numerator: 1
77
+ :thumbnail_image: (Binary data 5987 bytes)
78
+ :circle_of_confusion: 0.004 mm
79
+ :fov: 54.4 deg
80
+ :focal_length35efl: '4.3 mm (35 mm equivalent: 35.0 mm)'
81
+ :hyperfocal_distance: 2.08 m
82
+ :light_value: 15.8
@@ -0,0 +1,58 @@
1
+ require 'test_helper'
2
+
3
+ describe Exiftoolr::Parser do
4
+ it 'creates snake-case symbolic keys properly' do
5
+ p = Exiftoolr::Parser.new('HyperfocalDistance', '')
6
+ p.sym_key.must_equal :hyperfocal_distance
7
+ end
8
+
9
+ it 'creates display keys properly' do
10
+ p = Exiftoolr::Parser.new('InternalSerialNumber', '')
11
+ p.display_key.must_equal 'Internal Serial Number'
12
+ end
13
+
14
+ it 'parses date flags without warnings' do
15
+ p = Exiftoolr::Parser.new('DateStampMode', 'Off')
16
+ p.value.must_equal 'Off'
17
+ end
18
+
19
+ it 'parses dates without timezones' do
20
+ p = Exiftoolr::Parser.new('CreateDate', '2004:09:19 12:25:20')
21
+ p.value.must_equal Time.parse('2004-09-19 12:25:20')
22
+ end
23
+
24
+ it 'parses sub-second times' do
25
+ p = Exiftoolr::Parser.new('SubSecDateTimeOriginal', '2011:09:25 20:08:09.00')
26
+ p.value.must_equal Time.parse('2011-09-25 20:08:09')
27
+ end
28
+
29
+ it 'parses dates with timezones' do
30
+ p = Exiftoolr::Parser.new('FileAccessDate', '2013:07:14 10:50:33-07:00')
31
+ p.value.must_equal Time.parse('2013-07-14 10:50:33-07:00')
32
+ end
33
+
34
+ it 'parses fractions properly' do
35
+ p = Exiftoolr::Parser.new('ShutterSpeedValue', '1/6135')
36
+ p.value.must_equal Rational(1, 6135)
37
+ end
38
+
39
+ it 'parses N GPS coords' do
40
+ p = Exiftoolr::Parser.new('GPSLatitude', '37.50233333 N')
41
+ p.value.must_be_close_to 37.50233333
42
+ end
43
+
44
+ it 'parses S GPS coords' do
45
+ p = Exiftoolr::Parser.new('GPSLatitude', '37.50233333 S')
46
+ p.value.must_be_close_to -37.50233333
47
+ end
48
+
49
+ it 'parses E GPS coords' do
50
+ p = Exiftoolr::Parser.new('GPSLongitude', '122.47566667 E')
51
+ p.value.must_be_close_to 122.47566667
52
+ end
53
+
54
+ it 'parses W GPS coords' do
55
+ p = Exiftoolr::Parser.new('GPSLongitude', '122.47566667 W')
56
+ p.value.must_be_close_to -122.47566667
57
+ end
58
+ end
@@ -0,0 +1,14 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/great_expectations'
3
+ require 'yaml'
4
+ require 'exiftoolr'
5
+
6
+ # We need a predictable timezone offset so non-tz-offset timestamps are comparable:
7
+ ENV['TZ'] = 'UTC'
8
+
9
+ unless ENV['CI']
10
+ require 'minitest/reporters'
11
+ MiniTest::Reporters.use!
12
+ end
13
+
14
+ puts "Exiftoolr.exiftool_version = #{Exiftoolr.exiftool_version}"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exiftoolr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew McEachen
@@ -38,6 +38,76 @@ dependencies:
38
38
  - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
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
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-great_expectations
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: minitest-reporters
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
41
111
  description: Multiget ExifTool wrapper for ruby
42
112
  email:
43
113
  - matthew-github@mceachen.org
@@ -52,17 +122,22 @@ files:
52
122
  - Rakefile
53
123
  - exiftoolr.gemspec
54
124
  - lib/exiftoolr.rb
125
+ - lib/exiftoolr/parser.rb
55
126
  - lib/exiftoolr/result.rb
56
127
  - lib/exiftoolr/version.rb
57
128
  - test/Canon 20D.jpg
58
129
  - test/Canon 20D.jpg.yaml
59
130
  - test/Droid X.jpg
60
131
  - test/Droid X.jpg.yaml
132
+ - test/IMG_2452.jpg
133
+ - test/IMG_2452.jpg.yaml
134
+ - test/exiftoolr_test.rb
61
135
  - test/faces.jpg
62
136
  - test/faces.jpg.yaml
63
137
  - test/iPhone 4S.jpg
64
138
  - test/iPhone 4S.jpg.yaml
65
- - test/test_exiftoolr.rb
139
+ - test/parser_test.rb
140
+ - test/test_helper.rb
66
141
  homepage: https://github.com/mceachen/exiftoolr
67
142
  licenses:
68
143
  - MIT
@@ -83,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
158
  version: '0'
84
159
  requirements:
85
160
  - ExifTool (see http://www.sno.phy.queensu.ca/~phil/exiftool/)
86
- rubyforge_project: exiftoolr
161
+ rubyforge_project:
87
162
  rubygems_version: 2.0.2
88
163
  signing_key:
89
164
  specification_version: 4
@@ -93,8 +168,13 @@ test_files:
93
168
  - test/Canon 20D.jpg.yaml
94
169
  - test/Droid X.jpg
95
170
  - test/Droid X.jpg.yaml
171
+ - test/IMG_2452.jpg
172
+ - test/IMG_2452.jpg.yaml
173
+ - test/exiftoolr_test.rb
96
174
  - test/faces.jpg
97
175
  - test/faces.jpg.yaml
98
176
  - test/iPhone 4S.jpg
99
177
  - test/iPhone 4S.jpg.yaml
100
- - test/test_exiftoolr.rb
178
+ - test/parser_test.rb
179
+ - test/test_helper.rb
180
+ has_rdoc:
@@ -1,82 +0,0 @@
1
- require "test/unit"
2
- require "exiftoolr"
3
- require "yaml"
4
-
5
- class TestExiftoolr < Test::Unit::TestCase
6
-
7
- DUMP_RESULTS = false
8
-
9
- def test_missing
10
- assert_raise Exiftoolr::NoSuchFile do
11
- Exiftoolr.new("no/such/file")
12
- end
13
- end
14
-
15
- def test_directory
16
- assert_raise Exiftoolr::NotAFile do
17
- Exiftoolr.new("lib")
18
- end
19
- end
20
-
21
- def test_no_files
22
- assert !Exiftoolr.new([]).errors?
23
- end
24
-
25
- def test_invalid_exif
26
- assert Exiftoolr.new("Gemfile").errors?
27
- end
28
-
29
- def test_matches
30
- Dir["**/*.jpg"].each do |filename|
31
- e = Exiftoolr.new(filename)
32
- validate_result(e, filename)
33
- end
34
- end
35
-
36
- def validate_result(result, filename)
37
- yaml_file = "#{filename}.yaml"
38
- if File.exist?(yaml_file)
39
- assert !result.errors?
40
- else
41
- assert result.errors?
42
- return
43
- end
44
- exif = result.to_hash
45
- File.open(yaml_file, 'w') { |out| YAML.dump(exif, out) } if DUMP_RESULTS
46
- e = File.open(yaml_file) { |f| YAML::load(f) }
47
- exif.keys.each do |k|
48
- next if ignorable_key?(k)
49
- expected = e[k]
50
- actual = exif[k]
51
- if actual.is_a?(String)
52
- expected.downcase!
53
- actual.downcase!
54
- end
55
- assert_equal expected, actual, "Key '#{k}' was incorrect for #{filename}"
56
- end
57
- end
58
-
59
- TRANSLATED_KEY = /.*\-ml-\w\w-\w\w$/
60
-
61
- def ignorable_key? key
62
- @ignorable_keys ||= begin
63
- ignorable = [:file_modify_date, :directory, :source_file, :exif_tool_version]
64
- ignorable += [:modify_date, :create_date, :date_time_original, :nd_filter] if Exiftoolr.exiftool_version <= 8.2
65
- ignorable
66
- end.include?(key) || key.to_s =~ TRANSLATED_KEY
67
- end
68
-
69
- def test_multi_matches
70
- filenames = Dir["**/*.jpg"].to_a
71
- e = Exiftoolr.new(filenames)
72
- filenames.each { |f| validate_result(e.result_for(f), f) }
73
- end
74
-
75
- def test_error_filtering
76
- filenames = Dir["**/*.*"].to_a
77
- e = Exiftoolr.new(filenames)
78
- expected_files = Dir["**/*.jpg"].to_a.collect { |f| File.expand_path(f) }.sort
79
- assert_equal expected_files, e.files_with_results.sort
80
- filenames.each { |f| validate_result(e.result_for(f), f) }
81
- end
82
- end