Class: MiniExiftool

Inherits:
Object
  • Object
show all
Defined in:
lib/mini_exiftool.rb

Overview

Simple OO access to the Exiftool command-line application.

Defined Under Namespace

Classes: Error

Constant Summary

VERSION =
'1.5.1'
@@cmd =

Name of the Exiftool command-line application

'exiftool'
@@opts =

Hash of the standard options used when call MiniExiftool.new

{ :numerical => false, :composite => true, :convert_encoding => false, :ignore_minor_errors => false, :timestamps => Time }

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (MiniExiftool) initialize(filename = nil, opts = {})

opts support at the moment

  • :numerical for numerical values, default is false

  • :composite for including composite tags while loading, default is true

  • :convert_encoding convert encoding (See -L-option of the exiftool command-line application, default is false)

  • :ignore_minor_errors ignore minor errors (See -m-option

of the exiftool command-line application, default is false)

  • :timestamps generating DateTime objects instead of Time objects if set to DateTime, default is Time

    ATTENTION: Time objects are created using Time.local therefore they use your local timezone, DateTime objects instead are created without timezone!



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mini_exiftool.rb', line 52

def initialize filename=nil, opts={}
  opts = @@opts.merge opts
  @numerical = opts[:numerical]
  @composite = opts[:composite]
  @convert_encoding = opts[:convert_encoding]
  @ignore_minor_errors = opts[:ignore_minor_errors]
  @timestamps = opts[:timestamps]
  @values = TagHash.new
  @tag_names = TagHash.new
  @changed_values = TagHash.new
  @errors = TagHash.new
  load filename unless filename.nil?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(symbol, *args) (private)



310
311
312
313
314
315
316
317
# File 'lib/mini_exiftool.rb', line 310

def method_missing symbol, *args
  tag_name = symbol.id2name
  if tag_name.sub!(/=$/, '')
    self[tag_name] = args.first
  else
    self[tag_name]
  end
end

Instance Attribute Details

- (Object) composite

Returns the value of attribute composite



34
35
36
# File 'lib/mini_exiftool.rb', line 34

def composite
  @composite
end

- (Object) convert_encoding

Returns the value of attribute convert_encoding



34
35
36
# File 'lib/mini_exiftool.rb', line 34

def convert_encoding
  @convert_encoding
end

- (Object) errors

Returns the value of attribute errors



34
35
36
# File 'lib/mini_exiftool.rb', line 34

def errors
  @errors
end

- (Object) filename (readonly)

Returns the value of attribute filename



33
34
35
# File 'lib/mini_exiftool.rb', line 33

def filename
  @filename
end

- (Object) ignore_minor_errors

Returns the value of attribute ignore_minor_errors



34
35
36
# File 'lib/mini_exiftool.rb', line 34

def ignore_minor_errors
  @ignore_minor_errors
end

- (Object) numerical

Returns the value of attribute numerical



34
35
36
# File 'lib/mini_exiftool.rb', line 34

def numerical
  @numerical
end

- (Object) timestamps

Returns the value of attribute timestamps



34
35
36
# File 'lib/mini_exiftool.rb', line 34

def timestamps
  @timestamps
end

Class Method Details

+ (Object) all_tags

Returns a set of all known tags of Exiftool.



230
231
232
233
234
235
# File 'lib/mini_exiftool.rb', line 230

def self.all_tags
  unless defined? @@all_tags
    @@all_tags = pstore_get :all_tags
  end
  @@all_tags
end

+ (Object) command

Returns the command name of the called Exiftool application.



215
216
217
# File 'lib/mini_exiftool.rb', line 215

def self.command
  @@cmd
end

+ (Object) command=(cmd)

Setting the command name of the called Exiftool application.



220
221
222
# File 'lib/mini_exiftool.rb', line 220

def self.command= cmd
  @@cmd = cmd
end

+ (Object) exiftool_version

Returns the version of the Exiftool command-line application.



254
255
256
257
258
259
260
# File 'lib/mini_exiftool.rb', line 254

def self.exiftool_version
  output = `#{MiniExiftool.command} -ver 2>&1`
  unless $?.exitstatus == 0
    raise MiniExiftool::Error.new("Command '#{MiniExiftool.command}' not found")
  end
  output.chomp!
end

+ (Object) from_hash(hash)

Create a MiniExiftool instance from a hash



202
203
204
205
206
# File 'lib/mini_exiftool.rb', line 202

def self.from_hash hash
  instance = MiniExiftool.new
  instance.initialize_from_hash hash
  instance
end

+ (Object) from_yaml(yaml)

Create a MiniExiftool instance from YAML data created with MiniExiftool#to_yaml



210
211
212
# File 'lib/mini_exiftool.rb', line 210

def self.from_yaml yaml
  MiniExiftool.from_hash YAML.load(yaml)
end

+ (Object) opts

Returns the options hash.



225
226
227
# File 'lib/mini_exiftool.rb', line 225

def self.opts
  @@opts
end

+ (Object) original_tag(tag)

Returns the original Exiftool name of the given tag



246
247
248
249
250
251
# File 'lib/mini_exiftool.rb', line 246

def self.original_tag tag
  unless defined? @@all_tags_map
    @@all_tags_map = pstore_get :all_tags_map
  end
  @@all_tags_map[tag]
end

+ (Object) unify(tag)



