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 +38 -29
- data/Rakefile +12 -14
- data/lib/mini_exiftool.rb +37 -16
- data/test/data/Bad_PreviewIFD.jpg +0 -0
- data/test/data/test.jpg.json +106 -0
- data/test/test_from_hash.rb +22 -0
- data/test/test_save.rb +12 -0
- metadata +50 -67
- data/.yardopts +0 -1
- data/Manifest +0 -27
- data/TODO +0 -2
- data/Tutorial.rdoc +0 -139
- data/examples/external_photo.rb +0 -22
- data/examples/print_portraits.rb +0 -27
- data/examples/shift_time.rb +0 -30
- data/mini_exiftool.gemspec +0 -31
- data/setup.rb +0 -1586
data/Changelog
CHANGED
@@ -1,71 +1,80 @@
|
|
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
|
-
|
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
|
-
|
19
|
+
1.4.4
|
11
20
|
- Fix escaping of values for older versions of Shellwords.
|
12
21
|
|
13
|
-
|
22
|
+
1.4.3
|
14
23
|
- Fixing rubyforge bug [#29596] (Quotes in values)
|
15
24
|
Thanks to Michael Grove for reporting
|
16
25
|
|
17
|
-
|
26
|
+
1.4.2
|
18
27
|
- Add .yardopts file to gem.
|
19
28
|
|
20
|
-
|
29
|
+
1.4.1
|
21
30
|
- Update documentation for using yard.
|
22
31
|
|
23
|
-
|
32
|
+
1.4.0
|
24
33
|
- Allow symbols for tag access with [].
|
25
34
|
- Refactoring tests.
|
26
35
|
|
27
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
49
|
+
1.2.1
|
41
50
|
- Switching to echoe.
|
42
51
|
- Update e-mail address.
|
43
52
|
|
44
|
-
|
53
|
+
1.2.0
|
45
54
|
- Fixing time zone handling.
|
46
55
|
Thanks to ccoenen for the hint.
|
47
56
|
|
48
|
-
|
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
|
-
|
62
|
+
1.0.2
|
54
63
|
- Fixing warings
|
55
64
|
Thanks to Peter-Hinrich Krogmann for the hint.
|
56
65
|
|
57
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
105
|
+
0.4.1
|
97
106
|
- Compatibility for Ruby 1.9
|
98
107
|
|
99
|
-
|
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
|
-
|
118
|
+
0.3.1
|
110
119
|
- Typos fixed
|
111
120
|
|
112
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
154
|
+
0.1.0
|
146
155
|
- New method "revert"
|
147
156
|
- More tests
|
148
157
|
|
149
|
-
|
158
|
+
0.0.1
|
150
159
|
- Initial release
|
data/Rakefile
CHANGED
@@ -1,12 +1,18 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'rim'
|
2
|
+
require 'rim/check_version'
|
3
|
+
require 'rim/gem'
|
4
|
+
require 'rim/test'
|
3
5
|
|
4
|
-
|
5
|
-
|
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.
|
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
|
data/lib/mini_exiftool.rb
CHANGED
@@ -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.
|
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
|
-
@@
|
274
|
-
|
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
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
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
|
-
|
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
|
Binary file
|
@@ -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
|