Skip to content
Permalink
Browse files

directly sending parameters to stdin of exiftool, another take to fix #1

  • Loading branch information...
ccoenen committed Mar 24, 2015
1 parent d8910ce commit 416942cc6275f978d9574a0d6a62a2281def3810
@@ -1,6 +1,5 @@
# coding: utf-8
require 'open3'
require 'shellwords'

module MultiExiftool

@@ -36,15 +35,6 @@ def execute # :nodoc:

private

def escape str
Shellwords.escape(str.to_s)
end

def escaped_filenames
raise MultiExiftool::Error.new('No filenames.') if filenames.empty?
filenames.map { |fn| Shellwords.escape(fn) }
end

def options_args
opts = options
return [] if opts.empty?
@@ -63,7 +53,12 @@ def prepare_execution
end

def execute_command
stdin, @stdout, @stderr = Open3.popen3(command)
stdin, @stdout, @stderr = Open3.popen3(exiftool_command, '-@', '-')
command.each do |part|
stdin << part
stdin << "\n"
end
stdin.close
end

end
@@ -9,7 +9,7 @@ module MultiExiftool
# the results as well as possible errors.
class Reader

MANDATORY_ARGS = %w(-J)
MANDATORY_ARGS = %w(-J -charset FileName=utf8 -charset utf8)

attr_accessor :tags, :group

@@ -34,12 +34,13 @@ def options
# maybe even for creating a batch-file with exiftool command to be
# processed.
def command
cmd = [exiftool_command]
fail MultiExiftool::Error, 'No filenames.' if filenames.empty?
cmd = []
cmd << MANDATORY_ARGS
cmd << options_args
cmd << tags_args
cmd << escaped_filenames
cmd.flatten.join(' ')
cmd << filenames
cmd.flatten
end

alias read execute # :nodoc:
@@ -8,6 +8,9 @@ module MultiExiftool
# possible errors.
class Writer

MANDATORY_ARGS = %w(-charset FileName=utf8 -charset utf8)


attr_accessor :overwrite_original, :values

include Executable
@@ -29,11 +32,12 @@ def options
# maybe even for creating a batch-file with exiftool command to be
# processed.
def command
cmd = [exiftool_command]
fail MultiExiftool::Error, 'No filenames.' if filenames.empty?
cmd = []
cmd << options_args
cmd << values_args
cmd << escaped_filenames
cmd.flatten.join(' ')
cmd << filenames
cmd.flatten
end

alias write execute # :nodoc:
@@ -51,9 +55,9 @@ def values_to_param_array hash
if val.respond_to? :to_hash
res << values_to_param_array(val.to_hash).map {|arg| "#{tag}:#{arg}"}
elsif val.respond_to? :to_ary
res << val.map {|v| "#{tag}=#{escape(v)}"}
res << val.map {|v| "#{tag}=#{v}"}
else
res << "#{tag}=#{escape(val)}"
res << "#{tag}=#{val}"
end
end
res.flatten
@@ -22,12 +22,12 @@ def mocking_open3(command, outstr, errstr, &block)
executed = {exec: false}
open3_eigenclass = class << Open3; self; end
open3_eigenclass.module_exec(command, outstr, errstr, executed) do |cmd, out, err, exec|
define_method :popen3 do |arg|
define_method :popen3 do |*arg|
exec[:exec] = true
if arg == cmd
if arg.join(' ') == cmd
return [nil, StringIO.new(out), StringIO.new(err)]
else
raise ArgumentError.new("Expected call of Open3.popen3 with argument #{cmd.inspect} but was #{arg.inspect}.")
raise ArgumentError.new("Expected call of Open3.popen3 with argument #{cmd.inspect} but was #{arg.join(' ').inspect}.")
end
end
end
@@ -63,7 +63,7 @@ class TestFunctionalApi < Test::Unit::TestCase
end

