multi_exiftool 0.0.1 → 0.1.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.
- 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
|