mini_exiftool 1.5.1 → 1.6.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.
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