262
263
264
# File 'lib/mini_exiftool.rb', line 262

def self.unify tag
  tag.to_s.gsub(/[-_]/,'').downcase
end

+ (Object) writable_tags

Returns a set of all possible writable tags of Exiftool.



238
239
240
241
242
243
# File 'lib/mini_exiftool.rb', line 238

def self.writable_tags
  unless defined? @@writable_tags
    @@writable_tags = pstore_get :writable_tags
  end
  @@writable_tags
end

Instance Method Details

- (Object) [](tag)

Returns the value of a tag.



105
106
107
# File 'lib/mini_exiftool.rb', line 105

def [] tag
  @changed_values[tag] || @values[tag]
end

- (Object) []=(tag, val)

Set the value of a tag.



110
111
112
# File 'lib/mini_exiftool.rb', line 110

def []=(tag, val)
  @changed_values[tag] = val
end

- (Boolean) changed?(tag = false)

Returns true if any tag value is changed or if the value of a given tag is changed.

Returns:

  • (Boolean)


116
117
118
119
120
121
122
# File 'lib/mini_exiftool.rb', line 116

def changed? tag=false
  if tag
    @changed_values.include? tag
  else
    !@changed_values.empty?
  end
end

- (Object) changed_tags

Returns an array of all changed tags.



142
143
144
# File 'lib/mini_exiftool.rb', line 142

def changed_tags
  @changed_values.keys.map { |key| MiniExiftool.original_tag(key) }
end

- (Object) initialize_from_hash(hash)

:nodoc:



66
67
68
69
70
71
72
# File 'lib/mini_exiftool.rb', line 66

def initialize_from_hash hash # :nodoc:
  hash.each_pair do |tag,value|
    set_value tag, value
  end
  set_attributes_by_heuristic
  self
end

- (Object) load(filename)

Load the tags of filename.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/mini_exiftool.rb', line 75

def load filename
  unless filename && File.exist?(filename)
    raise MiniExiftool::Error.new("File '#{filename}' does not exist.")
  end
  if File.directory?(filename)
    raise MiniExiftool::Error.new("'#{filename}' is a directory.")
  end
  @filename = filename
  @values.clear
  @tag_names.clear
  @changed_values.clear
  opt_params = ''
  opt_params << (@numerical ? '-n ' : '')
  opt_params << (@composite ? '' : '-e ')
  opt_params << (@convert_encoding ? '-L ' : '')
  cmd = %Q(#@@cmd -q -q -s -t #{opt_params} #{@@sep_op} #{Shellwords.escape(filename)})
  if run(cmd)
    parse_output
  else
    raise MiniExiftool::Error.new(@error_text)
  end
  self
end

- (Object) reload

Reload the tags of an already read file.



100
101
102
# File 'lib/mini_exiftool.rb', line 100

def reload
  load @filename
end

- (Object) revert(tag = nil)

Revert all changes or the change of a given tag.



125
126
127
128
129
130
131
132
133
134
# File 'lib/mini_exiftool.rb', line 125

def revert tag=nil
  if tag
    val = @changed_values.delete(tag)
    res = val != nil
  else
    res = @changed_values.size > 0
    @changed_values.clear
  end
  res
end

- (Object) save

Save the changes to the file.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/mini_exiftool.rb', line 147

def save
  return false if @changed_values.empty?
  @errors.clear
  temp_file = Tempfile.new('mini_exiftool')
  temp_file.close
  temp_filename = temp_file.path
  FileUtils.cp filename, temp_filename
  all_ok = true
  @changed_values.each do |tag, val|
    original_tag = MiniExiftool.original_tag(tag)
    arr_val = val.kind_of?(Array) ? val : [val]
    arr_val.map! {|e| convert e}
    tag_params = ''
    arr_val.each do |v|
      tag_params << %Q(-#{original_tag}=#{Shellwords.escape(v.to_s)} )
    end
    opt_params = ''
    opt_params << (arr_val.detect {|x| x.kind_of?(Numeric)} ? '-n ' : '')
    opt_params << (@convert_encoding ? '-L ' : '')
    opt_params << (@ignore_minor_errors ? '-m' : '')
    cmd = %Q(#@@cmd -q -P -overwrite_original #{opt_params} #{tag_params} #{temp_filename})
    if convert_encoding && cmd.respond_to?(:encode)
      cmd.encode('ISO-8859-1')
    end
    result = run(cmd)
    unless result
      all_ok = false
      @errors[tag] = @error_text.gsub(/Nothing to do.\n\z/, '').chomp
    end
  end
  if all_ok
    FileUtils.cp temp_filename, filename
    reload
  end
  temp_file.delete
  all_ok
end

- (Object) tags

Returns an array of the tags (original tag names) of the read file.



137
138
139
# File 'lib/mini_exiftool.rb', line 137

def tags
  @values.keys.map { |key| @tag_names[key] }
end

- (Object) to_hash

Returns a hash of the original loaded values of the MiniExiftool instance.



187
188
189
190
191
192
193
# File 'lib/mini_exiftool.rb', line 187

def to_hash
  result = {}
  @values.each do |k,v|
    result[@tag_names[k]] = v
  end
  result
end

- (Object) to_yaml

Returns a YAML representation of the original loaded values of the MiniExiftool instance.



197
198
199
# File 'lib/mini_exiftool.rb', line 197

def to_yaml
  to_hash.to_yaml
end