multi_exiftool 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|