multi_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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8ca8548908a3e26fbdea1a74a49af9dc597361a8
4
+ data.tar.gz: f0bfc40076a49f6c5bc71cc8b416cb9321fb2afb
5
+ SHA512:
6
+ metadata.gz: 7a6ce9840e83312e0922373b2f485524b25ddbb9933e1a16f75d84f7e437cbc9637de32f17bae8174eea428d421592c62f626e4b67e321a9f9cf14a2fbc42879
7
+ data.tar.gz: 2f6ff90bcea1fc6852d0650a24258c70d9c710f9e6bc8d5ecccac5f338e40e1080b7afc0a605a2dd3639bc91456e3b7eea442530abfc6534fd47e46a5484a1d9
data/CHANGELOG CHANGED
@@ -1,11 +1,23 @@
1
- v0.2.0 Support writing to specific group with hash hierarchy.
1
+ 0.3.0
2
+ New functional api.
3
+ Update documentation.
4
+ Adding tests and new example for functional api.
5
+ Switching to rim.
6
+
7
+ 0.2.0
8
+ Support writing to specific group with hash hierarchy.
2
9
  Support array-like values for tags like keywords.
3
10
 
4
- v0.1.3 Improve README and adapt project url.
11
+ 0.1.3
12
+ Improve README and adapt project url.
5
13
 
