mini_exiftool 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
- == Examples (for further information and use cases see tests):
22
+ == Usage
23
23
 
24
- require 'mini_exiftool'
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)
@@ -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
@@ -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 exiftool command
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.2.0'
28
+ VERSION = '0.3.0'
29
29
 
30
- # opts at the moment only support :numerical for numerical values
31
- # (the -n parameter in the command line)
32
- def initialize filename, *opts
33
- @numerical = opts.include? :numerical
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
- unless File.exists? filename
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 = @numerical ? '-n' : ''
47
- cmd = %Q(#@@cmd -e -q -q -s -t #{opt_params} "#{filename}")
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
- unified_tag = unify tag
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
- unified_tag = unify tag
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
- unified_tag = unify tag
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
- result = false
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 -q -P -overwrite_original #{opt_params} -#{unified_tag}="#{converted_val}" "#{filename}")
119
- run(cmd)
120
- result = true
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
- reload
123
- result
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
- if $?.exitstatus == 0
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
- unified_tag = unify tag
203
- @tag_names[unified_tag] = tag
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
@@ -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 @mini_exiftool_num.tags.include?('FileSize')
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
@@ -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
@@ -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 'Horizontal (normal)', @mini_exiftool['Orientation']
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 test_access_not_existing_tags
55
+ def test_access_non_writable_tags
56
56
  @mini_exiftool_num['FileSize'] = 1
57
- assert_equal false, @mini_exiftool_num.changed?
58
- @mini_exiftool_num['SomeNotExitingName'] = 'test'
59
- assert_equal false, @mini_exiftool_num.changed?
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.2.0
7
- date: 2007-02-22 00:00:00 +01:00
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/test_other.rb
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/test_other.rb
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: []
@@ -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