micro_exiftool 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3392b6294a746659c23c9a0781fdce1e5cf4e52d
4
+ data.tar.gz: effe61579e027b82a6ac94678664522ccccea3fa
5
+ SHA512:
6
+ metadata.gz: cb967bc6f82725dc338e8a8ddca858f068cf77190cbb9cf54aae56eacf0671e6e9ed660394b5cdb93f74d4fc024a3d9b80bca6ef5eccd9eb488001ae12d5f33c
7
+ data.tar.gz: 459a170ef73c7f6d52c43c64de69fccd203caadd63aa2d78b1605e39e079089614934385e7ccb7ab2f397208998efa88d87aad81dc01b445a9e545bb7531d406
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.bundle
10
+ *.so
11
+ *.o
12
+ *.a
13
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ before_install:
3
+ - wget http://www.sno.phy.queensu.ca/~phil/exiftool/Image-ExifTool-9.99.tar.gz
4
+ - tar -xzf Image-ExifTool-9.99.tar.gz
5
+ - cd Image-ExifTool-9.99
6
+ - perl Makefile.PL
7
+ - make
8
+ - export PATH=$PATH:$PWD
9
+ - cd ..
10
+ - exiftool -ver
11
+ rvm:
12
+ - 1.9.3
13
+ - 2.1.2
14
+ - 2.2.1
15
+ script: bundle exec rspec
16
+ notifications:
17
+ email:
18
+ - fail@makandra.de
19
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in micro_exiftool.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ micro_exiftool (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rake (10.4.2)
11
+ rspec (3.3.0)
12
+ rspec-core (~> 3.3.0)
13
+ rspec-expectations (~> 3.3.0)
14
+ rspec-mocks (~> 3.3.0)
15
+ rspec-core (3.3.2)
16
+ rspec-support (~> 3.3.0)
17
+ rspec-expectations (3.3.1)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.3.0)
20
+ rspec-mocks (3.3.2)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.3.0)
23
+ rspec-support (3.3.0)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.7)
30
+ micro_exiftool!
31
+ rake (~> 10.0)
32
+ rspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Tobias Kraze
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # micro_exiftool [![Build Status](https://travis-ci.org/makandra/micro_exiftool.svg?branch=master)](https://travis-ci.org/makandra/micro_exiftool)
2
+
3
+ micro_exiftool is an extremely basic ruby wrapper for the [ExifTool](http://www.sno.phy.queensu.ca/~phil/exiftool/) command line tool.
4
+
5
+ It allows to read and write metadata for all files supported by ExifTools, such as JPG or MP3.
6
+
7
+ This was the simplest tool that fit my own needs and deliberately tries to do as little as possible.
8
+
9
+ If you need a more complete implementation, you might want to take a look at [mini_exiftool](https://github.com/janfri/mini_exiftool).
10
+
11
+
12
+ ## Installation
13
+
14
+ You need to have exiftool installed and on your PATH.
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'micro_exiftool'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install micro_exiftool
29
+
30
+ ## Usage
31
+
32
+ All attributes are plain strings.
33
+
34
+
35
+ ### Read attributes
36
+
37
+ ```
38
+ file = MicroExiftool::File.new(path_to_file)
39
+
40
+ file.attributes # hash including all attributes returned by exiftool
41
+ file['EXIF:Copyright'] # the EXIF copyright field
42
+ file['IPTC:CopyrightNotice'] # the IPTC copyright field
43
+ ```
44
+
45
+ ### Update attributes
46
+
47
+ ```
48
+ file = MicroExiftool::File.new(path_to_file)
49
+
50
+ file.update!(
51
+ 'EXIF:Copyright' => 'new EXIF copyright',
52
+ 'IPTC:CopyrightNotice' => 'new IPTC copyright',
53
+ )
54
+ ```
55
+
56
+ This will update the attributes of the file in place.
57
+
58
+ Note that there is (currently) no validation that the fields are actually valid metadata fields. If you set an unknown field, it will be silently ignored.
59
+
60
+
61
+ ## Author
62
+
63
+ Tobias Kraze from [makandra](http://makandra.com/)
64
+
65
+
66
+ ## License
67
+
68
+ Licensed under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,6 @@
1
+ require 'micro_exiftool/file'
2
+ require 'micro_exiftool/version'
3
+
4
+ module MicroExiftool
5
+
6
+ end
@@ -0,0 +1,64 @@
1
+ require 'open3'
2
+ require 'json'
3
+
4
+ module MicroExiftool
5
+
6
+ class NoSuchFile < StandardError; end
7
+ class ExifToolError < StandardError; end
8
+
9
+
10
+ class File
11
+
12
+ def initialize(path)
13
+ @path = path.to_s
14
+ unless ::File.exist?(@path)
15
+ raise NoSuchFile.new("No such file: #{@path}")
16
+ end
17
+ end
18
+
19
+ def [](key)
20
+ file_attributes[key]
21
+ end
22
+
23
+ def attributes
24
+ file_attributes.dup
25
+ end
26
+
27
+ def update!(new_attributes)
28
+ update_json = [new_attributes.merge('SourceFile' => @path)].to_json
29
+
30
+ run_exiftool(
31
+ '-P', # dont change timestamp of file
32
+ '-G0', # prefix all attributes with "EXIF:", "ITCP:" etc
33
+ '-overwrite_original', # dont make a backup copy
34
+ '-j=-', # read new attributes from stdin as json
35
+ stdin_data: update_json
36
+ )
37
+
38
+ @file_attributes.merge!(new_attributes) if defined? @file_attributes
39
+ true
40
+ end
41
+
42
+
43
+ private
44
+
45
+ def file_attributes
46
+ @file_attributes ||= load_attributes
47
+ end
48
+
49
+ def load_attributes
50
+ result = run_exiftool('-G0', '-j')
51
+ JSON.parse(result).first
52
+ end
53
+
54
+ def run_exiftool(*arguments)
55
+ options = arguments.last.is_a?(Hash) ? arguments.pop : {}
56
+ stdout_string, stderr_string, status = Open3.capture3('exiftool', @path, *arguments, options)
57
+ unless status.exitstatus == 0
58
+ raise ExifToolError.new("Error running exiftool:\n#{stderr_string}")
59
+ end
60
+ stdout_string
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ module MicroExiftool
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'micro_exiftool/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "micro_exiftool"
8
+ spec.version = MicroExiftool::VERSION
9
+ spec.authors = ["Tobias Kraze"]
10
+ spec.email = ["tobias.kraze@makandra.de"]
11
+ spec.summary = %q{Minimal ruby wrapper around exiftool..}
12
+ spec.homepage = ""
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.7"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec"
23
+ end
Binary file
data/spec/file_spec.rb ADDED
@@ -0,0 +1,138 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'spec_helper'
4
+ require 'tempfile'
5
+
6
+ describe MicroExiftool::File do
7
+
8
+ let(:sample_file_path) { File.join(File.dirname(__FILE__), 'assets', 'image.jpg') }
9
+
10
+ subject { described_class.new(sample_file_path) }
11
+
12
+ describe '.new' do
13
+
14
+ it 'complains about missing files' do
15
+ proc {
16
+ described_class.new('does/not/exist')
17
+ }.should raise_error(MicroExiftool::NoSuchFile)
18
+ end
19
+
20
+ end
21
+
22
+
23
+ describe '#attributes' do
24
+
25
+ it 'returns prefixed file attributes as a hash' do
26
+ subject.attributes.should include(
27
+ 'IPTC:ObjectName' => 'The IPTC Title',
28
+ 'IPTC:CopyrightNotice' => 'The IPTC Copyright',
29
+ 'EXIF:Copyright' => 'The EXIF Copyright'
30
+ )
31
+ end
32
+
33
+ end
34
+
35
+
36
+ describe '#[]' do
37
+
38
+ it 'returns single attributes' do
39
+ subject['IPTC:ObjectName'].should == 'The IPTC Title'
40
+ end
41
+
42
+ end
43
+
44
+ describe 'update!' do
45
+
46
+ let(:sample_file_copy) { Tempfile.new(['sample_file_copy', '.jpg']) }
47
+ let(:sample_file_copy_path) { sample_file_copy.path }
48
+
49
+ before do
50
+ sample_file_copy.write(File.read(sample_file_path))
51
+ sample_file_copy.close
52
+ end
53
+
54
+ subject { described_class.new(sample_file_copy_path) }
55
+ let(:duplicate_subject) { described_class.new(sample_file_copy_path) }
56
+
57
+
58
+ it 'modifies the given attributes in the file' do
59
+ subject.update!(
60
+ 'IPTC:CopyrightNotice' => 'The new IPTC Copyright',
61
+ 'EXIF:Copyright' => 'The new EXIF Copyright',
62
+ )
63
+
64
+ duplicate_subject.attributes.should include(
65
+ 'IPTC:CopyrightNotice' => 'The new IPTC Copyright',
66
+ 'EXIF:Copyright' => 'The new EXIF Copyright',
67
+ )
68
+ end
69
+
70
+ it 'does not touch other metadata' do
71
+ attributes_before = subject.attributes
72
+
73
+ subject.update!(
74
+ 'EXIF:Copyright' => 'The new EXIF Copyright',
75
+ )
76
+
77
+ attributes_after = duplicate_subject.attributes
78
+ %w[EXIF:Copyright File:FileAccessDate File:FileInodeChangeDate].each do |key|
79
+ attributes_before.delete(key)
80
+ attributes_after.delete(key)
81
+ end
82
+ attributes_after.should == attributes_before
83
+ end
84
+
85
+ it 'modifies the given attributes on the current instance' do
86
+ attributes_before = subject.attributes
87
+
88
+ subject.update!(
89
+ 'EXIF:Copyright' => 'The new EXIF Copyright',
90
+ )
91
+
92
+ attributes_before['EXIF:Copyright'].should eq 'The EXIF Copyright'
93
+ subject.attributes['EXIF:Copyright'].should eq 'The new EXIF Copyright'
94
+ end
95
+
96
+ it 'modifies files in place' do
97
+ subject.update!(
98
+ 'EXIF:Copyright' => 'The new EXIF Copyright',
99
+ )
100
+
101
+ File.exist?(sample_file_copy_path + '_original').should eq false
102
+ end
103
+
104
+ it 'can assign characters that might need escaping' do
105
+ new_copyright = %{'"& ;\/{}<>}
106
+ subject.update!(
107
+ 'EXIF:Copyright' => new_copyright,
108
+ 'IPTC:CopyrightNotice' => new_copyright,
109
+ )
110
+
111
+ duplicate_subject['EXIF:Copyright'].should eq new_copyright
112
+ duplicate_subject['IPTC:CopyrightNotice'].should eq new_copyright
113
+ end
114
+
115
+ it 'can assign non-ASCII characters' do
116
+ new_copyright = '版权所有'
117
+ subject.update!(
118
+ 'EXIF:Copyright' => new_copyright,
119
+ 'IPTC:CopyrightNotice' => new_copyright,
120
+ )
121
+
122
+ duplicate_subject['EXIF:Copyright'].should eq new_copyright
123
+ duplicate_subject['IPTC:CopyrightNotice'].should eq new_copyright
124
+ end
125
+
126
+ it 'complains about exiftool errors' do
127
+ Open3.stub(:capture3).and_return(['', 'some error', double('status', exitstatus: 1)])
128
+
129
+ proc {
130
+ subject.update!(
131
+ 'EXIF:Copyright' => 'The new EXIF Copyright',
132
+ )
133
+ }.should raise_error(MicroExiftool::ExifToolError, "Error running exiftool:\nsome error")
134
+ end
135
+
136
+ end
137
+
138
+ end
@@ -0,0 +1,48 @@
1
+ require 'bundler/setup'
2
+ require 'micro_exiftool'
3
+
4
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
5
+ RSpec.configure do |config|
6
+ config.expect_with :rspec do |expectations|
7
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
8
+ expectations.syntax = [:should, :expect]
9
+ end
10
+
11
+ config.mock_with :rspec do |mocks|
12
+ mocks.verify_partial_doubles = true
13
+ mocks.syntax = [:should, :expect]
14
+ end
15
+
16
+ # These two settings work together to allow you to limit a spec run
17
+ # to individual examples or groups you care about by tagging them with
18
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
19
+ # get run.
20
+ config.filter_run :focus
21
+ config.run_all_when_everything_filtered = true
22
+
23
+ # This setting enables warnings. It's recommended, but in some cases may
24
+ # be too noisy due to issues in dependencies.
25
+ config.warnings = true
26
+
27
+ # Many RSpec users commonly either run the entire suite or an individual
28
+ # file, and it's useful to allow more verbose output when running an
29
+ # individual spec file.
30
+ if config.files_to_run.one?
31
+ # Use the documentation formatter for detailed output,
32
+ # unless a formatter has already been configured
33
+ # (e.g. via a command-line flag).
34
+ config.default_formatter = 'doc'
35
+ end
36
+
37
+ # Run specs in random order to surface order dependencies. If you find an
38
+ # order dependency and want to debug it, you can fix the order by providing
39
+ # the seed, which is printed after each run.
40
+ # --seed 1234
41
+ config.order = :random
42
+
43
+ # Seed global randomization in this process using the `--seed` CLI option.
44
+ # Setting this allows you to use `--seed` to deterministically reproduce
45
+ # test failures related to randomization by passing the same `--seed` value
46
+ # as the one that triggered the failure.
47
+ Kernel.srand config.seed
48
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: micro_exiftool
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tobias Kraze
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - tobias.kraze@makandra.de
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - lib/micro_exiftool.rb
71
+ - lib/micro_exiftool/file.rb
72
+ - lib/micro_exiftool/version.rb
73
+ - micro_exiftool.gemspec
74
+ - spec/assets/image.jpg
75
+ - spec/file_spec.rb
76
+ - spec/spec_helper.rb
77
+ homepage: ''
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.4.8
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Minimal ruby wrapper around exiftool..
101
+ test_files:
102
+ - spec/assets/image.jpg
103
+ - spec/file_spec.rb
104
+ - spec/spec_helper.rb