exiftool 0.4.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- N2ZmZmRiYmQ2MWUyYzhhNWQwN2YxNDgxZjRmNzU2YTM0N2FiYzJjMw==
4
+ ZTRjNzEyZWQ4YWY0OTY1OGYzYWM2M2JhNTgyMjJmMGQ0NjE4YjNkMA==
5
5
  data.tar.gz: !binary |-
6
- MWZkNDUxYmJiM2M4MTQ3ZWFiNmI4MWE1Y2UwNTA0MzNiMmZkZTcxNA==
6
+ MDk0ZGNhMjk5NWRkMDM2ZTg3NWQxMWM1MmU0YmY2OTMzMDg2YTIxZA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YjIwMTdhODJlYzgzZWIyZDQ4M2M3MTUyOTEzNGE0YjE1YjhiZTA2MjFjMjkz
10
- NWUzNTgyZWRjMDIzYWZjMjdlZTM2NGE3ZTI2MGE4NGE1NGM3NTQxMzlhNDNj
11
- M2UyMjc0Yzg1ZGI2MWUxYjdhOGZmMTY0NTVkODU2MTJlODZlNDY=
9
+ MWVhMzkzYmIyMjc3NDFhOWZmOTQ0MzJhOWNkMWFlZTJhNjI3OWNjN2YyNzFm
10
+ OWEzOGUzNjg0NWIwNzc3Zjg3NGY2MTNkMmM1YTVhYzJjNTRiN2M3YjgxYzkz
11
+ NjYzZmQ0OTEzNDE5ZjlmOGIwZmRiOTI3ZmZmMTkwOTg4NTUyYjk=
12
12
  data.tar.gz: !binary |-
13
- ZjRhMjExY2QzZGFkOThlM2NmMDUzNWE4MjlmNjYyYTNlYzBlYmNiNmFjNjgx
14
- YjFjNmZjOTI0YjU5NzhmZmVlZGJkYjFhZjI2NmZkNzViOTcyMzIyZmRiMjUx
15
- MzQyNGJmNDM2MWRlNDU4N2EzZmMyNDEyY2JkNmVjNGJjOTgwOGU=
13
+ NTMyMzI1ODA1MDY1ZmQ1NmVlM2FmYTA3ZTI5ZWRkZjVjOWQwZDEwMGQ0MGIw
14
+ OTEyNTRjZmE0NTM5OGEwZDRkZjg1Mjg3M2ZhNGJhYjA1MzlmZGYwNjc0MmY3
15
+ MjYzODlhNzZiNmJiYmI0NzIyMjhiZGMyOWE5N2I3OWQzZGFiYTg=
@@ -1,11 +1,13 @@
1
1
  require 'json'
2
2
  require 'shellwords'
3
3
  require 'exiftool/result'
4
+ require 'forwardable'
4
5
 
5
6
  class Exiftool
6
7
  class NoSuchFile < StandardError ; end
7
8
  class NotAFile < StandardError ; end
8
9
  class ExiftoolNotInstalled < StandardError ; end
10
+ class NoDefaultResultWithMultiget < StandardError ; end
9
11
 
10
12
  def self.command=(path_to_exiftool)
11
13
  @command = path_to_exiftool
@@ -30,18 +32,22 @@ class Exiftool
30
32
  File.expand_path(filename)
31
33
  end
32
34
 
35
+ extend Forwardable
36
+
37
+ def_delegators :first_result, :to_hash, :to_display_hash, :symbol_display_hash, :raw, :[]
38
+
33
39
  def initialize(filenames, exiftool_opts = '')
34
40
  @file2result = {}
35
41
  filenames = [filenames] if filenames.is_a?(String)
36
42
  unless filenames.empty?
37
- escaped_filenames = filenames.collect do |f|
43
+ escaped_filenames = filenames.map do |f|
38
44
  Shellwords.escape(self.class.expand_path(f.to_s))
39
- end.join(" ")
45
+ end.join(' ')
40
46
  # I'd like to use -dateformat, but it doesn't support timezone offsets properly,
41
47
  # nor sub-second timestamps.
42
48
  cmd = "#{self.class.command} #{exiftool_opts} -j -coordFormat \"%.8f\" #{escaped_filenames} 2> /dev/null"
43
- json = `#{cmd}`
44
- raise ExiftoolNotInstalled if json == ""
49
+ json = `#{cmd}`.chomp
50
+ raise ExiftoolNotInstalled if json == ''
45
51
  JSON.parse(json).each do |raw|
46
52
  result = Result.new(raw)
47
53
  @file2result[result.source_file] = result
@@ -49,24 +55,20 @@ class Exiftool
49
55
  end
50
56
  end
51
57
 
58
+ def results(include_results_with_errors = false)
59
+ if include_results_with_errors
60
+ @file2result.values
61
+ else
62
+ @file2result.values.select { |ea| !ea.errors? }
63
+ end
64
+ end
65
+
52
66
  def result_for(filename)
