exiftool 1.2.0 → 1.2.4
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 +5 -5
- data/lib/exiftool/field_parser.rb +30 -26
- data/lib/exiftool/result.rb +3 -0
- data/lib/exiftool/version.rb +3 -1
- data/lib/exiftool.rb +36 -25
- metadata +98 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4ccd85d615e4b6908e771f60622dcdd5579424e6a700e76452db8e08eaabcbe3
|
4
|
+
data.tar.gz: 125032636ccd3943654e50b876c483be2f216fea541353d71b3f9516599fbb8a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7aee068c14fcbe11f952b76a96be0f5a44158e13738cb1c18c431b4111df554a58acc1cc17adaad15a0a717e6ffe93434375e2e355c5250e8ab58df078577093
|
7
|
+
data.tar.gz: e0b01c18f10a950a2a32bc8091d727087cc5ec90ad1ce5921891b2c75d413e6da7ffa4f624865a7a748b8506ac50907b0d71c2373625ca67a2d9184f93ad515d
|
@@ -1,13 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'time'
|
2
|
-
require 'rational'
|
3
4
|
|
4
5
|
class Exiftool
|
6
|
+
# Exiftool FiledParser Class
|
5
7
|
class FieldParser
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
ZERO_DATE_RE = /\A[+:0 ]+\z/
|
8
|
+
WORD_BOUNDARY_RES = [/([A-Z\d]+)([A-Z][a-z])/, /([a-z\d])([A-Z])/].freeze
|
9
|
+
FRACTION_RE = %r{^(\d+)/(\d+)$}.freeze
|
10
|
+
YMD_RE = /\A(\d{4}):(\d{2}):(\d{2})\b/.freeze
|
11
|
+
ZERO_DATE_RE = /\A[+:0 ]+\z/.freeze
|
11
12
|
|
12
13
|
attr_reader :key, :display_key, :sym_key, :raw_value
|
13
14
|
|
@@ -20,26 +21,28 @@ class Exiftool
|
|
20
21
|
|
21
22
|
def value
|
22
23
|
@value ||= if lat_long?
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
as_lat_long
|
25
|
+
elsif date?
|
26
|
+
as_date
|
27
|
+
elsif fraction?
|
28
|
+
as_fraction
|
29
|
+
else
|
30
|
+
raw_value
|
31
|
+
end
|
31
32
|
rescue StandardError => e
|
33
|
+
# :nocov:
|
32
34
|
"Warning: Parsing '#{raw_value}' for attribute '#{key}' raised #{e.message}"
|
35
|
+
# :nocov:
|
33
36
|
end
|
34
37
|
|
35
38
|
def civil_date
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
return unless date? && !zero_date?
|
40
|
+
|
41
|
+
ymd = raw_value.scan(YMD_RE).first
|
42
|
+
return unless ymd
|
43
|
+
|
44
|
+
ymd_a = ymd.map(&:to_i)
|
45
|
+
Date.civil(*ymd_a) if Date.valid_civil?(*ymd_a)
|
43
46
|
end
|
44
47
|
|
45
48
|
private
|
@@ -50,10 +53,11 @@ class Exiftool
|
|
50
53
|
|
51
54
|
def as_lat_long
|
52
55
|
return raw_value if raw_value.is_a?(Numeric)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
56
|
+
|
57
|
+
value, direction = raw_value.split
|
58
|
+
return unless value =~ /\A\d+\.?\d*\z/
|
59
|
+
|
60
|
+
value.to_f * (%w[S W].include?(direction) ? -1 : 1)
|
57
61
|
end
|
58
62
|
|
59
63
|
def date?
|
@@ -82,7 +86,7 @@ class Exiftool
|
|
82
86
|
|
83
87
|
def as_fraction
|
84
88
|
scan = raw_value.scan(FRACTION_RE).first
|
85
|
-
Rational(*scan.map
|
89
|
+
Rational(*scan.map(&:to_i)) unless scan.nil?
|
86
90
|
end
|
87
91
|
end
|
88
92
|
end
|
data/lib/exiftool/result.rb
CHANGED
data/lib/exiftool/version.rb
CHANGED
data/lib/exiftool.rb
CHANGED
@@ -1,16 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'json'
|
2
4
|
require 'shellwords'
|
3
5
|
require 'exiftool/result'
|
4
6
|
require 'forwardable'
|
7
|
+
require 'pathname'
|
5
8
|
|
9
|
+
# Exiftool Class
|
6
10
|
class Exiftool
|
7
|
-
class NoSuchFile < StandardError
|
8
|
-
|
9
|
-
class
|
10
|
-
|
11
|
+
class NoSuchFile < StandardError; end
|
12
|
+
|
13
|
+
class NotAFile < StandardError; end
|
14
|
+
|
15
|
+
class ExiftoolNotInstalled < StandardError; end
|
11
16
|
|
12
|
-
|
13
|
-
|
17
|
+
class NoDefaultResultWithMultiget < StandardError; end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
attr_writer :command
|
14
21
|
end
|
15
22
|
|
16
23
|
def self.command
|
@@ -18,7 +25,7 @@ class Exiftool
|
|
18
25
|
end
|
19
26
|
|
20
27
|
def self.exiftool_installed?
|
21
|
-
exiftool_version
|
28
|
+
exiftool_version.to_f.positive?
|
22
29
|
end
|
23
30
|
|
24
31
|
# This is a string, not a float, to handle versions like "9.40" properly.
|
@@ -28,7 +35,9 @@ class Exiftool
|
|
28
35
|
|
29
36
|
def self.expand_path(filename)
|
30
37
|
raise(NoSuchFile, filename) unless File.exist?(filename)
|
38
|
+
|
31
39
|
raise(NotAFile, filename) unless File.file?(filename)
|
40
|
+
|
32
41
|
File.expand_path(filename)
|
33
42
|
end
|
34
43
|
|
@@ -38,28 +47,29 @@ class Exiftool
|
|
38
47
|
|
39
48
|
def initialize(filenames, exiftool_opts = '')
|
40
49
|
@file2result = {}
|
41
|
-
filenames = [filenames] if
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
filenames = [filenames] if filenames.is_a?(String) || filenames.is_a?(Pathname)
|
51
|
+
return if filenames.empty?
|
52
|
+
|
53
|
+
escaped_filenames = filenames.map do |f|
|
54
|
+
Shellwords.escape(self.class.expand_path(f.to_s))
|
55
|
+
end.join(' ')
|
56
|
+
# I'd like to use -dateformat, but it doesn't support timezone offsets properly,
|
57
|
+
# nor sub-second timestamps.
|
58
|
+
cmd = "#{self.class.command} #{exiftool_opts} -j -coordFormat \"%.8f\" #{escaped_filenames} 2> /dev/null"
|
59
|
+
json = `#{cmd}`.chomp
|
60
|
+
raise ExiftoolNotInstalled if json == ''
|
61
|
+
|
62
|
+
JSON.parse(json).each do |raw|
|
63
|
+
result = Result.new(raw)
|
64
|
+
@file2result[result.source_file] = result
|
55
65
|
end
|
56
66
|
end
|
57
67
|
|
58
|
-
def results(include_results_with_errors
|
68
|
+
def results(include_results_with_errors: false)
|
59
69
|
if include_results_with_errors
|
60
70
|
@file2result.values
|
61
71
|
else
|
62
|
-
@file2result.values.
|
72
|
+
@file2result.values.reject(&:errors?)
|
63
73
|
end
|
64
74
|
end
|
65
75
|
|
@@ -68,17 +78,18 @@ class Exiftool
|
|
68
78
|
end
|
69
79
|
|
70
80
|
def files_with_results
|
71
|
-
results.map
|
81
|
+
results.map(&:source_file)
|
72
82
|
end
|
73
83
|
|
74
84
|
def errors?
|
75
|
-
@file2result.values.any?
|
85
|
+
@file2result.values.any?(&:errors?)
|
76
86
|
end
|
77
87
|
|
78
88
|
private
|
79
89
|
|
80
90
|
def first_result
|
81
91
|
raise(NoDefaultResultWithMultiget, 'use #result_for when multiple filenames are used') if @file2result.size > 1
|
92
|
+
|
82
93
|
@file2result.values.first
|
83
94
|
end
|
84
95
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exiftool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew McEachen
|
8
|
+
- Sergey Morozov
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-10-05 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: json
|
@@ -24,6 +25,62 @@ dependencies:
|
|
24
25
|
- - ">="
|
25
26
|
- !ruby/object:Gem::Version
|
26
27
|
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: bundler
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: minitest
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: minitest-great_expectations
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: minitest-reporters
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
27
84
|
- !ruby/object:Gem::Dependency
|
28
85
|
name: rake
|
29
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,7 +96,7 @@ dependencies:
|
|
39
96
|
- !ruby/object:Gem::Version
|
40
97
|
version: '0'
|
41
98
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
99
|
+
name: rubocop
|
43
100
|
requirement: !ruby/object:Gem::Requirement
|
44
101
|
requirements:
|
45
102
|
- - ">="
|
@@ -53,7 +110,7 @@ dependencies:
|
|
53
110
|
- !ruby/object:Gem::Version
|
54
111
|
version: '0'
|
55
112
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
113
|
+
name: rubocop-minitest
|
57
114
|
requirement: !ruby/object:Gem::Requirement
|
58
115
|
requirements:
|
59
116
|
- - ">="
|
@@ -67,7 +124,7 @@ dependencies:
|
|
67
124
|
- !ruby/object:Gem::Version
|
68
125
|
version: '0'
|
69
126
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
127
|
+
name: rubocop-rake
|
71
128
|
requirement: !ruby/object:Gem::Requirement
|
72
129
|
requirements:
|
73
130
|
- - ">="
|
@@ -81,7 +138,7 @@ dependencies:
|
|
81
138
|
- !ruby/object:Gem::Version
|
82
139
|
version: '0'
|
83
140
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
141
|
+
name: simplecov
|
85
142
|
requirement: !ruby/object:Gem::Requirement
|
86
143
|
requirements:
|
87
144
|
- - ">="
|
@@ -95,7 +152,35 @@ dependencies:
|
|
95
152
|
- !ruby/object:Gem::Version
|
96
153
|
version: '0'
|
97
154
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
155
|
+
name: simplecov-console
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
- !ruby/object:Gem::Dependency
|
169
|
+
name: simplecov_json_formatter
|
170
|
+
requirement: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: '0'
|
175
|
+
type: :development
|
176
|
+
prerelease: false
|
177
|
+
version_requirements: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
- !ruby/object:Gem::Dependency
|
183
|
+
name: yard
|
99
184
|
requirement: !ruby/object:Gem::Requirement
|
100
185
|
requirements:
|
101
186
|
- - ">="
|
@@ -110,7 +195,8 @@ dependencies:
|
|
110
195
|
version: '0'
|
111
196
|
description: Multiget ExifTool wrapper for ruby
|
112
197
|
email:
|
113
|
-
- matthew
|
198
|
+
- matthew+github@mceachen.org
|
199
|
+
- morozgrafix@gmail.com
|
114
200
|
executables: []
|
115
201
|
extensions: []
|
116
202
|
extra_rdoc_files: []
|
@@ -119,7 +205,7 @@ files:
|
|
119
205
|
- lib/exiftool/field_parser.rb
|
120
206
|
- lib/exiftool/result.rb
|
121
207
|
- lib/exiftool/version.rb
|
122
|
-
homepage: https://github.com/
|
208
|
+
homepage: https://github.com/exiftool-rb/exiftool.rb
|
123
209
|
licenses:
|
124
210
|
- MIT
|
125
211
|
metadata: {}
|
@@ -131,16 +217,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
217
|
requirements:
|
132
218
|
- - ">="
|
133
219
|
- !ruby/object:Gem::Version
|
134
|
-
version: '
|
220
|
+
version: '2.4'
|
135
221
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
222
|
requirements:
|
137
223
|
- - ">="
|
138
224
|
- !ruby/object:Gem::Version
|
139
225
|
version: '0'
|
140
226
|
requirements:
|
141
|
-
- ExifTool (see http://
|
142
|
-
|
143
|
-
rubygems_version: 2.5.1
|
227
|
+
- ExifTool (see http://exiftool.org)
|
228
|
+
rubygems_version: 3.1.6
|
144
229
|
signing_key:
|
145
230
|
specification_version: 4
|
146
231
|
summary: Multiget ExifTool wrapper for ruby
|