6
- v0.1.2 Preserve time zone in time objects (don't convert to local zone).
14
+ 0.1.2
15
+ Preserve time zone in time objects (don't convert to local zone).
7
16
  Thanks to Bernard aka gittycat for the hint.
8
17
 
9
- v0.1.1 Parsing timestamps without value for seconds. Thanks to gittycat for the hint.
18
+ 0.1.1
19
+ Parsing timestamps without value for seconds.
20
+ Thanks to gittycat for the hint.
10
21
 
11
- v0.1.0 First public release.
22
+ 0.1.0
23
+ First public release.
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2009-2012 Jan Friedrich
3
+ Copyright (c) 2009-2014 Jan Friedrich
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -14,9 +14,22 @@ the results.
14
14
 
15
15
  require 'multi_exiftool'
16
16
 
17
+ # Object oriented approach
17
18
  reader = MultiExiftool::Reader.new
18
19
  reader.filenames = Dir['*.jpg']
19
20
  results = reader.read
21
+ unless reader.errors.empty?
22
+ $stderr.puts reader.errors
23
+ end
24
+ results.each do |values|
25
+ puts "#{values.file_name}: #{values.comment}"
26
+ end
27
+
28
+ # Functional approach
29
+ results, errors = MultiExiftool.read(Dir['*.jpg'])
30
+ unless reader.errors.empty?
31
+ $stderr.puts reader.errors
32
+ end
20
33
  results.each do |values|
21
34
  puts "#{values.file_name}: #{values.comment}"
22
35
  end
@@ -25,13 +38,22 @@ the results.
25
38
 
26
39
  require 'multi_exiftool'
27
40
 
41
+ # Object oriented approach
28
42
  writer = MultiExiftool::Writer.new
29
43
  writer.filenames = Dir['*.jpg']
30
44
  writer.values = {creator: 'Jan Friedrich', copyright: 'Public Domain'}
31
45
  if writer.write
32
46
  puts 'ok'
33
47
  else
34
- puts writer.errors.join
48
+ puts writer.errors
49
+ end
50
+
51
+ # Functional approach
52
+ errors = MultiExiftool.write(Dir['*.jpg'], {creator: 'Jan Friedrich', copyright: 'Public Domain'})
53
+ if errors.empty?
54
+ puts 'ok'
55
+ else
56
+ puts writer.errors
35
57
  end
36
58
 
37
59
  === Further Examples
@@ -68,7 +90,7 @@ Jan Friedrich (janfri26 AT gmail DOT com)
68
90
 
69
91
  The MIT License
70
92
 
71
- Copyright (c) 2009-2012 Jan Friedrich
93
+ Copyright (c) 2009-2014 Jan Friedrich
72
94
 
73
95
  Permission is hereby granted, free of charge, to any person obtaining a copy
74
96
  of this software and associated documentation files (the "Software"), to deal
data/Rakefile CHANGED
@@ -1,12 +1,17 @@
1
- require 'echoe'
1
+ require 'rim'
2
+ require 'rim/check_version'
3
+ require 'rim/gem'
4
+ require 'rim/test'
2
5
 
3
- Echoe.new('multi_exiftool') do |p|
4
- p.author = 'Jan Friedrich'
6
+ Rim.setup do |p|
7
+ p.name = 'multi_exiftool'
8
+ p.version = '0.3.0'
9
+ p.authors = 'Jan Friedrich'
5
10
  p.email = 'janfri26@gmail.com'
6
11
  p.summary = 'This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool).'
7
12
  p.description = 'This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool) written by Phil Harvey. It is designed for dealing with multiple files at once by creating commands to call exiftool with various arguments, call it and parsing the results.'
8
13
  p.ruby_version = '>=1.9.1'
9
- p.url = 'http://gitorious.org/multi_exiftool'
14
+ p.homepage = 'http://gitorious.org/multi_exiftool'
10
15
  p.install_message = %q{
11
16
  +-----------------------------------------------------------------------+
12
17
  | Please ensure you have installed exiftool version 7.65 or higher and |
@@ -15,8 +20,6 @@ Echoe.new('multi_exiftool') do |p|
15
20
  | http://www.sno.phy.queensu.ca/~phil/exiftool/install.html |
16
21
  +-----------------------------------------------------------------------+
17
22
  }
18
- p.development_dependencies = ['contest']
19
- p.eval = proc do
20
- self.requirements << 'exiftool, version 7.65 or higher'
21
- end
23
+ p.development_dependencies << 'contest'
24
+ p.requirements << 'exiftool, version 7.65 or higher'
22
25
  end
@@ -5,6 +5,45 @@ require_relative 'multi_exiftool/writer'
5
5
 
6
6
  module MultiExiftool
7
7
 
8
+ # Reading metadata
9
+ # Be aware: it returns an array of two elements:
10
+ # values, errors
11
+ #
12
+ # Example:
13
+ # values, errors = MultiExiftool.read(Dir['*.jpg'])
14
+ # if errors.empty?
15
+ # values.each {|val| do_something_with(val) }
16
+ # else
17
+ # # error handling
18
+ # end
19
+ def self.read(filenames, opts={})
20
+ reader = Reader.new
21
+ reader.filenames = filenames
22
+ if val = opts.delete(:tags)
23
+ reader.tags = val
24
+ end
25
+ reader.options = opts unless opts.empty?
26
+ values = reader.read
27
+ [values, reader.errors]
28
+ end
29
+
30
+ # Writing metadata
31
+ # Returns an array of the error messages
32
+ #
33
+ # Example:
34
+ # errors = MultiExiftool.write(Dir['*.jpg'], {author: 'Jan Friedrich'})
35
+ # unless errors.empty?
36
+ # # do error handling
37
+ # end
38
+ def self.write(filenames, values, opts={})
39
+ writer = Writer.new
40
+ writer.filenames = filenames
41
+ writer.values = values
42
+ writer.options = opts unless opts.empty?
43
+ writer.write
44
+ writer.errors
45
+ end
46
+
8
47
  class Error < ::StandardError; end
9
48
 
10
49
  end
@@ -15,6 +15,7 @@ module MultiExiftool
15
15
  @exiftool_command = 'exiftool'
16
16
  @options = {}
17
17
  @filenames = []
18
+ @option_mapping = {numerical: :n}
18
19
  end
19
20
 
20
21
  def options
@@ -48,10 +49,11 @@ module MultiExiftool
48
49
  opts = options
49
50
  return [] if opts.empty?
50
51
  opts.map do |opt, val|
52
+ arg = @option_mapping[opt] || opt
51
53
  if val == true
52
- "-#{opt}"
54
+ "-#{arg}"
53
55
  else
54
- "-#{opt} #{val}"
56
+ "-#{arg} #{val}"
55
57
  end
56
58
  end
57
59
  end
@@ -17,13 +17,14 @@ module MultiExiftool
17
17
 
18
18
  def initialize
19
19
  super
20
+ @option_mapping.merge! group: :g
20
21
  end
21
22
 
22
23
  # Options to use with the exiftool command.
23
24
  def options
24
25
  opts = super
25
26
  if @group
26
- opts["g#{@group}"] = true
27
+ opts[:g] = @group
27
28
  end
28
29
  opts
29
30
  end
@@ -52,7 +53,8 @@ module MultiExiftool
52
53
 
53
54
  def parse_results
54
55
  stdout = @stdout.read
55
- @errors = @stderr.readlines
56
+ error_string = @stderr.read.gsub(/^ .*$/, '')
57
+ @errors = error_string.split(/\n/)
56
58
  json = JSON.parse(stdout)
57
59
  json.map {|values| Values.new(values)}
58
60
  rescue JSON::ParserError
@@ -60,7 +60,7 @@ module MultiExiftool
60
60
  end
61
61
 
62
62
  def parse_results
63
- @errors = @stderr.readlines
63
+ @errors = @stderr.read.split(/\n/)
64
64
  @errors.empty?
65
65
  end
66
66
 
@@ -0,0 +1,72 @@
1
+ # reading
2
+ "exiftool -J non_existing_file":
3
+ stdout: ""
4
+ stderr: "File non_existing_file not found."
5
+ "exiftool -J -fnumber -foo a.jpg xxx":
6
+ stdout: |
7
+ [{
8
+ "SourceFile": "a.jpg",
9
+ "FNumber": 9.5
10
+ }]
11
+ stderr: |
12
+ File not found: xxx
13
+ 1 image files read
14
+ 1 files could not be read
15
+ "exiftool -J a.jpg b.tif c.bmp":
16
+ stdout: |
17
+ [{
18
+ "SourceFile": "a.jpg",
19
+ "FNumber": 11.0,
20
+ "ISO": 400
21
+ },
22
+ {
23
+ "SourceFile": "b.tif",
24
+ "FNumber": 9.0,
25
+ "ISO": 200
26
+ },
27
+ {
28
+ "SourceFile": "c.bmp",
29
+ "FNumber": 8.0,
30
+ "ISO": 100
31
+ }]
32
+ stderr: ""
33
+ "exiftool -J -fnumber a.jpg b.tif c.bmp":
34
+ stdout: |
35
+ [{
36
+ "SourceFile": "a.jpg",
37
+ "FNumber": 11.0
38
+ },
39
+ {
40
+ "SourceFile": "b.tif",
41
+ "FNumber": 9.0
42
+ },
43
+ {
44
+ "SourceFile": "c.bmp",
45
+ "FNumber": 8.0
46
+ }]
47
+ stderr: ""
48
+ "exiftool -J -g 0 -fnumber a.jpg":
49
+ stdout: |
50
+ [{
51
+ "SourceFile": "a.jpg",
52
+ "EXIF": {
53
+ "FNumber": 7.1
54
+ },
55
+ "MakerNotes": {
56
+ "FNumber": 7.0
57
+ }
58
+ }]
59
+ stderr: ""
60
+
61
+ # writing
62
+ "exiftool -author=janfri a.jpg b.tif c.bmp":
63
+ stdout: |2
64
+ 1 image files updated
65
+ stderr: ""
66
+ "exiftool -author=janfri -foo=x a.jpg xxx":
67
+ stdout: |2
68
+ 1 image files updated
69
+ 1 files weren't updated due to errors
70
+ stderr: |
71
+ Warning: Tag 'foo' does not exist
72
+ Error: File not found - xxx
@@ -4,13 +4,26 @@ require 'test/unit'
4
4
  require 'contest'
5
5
  require 'open3'
6
6
  require 'stringio'
7
+ require 'yaml'
7
8
 
8
9
  module TestHelper
9
10
 
10
- def mocking_open3(command, outstr, errstr)
11
+ @@fixtures = YAML.load_file('test/fixtures.yml')
12
+
13
+ def use_fixture(name, &block)
14
+ @fixture = @@fixtures[name]
15
+ if @fixture.nil?
16
+ assert false, "Fixture #{name} not found!\n" << caller.first
17
+ end
18
+ mocking_open3(name, @fixture['stdout'], @fixture['stderr'], &block)
19
+ end
20
+
21
+ def mocking_open3(command, outstr, errstr, &block)
22
+ executed = {exec: false}
11
23
  open3_eigenclass = class << Open3; self; end
12
- open3_eigenclass.module_exec(command, outstr, errstr) do |cmd, out, err|
24
+ open3_eigenclass.module_exec(command, outstr, errstr, executed) do |cmd, out, err, exec|
13
25
  define_method :popen3 do |arg|
26
+ exec[:exec] = true
14
27
  if arg == cmd
15
28
  return [nil, StringIO.new(out), StringIO.new(err)]
16
29
  else
@@ -18,6 +31,12 @@ module TestHelper
18
31
  end
19
32
  end
20
33
  end
34
+ begin
35
+ yield
36
+ rescue ArgumentError => e
37
+ assert false, e.message
38
+ end
39
+ assert executed[:exec], "Open3.popen3 not executed!\n" << caller[0,2].inspect
21
40
  end
22
41
 
23
42
  end
@@ -0,0 +1,118 @@
1
+ # coding: utf-8
2
+ require_relative 'helper'
3
+
4
+ class TestFunctionalApi < Test::Unit::TestCase
5
+
6
+ context 'reading' do
7
+
8
+ test 'successful reading only filenames' do
9
+ use_fixture 'exiftool -J a.jpg b.tif c.bmp' do
10
+ values, errors = MultiExiftool.read(%w(a.jpg b.tif c.bmp))
11
+ assert_kind_of Array, values
12
+ assert_equal [11.0, 9.0, 8.0], values.map {|e| e['FNumber']}
13
+ assert_equal [400, 200, 100], values.map {|e| e['ISO']}
14
+ assert_equal [], errors
15
+ end
16
+ end
17
+
18
+ test 'successful reading with one tag' do
19
+ use_fixture 'exiftool -J -fnumber a.jpg b.tif c.bmp' do
20
+ values, errors = MultiExiftool.read(%w(a.jpg b.tif c.bmp), tags: %w(fnumber))
21
+ assert_kind_of Array, values
22
+ assert_equal [11.0, 9.0, 8.0], values.map {|e| e['FNumber']}
23
+ assert_equal [], errors
24
+ end
25
+ end
26
+
27
+ test 'successful reading of hierarichal data' do
28
+ use_fixture 'exiftool -J -g 0 -fnumber a.jpg' do
29
+ values, errors = MultiExiftool.read(%w(a.jpg), tags: %w[fnumber], group: 0)
30
+ res = values.first
31
+ assert_equal 'a.jpg', res.source_file
32
+ assert_equal 7.1, res.exif.fnumber
33
+ assert_equal 7.0, res.maker_notes.fnumber
34
+ assert_equal [], errors
35
+ end
36
+ end
37
+
38
+ test 'generate correct command for numerical option' do
39
+ mocking_open3 'exiftool -J -n -orientation a.jpg', '', '' do
40
+ MultiExiftool.read(%w[a.jpg], tags: %w[orientation], numerical: true)
41
+ end
42
+ end
43
+
44
+ test 'options with boolean argument' do
45
+ mocking_open3 'exiftool -J -e a.jpg b.tif c.bmp', '', '' do
46
+ MultiExiftool.read(%w[a.jpg b.tif c.bmp], e: true)
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ context 'writing' do
53
+
54
+ setup do
55
+ @filenames = %w(a.jpg b.tif c.bmp)
56
+ end
57
+
58
+ test 'simple case' do
59
+ mocking_open3 'exiftool -author=janfri a.jpg b.tif c.bmp', '', '' do
60
+ values = {:author => 'janfri'}
61
+ MultiExiftool.write @filenames, values
62
+ end
63
+ end
64
+
65
+ test 'tags with spaces in values' do
66
+ mocking_open3 'exiftool -author=janfri -comment=some\ comment a.jpg b.tif c.bmp', '', '' do
67
+ values = {:author => 'janfri', :comment => 'some comment'}
68
+ MultiExiftool.write @filenames, values
69
+ end
70
+ end
71
+
72
+ test 'tags with rational value' do
73
+ mocking_open3 'exiftool -shutterspeed=1/125 a.jpg b.tif c.bmp', '', '' do
74
+ values ={shutterspeed: Rational(1, 125)}
75
+ MultiExiftool.write @filenames, values
76
+ end
77
+ end
78
+
79
+ test 'tags with array-like values' do
80
+ mocking_open3 'exiftool -keywords=one -keywords=two -keywords=and\ three a.jpg b.tif c.bmp', '', '' do
81
+ values = {keywords: ['one', 'two', 'and three']}
82
+ MultiExiftool.write @filenames, values
83
+ end
84
+ end
85
+
86
+ test 'options with boolean argument' do
87
+ mocking_open3 'exiftool -overwrite_original -author=janfri a.jpg b.tif c.bmp', '', '' do
88
+ values = {:author => 'janfri'}
89
+ options = {:overwrite_original => true}
90
+ MultiExiftool.write @filenames, values, options
91
+ end
92
+ end
93
+
94
+ test 'options with value argument' do
95
+ mocking_open3 'exiftool -out output_file -author=janfri a.jpg b.tif c.bmp', '', '' do
96
+ values = {:author => 'janfri'}
97
+ options = {:out => 'output_file'}
98
+ MultiExiftool.write @filenames, values, options
99
+ end
100
+ end
101
+
102
+ test 'numerical flag' do
103
+ mocking_open3 'exiftool -n -author=janfri a.jpg b.tif c.bmp', '', '' do
104
+ values = {:author => 'janfri'}
105
+ MultiExiftool.write @filenames, values, numerical: true
106
+ end
107
+ end
108
+
109
+ test 'overwrite_original flag' do
110
+ mocking_open3 'exiftool -overwrite_original -author=janfri a.jpg b.tif c.bmp', '', '' do
111
+ values = {author: 'janfri'}
112
+ MultiExiftool.write @filenames, values, overwrite_original: true
113
+ end
114
+ end
115
+
116
+ end
117
+
118
+ end
@@ -68,10 +68,10 @@ class TestReader < Test::Unit::TestCase
68
68
  test 'group flag' do
69
69
  @reader.filenames = %w(a.jpg)
70
70
  @reader.group = 0
71
- command = 'exiftool -J -g0 a.jpg'
71
+ command = 'exiftool -J -g 0 a.jpg'
72
72
  assert_equal command, @reader.command
73
73
  @reader.group = 1
74
- command = 'exiftool -J -g1 a.jpg'
74
+ command = 'exiftool -J -g 1 a.jpg'
75
75
  assert_equal command, @reader.command
76
76
  end
77
77
 
@@ -80,60 +80,46 @@ class TestReader < Test::Unit::TestCase
80
80
  context 'read method' do
81
81
 
82
82
  test 'try to read a non-existing file' do
83
- mocking_open3('exiftool -J non_existing_file', '', 'File non_existing_file not found.')
84
- @reader.filenames = %w(non_existing_file)
85
- res = @reader.read
86
- assert_equal [], res
87
- assert_equal ['File non_existing_file not found.'], @reader.errors
83
+ use_fixture('exiftool -J non_existing_file') do
84
+ @reader.filenames = %w(non_existing_file)
85
+ res = @reader.read
86
+ assert_equal [], res
87
+ assert_equal ['File non_existing_file not found.'], @reader.errors
88
+ end
89
+ end
90
+
91
+ test 'read from an existing and a non-existing file' do
92
+ use_fixture('exiftool -J -fnumber -foo a.jpg xxx') do
93
+ @reader.filenames = %w(a.jpg xxx)
94
+ @reader.tags = %w(fnumber foo)
95
+ res = @reader.read
96
+ assert_equal [9.5], res.map {|e| e['FNumber']}
97
+ assert_equal ['File not found: xxx'], @reader.errors
98
+ end
88
99
  end
89
100
 
90
101
  test 'successful reading with one tag' do
91
- json = <<-EOS
92
- [{
93
- "SourceFile": "a.jpg",
94
- "FNumber": 11.0
95
- },
96
- {
97
- "SourceFile": "b.tif",
98
- "FNumber": 9.0
99
- },
100
- {
101
- "SourceFile": "c.bmp",
102
- "FNumber": 8.0
103
- }]
104
- EOS
105
- json.gsub!(/^ {8}/, '')
106
- mocking_open3('exiftool -J -fnumber a.jpg b.tif c.bmp', json, '')
107
- @reader.filenames = %w(a.jpg b.tif c.bmp)
108
- @reader.tags = %w(fnumber)
109
- res = @reader.read
110
- assert_kind_of Array, res
111
- assert_equal [11.0, 9.0, 8.0], res.map {|e| e['FNumber']}
112
- assert_equal [], @reader.errors
102
+ use_fixture('exiftool -J -fnumber a.jpg b.tif c.bmp') do
103
+ @reader.filenames = %w(a.jpg b.tif c.bmp)
104
+ @reader.tags = %w(fnumber)
105
+ res = @reader.read
106
+ assert_kind_of Array, res
107
+ assert_equal [11.0, 9.0, 8.0], res.map {|e| e['FNumber']}
108
+ assert_equal [], @reader.errors
109
+ end
113
110
  end
114
111
 
115
112
  test 'successful reading of hierarichal data' do
116
- json = <<-EOS
117
- [{
118
- "SourceFile": "a.jpg",
119
- "EXIF": {
120
- "FNumber": 7.1
121
- },
122
- "MakerNotes": {
123
- "FNumber": 7.0
124
- }
125
- }]
126
- EOS
127
- json.gsub!(/^ {8}/, '')
128
- mocking_open3('exiftool -J -g0 -fnumber a.jpg', json, '')
129
- @reader.filenames = %w(a.jpg)
130
- @reader.tags = %w(fnumber)
131
- @reader.group = 0
132
- res = @reader.read.first
133
- assert_equal 'a.jpg', res.source_file
134
- assert_equal 7.1, res.exif.fnumber
135
- assert_equal 7.0, res.maker_notes.fnumber
136
- assert_equal [], @reader.errors
113
+ use_fixture('exiftool -J -g 0 -fnumber a.jpg') do
114
+ @reader.filenames = %w(a.jpg)
115
+ @reader.tags = %w(fnumber)
116
+ @reader.group = 0
117
+ res = @reader.read.first
118
+ assert_equal 'a.jpg', res.source_file
119
+ assert_equal 7.1, res.exif.fnumber
120
+ assert_equal 7.0, res.maker_notes.fnumber
121
+ assert_equal [], @reader.errors
122
+ end
137
123
  end
138
124
 
139
125
  end
@@ -7,16 +7,9 @@ class TestWriter < Test::Unit::TestCase
7
7
  @writer = MultiExiftool::Writer.new
8
8
  end
9
9
 
10
- context 'command method' do
10
+ context 'various filename combinations' do
11
11
 
12
- test 'simple case' do
13
- @writer.filenames = %w(a.jpg b.tif c.bmp)
14
- @writer.values = {:author => 'janfri'}
15
- command = 'exiftool -author=janfri a.jpg b.tif c.bmp'
16
- assert_equal command, @writer.command
17
- end
18
-
19
- test 'no filenames set' do
12
+ test 'command method, no filenames set' do
20
13
  @writer.values = {:author => 'janfri'}
21
14
  assert_raises MultiExiftool::Error do
22
15
  @writer.command
@@ -34,8 +27,28 @@ class TestWriter < Test::Unit::TestCase
34
27
  assert_equal command, @writer.command
35
28
  end
36
29
 
37
- test 'no values set' do
30
+ test 'filenames with spaces' do
31
+ @writer.filenames = ['one file with spaces.jpg', 'another file with spaces.tif']
32
+ @writer.values = {:author => 'janfri'}
33
+ command = 'exiftool -author=janfri one\ file\ with\ spaces.jpg another\ file\ with\ spaces.tif'
34
+ assert_equal command, @writer.command
35
+ end
36
+
37
+ end
38
+
39
+ context 'command method, various tags' do
40
+
41
+ setup do
38
42
  @writer.filenames = %w(a.jpg b.tif c.bmp)
43
+ end
44
+
45
+ test 'simple case' do
46
+ @writer.values = {:author => 'janfri'}
47
+ command = 'exiftool -author=janfri a.jpg b.tif c.bmp'
48
+ assert_equal command, @writer.command
49
+ end
50
+
51
+ test 'no values set' do
39
52
  assert_raises MultiExiftool::Error do
40
53
  @writer.command
41
54
  end
@@ -46,35 +59,24 @@ class TestWriter < Test::Unit::TestCase
46
59
  end
47
60
 
48
61
  test 'tags with spaces in values' do
49
- @writer.filenames = %w(a.jpg b.tif c.bmp)
50
62
  @writer.values = {:author => 'janfri', :comment => 'some comment'}
51
63
  command = 'exiftool -author=janfri -comment=some\ comment a.jpg b.tif c.bmp'
52
64
  assert_equal command, @writer.command
53
65
  end
54
66
 
55
67
  test 'tags with rational value' do
56
- @writer.filenames = %w(a.jpg b.tif c.bmp)
57
68
  @writer.values ={shutterspeed: Rational(1, 125)}
58
69
  command = 'exiftool -shutterspeed=1/125 a.jpg b.tif c.bmp'
59
70
  assert_equal command, @writer.command
60
71
  end
61
72
 
62
73
  test 'tags with array-like values' do
63
- @writer.filenames = %w(a.jpg b.tif c.bmp)
64
74
  @writer.values = {keywords: ['one', 'two', 'and three']}
65
75
  command = 'exiftool -keywords=one -keywords=two -keywords=and\ three a.jpg b.tif c.bmp'
66
76
  assert_equal command, @writer.command
67
77
  end
68
78
 
69
- test 'filenames with spaces' do
70
- @writer.filenames = ['one file with spaces.jpg', 'another file with spaces.tif']
71
- @writer.values = {:author => 'janfri'}
72
- command = 'exiftool -author=janfri one\ file\ with\ spaces.jpg another\ file\ with\ spaces.tif'
73
- assert_equal command, @writer.command
74
- end
75
-
76
79
  test 'options with boolean argument' do
77
- @writer.filenames = %w(a.jpg b.tif c.bmp)
78
80
  @writer.values = {:author => 'janfri'}
79
81
  @writer.options = {:overwrite_original => true}
80
82
  command = 'exiftool -overwrite_original -author=janfri a.jpg b.tif c.bmp'
@@ -82,7 +84,6 @@ class TestWriter < Test::Unit::TestCase
82
84
  end
83
85
 
84
86
  test 'options with value argument' do
85
- @writer.filenames = %w(a.jpg b.tif c.bmp)
86
87
  @writer.values = {:author => 'janfri'}
87
88
  @writer.options = {:out => 'output_file'}
88
89
  command = 'exiftool -out output_file -author=janfri a.jpg b.tif c.bmp'
@@ -90,7 +91,6 @@ class TestWriter < Test::Unit::TestCase
90
91
  end
91
92
 
92
93
  test 'numerical flag' do
93
- @writer.filenames = %w(a.jpg b.tif c.bmp)
94
94
  @writer.values = {:author => 'janfri'}
95
95
  @writer.numerical = true
96
96
  command = 'exiftool -n -author=janfri a.jpg b.tif c.bmp'
@@ -98,7 +98,6 @@ class TestWriter < Test::Unit::TestCase
98
98
  end
99
99
 
100
100
  test 'overwrite_original flag' do
101
- @writer.filenames = %w(a.jpg b.tif c.bmp)
102
101
  @writer.values = {author: 'janfri'}
103
102
  @writer.overwrite_original = true
104
103
  command = 'exiftool -overwrite_original -author=janfri a.jpg b.tif c.bmp'
@@ -109,13 +108,24 @@ class TestWriter < Test::Unit::TestCase
109
108
 
110
109
  context 'write method' do
111
110
 
112
- test 'succsessfull write' do
113
- mocking_open3('exiftool -author=janfri a.jpg b.tif c.bmp', '', '')
114
- @writer.filenames = %w(a.jpg b.tif c.bmp)
115
- @writer.values = {:author => 'janfri'}
116
- rc = @writer.write
117
- assert_equal [], @writer.errors
118
- assert_equal true, rc
111
+ test 'successful write' do
112
+ use_fixture('exiftool -author=janfri a.jpg b.tif c.bmp') do
113
+ @writer.filenames = %w(a.jpg b.tif c.bmp)
114
+ @writer.values = {:author => 'janfri'}
115
+ rc = @writer.write
116
+ assert_equal [], @writer.errors
117
+ assert_equal true, rc
118
+ end
119
+ end
120
+
121
+ test 'unsuccessful write' do
122
+ use_fixture('exiftool -author=janfri -foo=x a.jpg xxx') do
123
+ @writer.filenames = %w(a.jpg xxx)
124
+ @writer.values = {author: 'janfri', foo: 'x'}
125
+ rc = @writer.write
126
+ assert_equal @fixture['stderr'].chomp, @writer.errors.join("\n")
127
+ assert_equal false, rc
128
+ end
119
129
  end
120
130
 
121
131
  end
metadata CHANGED
@@ -1,30 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi_exiftool
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jan Friedrich
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-05-11 00:00:00.000000000 Z
11
+ date: 2014-01-30 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rim
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.7.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.7.0
14
27
  - !ruby/object:Gem::Dependency
15
28
  name: contest
16
29
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
30
  requirements:
19
- - - ! '>='
31
+ - - ">="
20
32
  - !ruby/object:Gem::Version
21
33
  version: '0'
22
34
  type: :development
23
35
  prerelease: false
24
36
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
37
  requirements:
27
- - - ! '>='
38
+ - - ">="
28
39
  - !ruby/object:Gem::Version
29
40
  version: '0'
30
41
  description: This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool)
@@ -34,78 +45,53 @@ description: This library is wrapper for the Exiftool command-line application (
34
45
  email: janfri26@gmail.com
35
46
  executables: []
36
47
  extensions: []
37
- extra_rdoc_files:
38
- - CHANGELOG
39
- - LICENSE
40
- - README
41
- - lib/multi_exiftool.rb
42
- - lib/multi_exiftool/executable.rb
43
- - lib/multi_exiftool/reader.rb
44
- - lib/multi_exiftool/values.rb
45
- - lib/multi_exiftool/writer.rb
48
+ extra_rdoc_files: []
46
49
  files:
47
50
  - CHANGELOG
48
51
  - LICENSE
49
- - Manifest
50
- - README
52
+ - README.rdoc
51
53
  - Rakefile
52
- - examples/01_simple_reading.rb
53
- - examples/02_simple_writing.rb
54
- - examples/03_reading_using_groups.rb
55
- - examples/04_writing_using_groups.rb
56
54
  - lib/multi_exiftool.rb
57
55
  - lib/multi_exiftool/executable.rb
58
56
  - lib/multi_exiftool/reader.rb
59
57
  - lib/multi_exiftool/values.rb
60
58
  - lib/multi_exiftool/writer.rb
59
+ - test/fixtures.yml
61
60
  - test/helper.rb
62
61
  - test/test_executable.rb
62
+ - test/test_functional_api.rb
63
63
  - test/test_reader.rb
64
64
  - test/test_values.rb
65
65
  - test/test_values_using_groups.rb
66
66
  - test/test_writer.rb
67
67
  - test/test_writer_groups.rb
68
- - multi_exiftool.gemspec
69
68
  homepage: http://gitorious.org/multi_exiftool
70
69
  licenses: []
71
- post_install_message: ! "\n+-----------------------------------------------------------------------+\n|
70
+ metadata: {}
71
+ post_install_message: "\n+-----------------------------------------------------------------------+\n|
72
72
  Please ensure you have installed exiftool version 7.65 or higher and |\n| it's
73
73
  found in your PATH (Try \"exiftool -ver\" on your commandline). |\n| For more
74
74
  details see |\n| http://www.sno.phy.queensu.ca/~phil/exiftool/install.html
75
75
  \ |\n+-----------------------------------------------------------------------+\n
76
76
  \ "
77
- rdoc_options:
78
- - --line-numbers
79
- - --inline-source
80
- - --title
81
- - Multi_exiftool
82
- - --main
83
- - README
77
+ rdoc_options: []
84
78
  require_paths:
85
79
  - lib
86
80
  required_ruby_version: !ruby/object:Gem::Requirement
87
- none: false
88
81
  requirements:
89
- - - ! '>='
82
+ - - ">="
90
83
  - !ruby/object:Gem::Version
91
84
  version: 1.9.1
92
85
  required_rubygems_version: !ruby/object:Gem::Requirement
93
- none: false
94
86
  requirements:
95
- - - ! '>='
87
+ - - ">="
96
88
  - !ruby/object:Gem::Version
97
- version: '1.2'
89
+ version: '0'
98
90
  requirements:
99
91
  - exiftool, version 7.65 or higher
100
- rubyforge_project: multi_exiftool
101
- rubygems_version: 1.8.21
92
+ rubyforge_project:
93
+ rubygems_version: 2.2.1
102
94
  signing_key:
103
- specification_version: 3
95
+ specification_version: 4
104
96
  summary: This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool).
105
- test_files:
106
- - test/test_executable.rb
107
- - test/test_reader.rb
108
- - test/test_values.rb
109
- - test/test_values_using_groups.rb
110
- - test/test_writer.rb
111
- - test/test_writer_groups.rb
97
+ test_files: []
data/Manifest DELETED
@@ -1,21 +0,0 @@
1
- CHANGELOG
2
- LICENSE
3
- Manifest
4
- README
5
- Rakefile
6
- examples/01_simple_reading.rb
7
- examples/02_simple_writing.rb
8
- examples/03_reading_using_groups.rb
9
- examples/04_writing_using_groups.rb
10
- lib/multi_exiftool.rb
11
- lib/multi_exiftool/executable.rb
12
- lib/multi_exiftool/reader.rb
13
- lib/multi_exiftool/values.rb
14
- lib/multi_exiftool/writer.rb
15
- test/helper.rb
16
- test/test_executable.rb
17
- test/test_reader.rb
18
- test/test_values.rb
19
- test/test_values_using_groups.rb
20
- test/test_writer.rb
21
- test/test_writer_groups.rb
@@ -1,13 +0,0 @@
1
- require 'multi_exiftool'
2
-
3
- if ARGV.empty?
4
- $stderr.puts 'No filenames given.'
5
- exit -1
6
- end
7
-
8
- reader = MultiExiftool::Reader.new
9
- reader.filenames = ARGV
10
- results = reader.read
11
- results.each do |values|
12
- puts "#{values.file_name}: #{values.comment}"
13
- end
@@ -1,19 +0,0 @@
1
- require 'multi_exiftool'
2
-
3
- if ARGV.empty?
4
- $stderr.puts 'No filenames given.'
5
- exit -1
6
- end
7
-
8
- puts 'Please enter a comment for the given files:'
9
- comment = $stdin.gets.chomp
10
-
11
- writer = MultiExiftool::Writer.new
12
- writer.filenames = ARGV
13
- writer.overwrite_original = true
14
- writer.values = {comment: comment}
15
- if writer.write
16
- puts 'ok'
17
- else
18
- puts writer.errors.join
19
- end
@@ -1,28 +0,0 @@
1
- require 'multi_exiftool'
2
-
3
- if ARGV.empty?
4
- $stderr.puts 'No filenames given.'
5
- exit -1
6
- end
7
-
8
- reader = MultiExiftool::Reader.new
9
- reader.filenames = ARGV
10
- reader.group = 0
11
- results = reader.read
12
- results.each do |values|
13
- # direct access
14
- puts values.file.filename
15
- # access via block without parameter
16
- values.iptc do
17
- self.keywords do
18
- puts " Keywords (IPCT): #{Array(self).join(', ')}"
19
- end
20
- end
21
- # access via block with parameter
22
- values.xmp do |xmp|
23
- xmp.keywords do |kw|
24
- puts " Keywords (XMP): #{Array(kw).join(', ')}"
25
- end
26
- end
27
- end
28
-
@@ -1,33 +0,0 @@
1
- require 'multi_exiftool'
2
- require 'yaml'
3
-
4
- if ARGV.empty?
5
- $stderr.puts 'No filenames given.'
6
- exit -1
7
- end
8
-
9
- puts 'Please enter a description for the given files:'
10
- description = $stdin.gets.chomp
11
-
12
- puts 'Please enter a caption for the given files:'
13
- caption = $stdin.gets.chomp
14
-
15
- writer = MultiExiftool::Writer.new
16
- writer.filenames = ARGV
17
-
18
- # specifying group by prefix
19
- writer.values = {'exif:imagedescription' => description, 'xmp:description' => description}
20
-
21
- # specifying group hierarchical
22
- writer.values.merge! YAML.load <<-END
23
- iptc:
24
- caption-abstract: #{caption}
25
- xmp:
26
- caption: #{caption}
27
- END
28
-
29
- if writer.write
30
- puts 'ok'
31
- else
32
- puts writer.errors.join
33
- end
@@ -1,36 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- Gem::Specification.new do |s|
4
- s.name = "multi_exiftool"
5
- s.version = "0.2.0"
6
-
7
- s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["Jan Friedrich"]
9
- s.date = "2012-05-11"
10
- s.description = "This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool) written by Phil Harvey. It is designed for dealing with multiple files at once by creating commands to call exiftool with various arguments, call it and parsing the results."
11
- s.email = "janfri26@gmail.com"
12
- s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README", "lib/multi_exiftool.rb", "lib/multi_exiftool/executable.rb", "lib/multi_exiftool/reader.rb", "lib/multi_exiftool/values.rb", "lib/multi_exiftool/writer.rb"]
13
- s.files = ["CHANGELOG", "LICENSE", "Manifest", "README", "Rakefile", "examples/01_simple_reading.rb", "examples/02_simple_writing.rb", "examples/03_reading_using_groups.rb", "examples/04_writing_using_groups.rb", "lib/multi_exiftool.rb", "lib/multi_exiftool/executable.rb", "lib/multi_exiftool/reader.rb", "lib/multi_exiftool/values.rb", "lib/multi_exiftool/writer.rb", "test/helper.rb", "test/test_executable.rb", "test/test_reader.rb", "test/test_values.rb", "test/test_values_using_groups.rb", "test/test_writer.rb", "test/test_writer_groups.rb", "multi_exiftool.gemspec"]
14
- s.homepage = "http://gitorious.org/multi_exiftool"
15
- s.post_install_message = "\n+-----------------------------------------------------------------------+\n| Please ensure you have installed exiftool version 7.65 or higher and |\n| it's found in your PATH (Try \"exiftool -ver\" on your commandline). |\n| For more details see |\n| http://www.sno.phy.queensu.ca/~phil/exiftool/install.html |\n+-----------------------------------------------------------------------+\n "
16
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Multi_exiftool", "--main", "README"]
17
- s.require_paths = ["lib"]
18
- s.required_ruby_version = Gem::Requirement.new(">= 1.9.1")
19
- s.requirements = ["exiftool, version 7.65 or higher"]
20
- s.rubyforge_project = "multi_exiftool"
21
- s.rubygems_version = "1.8.21"
22
- s.summary = "This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool)."
23
- s.test_files = ["test/test_executable.rb", "test/test_reader.rb", "test/test_values.rb", "test/test_values_using_groups.rb", "test/test_writer.rb", "test/test_writer_groups.rb"]
24
-
25
- if s.respond_to? :specification_version then
26
- s.specification_version = 3
27
-
28
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
29
- s.add_development_dependency(%q<contest>, [">= 0"])
30
- else
31
- s.add_dependency(%q<contest>, [">= 0"])
32
- end
33
- else
34
- s.add_dependency(%q<contest>, [">= 0"])
35
- end
36
- end