mini_exiftool 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog CHANGED
@@ -1,71 +1,80 @@
1
- v1.5.1
1
+ 1.6.0
2
+ - Type conversion in MiniExiftool.from_hash.
3
+ Thanks to Ethan Soutar-Rau for the merge request.
4
+ - Switching to rim. (No longer troubles with echoe.)
5
+ - Exiftool version detection delayed.
6
+ Thanks to Sebastian Skałacki for the merge request.
7
+ - New method MiniExiftool#save!
8
+ Cherry-picked commit from Wil Gieseler.
9
+
10
+ 1.5.1
2
11
  - Make rational values work on Ruby 1.8.7.
3
12
 
4
- v1.5.0
13
+ 1.5.0
5
14
  - Supporting exiftool command-line option -m.
6
15
  rubyforge request [#29587]
7
16
  Thanks to Michael Grove for reporting.
8
17
  - Supporting rational values.
9
18
 
10
- v1.4.4
19
+ 1.4.4
11
20
  - Fix escaping of values for older versions of Shellwords.
12
21
 
13
- v1.4.3
22
+ 1.4.3
14
23
  - Fixing rubyforge bug [#29596] (Quotes in values)
15
24
  Thanks to Michael Grove for reporting
16
25
 
17
- v1.4.2
26
+ 1.4.2
18
27
  - Add .yardopts file to gem.
19
28
 
20
- v1.4.1
29
+ 1.4.1
21
30
  - Update documentation for using yard.
22
31
 
23
- v1.4.0
32
+ 1.4.0
24
33
  - Allow symbols for tag access with [].
25
34
  - Refactoring tests.
26
35
 
27
- v1.3.1
36
+ 1.3.1
28
37
  - Remove TestEscapeFilename test and releating test photo
29
38
  because the latter produces errors on windows systems.
30
39
  - Version check in prerelease task.
31
40
 
32
- v1.3.0
41
+ 1.3.0
33
42
  - MiniExiftool is now ready for Ruby 1.9
34
43
  All tests in the test suite pass. :)
35
44
 
36
- v1.2.2
45
+ 1.2.2
37
46
  - Fixing ptore directory naming convention for darwin.
38
47
  Thanks to Denis Barushev for the hint.
39
48
 
40
- v1.2.1
49
+ 1.2.1
41
50
  - Switching to echoe.
42
51
  - Update e-mail address.
43
52
 
44
- v1.2.0
53
+ 1.2.0
45
54
  - Fixing time zone handling.
46
55
  Thanks to ccoenen for the hint.
47
56
 
48
- v1.1.0
57
+ 1.1.0
49
58
  - Escaping filenames in shell commands
50
59
  Thanks to Michael Hoy for the hint and implementing a patch which was
51
60
  the base for this fix.
52
61
 
53
- v1.0.2
62
+ 1.0.2
54
63
  - Fixing warings
55
64
  Thanks to Peter-Hinrich Krogmann for the hint.
56
65
 
57
- v1.0.1
66
+ 1.0.1
58
67
  - Fixing bug [#22726]
59
68
  Making MiniExiftool::Error public.
60
69
  Thanks to Mathias Stjernstrom for sending a patch.
61
70
 
62
- v1.0.0
71
+ 1.0.0
63
72
  - Be aware changing in the interface:
64
73
  - List tags (e.g. Keywords, SupplementalCategories) are now handled as
65
74
  arrays.
66
75
  - Tag SubjectLocation is not longer an array value but a string value!
67
76
 
68
- v0.7.0
77
+ 0.7.0
69
78
  - Changing composite behaviour: Composite tags are now included as standard!
70
79
  - New method MiniExiftool.opts which returns a hash of the standard
71
80
  options used for MiniExiftool.new
@@ -73,7 +82,7 @@ v0.7.0
73
82
  of the exiftool command-line application (see online documentation for it)
74
83
  Thanks to Henning Kulander for the causing of this change.
75
84
 
76
- v0.6.0
85
+ 0.6.0
77
86
  - New methods for serialization:
78
87
  - MiniExiftool.from_hash
79
88
  - MiniExiftool.from_yaml
@@ -83,20 +92,20 @@ v0.6.0
83
92
  - Refactoring of tests
84
93
  - Small documetation update
85
94
 
86
- v0.5.1
95
+ 0.5.1
87
96
  - Warning "parenthesize argument(s) for future version" removed
88
97
  Thanks to Greg from knobby.ws
89
98
 
90
- v0.5.0
99
+ 0.5.0
91
100
  - New option :timestamps to create DateTime objects instead of Time objects
92
101
  for timestamps (Fixing bug #16328)
93
102
  - Invalid values of timestamps (i.e. 0000:00:00 00:00:00) are now mapped
94
103
  to false
95
104
 
96
- v0.4.1
105
+ 0.4.1
97
106
  - Compatibility for Ruby 1.9
98
107
 
99
- v0.4.0
108
+ 0.4.0
100
109
  - MiniExiftool::Error inherits now from StandardError
101
110
  - Alternative installation via setup.rb
102
111
  - Bugfix
@@ -106,10 +115,10 @@ v0.4.0
106
115
  - Interna: Original tag names (all and writable) are now saved via pstore in
107
116
  a file for better performance
108
117
 
109
- v0.3.1
118
+ 0.3.1
110
119
  - Typos fixed
111
120
 
112
- v0.3.0
121
+ 0.3.0
113
122
  - Documentation completed and a Mini Tutorial added
114
123
  - Interface changes:
115
124
  - Test if a value for a tag can be saved is now done in
@@ -124,27 +133,27 @@ v0.3.0
124
133
  - :composite => read also composite tags
125
134
  - Tests added
126
135
 
127
- v0.2.0
136
+ 0.2.0
128
137
  - Better error handling (i.e. error messages)
129
138
  - Checking if the exiftool command can be executed at loading the lib
130
139
  - New class method exiftool_version
131
140
  - Added tests
132
141
  - Documentation completed
133
142
 
134
- v0.1.2
143
+ 0.1.2
135
144
  - Bugfix for Windows (Tempfile)
136
145
  Thanks to Jérome Soika for testing
137
146
  - Regexes optimized (a little bit)
138
147
  - New class-method MiniExiftool.writable_tags
139
148
 
140
- v0.1.1
149
+ 0.1.1
141
150
  - Fixing bug [#8073]
142
151
  Handling the '-' in tag Self-timer
143
152
  Thanks to Eric Young
144
153
 
145
- v0.1.0
154
+ 0.1.0
146
155
  - New method "revert"
147
156
  - More tests
148
157
 
149
- v0.0.1
158
+ 0.0.1
150
159
  - Initial release
data/Rakefile CHANGED
@@ -1,12 +1,18 @@
1
- require 'rubygems'
2
- require 'echoe'
1
+ require 'rim'
2
+ require 'rim/check_version'
3
+ require 'rim/gem'
4
+ require 'rim/test'
3
5
 
4
- Echoe.new('mini_exiftool') do |p|
5
- p.author = 'Jan Friedrich'
6
+ $:.unshift 'lib'
7
+ require 'mini_exiftool'
8
+
9
+ Rim.setup do |p|
10
+ p.name = 'mini_exiftool'
11
+ p.version = MiniExiftool::VERSION
12
+ p.authors = 'Jan Friedrich'
6
13
  p.email = 'janfri26@gmail.com'
7
14
  p.summary = 'This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool).'
8
- p.url = 'http://gitorious.org/mini_exiftool'
9
- p.rdoc_files = %w(README.rdoc Tutorial.rdoc lib/*.rb)
15
+ p.homepage = 'http://gitorious.org/mini_exiftool'
10
16
  p.install_message = %q{
11
17
  +-----------------------------------------------------------------------+
12
18
  | Please ensure you have installed exiftool and it's found in your PATH |
@@ -14,12 +20,4 @@ Echoe.new('mini_exiftool') do |p|
14
20
  | http://www.sno.phy.queensu.ca/~phil/exiftool/install.html |
15
21
  +-----------------------------------------------------------------------+
16
22
  }
17
- p.changelog = 'Changelog'
18
- task :prerelease do
19
- require "#{File.dirname(__FILE__)}/lib/mini_exiftool"
20
- unless p.version == MiniExiftool::VERSION
21
- $stderr.puts "Version conflict: Release version is #{p.version} but MiniExiftool::VERSION is #{MiniExiftool::VERSION}."
22
- exit(1)
23
- end
24
- end
25
23
  end
@@ -33,7 +33,7 @@ class MiniExiftool
33
33
  attr_reader :filename
34
34
  attr_accessor :numerical, :composite, :convert_encoding, :ignore_minor_errors, :errors, :timestamps
35
35
 
36
- VERSION = '1.5.1'
36
+ VERSION = '1.6.0'
37
37
 
38
38
  # +opts+ support at the moment
39
39
  # * <code>:numerical</code> for numerical values, default is +false+
@@ -65,7 +65,7 @@ class MiniExiftool
65
65
 
66
66
  def initialize_from_hash hash # :nodoc:
67
67
  hash.each_pair do |tag,value|
68
- set_value tag, value
68
+ set_value tag, perform_conversions(value)
69
69
  end
70
70
  set_attributes_by_heuristic
71
71
  self
@@ -73,6 +73,7 @@ class MiniExiftool
73
73
 
74
74
  # Load the tags of filename.
75
75
  def load filename
76
+ MiniExiftool.setup
76
77
  unless filename && File.exist?(filename)
77
78
  raise MiniExiftool::Error.new("File '#{filename}' does not exist.")
78
79
  end
@@ -145,6 +146,7 @@ class MiniExiftool
145
146
 
146
147
  # Save the changes to the file.
147
148
  def save
149
+ MiniExiftool.setup
148
150
  return false if @changed_values.empty?
149
151
  @errors.clear
150
152
  temp_file = Tempfile.new('mini_exiftool')
@@ -182,6 +184,16 @@ class MiniExiftool
182
184
  all_ok
183
185
  end
184
186
 
187
+ def save!
188
+ unless save
189
+ err = []
190
+ self.errors.each do |key, value|
191
+ err << "(#{key}) #{value}"
192
+ end
193
+ raise MiniExiftool::Error.new("MiniExiftool couldn't save. The following errors occurred: #{err.empty? ? "None" : err.join(", ")}")
194
+ end
195
+ end
196
+
185
197
  # Returns a hash of the original loaded values of the MiniExiftool
186
198
  # instance.
187
199
  def to_hash
@@ -198,7 +210,7 @@ class MiniExiftool
198
210
  to_hash.to_yaml
199
211
  end
200
212
 
201
- # Create a MiniExiftool instance from a hash
213
+ # Create a MiniExiftool instance from a hash. Default value conversions will be applied if neccesary.
202
214
  def self.from_hash hash
203
215
  instance = MiniExiftool.new
204
216
  instance.initialize_from_hash hash
@@ -270,15 +282,20 @@ class MiniExiftool
270
282
  private
271
283
  ############################################################################
272
284
 
273
- @@error_file = Tempfile.new 'errors'
274
- @@error_file.close
285
+ @@setup_done = false
286
+ def self.setup
287
+ return if @@setup_done
288
+ @@error_file = Tempfile.new 'errors'
289
+ @@error_file.close
275
290
 
276
- if Float(exiftool_version) < 7.41
277
- @@separator = ', '
278
- @@sep_op = ''
279
- else
280
- @@separator = '@@'
281
- @@sep_op = '-sep @@'
291
+ if Float(exiftool_version) < 7.41
292
+ @@separator = ', '
293
+ @@sep_op = ''
294
+ else
295
+ @@separator = '@@'
296
+ @@sep_op = '-sep @@'
297
+ end
298
+ @@setup_done = true
282
299
  end
283
300
 
284
301
  def run cmd
@@ -325,7 +342,14 @@ class MiniExiftool
325
342
 
326
343
  def parse_line line
327
344
  if line =~ /^([^\t]+)\t(.*)$/
328
- tag, value = $1, $2
345
+ tag, value = $1, perform_conversions($2)
346
+ else
347
+ raise MiniExiftool::Error.new("Malformed line #{line.inspect} of exiftool output.")
348
+ end
349
+ return [tag, value]
350
+ end
351
+
352
+ def perform_conversions(value)
329
353
  case value
330
354
  when /^\d{4}:\d\d:\d\d \d\d:\d\d:\d\d/
331
355
  s = value.sub(/^(\d+):(\d+):/, '\1-\2-')
@@ -353,10 +377,7 @@ class MiniExiftool
353
377
  when /#{@@separator}/
354
378
  value = value.split @@separator
355
379
  end
356
- else
357
- raise MiniExiftool::Error.new("Malformed line #{line.inspect} of exiftool output.")
358
- end
359
- return [tag, value]
380
+ value
360
381
  end
361
382
 
362
383
  def set_value tag, value
@@ -0,0 +1,106 @@
1
+ [{
2
+ "SourceFile": "test/data/test.jpg",
3
+ "ExifToolVersion": 8.77,
4
+ "FileName": "test.jpg",
5
+ "Directory": "test/data",
6
+ "FileSize": "46 kB",
7
+ "FileModifyDate": "2012:07:05 20:28:24-07:00",
8
+ "FilePermissions": "rw-r--r--",
9
+ "FileType": "JPEG",
10
+ "MIMEType": "image/jpeg",
11
+ "JFIFVersion": 1.01,
12
+ "ExifByteOrder": "Big-endian (Motorola, MM)",
13
+ "ImageDescription": "KONICA MINOLTA DIGITAL CAMERA",
14
+ "Make": "KONICA MINOLTA",
15
+ "Model": "DYNAX 7D",
16
+ "Orientation": "Horizontal (normal)",
17
+ "XResolution": 72,
18
+ "YResolution": 72,
19
+ "ResolutionUnit": "inches",
20
+ "Software": "DYNAX 7D v1.10",
21
+ "ModifyDate": "2005:09:13 20:08:50",
22
+ "YCbCrPositioning": "Centered",
23
+ "ExposureTime": "1/60",
24
+ "FNumber": 9.5,
25
+ "ExposureProgram": "Program AE",
26
+ "ISO": 400,
27
+ "ExifVersion": "0221",
28
+ "DateTimeOriginal": "2005:09:13 20:08:50",
29
+ "CreateDate": "2005:09:13 20:08:50",
30
+ "ComponentsConfiguration": "Y, Cb, Cr, -",
31
+ "BrightnessValue": 4.5,
32
+ "ExposureCompensation": -1,
33
+ "MaxApertureValue": 4.5,
34
+ "MeteringMode": "Multi-segment",
35
+ "LightSource": "Unknown",
36
+ "Flash": "Off, Did not fire",
37
+ "FocalLength": "75.0 mm",
38
+ "SubjectArea": "1504 1000 256 304",
39
+ "MakerNoteVersion": "MLT0",
40
+ "MinoltaImageSize": "Large",
41
+ "WhiteBalance": "Auto",
42
+ "FocusMode": "AF-A",
43
+ "AFPoints": "Center",
44
+ "FlashMode": "Normal",
45
+ "ISOSetting": 400,
46
+ "FreeMemoryCardImages": 202,
47
+ "HueAdjustment": 0,
48
+ "Rotation": "Horizontal (normal)",
49
+ "ImageNumber": 6,
50
+ "NoiseReduction": "Unknown (2)",
51
+ "ImageNumber2": 50,
52
+ "ZoneMatchingOn": "Off",
53
+ "CompressedImageSize": 1598477,
54
+ "PreviewImageStart": 39152,
55
+ "PreviewImageLength": 0,
56
+ "SceneMode": "Standard",
57
+ "ColorMode": "Natural sRGB",
58
+ "MinoltaQuality": "Fine",
59
+ "FlashExposureComp": 0,
60
+ "Teleconverter": "None",
61
+ "ImageStabilization": "On",
62
+ "ZoneMatching": "ISO Setting Used",
63
+ "ColorTemperature": 0,
64
+ "LensType": "Minolta AF 28-135mm F4-4.5 or Sigma Lens",
65
+ "UserComment": "",
66
+ "FlashpixVersion": "0100",
67
+ "ColorSpace": "sRGB",
68
+ "ExifImageWidth": 3008,
69
+ "ExifImageHeight": 2000,
70
+ "CustomRendered": "Normal",
71
+ "ExposureMode": "Auto",
72
+ "DigitalZoomRatio": 0,
73
+ "FocalLengthIn35mmFormat": "112 mm",
74
+ "SceneCaptureType": "Standard",
75
+ "GainControl": "Low gain up",
76
+ "Contrast": "Normal",
77
+ "Saturation": "Normal",
78
+ "Sharpness": "Normal",
79
+ "PrintIMVersion": "0300",
80
+ "Compression": "JPEG (old-style)",
81
+ "ThumbnailOffset": 39274,
82
+ "ThumbnailLength": 1820,
83
+ "CurrentIPTCDigest": "dd8d51d28ddf04f08f870e5ff2f64d01",
84
+ "Keywords": ["Orange","Rot"],
85
+ "ApplicationRecordVersion": 4,
86
+ "SupplementalCategories": "Natur",
87
+ "XMPToolkit": "Image::ExifTool 7.03",
88
+ "Title": "Abenddämmerung",
89
+ "ImageWidth": 300,
90
+ "ImageHeight": 199,
91
+ "EncodingProcess": "Baseline DCT, Huffman coding",
92
+ "BitsPerSample": 8,
93
+ "ColorComponents": 3,
94
+ "YCbCrSubSampling": "YCbCr4:2:0 (2 2)",
95
+ "Aperture": 9.5,
96
+ "ImageSize": "300x199",
97
+ "LensID": "Minolta AF 28-135mm F4-4.5",
98
+ "ScaleFactor35efl": 1.5,
99
+ "ShutterSpeed": "1/60",
100
+ "ThumbnailImage": "(Binary data 1820 bytes)",
101
+ "CircleOfConfusion": "0.020 mm",
102
+ "FOV": "18.3 deg",
103
+ "FocalLength35efl": "75.0 mm (35 mm equivalent: 112.0 mm)",
104
+ "HyperfocalDistance": "29.43 m",
105
+ "LightValue": 10.4
106
+ }]
@@ -0,0 +1,22 @@
1
+ require 'helpers_for_test'
2
+ require 'json'
3
+
4
+ class TestFromHash < TestCase
5
+ def setup
6
+ @data_dir = File.dirname(__FILE__) + '/data'
7
+ hash_data = JSON.parse(File.read( @data_dir + '/test.jpg.json')).first
8
+ @mini_exiftool = MiniExiftool.from_hash hash_data
9
+ end
10
+
11
+ def test_conversion
12
+ assert_kind_of String, @mini_exiftool.model
13
+ assert_kind_of Time, @mini_exiftool['DateTimeOriginal']
14
+ assert_kind_of Float, @mini_exiftool['MaxApertureValue']
15
+ assert_kind_of String, @mini_exiftool.flash
16
+ assert_kind_of Fixnum, @mini_exiftool['ExposureCompensation']
17
+ assert_kind_of String, (@mini_exiftool['SubjectLocation'] || @mini_exiftool['SubjectArea'])
18
+ assert_kind_of Array, @mini_exiftool['Keywords']
19
+ assert_kind_of String, @mini_exiftool['SupplementalCategories']
20
+ assert_kind_of Rational, @mini_exiftool.shutterspeed
21
+ end
22
+ end