multi_exiftool 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +1 -1
- data/LICENSE +21 -0
- data/Manifest +16 -23
- data/README +77 -16
- data/Rakefile +17 -38
- data/examples/01_simple_reading.rb +13 -0
- data/examples/02_simple_writing.rb +19 -0
- data/examples/03_reading_using_groups.rb +28 -0
- data/lib/multi_exiftool.rb +6 -38
- data/lib/multi_exiftool/executable.rb +67 -0
- data/lib/multi_exiftool/reader.rb +60 -0
- data/lib/multi_exiftool/values.rb +60 -0
- data/lib/multi_exiftool/writer.rb +55 -0
- data/multi_exiftool.gemspec +25 -16
- data/test/helper.rb +27 -0
- data/test/test_reader.rb +135 -0
- data/test/test_values.rb +75 -0
- data/test/test_values_using_groups.rb +61 -0
- data/test/test_writer.rb +102 -0
- metadata +49 -47
- data/COPYING +0 -165
- data/data/fixtures/read_non_existing_file.stderr +0 -1
- data/data/fixtures/read_non_existing_file.stdout +0 -0
- data/data/fixtures/read_one_file.stderr +0 -0
- data/data/fixtures/read_one_file.stdout +0 -92
- data/data/fixtures/read_two_files.stderr +0 -0
- data/data/fixtures/read_two_files.stdout +0 -212
- data/data/regression/read_command.rb +0 -12
- data/data/regression/read_command.rb.out +0 -16
- data/data/regression/write_command.rb +0 -16
- data/data/regression/write_command.rb.out +0 -40
- data/lib/multi_exiftool/command_generator.rb +0 -68
- data/lib/multi_exiftool/parser.rb +0 -43
- data/lib/multi_exiftool/read_object.rb +0 -57
- data/script/colorize.rb +0 -6
- data/script/generate_fixture.rb +0 -27
- data/test/test_command_generator.rb +0 -89
- data/test/test_helper.rb +0 -44
- data/test/test_parser.rb +0 -51
- data/test/test_read_object.rb +0 -36
data/CHANGELOG
CHANGED
@@ -1 +1 @@
|
|
1
|
-
v0.0.
|
1
|
+
v0.1.0 First public release.
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2009-2010 Jan Friedrich
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/Manifest
CHANGED
@@ -1,25 +1,18 @@
|
|
1
|
-
|
1
|
+
CHANGELOG
|
2
|
+
LICENSE
|
2
3
|
Manifest
|
3
|
-
test/test_command_generator.rb
|
4
|
-
test/test_helper.rb
|
5
|
-
test/test_parser.rb
|
6
|
-
test/test_read_object.rb
|
7
|
-
lib/multi_exiftool.rb
|
8
|
-
lib/multi_exiftool/parser.rb
|
9
|
-
lib/multi_exiftool/command_generator.rb
|
10
|
-
lib/multi_exiftool/read_object.rb
|
11
4
|
README
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
5
|
+
Rakefile
|
6
|
+
examples/01_simple_reading.rb
|
7
|
+
examples/02_simple_writing.rb
|
8
|
+
examples/03_reading_using_groups.rb
|
9
|
+
lib/multi_exiftool.rb
|
10
|
+
lib/multi_exiftool/executable.rb
|
11
|
+
lib/multi_exiftool/reader.rb
|
12
|
+
lib/multi_exiftool/values.rb
|
13
|
+
lib/multi_exiftool/writer.rb
|
14
|
+
test/helper.rb
|
15
|
+
test/test_reader.rb
|
16
|
+
test/test_values.rb
|
17
|
+
test/test_values_using_groups.rb
|
18
|
+
test/test_writer.rb
|
data/README
CHANGED
@@ -1,29 +1,90 @@
|
|
1
|
-
=
|
2
|
-
Jan Friedrich
|
3
|
-
http://multi_exiftool.rubyforge.org
|
1
|
+
= MultiExiftool
|
4
2
|
|
5
|
-
==
|
3
|
+
== Description
|
6
4
|
|
7
|
-
|
5
|
+
This library is wrapper for the Exiftool command-line application
|
6
|
+
(http://www.sno.phy.queensu.ca/~phil/exiftool) written by Phil Harvey.
|
7
|
+
It is designed for dealing with multiple files at once by creating
|
8
|
+
commands to call exiftool with various arguments, call it and parsing
|
9
|
+
the results.
|
8
10
|
|
9
|
-
==
|
11
|
+
== Examples
|
10
12
|
|
11
|
-
|
13
|
+
=== Reading
|
12
14
|
|
13
|
-
|
15
|
+
require 'multi_exiftool'
|
14
16
|
|
15
|
-
|
17
|
+
reader = MultiExiftool::Reader.new
|
18
|
+
reader.filenames = Dir['*.jpg']
|
19
|
+
results = reader.read
|
20
|
+
results.each do |values|
|
21
|
+
puts "#{values.file_name}: #{values.comment}"
|
22
|
+
end
|
16
23
|
|
17
|
-
|
24
|
+
=== Writing
|
18
25
|
|
19
|
-
|
26
|
+
require 'multi_exiftool'
|
27
|
+
|
28
|
+
writer = MultiExiftool::Writer.new
|
29
|
+
writer.filenames = Dir['*.jpg']
|
30
|
+
writer.values = {creator: 'Jan Friedrich', copyright: 'Public Domain'}
|
31
|
+
if writer.write
|
32
|
+
puts 'ok'
|
33
|
+
else
|
34
|
+
puts writer.errors.join
|
35
|
+
end
|
20
36
|
|
21
|
-
|
37
|
+
=== Further Examples
|
22
38
|
|
23
|
-
|
39
|
+
See the examples in the examples directory.
|
24
40
|
|
25
|
-
== LICENSE:
|
26
41
|
|
27
|
-
|
42
|
+
== Requirements
|
43
|
+
|
44
|
+
- Ruby 1.9.1 or higher
|
45
|
+
- An installation of the Exiftool command-line application.
|
46
|
+
Instructions for installation you can find under
|
47
|
+
http://www.sno.phy.queensu.ca/~phil/exiftool/install.html .
|
48
|
+
|
49
|
+
== Installation
|
50
|
+
|
51
|
+
First you need Exiftool (see under Requirements above). Then you can simply
|
52
|
+
install the gem with
|
53
|
+
gem install multi_exiftool
|
54
|
+
|
55
|
+
== Contribution
|
56
|
+
|
57
|
+
The code is also hostet in a git repository on Gitorious at
|
58
|
+
http://gitorious.org/multi_exiftool
|
59
|
+
or
|
60
|
+
http://github.com/janfri/multi_exiftool-redesign
|
61
|
+
feel free to contribute!
|
62
|
+
|
63
|
+
== Author
|
64
|
+
|
65
|
+
Jan Friedrich (janfri26 AT gmail DOT com)
|
66
|
+
|
67
|
+
== Copyright / License
|
68
|
+
|
69
|
+
The MIT License
|
70
|
+
|
71
|
+
Copyright (c) 2009-2010 Jan Friedrich
|
72
|
+
|
73
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
74
|
+
of this software and associated documentation files (the "Software"), to deal
|
75
|
+
in the Software without restriction, including without limitation the rights
|
76
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
77
|
+
copies of the Software, and to permit persons to whom the Software is
|
78
|
+
furnished to do so, subject to the following conditions:
|
79
|
+
|
80
|
+
The above copyright notice and this permission notice shall be included in
|
81
|
+
all copies or substantial portions of the Software.
|
82
|
+
|
83
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
84
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
85
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
86
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
87
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
88
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
89
|
+
THE SOFTWARE.
|
28
90
|
|
29
|
-
See file COPYING.txt for more details.
|
data/Rakefile
CHANGED
@@ -1,43 +1,22 @@
|
|
1
1
|
require 'echoe'
|
2
2
|
|
3
|
-
Echoe.new
|
3
|
+
Echoe.new('multi_exiftool') do |p|
|
4
4
|
p.author = 'Jan Friedrich'
|
5
|
-
p.email = '
|
6
|
-
p.
|
7
|
-
p.
|
8
|
-
p.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
def target src
|
22
|
-
src + '.out'
|
5
|
+
p.email = 'janfri26@gmail.com'
|
6
|
+
p.summary = 'This library is wrapper for the Exiftool command-line application (http://www.sno.phy.queensu.ca/~phil/exiftool).'
|
7
|
+
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
|
+
p.ruby_version = '>=1.9.1'
|
9
|
+
p.url = 'http://rubyforge.org/projects/multiexiftool'
|
10
|
+
p.install_message = %q{
|
11
|
+
+-----------------------------------------------------------------------+
|
12
|
+
| Please ensure you have installed exiftool version 7.65 or higher and |
|
13
|
+
| it's found in your PATH (Try "exiftool -ver" on your commandline). |
|
14
|
+
| For more details see |
|
15
|
+
| http://www.sno.phy.queensu.ca/~phil/exiftool/install.html |
|
16
|
+
+-----------------------------------------------------------------------+
|
17
|
+
}
|
18
|
+
p.development_dependencies = ['contest']
|
19
|
+
p.eval = proc do
|
20
|
+
self.requirements << 'exiftool, version 7.65 or higher'
|
23
21
|
end
|
24
|
-
|
25
|
-
FileList[RB_FILES].each do |src|
|
26
|
-
target = target(src)
|
27
|
-
file target => src do |t|
|
28
|
-
sh "ruby #{t.prerequisites.first} > #{t.name}"
|
29
|
-
end
|
30
|
-
|
31
|
-
task :generate => target
|
32
|
-
end
|
33
|
-
|
34
|
-
desc 'Running regression tests'
|
35
|
-
task :test => :generate do
|
36
|
-
FileList[RB_FILES].each do |src|
|
37
|
-
target = target(src)
|
38
|
-
puts '-' * 8 << File.basename(src)
|
39
|
-
sh "ruby #{src} | wdiff -n #{target} - | #{File.join(SCRIPT_DIR, 'colorize.rb')}"# ; echo x >/dev/null"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
22
|
end
|
@@ -0,0 +1,13 @@
|
|
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
|
@@ -0,0 +1,19 @@
|
|
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
|
@@ -0,0 +1,28 @@
|
|
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
|
+
|
data/lib/multi_exiftool.rb
CHANGED
@@ -1,43 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require 'ostruct'
|
6
|
-
require 'logger'
|
7
|
-
|
8
|
-
# monkey patching --- the save way :D
|
9
|
-
class OpenStruct
|
10
|
-
unless self.new.respond_to? :to_hash
|
11
|
-
def to_hash
|
12
|
-
@table
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
1
|
+
# coding: utf-8
|
2
|
+
require_relative 'multi_exiftool/values'
|
3
|
+
require_relative 'multi_exiftool/reader'
|
4
|
+
require_relative 'multi_exiftool/writer'
|
16
5
|
|
17
6
|
module MultiExiftool
|
18
7
|
|
19
|
-
class
|
20
|
-
|
21
|
-
attr_accessor :logger
|
22
|
-
|
23
|
-
def read *filenames
|
24
|
-
cmd = CommandGenerator.read_command *filenames
|
25
|
-
stdin, stdout, stderr = Open3.popen3(cmd)
|
26
|
-
result = Parser.parse(stdout, stderr)
|
27
|
-
result.map {|r| ReadObject.new(r.data)}
|
28
|
-
end
|
29
|
-
|
30
|
-
|
31
|
-
def write change_set, *filenames
|
32
|
-
cmd = CommandGenerator.write_command change_set, *filenames
|
33
|
-
@logger.debug cmd
|
34
|
-
stdin, stdout, stderr = Open3.popen3(cmd)
|
35
|
-
result = Parser.parse(stdout, stderr)
|
36
|
-
result.inject(true) {|r| r.errors.empty?}
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
@logger = Logger.new nil
|
8
|
+
class Error < ::StandardError; end
|
42
9
|
|
43
10
|
end
|
11
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'open3'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
module MultiExiftool
|
6
|
+
|
7
|
+
# Mixin for Reader and Writer.
|
8
|
+
module Executable
|
9
|
+
|
10
|
+
attr_accessor :exiftool_command, :errors, :numerical
|
11
|
+
attr_writer :options, :filenames
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@exiftool_command = 'exiftool'
|
15
|
+
@options = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
def options
|
19
|
+
opts = @options.dup
|
20
|
+
opts[:n] = true if @numerical
|
21
|
+
opts
|
22
|
+
end
|
23
|
+
|
24
|
+
def filenames
|
25
|
+
Array(@filenames)
|
26
|
+
end
|
27
|
+
|
28
|
+
def execute # :nodoc:
|
29
|
+
prepare_execution
|
30
|
+
execute_command
|
31
|
+
parse_results
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def escape str
|
37
|
+
Shellwords.escape(str)
|
38
|
+
end
|
39
|
+
|
40
|
+
def escaped_filenames
|
41
|
+
raise MultiExiftool::Error.new('No filenames.') if filenames.empty?
|
42
|
+
@filenames.map { |fn| Shellwords.escape(fn) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def options_args
|
46
|
+
opts = options
|
47
|
+
return [] if opts.empty?
|
48
|
+
opts.map do |opt, val|
|
49
|
+
if val == true
|
50
|
+
"-#{opt}"
|
51
|
+
else
|
52
|
+
"-#{opt} #{val}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def prepare_execution
|
58
|
+
@errors = []
|
59
|
+
end
|
60
|
+
|
61
|
+
def execute_command
|
62
|
+
stdin, @stdout, @stderr = Open3.popen3(command)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require_relative 'executable'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module MultiExiftool
|
6
|
+
|
7
|
+
# Handle reading of metadata via exiftool.
|
8
|
+
# Composing the command for the command-line executing it and parsing
|
9
|
+
# the results as well as possible errors.
|
10
|
+
class Reader
|
11
|
+
|
12
|
+
MANDATORY_ARGS = %w(-J)
|
13
|
+
|
14
|
+
attr_accessor :tags, :group
|
15
|
+
|
16
|
+
include Executable
|
17
|
+
|
18
|
+
# Options to use with the exiftool command.
|
19
|
+
def options
|
20
|
+
opts = super
|
21
|
+
if @group
|
22
|
+
opts["g#{@group}"] = true
|
23
|
+
end
|
24
|
+
opts
|
25
|
+
end
|
26
|
+
|
27
|
+
# Getting the command for the command-line which would be executed
|
28
|
+
# when calling #read. It could be useful for logging, debugging or
|
29
|
+
# maybe even for creating a batch-file with exiftool command to be
|
30
|
+
# processed.
|
31
|
+
def command
|
32
|
+
cmd = [exiftool_command]
|
33
|
+
cmd << MANDATORY_ARGS
|
34
|
+
cmd << options_args
|
35
|
+
cmd << tags_args
|
36
|
+
cmd << escaped_filenames
|
37
|
+
cmd.flatten.join(' ')
|
38
|
+
end
|
39
|
+
|
40
|
+
alias read execute # :nodoc:
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def tags_args
|
45
|
+
return [] unless @tags
|
46
|
+
@tags.map {|tag| "-#{tag}"}
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_results
|
50
|
+
stdout = @stdout.read
|
51
|
+
@errors = @stderr.readlines
|
52
|
+
json = JSON.parse(stdout)
|
53
|
+
json.map {|values| Values.new(values)}
|
54
|
+
rescue JSON::ParserError
|
55
|
+
return []
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|