test 'tags with spaces in values' do
mocking_open3 'exiftool -author=janfri -comment=some\ comment a.jpg b.tif c.bmp', '', '' do
mocking_open3 'exiftool -author=janfri -comment=some comment a.jpg b.tif c.bmp', '', '' do
values = {:author => 'janfri', :comment => 'some comment'}
MultiExiftool.write @filenames, values
end
@@ -77,7 +77,7 @@ class TestFunctionalApi < Test::Unit::TestCase
end

test 'tags with array-like values' do
mocking_open3 'exiftool -keywords=one -keywords=two -keywords=and\ three a.jpg b.tif c.bmp', '', '' do
mocking_open3 'exiftool -keywords=one -keywords=two -keywords=and three a.jpg b.tif c.bmp', '', '' do
values = {keywords: ['one', 'two', 'and three']}
MultiExiftool.write @filenames, values
end
@@ -11,7 +11,7 @@ class TestReader < Test::Unit::TestCase

test 'simple case' do
@reader.filenames = %w(a.jpg b.tif c.bmp)
command = 'exiftool -J a.jpg b.tif c.bmp'
command = ['exiftool', '-J', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @reader.command
end

@@ -27,51 +27,51 @@ class TestReader < Test::Unit::TestCase

test 'one filename as string' do
@reader.filenames = 'a.jpg'
command = 'exiftool -J a.jpg'
command = ['exiftool', '-J', 'a.jpg']
assert_equal command, @reader.command
end

test 'filenames with spaces' do
@reader.filenames = ['one file with spaces.jpg', 'another file with spaces.tif']
command = 'exiftool -J one\ file\ with\ spaces.jpg another\ file\ with\ spaces.tif'
command = ['exiftool', '-J', 'one file with spaces.jpg', 'another file with spaces.tif']
assert_equal command, @reader.command
end

test 'tags' do
@reader.filenames = %w(a.jpg b.tif c.bmp)
@reader.tags = %w(author fnumber)
command = 'exiftool -J -author -fnumber a.jpg b.tif c.bmp'
command = ['exiftool', '-J', '-author', '-fnumber', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @reader.command
end

test 'options with boolean argument' do
@reader.filenames = %w(a.jpg b.tif c.bmp)
@reader.options = {:e => true}
command = 'exiftool -J -e a.jpg b.tif c.bmp'
command = ['exiftool', '-J', '-e', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @reader.command
end

test 'options with value argument' do
@reader.filenames = %w(a.jpg b.tif c.bmp)
@reader.options = {:lang => 'de'}
command = 'exiftool -J -lang de a.jpg b.tif c.bmp'
command = ['exiftool', '-J', '-lang de', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @reader.command
end

test 'numerical flag' do
@reader.filenames = %w(a.jpg b.tif c.bmp)
@reader.numerical = true
command = 'exiftool -J -n a.jpg b.tif c.bmp'
command = ['exiftool', '-J', '-n', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @reader.command
end

test 'group flag' do
@reader.filenames = %w(a.jpg)
@reader.group = 0
command = 'exiftool -J -g 0 a.jpg'
command = ['exiftool', '-J', '-g 0', 'a.jpg']
assert_equal command, @reader.command
@reader.group = 1
command = 'exiftool -J -g 1 a.jpg'
command = ['exiftool', '-J', '-g 1', 'a.jpg']
assert_equal command, @reader.command
end

@@ -23,14 +23,14 @@ class TestWriter < Test::Unit::TestCase
test 'one filename as string' do
@writer.values = {:author => 'janfri'}
@writer.filenames = 'a.jpg'
command = 'exiftool -author=janfri a.jpg'
command = ['exiftool', '-author=janfri', 'a.jpg']
assert_equal command, @writer.command
end

test 'filenames with spaces' do
@writer.filenames = ['one file with spaces.jpg', 'another file with spaces.tif']
@writer.values = {:author => 'janfri'}
command = 'exiftool -author=janfri one\ file\ with\ spaces.jpg another\ file\ with\ spaces.tif'
command = ['exiftool', '-author=janfri', 'one file with spaces.jpg', 'another file with spaces.tif']
assert_equal command, @writer.command
end

@@ -44,7 +44,7 @@ class TestWriter < Test::Unit::TestCase

test 'simple case' do
@writer.values = {:author => 'janfri'}
command = 'exiftool -author=janfri a.jpg b.tif c.bmp'
command = ['exiftool', '-author=janfri', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @writer.command
end

@@ -60,47 +60,47 @@ class TestWriter < Test::Unit::TestCase

test 'tags with spaces in values' do
@writer.values = {:author => 'janfri', :comment => 'some comment'}
command = 'exiftool -author=janfri -comment=some\ comment a.jpg b.tif c.bmp'
command = ['exiftool', '-author=janfri', '-comment=some comment', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @writer.command
end

test 'tags with rational value' do
@writer.values ={shutterspeed: Rational(1, 125)}
command = 'exiftool -shutterspeed=1/125 a.jpg b.tif c.bmp'
command = ['exiftool', '-shutterspeed=1/125', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @writer.command
end

test 'tags with array-like values' do
@writer.values = {keywords: ['one', 'two', 'and three']}
command = 'exiftool -keywords=one -keywords=two -keywords=and\ three a.jpg b.tif c.bmp'
command = ['exiftool', '-keywords=one', '-keywords=two', '-keywords=and three', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @writer.command
end

test 'options with boolean argument' do
@writer.values = {:author => 'janfri'}
@writer.options = {:overwrite_original => true}
command = 'exiftool -overwrite_original -author=janfri a.jpg b.tif c.bmp'
command = ['exiftool', '-overwrite_original', '-author=janfri', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @writer.command
end

test 'options with value argument' do
@writer.values = {:author => 'janfri'}
@writer.options = {:out => 'output_file'}
command = 'exiftool -out output_file -author=janfri a.jpg b.tif c.bmp'
command = ['exiftool', '-out output_file', '-author=janfri', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @writer.command
end

test 'numerical flag' do
@writer.values = {:author => 'janfri'}
@writer.numerical = true
command = 'exiftool -n -author=janfri a.jpg b.tif c.bmp'
command = ['exiftool', '-n', '-author=janfri', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @writer.command
end

test 'overwrite_original flag' do
@writer.values = {author: 'janfri'}
@writer.overwrite_original = true
command = 'exiftool -overwrite_original -author=janfri a.jpg b.tif c.bmp'
command = ['exiftool', '-overwrite_original', '-author=janfri', 'a.jpg', 'b.tif', 'c.bmp']
assert_equal command, @writer.command
end

@@ -11,7 +11,7 @@ class TestWriterGroups < Test::Unit::TestCase

test 'simple case' do
@writer.values = {:exif => {:comment => 'test'} }
command = 'exiftool -exif:comment=test a.jpg b.bmp c.tif'
command = ['exiftool', '-exif:comment=test', 'a.jpg', 'b.bmp', 'c.tif']
assert_equal command, @writer.command
end

@@ -24,7 +24,7 @@ class TestWriterGroups < Test::Unit::TestCase
author: janfri
subjectlocation: somewhere else
END
command = 'exiftool -exif:author=janfri -exif:comment=some\ comment -xmp:author=janfri -xmp:subjectlocation=somewhere\ else a.jpg b.bmp c.tif'
command = ['exiftool', '-exif:author=janfri', '-exif:comment=some comment', '-xmp:author=janfri', '-xmp:subjectlocation=somewhere else', 'a.jpg', 'b.bmp', 'c.tif']
assert_equal command, @writer.command
end

@@ -36,7 +36,7 @@ class TestWriterGroups < Test::Unit::TestCase
- two
- and three
END
command = 'exiftool -exif:keywords=one -exif:keywords=two -exif:keywords=and\ three a.jpg b.bmp c.tif'
command = ['exiftool', '-exif:keywords=one', '-exif:keywords=two', '-exif:keywords=and three', 'a.jpg', 'b.bmp', 'c.tif']
assert_equal command, @writer.command
end

0 comments on commit 416942c

Please sign in to comment.
You can’t perform that action at this time.