mini_exiftool 0.2.0 → 0.3.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 +15 -0
- data/README +3 -47
- data/Rakefile +1 -1
- data/Tutorial +110 -0
- data/examples/external_photo.rb +21 -0
- data/examples/print_portraits.rb +26 -0
- data/examples/shift_time.rb +29 -0
- data/lib/mini_exiftool.rb +73 -41
- data/test/test_class_methods.rb +61 -0
- data/test/test_composite.rb +23 -0
- data/test/test_read.rb +1 -44
- data/test/test_read_numerical.rb +33 -0
- data/test/test_save.rb +56 -0
- data/test/test_write.rb +6 -22
- metadata +15 -4
- data/test/test_other.rb +0 -28
data/Changelog
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
Version 0.3.0
|
2
|
+
- Documentation completed and a Mini Tutorial added
|
3
|
+
- Interface changes:
|
4
|
+
- Test if a value for a tag can be saved is now done in
|
5
|
+
MiniExiftool#save
|
6
|
+
=> There is no check at the moment you set a value:
|
7
|
+
the tag occurs in MiniExiftool#changed_values
|
8
|
+
=> While calling MiniExiftool#save errors can occur (see next point)
|
9
|
+
- MiniExiftool#save is a transaction: if one or more error occurs th file is
|
10
|
+
not changed! In such a case the errors can be found in MiniExiftool#errors
|
11
|
+
- Parameter opts of MiniExiftool.initialize is now a Hash with two options:
|
12
|
+
- :numerical => read metadata as numerical values
|
13
|
+
- :composite => read also composite tags
|
14
|
+
- Tests added
|
15
|
+
|
1
16
|
Version 0.2.0
|
2
17
|
- Better error handling (i.e. error messages)
|
3
18
|
- Checking if the exiftool command can be executed at loading the lib
|
data/README
CHANGED
@@ -19,51 +19,7 @@ Copyright (c) 2007 by Jan Friedrich
|
|
19
19
|
Licensed under the GNU LESSER GENERAL PUBLIC LICENSE, Version 2.1,
|
20
20
|
February 1999
|
21
21
|
|
22
|
-
==
|
22
|
+
== Usage
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
# copy the original test file therewith the original isn't changed
|
27
|
-
# and the tests work
|
28
|
-
require 'fileutils'
|
29
|
-
FileUtils.cp('test/data/test.jpg', './test.jpg')
|
30
|
-
|
31
|
-
mini_exiftool = MiniExiftool.new 'test.jpg'
|
32
|
-
|
33
|
-
# different methods to read information
|
34
|
-
|
35
|
-
mini_exiftool['Orientation'] # ==> 'Horizontal (normal)'
|
36
|
-
mini_exiftool['ISO'] # ==> 400
|
37
|
-
mini_exiftool['iso'] # ==> 400
|
38
|
-
mini_exiftool['DateTimeOriginal'].class # ==> Time
|
39
|
-
|
40
|
-
mini_exiftool.orientation # ==> 'Horizontal (normal)'
|
41
|
-
mini_exiftool.iso # ==> 400
|
42
|
-
mini_exiftool.datetimeoriginal.class # ==> Time
|
43
|
-
mini_exiftool.date_time_original.class # ==> Time
|
44
|
-
|
45
|
-
# numerical access
|
46
|
-
|
47
|
-
mini_exiftool_num = MiniExiftool.new 'test.jpg', :numerical
|
48
|
-
mini_exiftool_num['Orientation'] # ==> 1
|
49
|
-
|
50
|
-
|
51
|
-
# write access
|
52
|
-
|
53
|
-
mini_exiftool_num['Orientation'] = 2
|
54
|
-
mini_exiftool_num['ISO'] = 200
|
55
|
-
mini_exiftool_num['Orientation'] # ==> 2
|
56
|
-
mini_exiftool_num['ISO'] # ==> 200
|
57
|
-
mini_exiftool_num.reload
|
58
|
-
mini_exiftool_num['Orientation'] # ==> 1
|
59
|
-
mini_exiftool_num['ISO'] # ==> 400
|
60
|
-
|
61
|
-
mini_exiftool_num['Orientation'] = 2
|
62
|
-
mini_exiftool_num['ISO'] = 200
|
63
|
-
mini_exiftool_num.changed? # ==> true
|
64
|
-
mini_exiftool_num.changed_tags # ==> ["ISO", "Orientation"]
|
65
|
-
mini_exiftool_num.save
|
66
|
-
mini_exiftool_num.changed? # ==> false
|
67
|
-
mini_exiftool_num.changed_tags # ==> []
|
68
|
-
mini_exiftool_num['Orientation'] # ==> 2
|
69
|
-
mini_exiftool_num['ISO'] # ==> 200
|
24
|
+
For further information about using MiniExiftool read the Tutorial and
|
25
|
+
have a look at the examples in directory examples.
|
data/Rakefile
CHANGED
@@ -60,7 +60,7 @@ GENERAL_RDOC_OPTS = {
|
|
60
60
|
}
|
61
61
|
|
62
62
|
# Additional RDoc formatted files, besides the Ruby source files.
|
63
|
-
RDOC_FILES = FileList["README"]
|
63
|
+
RDOC_FILES = FileList["README", 'Tutorial']
|
64
64
|
# Remove the following line if you don't want to extract RDoc from
|
65
65
|
# the extension C sources.
|
66
66
|
RDOC_FILES.include(EXT_SOURCES)
|
data/Tutorial
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
= Mini Tutorial
|
2
|
+
|
3
|
+
|
4
|
+
== Installation
|
5
|
+
|
6
|
+
* Installing the Exiftool command-line application from Phil Harvay
|
7
|
+
(see http://www.sno.phy.queensu.ca/~phil/exiftool/install.html)
|
8
|
+
* Installing the Ruby library (<code>gem install mini_exiftool</code>)
|
9
|
+
|
10
|
+
|
11
|
+
== Lesson 1: Reading Meta Data
|
12
|
+
|
13
|
+
=== A Simple Example
|
14
|
+
|
15
|
+
require 'rubygems'
|
16
|
+
require 'mini_exiftool'
|
17
|
+
|
18
|
+
photo = MiniExiftool.new 'photo.jpg'
|
19
|
+
puts photo['DateTimeOriginal']
|
20
|
+
|
21
|
+
|
22
|
+
=== Smart Tag Names
|
23
|
+
In the example above we use <code>photo['DateTimeOriginal']</code> to
|
24
|
+
get the value for the time the photo was taken. But tag names are not
|
25
|
+
case sensitive and additional underlines are also irrelevant. So
|
26
|
+
following expressions are equivalent:
|
27
|
+
photo['DateTimeOriginal']
|
28
|
+
photo['datetimeoriginal']
|
29
|
+
photo['date_time_original']
|
30
|
+
|
31
|
+
|
32
|
+
=== Nicer Access Via Dynamic Methods
|
33
|
+
|
34
|
+
Using the []-method is the safest way to access to values of tags
|
35
|
+
(e. g. Self-timer you can only access this way) but the smarter way is
|
36
|
+
using dynamic method access. You can write:
|
37
|
+
photo.datetimeoriginal
|
38
|
+
or also
|
39
|
+
photo.date_time_original
|
40
|
+
|
41
|
+
|
42
|
+
=== Value Types
|
43
|
+
|
44
|
+
Following types of values are at the moment supported:
|
45
|
+
* Array (e. g. SubjectLocation => 1504 1000 256 304)
|
46
|
+
* Fixnum (e. g. ISO => 400)
|
47
|
+
* Float (e. g. FNumber => 9.5)
|
48
|
+
* String (e. g. Model => DYNAX 7D)
|
49
|
+
* Time (e. g. DateTimeOriginal => 2005:09:13 20:08:50)
|
50
|
+
|
51
|
+
The Exiftool command-line application has an option (-n) to get values
|
52
|
+
as numbers if possible, in MiniExiftool you can do this with setting
|
53
|
+
the <code>:numerical</code> option to +true+ while generating a new
|
54
|
+
instance with new or using the <code>numerical=</code>-method
|
55
|
+
combining with calling <code>reload</code>.
|
56
|
+
|
57
|
+
Let's make an example:
|
58
|
+
# standard: numerical is false
|
59
|
+
photo = MiniExiftool.new 'photo.jpg'
|
60
|
+
photo.exposure_time # => '1/16' (String)
|
61
|
+
# now with numerical is true
|
62
|
+
photo.numerical = true
|
63
|
+
photo.reload
|
64
|
+
photo.exposure_time # => 0.01666667 (Float)
|
65
|
+
This behaviour can be useful if you want to do calculations on the
|
66
|
+
value, if you only want to show the value the standard behaviour is
|
67
|
+
maybe better.
|
68
|
+
|
69
|
+
|
70
|
+
=== Further Example
|
71
|
+
|
72
|
+
For understanding reading access to meta data also have a look at the
|
73
|
+
example file <code>print_portraits.rb</code> in the +examples+
|
74
|
+
directory.
|
75
|
+
|
76
|
+
|
77
|
+
== Lesson 2: Writing Meta Data
|
78
|
+
|
79
|
+
|
80
|
+
=== Also A Very Simple Example
|
81
|
+
|
82
|
+
require 'rubygems'
|
83
|
+
require 'mini_exiftool'
|
84
|
+
|
85
|
+
photo = MiniExiftool.new 'photo.jpg'
|
86
|
+
photo.comment = 'hello world'
|
87
|
+
photo.save
|
88
|
+
|
89
|
+
|
90
|
+
=== Save Is Atomar
|
91
|
+
|
92
|
+
If you have changed serval values and call the +save+-method either
|
93
|
+
all changes will be written to the file or nothing. The return value
|
94
|
+
of the +save+-method is +true+ if all values are written to the file
|
95
|
+
otherwise save returns +false+. In the last case you can use the
|
96
|
+
+errors+-method which returns a hash of the tags which values couldn't
|
97
|
+
be writed with an error message for each of them.
|
98
|
+
|
99
|
+
|
100
|
+
=== Interesting Methods
|
101
|
+
|
102
|
+
Have a look at the <code>changed?</code>-method for checking if the
|
103
|
+
value of a specific tag is changed or a changing in general is
|
104
|
+
done. In the same way the +revert+-method reverts the value of a
|
105
|
+
specific tag or in general all changes.
|
106
|
+
|
107
|
+
|
108
|
+
=== Further Example
|
109
|
+
|
110
|
+
See <code>shift_time.rb</code> in the +examples+ directory.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'mini_exiftool'
|
4
|
+
|
5
|
+
unless ARGV.size == 1
|
6
|
+
puts "usage: ruby #{__FILE__} URI"
|
7
|
+
puts " i.e.: ruby #{__FILE__} http://www.23hq.com/janfri/photo/1535332/large"
|
8
|
+
exit -1
|
9
|
+
end
|
10
|
+
|
11
|
+
# Fetch an external photo
|
12
|
+
filename = open(ARGV.first).path
|
13
|
+
|
14
|
+
# Read the metadata
|
15
|
+
photo = MiniExiftool.new filename
|
16
|
+
|
17
|
+
# Print the metadata
|
18
|
+
photo.tags.sort.each do |tag|
|
19
|
+
# puts "#{tag}: #{photo[tag]}"
|
20
|
+
puts tag.ljust(28) + photo[tag].to_s
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mini_exiftool'
|
3
|
+
|
4
|
+
unless ARGV.size > 0
|
5
|
+
puts "usage: ruby #{__FILE__} FILES"
|
6
|
+
puts " i.e.: ruby #{__FILE__} *.jpg"
|
7
|
+
exit -1
|
8
|
+
end
|
9
|
+
|
10
|
+
# Loop at all given files
|
11
|
+
ARGV.each do |filename|
|
12
|
+
# If a given file isn't a photo MiniExiftool new method will throw
|
13
|
+
# an exception this we will catch
|
14
|
+
begin
|
15
|
+
photo = MiniExiftool.new filename
|
16
|
+
height = photo.image_height
|
17
|
+
width = photo.image_width
|
18
|
+
# We define portait as a photo wich ratio of height to width is
|
19
|
+
# larger than 0.7
|
20
|
+
if height / width > 0.7
|
21
|
+
puts filename
|
22
|
+
end
|
23
|
+
rescue MiniExiftool::Error => e
|
24
|
+
$stderr.puts e.message
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'mini_exiftool'
|
3
|
+
|
4
|
+
if ARGV.size < 2
|
5
|
+
puts "usage: ruby #{__FILE__} [+|-]SECONDS FILES"
|
6
|
+
puts " i.e.: ruby #{__FILE__} 3600 *.jpg"
|
7
|
+
exit -1
|
8
|
+
end
|
9
|
+
|
10
|
+
delta = ARGV.shift.to_i
|
11
|
+
|
12
|
+
ARGV.each do |filename|
|
13
|
+
begin
|
14
|
+
photo = MiniExiftool.new filename
|
15
|
+
rescue MiniExiftool::Error => e
|
16
|
+
$stderr.puts e.message
|
17
|
+
exit -1
|
18
|
+
end
|
19
|
+
time = photo.date_time_original
|
20
|
+
# time is a Time object, so we can use the methods of it :)
|
21
|
+
photo.date_time_original = time + delta
|
22
|
+
save_ok = photo.save
|
23
|
+
if save_ok
|
24
|
+
fmt = '%Y-%m-%d %H:%M:%S'
|
25
|
+
puts "#{filename} changed: #{time.strftime(fmt)} -> #{(time + delta).strftime(fmt)}"
|
26
|
+
else
|
27
|
+
puts "#{filename} could not be changed"
|
28
|
+
end
|
29
|
+
end
|
data/lib/mini_exiftool.rb
CHANGED
@@ -19,32 +19,45 @@ require 'set'
|
|
19
19
|
# Simple OO access to the Exiftool command-line application.
|
20
20
|
class MiniExiftool
|
21
21
|
|
22
|
-
# Name of the
|
22
|
+
# Name of the Exiftool command-line application
|
23
23
|
@@cmd = 'exiftool'
|
24
24
|
|
25
25
|
attr_reader :filename
|
26
|
-
attr_accessor :numerical
|
26
|
+
attr_accessor :numerical, :composite, :errors
|
27
27
|
|
28
|
-
VERSION = '0.
|
28
|
+
VERSION = '0.3.0'
|
29
29
|
|
30
|
-
# opts at the moment
|
31
|
-
#
|
32
|
-
|
33
|
-
|
30
|
+
# opts support at the moment
|
31
|
+
# * <code>:numerical</code> for numerical values, default is +false+
|
32
|
+
# * <code>:composite</code> for including composite tags while loading,
|
33
|
+
# default is +false+
|
34
|
+
def initialize filename, opts={}
|
35
|
+
std_opts = {:numerical => false, :composite => false}
|
36
|
+
opts = std_opts.update opts
|
37
|
+
@numerical = opts[:numerical]
|
38
|
+
@composite = opts[:composite]
|
39
|
+
@values = TagHash.new
|
40
|
+
@tag_names = TagHash.new
|
41
|
+
@changed_values = TagHash.new
|
42
|
+
@errors = TagHash.new
|
34
43
|
load filename
|
35
44
|
end
|
36
45
|
|
37
46
|
# Load the tags of filename
|
38
47
|
def load filename
|
39
|
-
|
48
|
+
if filename.nil? || !File.exists?(filename)
|
40
49
|
raise MiniExiftool::Error.new("File '#{filename}' does not exist.")
|
50
|
+
elsif File.directory?(filename)
|
51
|
+
raise MiniExiftool::Error.new("'#{filename}' is a directory.")
|
41
52
|
end
|
42
53
|
@filename = filename
|
43
|
-
@values
|
44
|
-
@tag_names
|
45
|
-
@changed_values
|
46
|
-
opt_params =
|
47
|
-
|
54
|
+
@values.clear
|
55
|
+
@tag_names.clear
|
56
|
+
@changed_values.clear
|
57
|
+
opt_params = ''
|
58
|
+
opt_params << (@numerical ? '-n ' : '')
|
59
|
+
opt_params << (@composite ? '' : '-e ')
|
60
|
+
cmd = %Q(#@@cmd -q -q -s -t #{opt_params} "#{filename}")
|
48
61
|
if run(cmd)
|
49
62
|
parse_output
|
50
63
|
else
|
@@ -60,19 +73,12 @@ class MiniExiftool
|
|
60
73
|
|
61
74
|
# Returns the value of a tag
|
62
75
|
def [] tag
|
63
|
-
|
64
|
-
@changed_values[unified_tag] || @values[unified_tag]
|
76
|
+
@changed_values[tag] || @values[tag]
|
65
77
|
end
|
66
78
|
|
67
79
|
# Set the value of a tag
|
68
80
|
def []=(tag, val)
|
69
|
-
|
70
|
-
converted_val = convert val
|
71
|
-
opt_params = converted_val.kind_of?(Numeric) ? '-n' : ''
|
72
|
-
cmd = %Q(#@@cmd -q -q -P -overwrite_original #{opt_params} -#{unified_tag}="#{converted_val}" "#{temp_filename}")
|
73
|
-
if run(cmd)
|
74
|
-
@changed_values[unified_tag] = val
|
75
|
-
end
|
81
|
+
@changed_values[tag] = val
|
76
82
|
end
|
77
83
|
|
78
84
|
# Return true if any tag value is changed or if the value of a
|
@@ -88,8 +94,7 @@ class MiniExiftool
|
|
88
94
|
# Revert all changes or the change of a given tag
|
89
95
|
def revert tag=nil
|
90
96
|
if tag
|
91
|
-
|
92
|
-
val = @changed_values.delete(unified_tag)
|
97
|
+
val = @changed_values.delete(tag)
|
93
98
|
res = val != nil
|
94
99
|
else
|
95
100
|
res = @changed_values.size > 0
|
@@ -110,17 +115,29 @@ class MiniExiftool
|
|
110
115
|
|
111
116
|
# Save the changes to the file
|
112
117
|
def save
|
113
|
-
|
118
|
+
return false if @changed_values.empty?
|
119
|
+
@errors.clear
|
120
|
+
temp_file = Tempfile.new('mini_exiftool')
|
121
|
+
temp_file.close
|
122
|
+
temp_filename = temp_file.path
|
123
|
+
FileUtils.cp filename, temp_filename
|
124
|
+
all_ok = true
|
114
125
|
@changed_values.each do |tag, val|
|
115
|
-
unified_tag = unify tag
|
116
126
|
converted_val = convert val
|
117
127
|
opt_params = converted_val.kind_of?(Numeric) ? '-n' : ''
|
118
|
-
cmd = %Q(#@@cmd -q -
|
119
|
-
run(cmd)
|
120
|
-
result
|
128
|
+
cmd = %Q(#@@cmd -q -P -overwrite_original #{opt_params} -#{tag}="#{converted_val}" "#{temp_filename}")
|
129
|
+
result = run(cmd)
|
130
|
+
unless result
|
131
|
+
all_ok = false
|
132
|
+
@errors[tag] = @error_text.gsub(/Nothing to do.\n\z/, '').chomp
|
133
|
+
end
|
134
|
+
end
|
135
|
+
if all_ok
|
136
|
+
FileUtils.cp temp_filename, filename
|
137
|
+
reload
|
121
138
|
end
|
122
|
-
|
123
|
-
|
139
|
+
temp_file.delete
|
140
|
+
all_ok
|
124
141
|
end
|
125
142
|
|
126
143
|
# Returns the command name of the called Exiftool application
|
@@ -151,11 +168,10 @@ class MiniExiftool
|
|
151
168
|
# Returns the version of the Exiftool command-line application
|
152
169
|
def self.exiftool_version
|
153
170
|
output = `#{MiniExiftool.command} -ver 2>&1`
|
154
|
-
|
155
|
-
return output
|
156
|
-
else
|
171
|
+
unless $?.exitstatus == 0
|
157
172
|
raise MiniExiftool::Error.new("Command '#{MiniExiftool.command}' not found")
|
158
173
|
end
|
174
|
+
output.chomp!
|
159
175
|
end
|
160
176
|
|
161
177
|
private
|
@@ -175,10 +191,6 @@ class MiniExiftool
|
|
175
191
|
end
|
176
192
|
end
|
177
193
|
|
178
|
-
def unify name
|
179
|
-
name.gsub(/[_\-]/, '').downcase
|
180
|
-
end
|
181
|
-
|
182
194
|
def convert val
|
183
195
|
case val
|
184
196
|
when Time
|
@@ -199,9 +211,8 @@ class MiniExiftool
|
|
199
211
|
def parse_output
|
200
212
|
@output.each_line do |line|
|
201
213
|
tag, value = parse_line line
|
202
|
-
|
203
|
-
@
|
204
|
-
@values[unified_tag] = value
|
214
|
+
@tag_names[tag] = tag
|
215
|
+
@values[tag] = value
|
205
216
|
end
|
206
217
|
end
|
207
218
|
|
@@ -236,6 +247,27 @@ class MiniExiftool
|
|
236
247
|
@temp_filename
|
237
248
|
end
|
238
249
|
|
250
|
+
# Hash with indifferent access:
|
251
|
+
# DateTimeOriginal == datetimeoriginal == date_time_original
|
252
|
+
class TagHash < Hash
|
253
|
+
def[] k
|
254
|
+
super(unify(k))
|
255
|
+
end
|
256
|
+
def []= k, v
|
257
|
+
super(unify(k), v)
|
258
|
+
end
|
259
|
+
def delete k
|
260
|
+
super(unify(k))
|
261
|
+
end
|
262
|
+
|
263
|
+
private
|
264
|
+
def unify tag
|
265
|
+
tag.gsub(/[-_]/,'').downcase
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
# Exception class
|
239
271
|
class MiniExiftool::Error < Exception; end
|
240
272
|
|
241
273
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'mini_exiftool'
|
2
|
+
require 'test/unit'
|
3
|
+
begin
|
4
|
+
require 'turn'
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
|
8
|
+
class TestClassMethods < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def test_new
|
11
|
+
assert_raises MiniExiftool::Error do
|
12
|
+
MiniExiftool.new nil
|
13
|
+
end
|
14
|
+
assert_raises MiniExiftool::Error do
|
15
|
+
MiniExiftool.new ''
|
16
|
+
end
|
17
|
+
assert_raises MiniExiftool::Error do
|
18
|
+
MiniExiftool.new 'not_existing_file'
|
19
|
+
end
|
20
|
+
assert_raises MiniExiftool::Error do
|
21
|
+
MiniExiftool.new '.' # directory
|
22
|
+
end
|
23
|
+
begin
|
24
|
+
MiniExiftool.new 'not_existing_file'
|
25
|
+
rescue MiniExiftool::Error => e
|
26
|
+
assert_match /File 'not_existing_file' does not exist/, e.message
|
27
|
+
end
|
28
|
+
assert_raises MiniExiftool::Error do
|
29
|
+
MiniExiftool.new __FILE__ # file type wich Exiftool can not handle
|
30
|
+
end
|
31
|
+
begin
|
32
|
+
MiniExiftool.new __FILE__ # file type wich Exiftool can not handle
|
33
|
+
rescue MiniExiftool::Error => e
|
34
|
+
assert_match /Error: Unknown (?:image|file) type/, e.message
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_command
|
39
|
+
cmd = MiniExiftool.command
|
40
|
+
assert_equal 'exiftool', cmd
|
41
|
+
MiniExiftool.command = 'non_existend'
|
42
|
+
assert_equal 'non_existend', MiniExiftool.command
|
43
|
+
assert_raises MiniExiftool::Error do
|
44
|
+
met = MiniExiftool.new(File.join(File.dirname(__FILE__),
|
45
|
+
'data/test.jpg'))
|
46
|
+
end
|
47
|
+
MiniExiftool.command = cmd
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_writable_tags
|
51
|
+
w_tags = MiniExiftool.writable_tags
|
52
|
+
assert w_tags.include?('ISO')
|
53
|
+
assert_equal false, w_tags.include?('xxxxxx')
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_exiftool_version
|
57
|
+
v = MiniExiftool.exiftool_version
|
58
|
+
assert_match /\A\d+\.\d+\z/, v
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'mini_exiftool'
|
2
|
+
require 'test/unit'
|
3
|
+
begin
|
4
|
+
require 'turn'
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
|
8
|
+
class TestComposite < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@data_dir = File.dirname(__FILE__) + '/data'
|
12
|
+
@filename_test = @data_dir + '/test.jpg'
|
13
|
+
@mini_exiftool = MiniExiftool.new @filename_test
|
14
|
+
@mini_exiftool_c = MiniExiftool.new @filename_test, :composite => true
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_composite_tags
|
18
|
+
assert_equal false, @mini_exiftool.tags.include?('Aperture')
|
19
|
+
assert_equal true, @mini_exiftool_c.tags.include?('Aperture')
|
20
|
+
assert_equal 9.5, @mini_exiftool_c['Aperture']
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/test/test_read.rb
CHANGED
@@ -11,32 +11,6 @@ class TestRead < Test::Unit::TestCase
|
|
11
11
|
@data_dir = File.dirname(__FILE__) + '/data'
|
12
12
|
@filename_test = @data_dir + '/test.jpg'
|
13
13
|
@mini_exiftool = MiniExiftool.new @filename_test
|
14
|
-
@mini_exiftool_num = MiniExiftool.new @filename_test, :numerical
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_initialize
|
18
|
-
assert_raises MiniExiftool::Error do
|
19
|
-
MiniExiftool.new ''
|
20
|
-
end
|
21
|
-
assert_raises MiniExiftool::Error do
|
22
|
-
MiniExiftool.new 'not_existing_file'
|
23
|
-
end
|
24
|
-
begin
|
25
|
-
MiniExiftool.new 'not_existing_file'
|
26
|
-
rescue MiniExiftool::Error => e
|
27
|
-
assert_match /File 'not_existing_file' does not exist/, e.message
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_wrong_file
|
32
|
-
assert_raises MiniExiftool::Error do
|
33
|
-
MiniExiftool.new __FILE__ # file type wich Exiftool can not handle
|
34
|
-
end
|
35
|
-
begin
|
36
|
-
MiniExiftool.new __FILE__ # file type wich Exiftool can not handle
|
37
|
-
rescue MiniExiftool::Error => e
|
38
|
-
assert_match /Error: Unknown image type/, e.message
|
39
|
-
end
|
40
14
|
end
|
41
15
|
|
42
16
|
def test_access
|
@@ -46,15 +20,8 @@ class TestRead < Test::Unit::TestCase
|
|
46
20
|
assert_equal 400, @mini_exiftool.iso
|
47
21
|
end
|
48
22
|
|
49
|
-
def test_access_numerical
|
50
|
-
assert_equal 'DYNAX 7D', @mini_exiftool_num['Model']
|
51
|
-
assert_equal 'MLT0', @mini_exiftool_num['maker_note_version']
|
52
|
-
assert_equal 'MLT0', @mini_exiftool_num.maker_note_version
|
53
|
-
assert_equal 400, @mini_exiftool_num.iso
|
54
|
-
end
|
55
|
-
|
56
23
|
def test_tags
|
57
|
-
assert @
|
24
|
+
assert @mini_exiftool.tags.include?('FileSize')
|
58
25
|
end
|
59
26
|
|
60
27
|
def test_conversion
|
@@ -66,14 +33,4 @@ class TestRead < Test::Unit::TestCase
|
|
66
33
|
assert_kind_of Array, @mini_exiftool['SubjectLocation']
|
67
34
|
end
|
68
35
|
|
69
|
-
def test_conversion_numerical
|
70
|
-
assert_kind_of String, @mini_exiftool_num.model
|
71
|
-
assert_kind_of Time, @mini_exiftool_num['DateTimeOriginal']
|
72
|
-
assert_kind_of Float, @mini_exiftool_num['MaxApertureValue']
|
73
|
-
assert_kind_of Fixnum, @mini_exiftool_num.flash
|
74
|
-
assert_kind_of String, @mini_exiftool_num.exif_version
|
75
|
-
assert_kind_of Fixnum, @mini_exiftool_num['ExposureCompensation']
|
76
|
-
assert_kind_of Array, @mini_exiftool_num['SubjectLocation']
|
77
|
-
end
|
78
|
-
|
79
36
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'mini_exiftool'
|
2
|
+
require 'test/unit'
|
3
|
+
begin
|
4
|
+
require 'turn'
|
5
|
+
rescue LoadError
|
6
|
+
end
|
7
|
+
|
8
|
+
class TestReadNumerical < Test::Unit::TestCase
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@data_dir = File.dirname(__FILE__) + '/data'
|
12
|
+
@filename_test = @data_dir + '/test.jpg'
|
13
|
+
@mini_exiftool_num = MiniExiftool.new @filename_test, :numerical => true
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_access_numerical
|
17
|
+
assert_equal 'DYNAX 7D', @mini_exiftool_num['Model']
|
18
|
+
assert_equal 'MLT0', @mini_exiftool_num['maker_note_version']
|
19
|
+
assert_equal 'MLT0', @mini_exiftool_num.maker_note_version
|
20
|
+
assert_equal 400, @mini_exiftool_num.iso
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_conversion_numerical
|
24
|
+
assert_kind_of String, @mini_exiftool_num.model
|
25
|
+
assert_kind_of Time, @mini_exiftool_num['DateTimeOriginal']
|
26
|
+
assert_kind_of Float, @mini_exiftool_num['MaxApertureValue']
|
27
|
+
assert_kind_of Fixnum, @mini_exiftool_num.flash
|
28
|
+
assert_kind_of String, @mini_exiftool_num.exif_version
|
29
|
+
assert_kind_of Fixnum, @mini_exiftool_num['ExposureCompensation']
|
30
|
+
assert_kind_of Array, @mini_exiftool_num['SubjectLocation']
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/test/test_save.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'mini_exiftool'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'test/unit'
|
6
|
+
begin
|
7
|
+
require 'turn'
|
8
|
+
rescue LoadError
|
9
|
+
end
|
10
|
+
|
11
|
+
class TestSave < Test::Unit::TestCase
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@temp_file = Tempfile.new('test')
|
15
|
+
@temp_file.close
|
16
|
+
@temp_filename = @temp_file.path
|
17
|
+
@org_filename = File.dirname(__FILE__) + '/data/test.jpg'
|
18
|
+
FileUtils.cp(@org_filename, @temp_filename)
|
19
|
+
@mini_exiftool = MiniExiftool.new @temp_filename
|
20
|
+
@mini_exiftool_num = MiniExiftool.new @temp_filename, :numerical => true
|
21
|
+
@org_md5 = Digest::MD5.hexdigest(File.read(@org_filename))
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_allowed_value
|
25
|
+
@mini_exiftool_num['Orientation'] = 2
|
26
|
+
result = @mini_exiftool_num.save
|
27
|
+
assert_equal true, result
|
28
|
+
assert_equal @org_md5, Digest::MD5.hexdigest(File.read(@org_filename))
|
29
|
+
assert_not_equal @org_md5, Digest::MD5.hexdigest(File.read(@temp_filename))
|
30
|
+
assert_equal false, @mini_exiftool_num.changed?
|
31
|
+
result = @mini_exiftool_num.save
|
32
|
+
assert_equal false, result
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_non_allowed_value
|
36
|
+
@mini_exiftool['Orientation'] = 'some string'
|
37
|
+
result = @mini_exiftool.save
|
38
|
+
assert_equal false, result
|
39
|
+
assert_equal 1, @mini_exiftool.errors.size
|
40
|
+
assert_equal("Can't convert IFD0:Orientation (not in PrintConv)",
|
41
|
+
@mini_exiftool.errors['Orientation'])
|
42
|
+
assert @mini_exiftool.changed?
|
43
|
+
assert @mini_exiftool.changed_tags.include?('Orientation')
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_no_changing_of_file_when_error
|
47
|
+
@mini_exiftool['ISO'] = 800
|
48
|
+
@mini_exiftool['Orientation'] = 'some value'
|
49
|
+
@mini_exiftool['ExposureTime'] = '1/30'
|
50
|
+
result = @mini_exiftool.save
|
51
|
+
assert_equal false, result
|
52
|
+
assert_equal @org_md5, Digest::MD5.hexdigest(File.read(@org_filename))
|
53
|
+
assert_equal @org_md5, Digest::MD5.hexdigest(File.read(@temp_filename))
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/test/test_write.rb
CHANGED
@@ -17,7 +17,7 @@ class TestWrite < Test::Unit::TestCase
|
|
17
17
|
@org_filename = File.dirname(__FILE__) + '/data/test.jpg'
|
18
18
|
FileUtils.cp(@org_filename, @temp_filename)
|
19
19
|
@mini_exiftool = MiniExiftool.new @temp_filename
|
20
|
-
@mini_exiftool_num = MiniExiftool.new @temp_filename, :numerical
|
20
|
+
@mini_exiftool_num = MiniExiftool.new @temp_filename, :numerical => true
|
21
21
|
end
|
22
22
|
|
23
23
|
def teardown
|
@@ -27,7 +27,7 @@ class TestWrite < Test::Unit::TestCase
|
|
27
27
|
def test_access_existing_tags
|
28
28
|
assert_equal 'Horizontal (normal)', @mini_exiftool['Orientation']
|
29
29
|
@mini_exiftool['Orientation'] = 'some string'
|
30
|
-
assert_equal '
|
30
|
+
assert_equal 'some string', @mini_exiftool['Orientation']
|
31
31
|
assert_equal false, @mini_exiftool.changed?('Orientation')
|
32
32
|
@mini_exiftool['Orientation'] = 2
|
33
33
|
assert_equal 2, @mini_exiftool['Orientation']
|
@@ -52,11 +52,11 @@ class TestWrite < Test::Unit::TestCase
|
|
52
52
|
assert_equal 'Rotate 180', @mini_exiftool['Orientation']
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
55
|
+
def test_access_non_writable_tags
|
56
56
|
@mini_exiftool_num['FileSize'] = 1
|
57
|
-
assert_equal
|
58
|
-
@mini_exiftool_num['
|
59
|
-
assert_equal
|
57
|
+
assert_equal true, @mini_exiftool_num.changed?
|
58
|
+
@mini_exiftool_num['SomeNonWritableName'] = 'test'
|
59
|
+
assert_equal true, @mini_exiftool_num.changed?
|
60
60
|
end
|
61
61
|
|
62
62
|
def test_time_conversion
|
@@ -113,20 +113,4 @@ class TestWrite < Test::Unit::TestCase
|
|
113
113
|
assert_equal false, res
|
114
114
|
end
|
115
115
|
|
116
|
-
def test_save
|
117
|
-
org_md5 = Digest::MD5.hexdigest(File.read(@org_filename))
|
118
|
-
temp_md5 = Digest::MD5.hexdigest(File.read(@temp_filename))
|
119
|
-
assert_equal org_md5, temp_md5
|
120
|
-
@mini_exiftool_num['Orientation'] = 2
|
121
|
-
result = @mini_exiftool_num.save
|
122
|
-
assert_equal true, result
|
123
|
-
org_md5_2 = Digest::MD5.hexdigest(File.read(@org_filename))
|
124
|
-
assert_equal org_md5, org_md5_2
|
125
|
-
temp_md5_2 = Digest::MD5.hexdigest(File.read(@temp_filename))
|
126
|
-
assert_not_equal temp_md5, temp_md5_2
|
127
|
-
assert_equal false, @mini_exiftool_num.changed?
|
128
|
-
result = @mini_exiftool_num.save
|
129
|
-
assert_equal false, result
|
130
|
-
end
|
131
|
-
|
132
116
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.1
|
|
3
3
|
specification_version: 1
|
4
4
|
name: mini_exiftool
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.3.0
|
7
|
+
date: 2007-03-29 00:00:00 +02:00
|
8
8
|
summary: A library for nice OO access to the Exiftool command-line application written by Phil Harvey.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -33,7 +33,13 @@ files:
|
|
33
33
|
- test/test_write.rb
|
34
34
|
- test/test_read.rb
|
35
35
|
- test/test_special.rb
|
36
|
-
- test/
|
36
|
+
- test/test_class_methods.rb
|
37
|
+
- test/test_save.rb
|
38
|
+
- test/test_composite.rb
|
39
|
+
- test/test_read_numerical.rb
|
40
|
+
- examples/external_photo.rb
|
41
|
+
- examples/print_portraits.rb
|
42
|
+
- examples/shift_time.rb
|
37
43
|
- Rakefile
|
38
44
|
- COPYING
|
39
45
|
- Changelog
|
@@ -41,11 +47,15 @@ files:
|
|
41
47
|
- test/data/Canon.jpg
|
42
48
|
- test/data/INFORMATION
|
43
49
|
- README
|
50
|
+
- Tutorial
|
44
51
|
test_files:
|
45
52
|
- test/test_write.rb
|
46
53
|
- test/test_read.rb
|
47
54
|
- test/test_special.rb
|
48
|
-
- test/
|
55
|
+
- test/test_class_methods.rb
|
56
|
+
- test/test_save.rb
|
57
|
+
- test/test_composite.rb
|
58
|
+
- test/test_read_numerical.rb
|
49
59
|
rdoc_options:
|
50
60
|
- --title
|
51
61
|
- MiniExiftool API documentation
|
@@ -53,6 +63,7 @@ rdoc_options:
|
|
53
63
|
- README
|
54
64
|
extra_rdoc_files:
|
55
65
|
- README
|
66
|
+
- Tutorial
|
56
67
|
executables: []
|
57
68
|
|
58
69
|
extensions: []
|
data/test/test_other.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'mini_exiftool'
|
2
|
-
require 'test/unit'
|
3
|
-
begin
|
4
|
-
require 'turn'
|
5
|
-
rescue LoadError
|
6
|
-
end
|
7
|
-
|
8
|
-
class TestOther < Test::Unit::TestCase
|
9
|
-
|
10
|
-
def test_command
|
11
|
-
cmd = MiniExiftool.command
|
12
|
-
assert_equal 'exiftool', cmd
|
13
|
-
MiniExiftool.command = 'non_existend'
|
14
|
-
assert_equal 'non_existend', MiniExiftool.command
|
15
|
-
assert_raises MiniExiftool::Error do
|
16
|
-
met = MiniExiftool.new(File.join(File.dirname(__FILE__),
|
17
|
-
'data/test.jpg'))
|
18
|
-
end
|
19
|
-
MiniExiftool.command = cmd
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_writable_tags
|
23
|
-
w_tags = MiniExiftool.writable_tags
|
24
|
-
assert w_tags.include?('ISO')
|
25
|
-
assert_equal false, w_tags.include?('xxxxxx')
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|