multi_exiftool 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/CHANGELOG +11 -1
- data/LICENSE +1 -1
- data/README.rdoc +8 -5
- data/Rakefile +9 -8
- data/lib/multi_exiftool.rb +23 -0
- data/lib/multi_exiftool/executable.rb +11 -14
- data/lib/multi_exiftool/reader.rb +21 -10
- data/lib/multi_exiftool/values.rb +6 -0
- data/lib/multi_exiftool/writer.rb +17 -7
- data/test/data/a.jpg +0 -0
- data/test/data/b.jpg +0 -0
- data/test/data/c.jpg +0 -0
- data/test/helper.rb +9 -28
- data/test/temp/a.jpg +0 -0
- data/test/temp/b.jpg +0 -0
- data/test/temp/c.jpg +0 -0
- data/test/test_exiftool_stuff.rb +35 -0
- data/test/test_functional_api.rb +73 -51
- data/test/test_reader.rb +62 -37
- data/test/test_values.rb +10 -0
- data/test/test_writer.rb +46 -45
- data/test/test_writer_groups.rb +14 -9
- metadata +30 -9
- data/test/fixtures.yml +0 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab58cfbd7358a3bf89c39cfecaddbb22f80b50b8
|
4
|
+
data.tar.gz: 224cfd83f86b6dff424400d0d69ab5cc93428553
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3212194490e8eea822f5d064ede3b51f5a755b60f7fb7018288c05b7507663a19c1d2162c8cd2225407226991eacca712031e746b3861bef0af6b1e5c8fd44f
|
7
|
+
data.tar.gz: 9da30d30b957eb0e8e16c91e26529ab54ec87a9f93c619fda500c2a796e25d5c4fb224b782a4b2c53b472a31c25e60627b505cc54d5d910fa07eaa279a2acec1
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.4.0
|
2
|
+
New method Values#tags to get access to unmodified tag names.
|
3
|
+
Directly sending parameters to stdin of exiftool to make it
|
4
|
+
work on windows with umlauts in filenames (Many thanks to
|
5
|
+
Claudius Coenen for the research, implementing and testing the
|
6
|
+
idea!).
|
7
|
+
Complete rewrite of the test suite to use real tests.
|
8
|
+
Allow to set tags as single value.
|
9
|
+
A lot of internal refactoring.
|
10
|
+
|
1
11
|
0.3.0
|
2
12
|
New functional api.
|
3
13
|
Update documentation.
|
@@ -9,7 +19,7 @@ Support writing to specific group with hash hierarchy.
|
|
9
19
|
Support array-like values for tags like keywords.
|
10
20
|
|
11
21
|
0.1.3
|
12
|
-
Improve README and adapt project
|
22
|
+
Improve README and adapt project URL.
|
13
23
|
|
14
24
|
0.1.2
|
15
25
|
Preserve time zone in time objects (don't convert to local zone).
|
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -67,6 +67,9 @@ See the examples in the examples directory.
|
|
67
67
|
- An installation of the Exiftool command-line application (version 7.65 or
|
68
68
|
higher). Instructions for installation you can find under
|
69
69
|
http://www.sno.phy.queensu.ca/~phil/exiftool/install.html .
|
70
|
+
- If you have problems with special characters (like German umlauts) in
|
71
|
+
filenames on windows system it is recommended to use exiftool version 9.79
|
72
|
+
or higher.
|
70
73
|
|
71
74
|
== Installation
|
72
75
|
|
@@ -76,21 +79,21 @@ install the gem with
|
|
76
79
|
|
77
80
|
== Contribution
|
78
81
|
|
79
|
-
The code is also
|
80
|
-
http://
|
82
|
+
The code is also hosted in a git repository at
|
83
|
+
http://github.com/janfri/multi_exiftool
|
81
84
|
or
|
82
|
-
|
85
|
+
https://bitbucket.org/janfri/multi_exiftool
|
83
86
|
feel free to contribute!
|
84
87
|
|
85
88
|
== Author
|
86
89
|
|
87
|
-
Jan Friedrich
|
90
|
+
Jan Friedrich <janfri26gmail.com>
|
88
91
|
|
89
92
|
== Copyright / License
|
90
93
|
|
91
94
|
The MIT License
|
92
95
|
|
93
|
-
Copyright (c) 2009-
|
96
|
+
Copyright (c) 2009-2015 Jan Friedrich
|
94
97
|
|
95
98
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
96
99
|
of this software and associated documentation files (the "Software"), to deal
|
data/Rakefile
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
require 'rim'
|
2
|
-
require 'rim/
|
3
|
-
require 'rim/
|
4
|
-
require '
|
1
|
+
require 'rim/tire'
|
2
|
+
require 'rim/aspell'
|
3
|
+
require 'rim/version'
|
4
|
+
require 'regtest/task'
|
5
5
|
|
6
6
|
Rim.setup do |p|
|
7
7
|
p.name = 'multi_exiftool'
|
8
|
-
p.version = '0.
|
8
|
+
p.version = '0.4.0'
|
9
9
|
p.authors = 'Jan Friedrich'
|
10
10
|
p.email = 'janfri26@gmail.com'
|
11
|
-
p.summary = 'This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool).'
|
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.'
|
11
|
+
p.summary = 'This library is a wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool).'
|
12
|
+
p.description = 'This library a 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.'
|
13
13
|
p.ruby_version = '>=1.9.1'
|
14
|
+
p.license = 'MIT'
|
14
15
|
p.homepage = 'http://gitorious.org/multi_exiftool'
|
15
16
|
p.install_message = %q{
|
16
17
|
+-----------------------------------------------------------------------+
|
@@ -20,6 +21,6 @@ Rim.setup do |p|
|
|
20
21
|
| http://www.sno.phy.queensu.ca/~phil/exiftool/install.html |
|
21
22
|
+-----------------------------------------------------------------------+
|
22
23
|
}
|
23
|
-
p.development_dependencies << 'contest'
|
24
|
+
p.development_dependencies << 'contest' << 'regtest'
|
24
25
|
p.requirements << 'exiftool, version 7.65 or higher'
|
25
26
|
end
|
data/lib/multi_exiftool.rb
CHANGED
@@ -22,6 +22,9 @@ module MultiExiftool
|
|
22
22
|
if val = opts.delete(:tags)
|
23
23
|
reader.tags = val
|
24
24
|
end
|
25
|
+
if val = opts.delete(:group)
|
26
|
+
reader.group = val
|
27
|
+
end
|
25
28
|
reader.options = opts unless opts.empty?
|
26
29
|
values = reader.read
|
27
30
|
[values, reader.errors]
|
@@ -46,5 +49,25 @@ module MultiExiftool
|
|
46
49
|
|
47
50
|
class Error < ::StandardError; end
|
48
51
|
|
52
|
+
@exiftool_command = 'exiftool'
|
53
|
+
|
54
|
+
class << self
|
55
|
+
|
56
|
+
attr_accessor :exiftool_command
|
57
|
+
attr_reader :exiftool_version
|
58
|
+
|
59
|
+
def exiftool_command= cmd
|
60
|
+
@exiftool_command = cmd
|
61
|
+
@exiftool_version = nil
|
62
|
+
end
|
63
|
+
|
64
|
+
# Exiftool version as float (since exiftool versions
|
65
|
+
# are numbered "float friendly")
|
66
|
+
def exiftool_version
|
67
|
+
@exiftool_version ||= `#{exiftool_command} -ver`.to_f
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
49
72
|
end
|
50
73
|
|
@@ -1,18 +1,15 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
require 'open3'
|
3
|
-
require 'shellwords'
|
4
3
|
|
5
4
|
module MultiExiftool
|
6
5
|
|
7
6
|
# Mixin for Reader and Writer.
|
8
7
|
module Executable
|
9
8
|
|
10
|
-
attr_reader :
|
11
|
-
attr_accessor :
|
12
|
-
attr_writer :options
|
9
|
+
attr_reader :errors
|
10
|
+
attr_accessor :filenames, :numerical, :options
|
13
11
|
|
14
12
|
def initialize
|
15
|
-
@exiftool_command = 'exiftool'
|
16
13
|
@options = {}
|
17
14
|
@filenames = []
|
18
15
|
@option_mapping = {numerical: :n}
|
@@ -36,13 +33,8 @@ module MultiExiftool
|
|
36
33
|
|
37
34
|
private
|
38
35
|
|
39
|
-
def
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
def escaped_filenames
|
44
|
-
raise MultiExiftool::Error.new('No filenames.') if filenames.empty?
|
45
|
-
filenames.map { |fn| Shellwords.escape(fn) }
|
36
|
+
def exiftool_command
|
37
|
+
MultiExiftool.exiftool_command
|
46
38
|
end
|
47
39
|
|
48
40
|
def options_args
|
@@ -53,7 +45,7 @@ module MultiExiftool
|
|
53
45
|
if val == true
|
54
46
|
"-#{arg}"
|
55
47
|
else
|
56
|
-
|
48
|
+
%W[-#{arg} #{val}]
|
57
49
|
end
|
58
50
|
end
|
59
51
|
end
|
@@ -63,7 +55,12 @@ module MultiExiftool
|
|
63
55
|
end
|
64
56
|
|
65
57
|
def execute_command
|
66
|
-
stdin, @stdout, @stderr = Open3.popen3(
|
58
|
+
stdin, @stdout, @stderr = Open3.popen3(exiftool_command, '-@', '-')
|
59
|
+
exiftool_args.each do |part|
|
60
|
+
stdin << part
|
61
|
+
stdin << "\n"
|
62
|
+
end
|
63
|
+
stdin.close
|
67
64
|
end
|
68
65
|
|
69
66
|
end
|
@@ -9,41 +9,52 @@ module MultiExiftool
|
|
9
9
|
# the results as well as possible errors.
|
10
10
|
class Reader
|
11
11
|
|
12
|
-
MANDATORY_ARGS = %w(-J)
|
13
|
-
|
14
12
|
attr_accessor :tags, :group
|
15
13
|
|
16
14
|
include Executable
|
17
15
|
|
18
16
|
def initialize
|
19
17
|
super
|
20
|
-
@
|
18
|
+
@tags = []
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.mandatory_args
|
22
|
+
if MultiExiftool.exiftool_version >= 9.79
|
23
|
+
%w(-J -charset FileName=utf8 -charset utf8)
|
24
|
+
else
|
25
|
+
%w(-J -charset utf8)
|
26
|
+
end
|
21
27
|
end
|
22
28
|
|
23
29
|
# Options to use with the exiftool command.
|
24
30
|
def options
|
25
31
|
opts = super
|
26
32
|
if @group
|
27
|
-
opts[
|
33
|
+
opts["g#@group"] = true
|
28
34
|
end
|
29
35
|
opts
|
30
36
|
end
|
31
37
|
|
32
|
-
# Getting the command
|
38
|
+
# Getting the command-line arguments which would be executed
|
33
39
|
# when calling #read. It could be useful for logging, debugging or
|
34
40
|
# maybe even for creating a batch-file with exiftool command to be
|
35
41
|
# processed.
|
36
|
-
def
|
37
|
-
|
38
|
-
cmd
|
42
|
+
def exiftool_args
|
43
|
+
fail MultiExiftool::Error, 'No filenames.' if filenames.empty?
|
44
|
+
cmd = []
|
45
|
+
cmd << Reader.mandatory_args
|
39
46
|
cmd << options_args
|
40
47
|
cmd << tags_args
|
41
|
-
cmd <<
|
42
|
-
cmd.flatten
|
48
|
+
cmd << filenames
|
49
|
+
cmd.flatten
|
43
50
|
end
|
44
51
|
|
45
52
|
alias read execute # :nodoc:
|
46
53
|
|
54
|
+
def tags= value
|
55
|
+
@tags = Array(value)
|
56
|
+
end
|
57
|
+
|
47
58
|
private
|
48
59
|
|
49
60
|
def tags_args
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
require 'date'
|
3
|
+
require 'set'
|
4
|
+
|
3
5
|
module MultiExiftool
|
4
6
|
|
5
7
|
# Representing (tag, value) pairs of metadata.
|
@@ -7,9 +9,13 @@ module MultiExiftool
|
|
7
9
|
# method_missing.
|
8
10
|
class Values
|
9
11
|
|
12
|
+
attr_reader :tags
|
13
|
+
|
10
14
|
def initialize values
|
11
15
|
@values = {}
|
16
|
+
@tags = Set.new
|
12
17
|
values.map do |tag,val|
|
18
|
+
@tags << tag
|
13
19
|
val = val.kind_of?(Hash) ? Values.new(val) : val
|
14
20
|
@values[Values.unify_tag(tag)] = val
|
15
21
|
end
|
@@ -17,6 +17,14 @@ module MultiExiftool
|
|
17
17
|
@values = {}
|
18
18
|
end
|
19
19
|
|
20
|
+
def self.mandatory_args
|
21
|
+
if MultiExiftool.exiftool_version >= 9.79
|
22
|
+
%w(-charset FileName=utf8 -charset utf8)
|
23
|
+
else
|
24
|
+
%w(-charset utf8)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
20
28
|
# Options to use with the exiftool command.
|
21
29
|
def options
|
22
30
|
opts = super
|
@@ -24,16 +32,18 @@ module MultiExiftool
|
|
24
32
|
opts
|
25
33
|
end
|
26
34
|
|
27
|
-
# Getting the command
|
35
|
+
# Getting the command-line arguments which would be executed
|
28
36
|
# when calling #write. It could be useful for logging, debugging or
|
29
37
|
# maybe even for creating a batch-file with exiftool command to be
|
30
38
|
# processed.
|
31
|
-
def
|
32
|
-
|
39
|
+
def exiftool_args
|
40
|
+
fail MultiExiftool::Error, 'No filenames.' if filenames.empty?
|
41
|
+
cmd = []
|
42
|
+
cmd << Writer.mandatory_args
|
33
43
|
cmd << options_args
|
34
44
|
cmd << values_args
|
35
|
-
cmd <<
|
36
|
-
cmd.flatten
|
45
|
+
cmd << filenames
|
46
|
+
cmd.flatten
|
37
47
|
end
|
38
48
|
|
39
49
|
alias write execute # :nodoc:
|
@@ -51,9 +61,9 @@ module MultiExiftool
|
|
51
61
|
if val.respond_to? :to_hash
|
52
62
|
res << values_to_param_array(val.to_hash).map {|arg| "#{tag}:#{arg}"}
|
53
63
|
elsif val.respond_to? :to_ary
|
54
|
-
res << val.map {|v| "#{tag}=#{
|
64
|
+
res << val.map {|v| "#{tag}=#{v}"}
|
55
65
|
else
|
56
|
-
res << "#{tag}=#{
|
66
|
+
res << "#{tag}=#{val}"
|
57
67
|
end
|
58
68
|
end
|
59
69
|
res.flatten
|
data/test/data/a.jpg
ADDED
Binary file
|
data/test/data/b.jpg
ADDED
Binary file
|
data/test/data/c.jpg
ADDED
Binary file
|
data/test/helper.rb
CHANGED
@@ -1,42 +1,23 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
require_relative '../lib/multi_exiftool'
|
3
|
+
require 'fileutils'
|
3
4
|
require 'test/unit'
|
4
5
|
require 'contest'
|
5
|
-
require 'open3'
|
6
|
-
require 'stringio'
|
7
|
-
require 'yaml'
|
8
6
|
|
9
7
|
module TestHelper
|
10
8
|
|
11
|
-
|
9
|
+
DATA_DIR = File.join(File.dirname(__FILE__), 'data')
|
10
|
+
TEMP_DIR = File.join(File.dirname(__FILE__), 'temp')
|
12
11
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
assert false, "Fixture #{name} not found!\n" << caller.first
|
17
|
-
end
|
18
|
-
mocking_open3(name, @fixture['stdout'], @fixture['stderr'], &block)
|
12
|
+
def prepare_temp_dir
|
13
|
+
FileUtils.rm_rf TEMP_DIR
|
14
|
+
FileUtils.cp_r DATA_DIR, TEMP_DIR
|
19
15
|
end
|
20
16
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
open3_eigenclass.module_exec(command, outstr, errstr, executed) do |cmd, out, err, exec|
|
25
|
-
define_method :popen3 do |arg|
|
26
|
-
exec[:exec] = true
|
27
|
-
if arg == cmd
|
28
|
-
return [nil, StringIO.new(out), StringIO.new(err)]
|
29
|
-
else
|
30
|
-
raise ArgumentError.new("Expected call of Open3.popen3 with argument #{cmd.inspect} but was #{arg.inspect}.")
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
begin
|
35
|
-
yield
|
36
|
-
rescue ArgumentError => e
|
37
|
-
assert false, e.message
|
17
|
+
def run_in_temp_dir &block
|
18
|
+
Dir.chdir TEMP_DIR do
|
19
|
+
block.call
|
38
20
|
end
|
39
|
-
assert executed[:exec], "Open3.popen3 not executed!\n" << caller[0,2].inspect
|
40
21
|
end
|
41
22
|
|
42
23
|
end
|
data/test/temp/a.jpg
ADDED
Binary file
|
data/test/temp/b.jpg
ADDED
Binary file
|
data/test/temp/c.jpg
ADDED
Binary file
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require_relative 'helper'
|
3
|
+
|
4
|
+
class TestExiftoolStuff < Test::Unit::TestCase
|
5
|
+
|
6
|
+
test 'setting exiftool_command resets exiftool_version' do
|
7
|
+
MultiExiftool.exiftool_version # ensure @exiftool_version is set
|
8
|
+
assert_not_nil MultiExiftool.instance_variable_get('@exiftool_version')
|
9
|
+
MultiExiftool.exiftool_command = MultiExiftool.exiftool_command
|
10
|
+
assert_nil MultiExiftool.instance_variable_get('@exiftool_version')
|
11
|
+
end
|
12
|
+
|
13
|
+
test 'attribute exiftool_version is cached' do
|
14
|
+
MultiExiftool.instance_variable_set '@exiftool_version', nil
|
15
|
+
t_org = time do
|
16
|
+
v = MultiExiftool.exiftool_version
|
17
|
+
assert_not_nil v
|
18
|
+
end
|
19
|
+
t_now = time do
|
20
|
+
v = MultiExiftool.exiftool_version
|
21
|
+
assert_not_nil v
|
22
|
+
end
|
23
|
+
assert t_now * 100 < t_org
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def time
|
29
|
+
a = Time.now
|
30
|
+
yield
|
31
|
+
b = Time.now
|
32
|
+
b - a
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/test/test_functional_api.rb
CHANGED
@@ -3,47 +3,62 @@ require_relative 'helper'
|
|
3
3
|
|
4
4
|
class TestFunctionalApi < Test::Unit::TestCase
|
5
5
|
|
6
|
+
setup do
|
7
|
+
prepare_temp_dir
|
8
|
+
end
|
9
|
+
|
6
10
|
context 'reading' do
|
7
11
|
|
12
|
+
setup do
|
13
|
+
@abc_authors = ['Jan Friedrich'] * 3
|
14
|
+
@abc_fnumbers = [5.6, 6.7, 8]
|
15
|
+
@abc_titles = 'Title A,Title B,Title C'.split(/,/)
|
16
|
+
end
|
17
|
+
|
8
18
|
test 'successful reading only filenames' do
|
9
|
-
|
10
|
-
values, errors = MultiExiftool.read(%w(a.jpg b.
|
11
|
-
|
12
|
-
assert_equal
|
13
|
-
assert_equal
|
19
|
+
run_in_temp_dir do
|
20
|
+
values, errors = MultiExiftool.read(%w(a.jpg b.jpg c.jpg))
|
21
|
+
assert_equal @abc_authors, values.map {|e| e['Author']}
|
22
|
+
assert_equal @abc_fnumbers, values.map {|e| e['FNumber']}
|
23
|
+
assert_equal @abc_titles, values.map {|e| e['Title']}
|
14
24
|
assert_equal [], errors
|
15
25
|
end
|
16
26
|
end
|
17
27
|
|
18
28
|
test 'successful reading with one tag' do
|
19
|
-
|
20
|
-
values, errors = MultiExiftool.read(%w(a.jpg b.
|
21
|
-
|
22
|
-
assert_equal [
|
29
|
+
run_in_temp_dir do
|
30
|
+
values, errors = MultiExiftool.read(%w(a.jpg b.jpg c.jpg), tags: %w(title))
|
31
|
+
assert_equal @abc_titles, values.map {|e| e['Title']}
|
32
|
+
assert_equal [nil] * 3, values.map {|e| e['Author']}
|
23
33
|
assert_equal [], errors
|
24
34
|
end
|
25
35
|
end
|
26
36
|
|
27
37
|
test 'successful reading of hierarichal data' do
|
28
|
-
|
29
|
-
values, errors = MultiExiftool.read(%w(a.jpg),
|
38
|
+
run_in_temp_dir do
|
39
|
+
values, errors = MultiExiftool.read(%w(a.jpg), group: 0)
|
30
40
|
res = values.first
|
31
41
|
assert_equal 'a.jpg', res.source_file
|
32
|
-
assert_equal
|
33
|
-
assert_equal 7.0, res.maker_notes.fnumber
|
42
|
+
assert_equal 5.6, res.exif.fnumber
|
34
43
|
assert_equal [], errors
|
35
44
|
end
|
36
45
|
end
|
37
46
|
|
38
|
-
test '
|
39
|
-
|
40
|
-
MultiExiftool.read(%w[a.jpg], tags: %w[orientation], numerical: true)
|
47
|
+
test 'successful reading with numerical option' do
|
48
|
+
run_in_temp_dir do
|
49
|
+
values, errors = MultiExiftool.read(%w[a.jpg b.jpg c.jpg], tags: %w[orientation], numerical: true)
|
50
|
+
assert_equal [1, 2, 3], values.map {|e| e.orientation}
|
51
|
+
assert_equal [], errors
|
41
52
|
end
|
42
53
|
end
|
43
54
|
|
44
55
|
test 'options with boolean argument' do
|
45
|
-
|
46
|
-
MultiExiftool.read(
|
56
|
+
run_in_temp_dir do
|
57
|
+
values, errors = MultiExiftool.read('a.jpg')
|
58
|
+
assert_equal 5.6, values.first.aperture
|
59
|
+
values, errors = MultiExiftool.read('a.jpg', e: true)
|
60
|
+
assert_equal nil, values.first.aperture
|
61
|
+
assert_equal [], errors
|
47
62
|
end
|
48
63
|
end
|
49
64
|
|
@@ -52,64 +67,71 @@ class TestFunctionalApi < Test::Unit::TestCase
|
|
52
67
|
context 'writing' do
|
53
68
|
|
54
69
|
setup do
|
55
|
-
@filenames = %w(a.jpg b.
|
70
|
+
@filenames = %w(a.jpg b.jpg c.jpg)
|
56
71
|
end
|
57
72
|
|
58
73
|
test 'simple case' do
|
59
|
-
|
60
|
-
values = {:
|
61
|
-
MultiExiftool.write
|
74
|
+
run_in_temp_dir do
|
75
|
+
values = {comment: 'foo'}
|
76
|
+
errors = MultiExiftool.write(@filenames, values)
|
77
|
+
assert errors.empty?
|
78
|
+
values, _errors = MultiExiftool.read(@filenames)
|
79
|
+
assert_equal %w(foo) * 3, values.map {|e| e.comment}
|
62
80
|
end
|
63
81
|
end
|
64
82
|
|
65
83
|
test 'tags with spaces in values' do
|
66
|
-
|
67
|
-
values = {
|
68
|
-
MultiExiftool.write
|
84
|
+
run_in_temp_dir do
|
85
|
+
values = {author: 'Mister X'}
|
86
|
+
errors = MultiExiftool.write(@filenames, values)
|
87
|
+
assert errors.empty?
|
88
|
+
values, _errors = MultiExiftool.read(@filenames)
|
89
|
+
assert_equal ['Mister X'] * 3, values.map {|e| e.author}
|
69
90
|
end
|
70
91
|
end
|
71
92
|
|
72
93
|
test 'tags with rational value' do
|
73
|
-
|
74
|
-
values ={
|
75
|
-
MultiExiftool.write
|
94
|
+
run_in_temp_dir do
|
95
|
+
values ={exposuretime: Rational(1, 125)}
|
96
|
+
errors = MultiExiftool.write(@filenames, values)
|
97
|
+
assert errors.empty?
|
98
|
+
values, _errors = MultiExiftool.read(@filenames)
|
99
|
+
assert_equal [Rational(1, 125)] * 3, values.map {|e| e.exposuretime}
|
76
100
|
end
|
77
101
|
end
|
78
102
|
|
79
103
|
test 'tags with array-like values' do
|
80
|
-
|
81
|
-
|
82
|
-
|
104
|
+
run_in_temp_dir do
|
105
|
+
keywords = ['one', 'two', 'and three']
|
106
|
+
values = {keywords: keywords}
|
107
|
+
errors = MultiExiftool.write('a.jpg', values)
|
108
|
+
assert errors.empty?
|
109
|
+
values, _errors = MultiExiftool.read('a.jpg')
|
110
|
+
assert_equal keywords, values.first.keywords
|
83
111
|
end
|
84
112
|
end
|
85
113
|
|
86
114
|
test 'options with boolean argument' do
|
87
|
-
|
88
|
-
values = {:
|
89
|
-
options = {:
|
90
|
-
MultiExiftool.write
|
115
|
+
run_in_temp_dir do
|
116
|
+
values = {comment: 'foo'}
|
117
|
+
options = {overwrite_original: true}
|
118
|
+
errors = MultiExiftool.write(@filenames, values, options)
|
119
|
+
assert errors.empty?
|
120
|
+
assert_equal [], Dir['*_original']
|
91
121
|
end
|
92
122
|
end
|
93
123
|
|
94
|
-
test '
|
95
|
-
|
96
|
-
values = {:author => 'janfri'}
|
97
|
-
options = {:out => 'output_file'}
|
98
|
-
MultiExiftool.write @filenames, values, options
|
99
|
-
end
|
124
|
+
test 'option with value argument' do
|
125
|
+
pend 'find a good example' if respond_to? :pend
|
100
126
|
end
|
101
127
|
|
102
128
|
test 'numerical flag' do
|
103
|
-
|
104
|
-
values = {:
|
105
|
-
MultiExiftool.write
|
106
|
-
|
107
|
-
|
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
|
129
|
+
run_in_temp_dir do
|
130
|
+
values = {orientation: 2}
|
131
|
+
errors = MultiExiftool.write(@filenames, values)
|
132
|
+
assert_equal ["Warning: Can't convert IFD0:Orientation (matches more than one PrintConv)", "Nothing to do."], errors
|
133
|
+
errors = MultiExiftool.write(@filenames, values, numerical: true)
|
134
|
+
assert errors.empty?
|
113
135
|
end
|
114
136
|
end
|
115
137
|
|
data/test/test_reader.rb
CHANGED
@@ -3,76 +3,91 @@ require_relative 'helper'
|
|
3
3
|
|
4
4
|
class TestReader < Test::Unit::TestCase
|
5
5
|
|
6
|
+
MANDATORY_ARGS = MultiExiftool::Reader.mandatory_args
|
7
|
+
|
6
8
|
setup do
|
7
9
|
@reader = MultiExiftool::Reader.new
|
8
10
|
end
|
9
11
|
|
10
|
-
context '
|
12
|
+
context 'tags' do
|
13
|
+
|
14
|
+
test 'tags are initialized as array' do
|
15
|
+
assert_equal [], @reader.tags
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'tags could be set as single value' do
|
19
|
+
@reader.tags = 'fnumber'
|
20
|
+
assert_equal ['fnumber'], @reader.tags
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'exiftool_args method' do
|
11
26
|
|
12
27
|
test 'simple case' do
|
13
|
-
@reader.filenames = %w(a.jpg b.
|
14
|
-
|
15
|
-
assert_equal
|
28
|
+
@reader.filenames = %w(a.jpg b.jpg c.jpg)
|
29
|
+
exiftool_args = MANDATORY_ARGS + %w(a.jpg b.jpg c.jpg)
|
30
|
+
assert_equal exiftool_args, @reader.exiftool_args
|
16
31
|
end
|
17
32
|
|
18
33
|
test 'no filenames' do
|
19
34
|
assert_raises MultiExiftool::Error do
|
20
|
-
@reader.
|
35
|
+
@reader.exiftool_args
|
21
36
|
end
|
22
37
|
@reader.filenames = []
|
23
38
|
assert_raises MultiExiftool::Error do
|
24
|
-
@reader.
|
39
|
+
@reader.exiftool_args
|
25
40
|
end
|
26
41
|
end
|
27
42
|
|
28
43
|
test 'one filename as string' do
|
29
44
|
@reader.filenames = 'a.jpg'
|
30
|
-
|
31
|
-
assert_equal
|
45
|
+
exiftool_args = MANDATORY_ARGS + %w(a.jpg)
|
46
|
+
assert_equal exiftool_args, @reader.exiftool_args
|
32
47
|
end
|
33
48
|
|
34
49
|
test 'filenames with spaces' do
|
35
50
|
@reader.filenames = ['one file with spaces.jpg', 'another file with spaces.tif']
|
36
|
-
|
37
|
-
assert_equal
|
51
|
+
exiftool_args = MANDATORY_ARGS + ['one file with spaces.jpg', 'another file with spaces.tif']
|
52
|
+
assert_equal exiftool_args, @reader.exiftool_args
|
38
53
|
end
|
39
54
|
|
40
55
|
test 'tags' do
|
41
|
-
@reader.filenames = %w(a.jpg b.
|
56
|
+
@reader.filenames = %w(a.jpg b.jpg c.jpg)
|
42
57
|
@reader.tags = %w(author fnumber)
|
43
|
-
|
44
|
-
assert_equal
|
58
|
+
exiftool_args = MANDATORY_ARGS + %w(-author -fnumber a.jpg b.jpg c.jpg)
|
59
|
+
assert_equal exiftool_args, @reader.exiftool_args
|
45
60
|
end
|
46
61
|
|
47
62
|
test 'options with boolean argument' do
|
48
|
-
@reader.filenames = %w(a.jpg b.
|
63
|
+
@reader.filenames = %w(a.jpg b.jpg c.jpg)
|
49
64
|
@reader.options = {:e => true}
|
50
|
-
|
51
|
-
assert_equal
|
65
|
+
exiftool_args = MANDATORY_ARGS + %w(-e a.jpg b.jpg c.jpg)
|
66
|
+
assert_equal exiftool_args, @reader.exiftool_args
|
52
67
|
end
|
53
68
|
|
54
69
|
test 'options with value argument' do
|
55
|
-
@reader.filenames = %w(a.jpg b.
|
70
|
+
@reader.filenames = %w(a.jpg b.jpg c.jpg)
|
56
71
|
@reader.options = {:lang => 'de'}
|
57
|
-
|
58
|
-
assert_equal
|
72
|
+
exiftool_args = MANDATORY_ARGS + %w(-lang de a.jpg b.jpg c.jpg)
|
73
|
+
assert_equal exiftool_args, @reader.exiftool_args
|
59
74
|
end
|
60
75
|
|
61
76
|
test 'numerical flag' do
|
62
|
-
@reader.filenames = %w(a.jpg b.
|
77
|
+
@reader.filenames = %w(a.jpg b.jpg c.jpg)
|
63
78
|
@reader.numerical = true
|
64
|
-
|
65
|
-
assert_equal
|
79
|
+
exiftool_args = MANDATORY_ARGS + %w(-n a.jpg b.jpg c.jpg)
|
80
|
+
assert_equal exiftool_args, @reader.exiftool_args
|
66
81
|
end
|
67
82
|
|
68
83
|
test 'group flag' do
|
69
84
|
@reader.filenames = %w(a.jpg)
|
70
85
|
@reader.group = 0
|
71
|
-
|
72
|
-
assert_equal
|
86
|
+
exiftool_args = MANDATORY_ARGS + %w(-g0 a.jpg)
|
87
|
+
assert_equal exiftool_args, @reader.exiftool_args
|
73
88
|
@reader.group = 1
|
74
|
-
|
75
|
-
assert_equal
|
89
|
+
exiftool_args = MANDATORY_ARGS + %w(-g1 a.jpg)
|
90
|
+
assert_equal exiftool_args, @reader.exiftool_args
|
76
91
|
end
|
77
92
|
|
78
93
|
end
|
@@ -80,44 +95,54 @@ class TestReader < Test::Unit::TestCase
|
|
80
95
|
context 'read method' do
|
81
96
|
|
82
97
|
test 'try to read a non-existing file' do
|
83
|
-
|
98
|
+
run_in_temp_dir do
|
84
99
|
@reader.filenames = %w(non_existing_file)
|
85
100
|
res = @reader.read
|
86
101
|
assert_equal [], res
|
87
|
-
assert_equal ['File
|
102
|
+
assert_equal ['File not found: non_existing_file'], @reader.errors
|
88
103
|
end
|
89
104
|
end
|
90
105
|
|
91
106
|
test 'read from an existing and a non-existing file' do
|
92
|
-
|
107
|
+
run_in_temp_dir do
|
93
108
|
@reader.filenames = %w(a.jpg xxx)
|
94
109
|
@reader.tags = %w(fnumber foo)
|
95
110
|
res = @reader.read
|
96
|
-
assert_equal [
|
111
|
+
assert_equal [5.6], res.map {|e| e['FNumber']}
|
97
112
|
assert_equal ['File not found: xxx'], @reader.errors
|
98
113
|
end
|
99
114
|
end
|
100
115
|
|
101
116
|
test 'successful reading with one tag' do
|
102
|
-
|
103
|
-
@reader.filenames = %w(a.jpg b.
|
117
|
+
run_in_temp_dir do
|
118
|
+
@reader.filenames = %w(a.jpg b.jpg c.jpg)
|
104
119
|
@reader.tags = %w(fnumber)
|
105
120
|
res = @reader.read
|
106
|
-
|
107
|
-
assert_equal
|
121
|
+
assert_equal [5.6, 6.7, 8], res.map {|e| e['FNumber']}
|
122
|
+
assert_equal Set.new(%w(SourceFile FNumber)), res.first.tags
|
123
|
+
assert_equal [], @reader.errors
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
test 'successful reading with one tag as symbol' do
|
128
|
+
run_in_temp_dir do
|
129
|
+
@reader.filenames = %w(a.jpg b.jpg c.jpg)
|
130
|
+
@reader.tags = :fnumber
|
131
|
+
res = @reader.read
|
132
|
+
assert_equal [5.6, 6.7, 8], res.map {|e| e.fnumber}
|
133
|
+
assert_equal Set.new(%w(SourceFile FNumber)), res.first.tags
|
108
134
|
assert_equal [], @reader.errors
|
109
135
|
end
|
110
136
|
end
|
111
137
|
|
112
138
|
test 'successful reading of hierarichal data' do
|
113
|
-
|
139
|
+
run_in_temp_dir do
|
114
140
|
@reader.filenames = %w(a.jpg)
|
115
141
|
@reader.tags = %w(fnumber)
|
116
142
|
@reader.group = 0
|
117
143
|
res = @reader.read.first
|
118
144
|
assert_equal 'a.jpg', res.source_file
|
119
|
-
assert_equal
|
120
|
-
assert_equal 7.0, res.maker_notes.fnumber
|
145
|
+
assert_equal 5.6, res.exif.fnumber
|
121
146
|
assert_equal [], @reader.errors
|
122
147
|
end
|
123
148
|
end
|
data/test/test_values.rb
CHANGED
@@ -79,4 +79,14 @@ class TestValues < Test::Unit::TestCase
|
|
79
79
|
|
80
80
|
end
|
81
81
|
|
82
|
+
context 'tags' do
|
83
|
+
|
84
|
+
test 'tags preserves the original tag names' do
|
85
|
+
hash = {'FNumber' => 8, 'Author' => 'janfri', 'E-MailAddress' => 'janfri26@gmail.com'}
|
86
|
+
@values = MultiExiftool::Values.new(hash)
|
87
|
+
assert_equal hash.keys, @values.tags.to_a
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
82
92
|
end
|
data/test/test_writer.rb
CHANGED
@@ -3,105 +3,106 @@ require_relative 'helper'
|
|
3
3
|
|
4
4
|
class TestWriter < Test::Unit::TestCase
|
5
5
|
|
6
|
+
MANDATORY_ARGS = MultiExiftool::Writer.mandatory_args
|
7
|
+
|
6
8
|
setup do
|
7
9
|
@writer = MultiExiftool::Writer.new
|
8
10
|
end
|
9
11
|
|
10
12
|
context 'various filename combinations' do
|
11
13
|
|
12
|
-
test '
|
13
|
-
@writer.values = {:
|
14
|
+
test 'exiftool_args method, no filenames set' do
|
15
|
+
@writer.values = {comment: 'foo'}
|
14
16
|
assert_raises MultiExiftool::Error do
|
15
|
-
@writer.
|
17
|
+
@writer.exiftool_args
|
16
18
|
end
|
17
19
|
@writer.filenames = []
|
18
20
|
assert_raises MultiExiftool::Error do
|
19
|
-
@writer.
|
21
|
+
@writer.exiftool_args
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
test 'one filename as string' do
|
24
|
-
@writer.values = {:
|
26
|
+
@writer.values = {comment: 'foo'}
|
25
27
|
@writer.filenames = 'a.jpg'
|
26
|
-
|
27
|
-
assert_equal
|
28
|
+
exiftool_args = MANDATORY_ARGS + %w(-comment=foo a.jpg)
|
29
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
28
30
|
end
|
29
31
|
|
30
32
|
test 'filenames with spaces' do
|
31
33
|
@writer.filenames = ['one file with spaces.jpg', 'another file with spaces.tif']
|
32
|
-
@writer.values = {:
|
33
|
-
|
34
|
-
|
34
|
+
@writer.values = {comment: 'foo'}
|
35
|
+
exiftool_args = MANDATORY_ARGS + ['-comment=foo', 'one file with spaces.jpg',
|
36
|
+
'another file with spaces.tif']
|
37
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
35
38
|
end
|
36
39
|
|
37
40
|
end
|
38
41
|
|
39
|
-
context '
|
42
|
+
context 'exiftool_args method, various tags' do
|
40
43
|
|
41
44
|
setup do
|
42
|
-
@writer.filenames = %w(a.jpg b.
|
45
|
+
@writer.filenames = %w(a.jpg b.jpg c.jpg)
|
43
46
|
end
|
44
47
|
|
45
48
|
test 'simple case' do
|
46
|
-
@writer.values = {:
|
47
|
-
|
48
|
-
assert_equal
|
49
|
+
@writer.values = {comment: 'foo'}
|
50
|
+
exiftool_args = MANDATORY_ARGS + %w(-comment=foo a.jpg b.jpg c.jpg)
|
51
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
49
52
|
end
|
50
53
|
|
51
54
|
test 'no values set' do
|
52
55
|
assert_raises MultiExiftool::Error do
|
53
|
-
@writer.
|
56
|
+
@writer.exiftool_args
|
54
57
|
end
|
55
58
|
@writer.values = {}
|
56
59
|
assert_raises MultiExiftool::Error do
|
57
|
-
@writer.
|
60
|
+
@writer.exiftool_args
|
58
61
|
end
|
59
62
|
end
|
60
63
|
|
61
64
|
test 'tags with spaces in values' do
|
62
|
-
@writer.values = {:
|
63
|
-
|
64
|
-
assert_equal
|
65
|
+
@writer.values = {title: 'title', :comment => 'some comment'}
|
66
|
+
exiftool_args = MANDATORY_ARGS + ['-title=title', '-comment=some comment', 'a.jpg', 'b.jpg', 'c.jpg']
|
67
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
65
68
|
end
|
66
69
|
|
67
70
|
test 'tags with rational value' do
|
68
71
|
@writer.values ={shutterspeed: Rational(1, 125)}
|
69
|
-
|
70
|
-
assert_equal
|
72
|
+
exiftool_args = MANDATORY_ARGS + %w(-shutterspeed=1/125 a.jpg b.jpg c.jpg)
|
73
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
71
74
|
end
|
72
75
|
|
73
76
|
test 'tags with array-like values' do
|
74
77
|
@writer.values = {keywords: ['one', 'two', 'and three']}
|
75
|
-
|
76
|
-
|
78
|
+
exiftool_args = MANDATORY_ARGS + ['-keywords=one', '-keywords=two', '-keywords=and three',
|
79
|
+
'a.jpg', 'b.jpg', 'c.jpg']
|
80
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
77
81
|
end
|
78
82
|
|
79
83
|
test 'options with boolean argument' do
|
80
|
-
@writer.values = {:
|
84
|
+
@writer.values = {comment: 'foo'}
|
81
85
|
@writer.options = {:overwrite_original => true}
|
82
|
-
|
83
|
-
assert_equal
|
86
|
+
exiftool_args = MANDATORY_ARGS + %w(-overwrite_original -comment=foo a.jpg b.jpg c.jpg)
|
87
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
84
88
|
end
|
85
89
|
|
86
90
|
test 'options with value argument' do
|
87
|
-
|
88
|
-
@writer.options = {:out => 'output_file'}
|
89
|
-
command = 'exiftool -out output_file -author=janfri a.jpg b.tif c.bmp'
|
90
|
-
assert_equal command, @writer.command
|
91
|
+
pend 'find a good example' if respond_to? :pend
|
91
92
|
end
|
92
93
|
|
93
94
|
test 'numerical flag' do
|
94
|
-
@writer.values = {:
|
95
|
+
@writer.values = {comment: 'foo'}
|
95
96
|
@writer.numerical = true
|
96
|
-
|
97
|
-
assert_equal
|
97
|
+
exiftool_args = MANDATORY_ARGS + %w(-n -comment=foo a.jpg b.jpg c.jpg)
|
98
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
98
99
|
end
|
99
100
|
|
100
101
|
test 'overwrite_original flag' do
|
101
|
-
@writer.values = {
|
102
|
+
@writer.values = {comment: 'foo'}
|
102
103
|
@writer.overwrite_original = true
|
103
|
-
|
104
|
-
assert_equal
|
104
|
+
exiftool_args = MANDATORY_ARGS + %w(-overwrite_original -comment=foo a.jpg b.jpg c.jpg)
|
105
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
105
106
|
end
|
106
107
|
|
107
108
|
end
|
@@ -109,22 +110,22 @@ class TestWriter < Test::Unit::TestCase
|
|
109
110
|
context 'write method' do
|
110
111
|
|
111
112
|
test 'successful write' do
|
112
|
-
|
113
|
-
@writer.filenames = %w(a.jpg b.
|
114
|
-
@writer.values = {:
|
113
|
+
run_in_temp_dir do
|
114
|
+
@writer.filenames = %w(a.jpg b.jpg c.jpg)
|
115
|
+
@writer.values = {comment: 'foo'}
|
115
116
|
rc = @writer.write
|
117
|
+
assert rc
|
116
118
|
assert_equal [], @writer.errors
|
117
|
-
assert_equal true, rc
|
118
119
|
end
|
119
120
|
end
|
120
121
|
|
121
122
|
test 'unsuccessful write' do
|
122
|
-
|
123
|
+
run_in_temp_dir do
|
123
124
|
@writer.filenames = %w(a.jpg xxx)
|
124
|
-
@writer.values = {
|
125
|
+
@writer.values = {comment: 'foo', bar: 'x'}
|
125
126
|
rc = @writer.write
|
126
|
-
|
127
|
-
assert_equal
|
127
|
+
assert !rc
|
128
|
+
assert_equal ["Warning: Tag 'bar' does not exist", "Error: File not found - xxx"], @writer.errors
|
128
129
|
end
|
129
130
|
end
|
130
131
|
|
data/test/test_writer_groups.rb
CHANGED
@@ -4,28 +4,32 @@ require 'yaml'
|
|
4
4
|
|
5
5
|
class TestWriterGroups < Test::Unit::TestCase
|
6
6
|
|
7
|
+
MANDATORY_ARGS = MultiExiftool::Writer.mandatory_args
|
8
|
+
|
7
9
|
setup do
|
8
10
|
@writer = MultiExiftool::Writer.new
|
9
|
-
@writer.filenames = %w(a.jpg b.
|
11
|
+
@writer.filenames = %w(a.jpg b.jpg c.jpg)
|
10
12
|
end
|
11
13
|
|
12
14
|
test 'simple case' do
|
13
15
|
@writer.values = {:exif => {:comment => 'test'} }
|
14
|
-
|
15
|
-
assert_equal
|
16
|
+
exiftool_args = MANDATORY_ARGS + %w(-exif:comment=test a.jpg b.jpg c.jpg)
|
17
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
16
18
|
end
|
17
19
|
|
18
20
|
test 'more than one groups and tags' do
|
19
21
|
@writer.values = YAML.load <<-END
|
20
22
|
exif:
|
21
|
-
author:
|
23
|
+
author: Mr. X
|
22
24
|
comment: some comment
|
23
25
|
xmp:
|
24
|
-
author:
|
26
|
+
author: Mr. X
|
25
27
|
subjectlocation: somewhere else
|
26
28
|
END
|
27
|
-
|
28
|
-
|
29
|
+
exiftool_args = MANDATORY_ARGS + ['-exif:author=Mr. X', '-exif:comment=some comment',
|
30
|
+
'-xmp:author=Mr. X', '-xmp:subjectlocation=somewhere else',
|
31
|
+
'a.jpg', 'b.jpg', 'c.jpg']
|
32
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
29
33
|
end
|
30
34
|
|
31
35
|
test 'tags with array-like values' do
|
@@ -36,8 +40,9 @@ class TestWriterGroups < Test::Unit::TestCase
|
|
36
40
|
- two
|
37
41
|
- and three
|
38
42
|
END
|
39
|
-
|
40
|
-
|
43
|
+
exiftool_args = MANDATORY_ARGS + ['-exif:keywords=one', '-exif:keywords=two', '-exif:keywords=and three',
|
44
|
+
'a.jpg', 'b.jpg', 'c.jpg']
|
45
|
+
assert_equal exiftool_args, @writer.exiftool_args
|
41
46
|
end
|
42
47
|
|
43
48
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multi_exiftool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Friedrich
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rim
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '2.5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '2.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: contest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,7 +38,21 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: regtest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: This library a is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool)
|
42
56
|
written by Phil Harvey. It is designed for dealing with multiple files at once by
|
43
57
|
creating commands to call exiftool with various arguments, call it and parsing the
|
44
58
|
results.
|
@@ -56,9 +70,15 @@ files:
|
|
56
70
|
- lib/multi_exiftool/reader.rb
|
57
71
|
- lib/multi_exiftool/values.rb
|
58
72
|
- lib/multi_exiftool/writer.rb
|
59
|
-
- test/
|
73
|
+
- test/data/a.jpg
|
74
|
+
- test/data/b.jpg
|
75
|
+
- test/data/c.jpg
|
60
76
|
- test/helper.rb
|
77
|
+
- test/temp/a.jpg
|
78
|
+
- test/temp/b.jpg
|
79
|
+
- test/temp/c.jpg
|
61
80
|
- test/test_executable.rb
|
81
|
+
- test/test_exiftool_stuff.rb
|
62
82
|
- test/test_functional_api.rb
|
63
83
|
- test/test_reader.rb
|
64
84
|
- test/test_values.rb
|
@@ -66,7 +86,8 @@ files:
|
|
66
86
|
- test/test_writer.rb
|
67
87
|
- test/test_writer_groups.rb
|
68
88
|
homepage: http://gitorious.org/multi_exiftool
|
69
|
-
licenses:
|
89
|
+
licenses:
|
90
|
+
- MIT
|
70
91
|
metadata: {}
|
71
92
|
post_install_message: "\n+-----------------------------------------------------------------------+\n|
|
72
93
|
Please ensure you have installed exiftool version 7.65 or higher and |\n| it's
|
@@ -90,8 +111,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
111
|
requirements:
|
91
112
|
- exiftool, version 7.65 or higher
|
92
113
|
rubyforge_project:
|
93
|
-
rubygems_version: 2.
|
114
|
+
rubygems_version: 2.4.5
|
94
115
|
signing_key:
|
95
116
|
specification_version: 4
|
96
|
-
summary: This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool).
|
117
|
+
summary: This library is a wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool).
|
97
118
|
test_files: []
|
data/test/fixtures.yml
DELETED
@@ -1,72 +0,0 @@
|
|
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
|