53
67
  @file2result[self.class.expand_path(filename)]
54
68
  end
55
69
 
56
70
  def files_with_results
57
- @file2result.values.collect { |r| r.source_file unless r.errors? }.compact
58
- end
59
-
60
- def to_hash
61
- first.to_hash
62
- end
63
-
64
- def to_display_hash
65
- first.to_display_hash
66
- end
67
-
68
- def symbol_display_hash
69
- first.symbol_display_hash
71
+ results.map { |ea| ea.source_file }
70
72
  end
71
73
 
72
74
  def errors?
@@ -75,8 +77,8 @@ class Exiftool
75
77
 
76
78
  private
77
79
 
78
- def first
79
- raise InvalidArgument, 'use #result_for when multiple filenames are used' if @file2result.size > 1
80
+ def first_result
81
+ raise(NoDefaultResultWithMultiget, 'use #result_for when multiple filenames are used') if @file2result.size > 1
80
82
  @file2result.values.first
81
83
  end
82
84
  end
@@ -2,7 +2,7 @@ require 'time'
2
2
  require 'rational'
3
3
 
4
4
  class Exiftool
5
- class Parser
5
+ class FieldParser
6
6
 
7
7
  WORD_BOUNDARY_RES = [/([A-Z\d]+)([A-Z][a-z])/, /([a-z\d])([A-Z])/]
8
8
  FRACTION_RE = /^(\d+)\/(\d+)$/
@@ -25,6 +25,15 @@ class Exiftool
25
25
  "Warning: Parsing '#{raw_value}' for attribute '#{key}' raised #{e.message}"
26
26
  end
27
27
 
28
+ YMD_RE = /\A(\d{4}):(\d{2}):(\d{2})\b/
29
+
30
+ def ymd_value
31
+ if datish?
32
+ ymd = raw_value.scan(YMD_RE).first
33
+ ymd.join.to_i if ymd
34
+ end
35
+ end
36
+
28
37
  private
29
38
 
30
39
  def for_lat_long
@@ -36,8 +45,12 @@ class Exiftool
36
45
  end
37
46
  end
38
47
 
48
+ def datish?
49
+ raw_value.is_a?(String) && display_key =~ /\bdate\b/i
50
+ end
51
+
39
52
  def for_date
40
- if raw_value.is_a?(String) && display_key =~ /\bdate\b/i
53
+ if datish?
41
54
  try_parse { Time.strptime(raw_value, '%Y:%m:%d %H:%M:%S%z') } ||
42
55
  try_parse { Time.strptime(raw_value, '%Y:%m:%d %H:%M:%S.%L%z') }
43
56
  end
@@ -1,21 +1,28 @@
1
- require 'exiftool/parser'
1
+ require 'exiftool/field_parser'
2
2
 
3
3
  class Exiftool
4
4
  class Result
5
- attr_reader :raw_hash, :to_hash, :to_display_hash, :symbol_display_hash
5
+ attr_reader :raw, :to_hash, :to_display_hash, :sym2display, :display2sym
6
6
 
7
7
  def initialize(raw_hash)
8
- @raw_hash = {}
8
+ @raw = {}
9
9
  @to_hash = {}
10
10
  @to_display_hash = {}
11
- @symbol_display_hash = {}
11
+ @sym2display = {}
12
12
  raw_hash.each do |key, raw_value|
13
- p = Parser.new(key, raw_value)
14
- @raw_hash[p.sym_key] = raw_value
13
+ p = FieldParser.new(key, raw_value)
14
+ @raw[p.sym_key] = raw_value
15
15
  @to_hash[p.sym_key] = p.value
16
16
  @to_display_hash[p.display_key] = p.value
17
- @symbol_display_hash[p.sym_key] = p.display_key
17
+ @sym2display[p.sym_key] = p.display_key
18
+
19
+ ymd = p.ymd_value
20
+ if ymd
21
+ ymd_key = "#{p.sym_key}_ymd".to_sym
22
+ @to_hash[ymd_key] = ymd
23
+ end
18
24
  end
25
+ @display2sym = @sym2display.invert
19
26
  end
20
27
 
21
28
  def [](key)
@@ -1,3 +1,3 @@
1
1
  class Exiftool
2
- VERSION = Gem::Version.new('0.4.0')
2
+ VERSION = Gem::Version.new('0.5.0')
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exiftool
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew McEachen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-30 00:00:00.000000000 Z
11
+ date: 2013-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -116,7 +116,7 @@ extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
118
  - lib/exiftool.rb
119
- - lib/exiftool/parser.rb
119
+ - lib/exiftool/field_parser.rb
120
120
  - lib/exiftool/result.rb
121
121
  - lib/exiftool/version.rb
122
122
  homepage: https://github.com/mceachen/exiftoolr