mini_exiftool 0.7.0 → 1.0.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 +5 -0
- data/Tutorial +26 -4
- data/lib/mini_exiftool.rb +42 -8
- data/test/data/test.jpg +0 -0
- data/test/test_read.rb +10 -1
- data/test/test_read_numerical.rb +4 -1
- data/test/test_special.rb +1 -1
- data/test/test_write.rb +17 -0
- metadata +16 -16
data/Changelog
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
Version 1.0.0
|
2
|
+
- Be aware changing in the interface:
|
3
|
+
- List tags (e.g. Keywords, SupplementalCategories) are now handled as
|
4
|
+
arrays.
|
5
|
+
- Tag SubjectLocation is not longer an array value but a string value!
|
1
6
|
Version 0.7.0
|
2
7
|
- Changing composite behaviour: Composite tags are now included as standard!
|
3
8
|
- New method MiniExiftool.opts which returns a hash of the standard
|
data/Tutorial
CHANGED
@@ -42,12 +42,27 @@ or also
|
|
42
42
|
=== Value Types
|
43
43
|
|
44
44
|
Following types of values are at the moment supported:
|
45
|
-
* Array (e. g.
|
45
|
+
* Array (e. g. Keywords => ['tree', 'gras'])
|
46
46
|
* Fixnum (e. g. ISO => 400)
|
47
47
|
* Float (e. g. FNumber => 9.5)
|
48
48
|
* String (e. g. Model => DYNAX 7D)
|
49
49
|
* Time (e. g. DateTimeOriginal => 2005:09:13 20:08:50)
|
50
50
|
|
51
|
+
Be aware, if there is only one value in a tag which can hold multiple
|
52
|
+
values the result is'nt an array! But you can get one with the to_a
|
53
|
+
method:
|
54
|
+
# only _one_ keyword
|
55
|
+
p1 = MiniExiftool.new 'p1.jpg'
|
56
|
+
p1.keywords # => 'red'
|
57
|
+
# _more than one_ keywords
|
58
|
+
p3 = MiniExiftool.new 'p3.jpg'
|
59
|
+
p3.keywords # => ['red', 'yellow', 'green']
|
60
|
+
|
61
|
+
# if we want to get an array in both cases and don't know
|
62
|
+
# if there is one ore more values set let's take to_a
|
63
|
+
p1.keywords.to_a # => ['red']
|
64
|
+
p3.keywords.to_a # => ['red', 'yellow', 'green']
|
65
|
+
|
51
66
|
The Exiftool command-line application has an option (-n) to get values
|
52
67
|
as numbers if possible, in MiniExiftool you can do this with setting
|
53
68
|
the <code>:numerical</code> option to +true+ while generating a new
|
@@ -66,15 +81,22 @@ This behaviour can be useful if you want to do calculations on the
|
|
66
81
|
value, if you only want to show the value the standard behaviour is
|
67
82
|
maybe better.
|
68
83
|
|
84
|
+
The Time class of Ruby cannot handle timestamps before 1st January 1970
|
85
|
+
on some platforms. If there are timestamps in files before this date it
|
86
|
+
will result in an error. In this case we can set the option
|
87
|
+
<code>:timestamps</code> to +DateTime+ to use DateTime objects instead
|
88
|
+
of Time objects.
|
89
|
+
|
90
|
+
There is another option <code>:composite</code>. If this is set to
|
91
|
+
+false+ the composite tags are not calculated by the exiftool
|
92
|
+
command-line application (option -e).
|
93
|
+
|
69
94
|
=== Further Example
|
70
95
|
|
71
96
|
For understanding reading access to meta data also have a look at the
|
72
97
|
example file <code>print_portraits.rb</code> in the +examples+
|
73
98
|
directory.
|
74
99
|
|
75
|
-
<b>TODO:</b> Describing the options <code>:composite</code> and
|
76
|
-
<code>:timestamps</code>!
|
77
|
-
|
78
100
|
== Lesson 2: Writing Meta Data
|
79
101
|
|
80
102
|
|
data/lib/mini_exiftool.rb
CHANGED
@@ -14,7 +14,6 @@
|
|
14
14
|
|
15
15
|
require 'fileutils'
|
16
16
|
require 'tempfile'
|
17
|
-
require 'tmpdir'
|
18
17
|
require 'pstore'
|
19
18
|
require 'set'
|
20
19
|
|
@@ -30,7 +29,7 @@ class MiniExiftool
|
|
30
29
|
attr_reader :filename
|
31
30
|
attr_accessor :numerical, :composite, :convert_encoding, :errors, :timestamps
|
32
31
|
|
33
|
-
VERSION = '0.
|
32
|
+
VERSION = '1.0.0'
|
34
33
|
|
35
34
|
# +opts+ support at the moment
|
36
35
|
# * <code>:numerical</code> for numerical values, default is +false+
|
@@ -81,7 +80,7 @@ class MiniExiftool
|
|
81
80
|
opt_params << (@numerical ? '-n ' : '')
|
82
81
|
opt_params << (@composite ? '' : '-e ')
|
83
82
|
opt_params << (@convert_encoding ? '-L ' : '')
|
84
|
-
cmd = %Q(#@@cmd -q -q -s -t #{opt_params} "#{filename}")
|
83
|
+
cmd = %Q(#@@cmd -q -q -s -t #{opt_params} #{@@sep_op} "#{filename}")
|
85
84
|
if run(cmd)
|
86
85
|
parse_output
|
87
86
|
else
|
@@ -148,11 +147,16 @@ class MiniExiftool
|
|
148
147
|
all_ok = true
|
149
148
|
@changed_values.each do |tag, val|
|
150
149
|
original_tag = MiniExiftool.original_tag(tag)
|
151
|
-
|
150
|
+
arr_val = val.kind_of?(Array) ? val : [val]
|
151
|
+
arr_val.map! {|e| convert e}
|
152
|
+
tag_params = ''
|
153
|
+
arr_val.each do |v|
|
154
|
+
tag_params << %Q(-#{original_tag}="#{v}" )
|
155
|
+
end
|
152
156
|
opt_params = ''
|
153
|
-
opt_params << (
|
157
|
+
opt_params << (arr_val.detect {|x| x.kind_of?(Numeric)} ? '-n ' : '')
|
154
158
|
opt_params << (@convert_encoding ? '-L ' : '')
|
155
|
-
cmd = %Q(#@@cmd -q -P -overwrite_original #{opt_params}
|
159
|
+
cmd = %Q(#@@cmd -q -P -overwrite_original #{opt_params} #{tag_params} "#{temp_filename}")
|
156
160
|
result = run(cmd)
|
157
161
|
unless result
|
158
162
|
all_ok = false
|
@@ -255,6 +259,14 @@ class MiniExiftool
|
|
255
259
|
@@error_file = Tempfile.new 'errors'
|
256
260
|
@@error_file.close
|
257
261
|
|
262
|
+
if Float(exiftool_version) < 7.41
|
263
|
+
@@separator = ', '
|
264
|
+
@@sep_op = ''
|
265
|
+
else
|
266
|
+
@@separator = '@@'
|
267
|
+
@@sep_op = '-sep @@'
|
268
|
+
end
|
269
|
+
|
258
270
|
def run cmd
|
259
271
|
if $DEBUG
|
260
272
|
$stderr.puts cmd
|
@@ -319,11 +331,20 @@ class MiniExiftool
|
|
319
331
|
when /^-?\d+$/
|
320
332
|
value = value.to_i
|
321
333
|
when /^[\d ]+$/
|
322
|
-
|
334
|
+
# nothing => String
|
335
|
+
when /#{@@separator}/
|
336
|
+
value = value.split @@separator
|
323
337
|
end
|
324
338
|
else
|
325
339
|
raise MiniExiftool::Error.new("Malformed line #{line.inspect} of exiftool output.")
|
326
340
|
end
|
341
|
+
unless value.respond_to?('to_a')
|
342
|
+
class << value
|
343
|
+
def to_a
|
344
|
+
[self]
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
327
348
|
return [tag, value]
|
328
349
|
end
|
329
350
|
|
@@ -359,7 +380,11 @@ class MiniExiftool
|
|
359
380
|
end
|
360
381
|
|
361
382
|
def self.load_or_create_pstore
|
362
|
-
|
383
|
+
# This will hopefully work on *NIX and Windows systems
|
384
|
+
home = ENV['HOME'] || ENV['HOMEDRIVE'] + ENV['HOMEPATH'] || ENV['USERPROFILE']
|
385
|
+
subdir = RUBY_PLATFORM =~ /win/i ? '_mini_exiftool' : '.mini_exiftool'
|
386
|
+
FileUtils.mkdir_p(File.join(home, subdir))
|
387
|
+
filename = File.join(home, subdir, 'exiftool_tags_' << exiftool_version.gsub('.', '_') << '.pstore')
|
363
388
|
@@pstore = PStore.new filename
|
364
389
|
if !File.exist?(filename) || File.size(filename) == 0
|
365
390
|
@@pstore.transaction do |ps|
|
@@ -408,5 +433,14 @@ class MiniExiftool
|
|
408
433
|
|
409
434
|
end
|
410
435
|
|
436
|
+
# Add to_a to Numerical if it's not yet defined
|
437
|
+
unless Numeric.instance_methods.include? 'to_a'
|
438
|
+
class Numeric
|
439
|
+
def to_a
|
440
|
+
[self]
|
441
|
+
end
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
411
445
|
# Test if we can run the Exiftool command
|
412
446
|
MiniExiftool.exiftool_version
|
data/test/data/test.jpg
CHANGED
Binary file
|
data/test/test_read.rb
CHANGED
@@ -25,7 +25,16 @@ class TestRead < TestCase
|
|
25
25
|
assert_kind_of Float, @mini_exiftool['MaxApertureValue']
|
26
26
|
assert_kind_of String, @mini_exiftool.flash
|
27
27
|
assert_kind_of Fixnum, @mini_exiftool['ExposureCompensation']
|
28
|
-
assert_kind_of
|
28
|
+
assert_kind_of String, @mini_exiftool['SubjectLocation']
|
29
|
+
assert_kind_of Array, @mini_exiftool['Keywords']
|
30
|
+
assert_kind_of String, @mini_exiftool['SupplementalCategories']
|
31
|
+
assert_kind_of Array, @mini_exiftool['SupplementalCategories'].to_a
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_list_tags
|
35
|
+
assert_equal ['Orange', 'Rot'], @mini_exiftool['Keywords']
|
36
|
+
assert_equal 'Natur', @mini_exiftool['SupplementalCategories']
|
37
|
+
assert_equal ['Natur'], @mini_exiftool['SupplementalCategories'].to_a
|
29
38
|
end
|
30
39
|
|
31
40
|
def test_encoding_conversion
|
data/test/test_read_numerical.rb
CHANGED
@@ -22,7 +22,10 @@ class TestReadNumerical < TestCase
|
|
22
22
|
assert_kind_of Fixnum, @mini_exiftool_num.flash
|
23
23
|
assert_kind_of String, @mini_exiftool_num.exif_version
|
24
24
|
assert_kind_of Fixnum, @mini_exiftool_num['ExposureCompensation']
|
25
|
-
assert_kind_of
|
25
|
+
assert_kind_of String, @mini_exiftool_num['SubjectLocation']
|
26
|
+
assert_kind_of Array, @mini_exiftool_num['Keywords']
|
27
|
+
assert_kind_of String, @mini_exiftool_num['SupplementalCategories']
|
28
|
+
assert_kind_of Array, @mini_exiftool_num['SupplementalCategories'].to_a
|
26
29
|
end
|
27
30
|
|
28
31
|
end
|
data/test/test_special.rb
CHANGED
@@ -22,7 +22,7 @@ class TestSpecial < TestCase
|
|
22
22
|
assert_not_nil @canon['Self-timer']
|
23
23
|
assert_not_nil @canon.self_timer
|
24
24
|
# preserving the original tag name
|
25
|
-
assert @canon.tags.include?('Self-timer')
|
25
|
+
assert @canon.tags.include?('Self-timer') || @canon.tags.include?('SelfTimer')
|
26
26
|
assert !@canon.tags.include?('self_timer')
|
27
27
|
end
|
28
28
|
|
data/test/test_write.rb
CHANGED
@@ -86,6 +86,23 @@ class TestWrite < TestCase
|
|
86
86
|
assert_equal new_mode, @mini_exiftool_num['MeteringMode']
|
87
87
|
end
|
88
88
|
|
89
|
+
def test_list_conversion
|
90
|
+
arr = ['a', 'b', 'c']
|
91
|
+
@mini_exiftool['Keywords'] = arr
|
92
|
+
ok = @mini_exiftool.save
|
93
|
+
assert ok
|
94
|
+
assert_equal arr, @mini_exiftool['Keywords']
|
95
|
+
arr = ['text, with', 'commas, let us look']
|
96
|
+
@mini_exiftool['Keywords'] = arr
|
97
|
+
ok = @mini_exiftool.save
|
98
|
+
assert ok
|
99
|
+
if MiniExiftool.exiftool_version.to_f < 7.41
|
100
|
+
assert_equal ['text', 'with', 'commas', 'let us look'], @mini_exiftool['Keywords']
|
101
|
+
else
|
102
|
+
assert_equal arr, @mini_exiftool['Keywords']
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
89
106
|
def test_revert_one
|
90
107
|
@mini_exiftool_num['Orientation'] = 2
|
91
108
|
@mini_exiftool_num['ISO'] = 200
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mini_exiftool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Friedrich
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-09-12 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -24,27 +24,27 @@ extra_rdoc_files:
|
|
24
24
|
- Tutorial
|
25
25
|
files:
|
26
26
|
- lib/mini_exiftool.rb
|
27
|
-
- test/test_write.rb
|
28
27
|
- test/test_read.rb
|
29
|
-
- test/
|
30
|
-
- test/test_class_methods.rb
|
31
|
-
- test/test_save.rb
|
28
|
+
- test/test_write.rb
|
32
29
|
- test/test_composite.rb
|
33
|
-
- test/
|
34
|
-
- test/helpers_for_test.rb
|
30
|
+
- test/test_save.rb
|
35
31
|
- test/test_special_dates.rb
|
32
|
+
- test/helpers_for_test.rb
|
36
33
|
- test/test_dumping.rb
|
34
|
+
- test/test_read_numerical.rb
|
35
|
+
- test/test_special.rb
|
36
|
+
- test/test_class_methods.rb
|
37
|
+
- examples/shift_time.rb
|
37
38
|
- examples/external_photo.rb
|
38
39
|
- examples/print_portraits.rb
|
39
|
-
- examples/shift_time.rb
|
40
40
|
- setup.rb
|
41
41
|
- Rakefile
|
42
42
|
- COPYING
|
43
43
|
- Changelog
|
44
|
-
- test/data/test.jpg
|
45
44
|
- test/data/Canon.jpg
|
46
|
-
- test/data/INFORMATION
|
47
45
|
- test/data/test_special_dates.jpg
|
46
|
+
- test/data/INFORMATION
|
47
|
+
- test/data/test.jpg
|
48
48
|
- README
|
49
49
|
- Tutorial
|
50
50
|
has_rdoc: true
|
@@ -77,12 +77,12 @@ signing_key:
|
|
77
77
|
specification_version: 2
|
78
78
|
summary: A library for nice OO access to the Exiftool command-line application written by Phil Harvey.
|
79
79
|
test_files:
|
80
|
-
- test/test_write.rb
|
81
80
|
- test/test_read.rb
|
82
|
-
- test/
|
83
|
-
- test/test_class_methods.rb
|
84
|
-
- test/test_save.rb
|
81
|
+
- test/test_write.rb
|
85
82
|
- test/test_composite.rb
|
86
|
-
- test/
|
83
|
+
- test/test_save.rb
|
87
84
|
- test/test_special_dates.rb
|
88
85
|
- test/test_dumping.rb
|
86
|
+
- test/test_read_numerical.rb
|
87
|
+
- test/test_special.rb
|
88
|
+
- test/test_class_methods.rb
|