image_optimizer 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- N2Q4ZWYzYjZjMWMzYTkwMTUxNTExMzBkNTFjNjZkNTBmNGFjODJiZQ==
5
- data.tar.gz: !binary |-
6
- ODc5MzY0MzA4NjY2YTgzZTYzZDUzZTA2MDBmMzBmY2Q2OGZhZGVkMA==
2
+ SHA1:
3
+ metadata.gz: 970982e519567a730a3feb024bbed88cfbb837b6
4
+ data.tar.gz: 92198c8d8fbaa3ce8caa6ef2e270f6872a7b1829
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MTM3MjhhYmEwZTJjNTI4Y2MxYTcxOGM3M2ZiZTk5Nzk2NTUzMjA4ZWE1NmU2
10
- YmFhMzhjNjRhNzY1NTVkMjk5ZWI0MDNhOTYxNDc5MTU5ZWU3NmJhMWQ4NThh
11
- YjYyNjg2YjMyMzhmYjI3ODMxOTdiNzU5OTgxOWFmODBmZWFmYjY=
12
- data.tar.gz: !binary |-
13
- NDdlZTM1N2Q3YTMwMWNhNGQxZDQ4Mzc3Mjg5ZWIzM2NmYzY2Y2IzOWQzNGVj
14
- N2M1YjlkMmU3ZTU0MjQ0N2VjMWVhZTA3NWQ3YTNhYjM2Nzc1YWM4MDUxZWFl
15
- Njc2OGMzMDllYThjNGE3NWQzZDU5ZThhMjI2MDc1MmJmNGJhMDU=
6
+ metadata.gz: cbe10141847ab85f09fc245f813db416448a9ca391b6c8e3f66b26489ce2df423228e8875fea6ff96475518dada29c597d448ce74a69c1e41a793f6b49436a9d
7
+ data.tar.gz: 17432c5a63ea32496a5442f60e9a53f257d3f338e828558bdc31f4c7aef72c7213d95ea1bd7ec228ac193297586167ef8559365f303c4274ae7729d9ef9704b0
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -84,6 +84,19 @@ optimization. PNGs will ignore the quality setting.
84
84
  ImageOptimizer.new('path/to/file.jpg', quality: 80).optimize
85
85
  ```
86
86
 
87
+ ##### Use identify
88
+
89
+ Pass an optional `identify` parameter to identify file types using ImageMagick or GraphicsMagick `identify`
90
+ instead of the filename extension, default is false.
91
+
92
+ ```ruby
93
+ ImageOptimizer.new('path/to/file.jpg', identify: true).optimize
94
+ ```
95
+
96
+ ## Set bin directories
97
+
98
+ Optionally set binary directories with the `OPTIPNG_BIN`, `JPEGOPTIM_BIN` and `IDENTIFY_BIN` environment variables.
99
+
87
100
 
88
101
  ## Contributing
89
102
 
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDdDCCAlygAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMRIwEAYDVQQDDAlqYXRl
3
+ c2NoZXIxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
4
+ bTAeFw0xNDA5MjkyMTIzNDhaFw0xNTA5MjkyMTIzNDhaMEAxEjAQBgNVBAMMCWph
5
+ dGVzY2hlcjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
6
+ Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAshN+oQWZWrd06HAk
7
+ Ym6hJrg3ILAaF/BVUhsiw5Pi1Z8+4UrCY1dQKSkoU8rcpAyKlozbiAyiTgpy3rwG
8
+ s9K+++4c3Nq3n4U+TrziwdLYR6O6CceA39HYXgo8sdJNQp/dTrN/UJ9i5XjGVsj5
9
+ EZ/GxVjzFcfaxGhOtRRSxxV8cML2xPO4jdj7s1i2PdD2W8E199pZo6aQGmoViTku
10
+ AtmDOhJBi3RUUtrYPkC2ts74zdrIiRs4sPnqRAwg88ssWHBAInaqskxe8T9JMGhG
11
+ DxQEOU1cI2f6WtngbM3Grqz4zsinXaN5UNJug4MIeMw0ufVS2n9x33tl5TQbqEFE
12
+ R4lgOQIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
13
+ iZKdXYDw8pqTJRPmIgL+1fiLQ2YwHgYDVR0RBBcwFYETamF0ZXNjaGVyQGdtYWls
14
+ LmNvbTAeBgNVHRIEFzAVgRNqYXRlc2NoZXJAZ21haWwuY29tMA0GCSqGSIb3DQEB
15
+ BQUAA4IBAQBOhrOaKUTe9WSuIdWMT0EwyKa5nuBGOW+TvbZ722RFb1m/t53JrhZk
16
+ e9fcuBPqP3OP4Sm1zuJApG54g4MfVRoH4VSVXIME8SCVix2AA40Wo/kuKkpusk9o
17
+ DI8YB1wuKHvxz5Dp9TqUhW6U0xflFdBIvMxDYW4cBhBCXMNGIORi1vX2IqpMmTB/
18
+ H1OPGmibxwLAMvjJ9zmMX0JTeNl4vrOMwrqntPCN7wifzRWQQjDpr7FlR35P30jd
19
+ g//+Q17/DxaA78vyZM5fABBBpCg/ds7axx7I2n/CG+4WzyGUK2Lgn5kF5aRY3Ugh
20
+ at/y9WkZyjaptzzmD0bwLUxK3brbGZsC
21
+ -----END CERTIFICATE-----
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
13
13
  gem.homepage = "https://github.com/jtescher/image_optimizer"
14
14
  gem.license = 'MIT'
15
15
  gem.signing_key = File.expand_path('~/.ssh/gem-private_key.pem') if $0 =~ /gem\z/
16
- gem.cert_chain = ['gem-public_cert.pem']
16
+ gem.cert_chain = ['certs/jtescher.pem']
17
17
 
18
18
  gem.files = `git ls-files`.split($/)
19
19
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -1,17 +1,51 @@
1
1
  require 'image_optimizer/version'
2
+ require 'image_optimizer/shell'
3
+ require 'image_optimizer/image_optimizer_base'
2
4
  require 'image_optimizer/jpeg_optimizer'
3
5
  require 'image_optimizer/png_optimizer'
4
6
 
5
7
  class ImageOptimizer
6
- attr_reader :path, :options
8
+ include Shell
7
9
 
10
+ attr_reader :path, :options
8
11
  def initialize(path, options = {})
9
12
  @path = path
10
13
  @options = options
11
14
  end
12
15
 
13
16
  def optimize
17
+ identify_format if options[:identify]
14
18
  JPEGOptimizer.new(path, options).optimize
15
19
  PNGOptimizer.new(path, options).optimize
16
20
  end
21
+
22
+ private
23
+
24
+ def identify_format
25
+ if identify_bin?
26
+ match = run_command("#{identify_bin} -ping#{quiet} #{path}").match(/PNG|JPG|TIFF|GIF|JPEG/)
27
+ if match
28
+ options[:identified_format] = match[0].downcase
29
+ end
30
+ else
31
+ warn 'Attempting to retrieve image format without identify installed. Using file name extension instead...'
32
+ end
33
+ end
34
+
35
+ def quiet
36
+ ' -quiet' if image_magick?
37
+ end
38
+
39
+ def image_magick?
40
+ !!which('mogrify')
41
+ end
42
+
43
+ def identify_bin?
44
+ !!identify_bin
45
+ end
46
+
47
+ def identify_bin
48
+ ENV['IDENTIFY_BIN'] || which('identify')
49
+ end
50
+
17
51
  end
@@ -0,0 +1,44 @@
1
+ class ImageOptimizer
2
+ class ImageOptimizerBase
3
+ include Shell
4
+
5
+ attr_reader :path, :options
6
+ def initialize(path, options = {})
7
+ @path = path
8
+ @options = options
9
+ end
10
+
11
+ def optimize
12
+ return unless correct_format?
13
+
14
+ if optimizer_bin?
15
+ perform_optimizations
16
+ else
17
+ warn "Attempting to optimize a #{type} without #{bin_name} installed. Skipping..."
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def correct_format?
24
+ extensions.include?(options[:identified_format] || extension(path))
25
+ end
26
+
27
+ def extension(path)
28
+ path.split('.').last.downcase
29
+ end
30
+
31
+ def perform_optimizations
32
+ system(optimizer_bin, *command_options)
33
+ end
34
+
35
+ def optimizer_bin?
36
+ !!optimizer_bin
37
+ end
38
+
39
+ def optimizer_bin
40
+ ENV["#{bin_name.upcase}_BIN"] || which(bin_name)
41
+ end
42
+
43
+ end
44
+ end
@@ -1,36 +1,8 @@
1
1
  class ImageOptimizer
2
- class JPEGOptimizer
3
- attr_reader :path, :options
4
-
5
- def initialize(path, options = {})
6
- @path = path
7
- @options = options
8
- end
9
-
10
- def optimize
11
- return unless jpeg_format?
12
-
13
- if jpeg_optimizer_present?
14
- optimize_jpeg
15
- else
16
- warn 'Attempting to optimize a jpeg without jpegoptim installed. Skipping...'
17
- end
18
- end
2
+ class JPEGOptimizer < ImageOptimizerBase
19
3
 
20
4
  private
21
5
 
22
- def jpeg_format?
23
- ['jpeg', 'jpg'].include? extension(path)
24
- end
25
-
26
- def extension(path)
27
- path.split('.').last.downcase
28
- end
29
-
30
- def optimize_jpeg
31
- system(jpeg_optimizer_bin, *command_options)
32
- end
33
-
34
6
  def command_options
35
7
  flags = ['-f', '--strip-all', '--all-progressive']
36
8
  flags << max_quantity if (0..100).include?(options[:quality])
@@ -46,12 +18,16 @@ class ImageOptimizer
46
18
  '--quiet'
47
19
  end
48
20
 
49
- def jpeg_optimizer_present?
50
- !jpeg_optimizer_bin.nil? && !jpeg_optimizer_bin.empty?
21
+ def extensions
22
+ %w[jpeg jpg]
23
+ end
24
+
25
+ def type
26
+ 'jpeg'
51
27
  end
52
28
 
53
- def jpeg_optimizer_bin
54
- @jpeg_optimizer_bin ||= ENV['JPEGOPTIM_BIN'] || `which jpegoptim`.strip
29
+ def bin_name
30
+ 'jpegoptim'
55
31
  end
56
32
 
57
33
  end
@@ -1,36 +1,8 @@
1
1
  class ImageOptimizer
2
- class PNGOptimizer
3
- attr_reader :path, :options
4
-
5
- def initialize(path, options = {})
6
- @path = path
7
- @options = options
8
- end
9
-
10
- def optimize
11
- return unless png_format?
12
-
13
- if png_optimizer_present?
14
- optimize_png
15
- else
16
- warn 'Attempting to optimize a png without optipng installed. Skipping...'
17
- end
18
- end
2
+ class PNGOptimizer < ImageOptimizerBase
19
3
 
20
4
  private
21
5
 
22
- def png_format?
23
- ['png', 'gif'].include? extension(path)
24
- end
25
-
26
- def extension(path)
27
- path.split('.').last.downcase
28
- end
29
-
30
- def optimize_png
31
- system(png_optimizer_bin, *command_options)
32
- end
33
-
34
6
  def command_options
35
7
  flags = %w[-o7]
36
8
  flags << quiet if options[:quiet]
@@ -41,12 +13,16 @@ class ImageOptimizer
41
13
  '-quiet'
42
14
  end
43
15
 
44
- def png_optimizer_present?
45
- !png_optimizer_bin.nil? && !png_optimizer_bin.empty?
16
+ def type
17
+ 'png'
18
+ end
19
+
20
+ def extensions
21
+ %w[png gif]
46
22
  end
47
23
 
48
- def png_optimizer_bin
49
- @png_optimzer_bin ||= ENV['OPTIPNG_BIN'] || `which optipng`.strip
24
+ def bin_name
25
+ 'optipng'
50
26
  end
51
27
 
52
28
  end
@@ -0,0 +1,36 @@
1
+ class ImageOptimizer
2
+ module Shell
3
+ # most of the code from MiniMagick, they didn't write any tests
4
+
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ def which(cmd)
10
+ self.class.which(cmd)
11
+ end
12
+
13
+ def run_command(command)
14
+ self.class.run_command(command)
15
+ end
16
+
17
+ module ClassMethods
18
+ # Cross-platform way of finding an executable in the $PATH.
19
+ def which(cmd)
20
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
21
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
22
+ exts.each do |ext|
23
+ exe = File.join(path, "#{cmd}#{ext}")
24
+ return exe if File.executable? exe
25
+ end
26
+ end
27
+ nil
28
+ end
29
+
30
+ def run_command(command)
31
+ `#{command}`
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -1,3 +1,3 @@
1
1
  class ImageOptimizer
2
- VERSION = '1.2.1'
2
+ VERSION = '1.3.0'
3
3
  end
@@ -2,43 +2,68 @@ require 'spec_helper'
2
2
 
3
3
  describe ImageOptimizer::JPEGOptimizer do
4
4
  describe '#optimize' do
5
- let(:jpeg_optimizer) { ImageOptimizer::JPEGOptimizer.new('/path/to/file.jpg') }
5
+ let(:options) { {} }
6
+ let(:jpeg_optimizer) { ImageOptimizer::JPEGOptimizer.new('/path/to/file.jpg', options) }
7
+ after { ImageOptimizer::JPEGOptimizer.instance_variable_set(:@bin, nil) }
8
+ subject { jpeg_optimizer.optimize }
6
9
 
7
- it 'optimizes the jpeg' do
8
- jpeg_optimizer.stub(:jpeg_optimizer_bin => '/usr/local/bin/jpegoptim')
9
- optimizer_options = %w[-f --strip-all --all-progressive /path/to/file.jpg]
10
- jpeg_optimizer.should_receive(:system).with('/usr/local/bin/jpegoptim', *optimizer_options)
11
- jpeg_optimizer.optimize
12
- end
10
+ context 'jpeg optimizing utility is installed' do
11
+ before do
12
+ allow(ImageOptimizer::JPEGOptimizer).to receive(:which).and_return('/usr/local/bin/jpegoptim')
13
+ end
13
14
 
14
- it 'warns the user if the jpeg optimizing utility is not installed' do
15
- jpeg_optimizer.stub(:jpeg_optimizer_bin => '')
16
- jpeg_optimizer.should_receive(:warn).with('Attempting to optimize a jpeg without jpegoptim installed. Skipping...')
17
- jpeg_optimizer.optimize
18
- end
15
+ it 'optimizes the jpeg' do
16
+ optimizer_options = %w[-f --strip-all --all-progressive /path/to/file.jpg]
17
+ expect(jpeg_optimizer).to receive(:system).with('/usr/local/bin/jpegoptim', *optimizer_options)
18
+ subject
19
+ end
19
20
 
20
- it 'detects if there is an ENV variable path to jpegoptim' do
21
- image_optim_jpegoptim_bin_path = '/app/vendor/bundle/ruby/2.0.0/gems/image_optim_bin-0.0.2/bin/jpegoptim'
22
- ENV['JPEGOPTIM_BIN'] = image_optim_jpegoptim_bin_path
23
- optimizer_options = %w[-f --strip-all --all-progressive /path/to/file.jpg]
24
- jpeg_optimizer.should_receive(:system).with(image_optim_jpegoptim_bin_path, *optimizer_options)
25
- jpeg_optimizer.optimize
26
- end
21
+ context 'ENV variable path to jpegoptim' do
22
+ let(:image_optim_jpegoptim_bin_path) { '/app/vendor/bundle/ruby/2.0.0/gems/image_optim_bin-0.0.2/bin/jpegoptim' }
23
+ before do
24
+ ENV['JPEGOPTIM_BIN'] = image_optim_jpegoptim_bin_path
25
+ end
26
+ after do
27
+ ENV['JPEGOPTIM_BIN'] = nil
28
+ end
29
+
30
+ it 'should optimize using the given path' do
31
+ optimizer_options = %w[-f --strip-all --all-progressive /path/to/file.jpg]
32
+ expect(jpeg_optimizer).to receive(:system).with(image_optim_jpegoptim_bin_path, *optimizer_options)
33
+ subject
34
+ end
35
+ end
27
36
 
28
- it 'accepts an optional quality parameter' do
29
- jpeg_optimizer = ImageOptimizer::JPEGOptimizer.new('/path/to/file.jpg', :quality => 50)
30
- jpeg_optimizer.stub(:jpeg_optimizer_bin => '/usr/local/bin/jpegoptim')
31
- optimizer_options = %w[-f --strip-all --all-progressive --max=50 /path/to/file.jpg]
32
- jpeg_optimizer.should_receive(:system).with('/usr/local/bin/jpegoptim', *optimizer_options)
33
- jpeg_optimizer.optimize
37
+ context 'with quality parameter' do
38
+ let(:options) { { :quality => 50 } }
39
+
40
+ it 'optimizes the jpeg with the quality' do
41
+ optimizer_options = %w[-f --strip-all --all-progressive --max=50 /path/to/file.jpg]
42
+ expect(jpeg_optimizer).to receive(:system).with('/usr/local/bin/jpegoptim', *optimizer_options)
43
+ subject
44
+ end
45
+ end
46
+
47
+ context 'with quiet parameter' do
48
+ let(:options) { { :quiet => true } }
49
+
50
+ it 'accepts an optional quiet parameter' do
51
+ optimizer_options = %w[-f --strip-all --all-progressive --quiet /path/to/file.jpg]
52
+ expect(jpeg_optimizer).to receive(:system).with('/usr/local/bin/jpegoptim', *optimizer_options)
53
+ subject
54
+ end
55
+ end
34
56
  end
35
57
 
36
- it 'accepts an optional quiet parameter' do
37
- jpeg_optimizer = ImageOptimizer::JPEGOptimizer.new('/path/to/file.jpg', :quiet => true)
38
- jpeg_optimizer.stub(:jpeg_optimizer_bin => '/usr/local/bin/jpegoptim')
39
- optimizer_options = %w[-f --strip-all --all-progressive --quiet /path/to/file.jpg]
40
- jpeg_optimizer.should_receive(:system).with('/usr/local/bin/jpegoptim', *optimizer_options)
41
- jpeg_optimizer.optimize
58
+ context 'optimizing utility is not installed' do
59
+ before do
60
+ allow(ImageOptimizer::JPEGOptimizer).to receive(:which).and_return(nil)
61
+ end
62
+
63
+ it 'warns the user if the jpeg' do
64
+ expect(jpeg_optimizer).to receive(:warn).with('Attempting to optimize a jpeg without jpegoptim installed. Skipping...')
65
+ subject
66
+ end
42
67
  end
43
68
  end
44
- end
69
+ end
@@ -2,32 +2,54 @@ require 'spec_helper'
2
2
 
3
3
  describe ImageOptimizer::PNGOptimizer do
4
4
  describe '#optimize' do
5
- let(:png_optimizer) { ImageOptimizer::PNGOptimizer.new('/path/to/file.png') }
5
+ let(:options) { {} }
6
+ let(:png_optimizer) { ImageOptimizer::PNGOptimizer.new('/path/to/file.png', options) }
7
+ after { ImageOptimizer::PNGOptimizer.instance_variable_set(:@bin, nil) }
8
+ subject { png_optimizer.optimize }
6
9
 
7
- it 'optimizes the png' do
8
- png_optimizer.stub(:png_optimizer_bin => '/usr/local/bin/optipng')
9
- png_optimizer.should_receive(:system).with('/usr/local/bin/optipng', '-o7', '/path/to/file.png')
10
- png_optimizer.optimize
11
- end
10
+ context 'with png optimizing utility installed' do
11
+ before do
12
+ allow(ImageOptimizer::PNGOptimizer).to receive(:which).and_return('/usr/local/bin/optipng')
13
+ end
12
14
 
13
- it 'warns the user if the png optimizing utility is not installed' do
14
- png_optimizer.stub(:png_optimizer_bin => '')
15
- png_optimizer.should_receive(:warn).with('Attempting to optimize a png without optipng installed. Skipping...')
16
- png_optimizer.optimize
17
- end
15
+ it 'optimizes the png' do
16
+ expect(png_optimizer).to receive(:system).with('/usr/local/bin/optipng', '-o7', '/path/to/file.png')
17
+ subject
18
+ end
19
+
20
+ context 'ENV variable path to optipng' do
21
+ let(:image_optim_optipng_bin_path) { '/app/vendor/bundle/ruby/2.0.0/gems/image_optim_bin-0.0.2/bin/optipng' }
22
+ before do
23
+ ENV['OPTIPNG_BIN'] = image_optim_optipng_bin_path
24
+ end
25
+ after do
26
+ ENV['OPTIPNG_BIN'] = nil
27
+ end
18
28
 
19
- it 'detects if there is an ENV variable path to optipng' do
20
- image_optim_optipng_bin_path = '/app/vendor/bundle/ruby/2.0.0/gems/image_optim_bin-0.0.2/bin/optipng'
21
- ENV['OPTIPNG_BIN'] = image_optim_optipng_bin_path
22
- png_optimizer.should_receive(:system).with(image_optim_optipng_bin_path, '-o7', '/path/to/file.png')
23
- png_optimizer.optimize
29
+ it 'detects if there is an ENV variable path to optipng' do
30
+ expect(png_optimizer).to receive(:system).with(image_optim_optipng_bin_path, '-o7', '/path/to/file.png')
31
+ subject
32
+ end
33
+ end
34
+
35
+ context 'with quiet parameter' do
36
+ let(:options) { { :quiet => true } }
37
+ it 'optimizes the png' do
38
+ expect(png_optimizer).to receive(:system).with('/usr/local/bin/optipng', '-o7', '-quiet', '/path/to/file.png')
39
+ subject
40
+ end
41
+ end
24
42
  end
25
43
 
26
- it 'accepts an optional quiet parameter' do
27
- png_optimizer = ImageOptimizer::PNGOptimizer.new('/path/to/file.png', :quiet => true)
28
- png_optimizer.stub(:png_optimizer_bin => '/usr/local/bin/optipng')
29
- png_optimizer.should_receive(:system).with('/usr/local/bin/optipng', '-o7', '-quiet', '/path/to/file.png')
30
- png_optimizer.optimize
44
+ context 'with png optimizing utility not installed' do
45
+ before do
46
+ allow(ImageOptimizer::PNGOptimizer).to receive(:which).and_return(nil)
47
+ end
48
+
49
+ it 'warns the user' do
50
+ expect(png_optimizer).to receive(:warn).with('Attempting to optimize a png without optipng installed. Skipping...')
51
+ subject
52
+ end
31
53
  end
32
54
  end
33
55
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ class TestShell
4
+ include ImageOptimizer::Shell
5
+ end
6
+
7
+ describe ImageOptimizer::Shell do
8
+ subject { TestShell.new }
9
+
10
+ describe '#which' do
11
+ it 'should find ruby' do
12
+ expect(subject.which('ruby')).to_not be_nil
13
+ end
14
+
15
+ it 'should not find it' do
16
+ expect(subject.which('something_that_should_not_exist_ever')).to be_nil
17
+ end
18
+ end
19
+
20
+ describe '#run_command' do
21
+ it 'run the command successfully' do
22
+ expect(subject.run_command('ruby -v')).to_not be_nil
23
+ end
24
+ end
25
+ end
@@ -2,6 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe ImageOptimizer do
4
4
  it 'should have a VERSION constant' do
5
- ImageOptimizer::VERSION.should_not be_empty
5
+ expect(ImageOptimizer::VERSION).to_not be_empty
6
6
  end
7
7
  end
@@ -1,11 +1,129 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ImageOptimizer do
4
+ let(:options) { {} }
5
+ let(:image_path) { '/path/to/file.jpg' }
6
+
4
7
  describe '#optimize' do
8
+ subject { ImageOptimizer.new(File.join(image_path), options) }
9
+
5
10
  it 'delegates to jpeg and png optimizers' do
6
- ImageOptimizer::JPEGOptimizer.any_instance.should_receive(:optimize)
7
- ImageOptimizer::PNGOptimizer.any_instance.should_receive(:optimize)
8
- ImageOptimizer.new('/path/to/image.jpg').optimize
11
+ expect_any_instance_of(ImageOptimizer::JPEGOptimizer).to receive(:optimize)
12
+ expect_any_instance_of(ImageOptimizer::PNGOptimizer).to receive(:optimize)
13
+ subject.optimize
14
+ end
15
+ end
16
+
17
+ describe '#identify_format' do
18
+
19
+ context 'with identify option off' do
20
+ subject { ImageOptimizer.new(File.join(image_path), options) }
21
+
22
+ it 'does nothing' do
23
+ expect(subject).to_not receive(:identify_format)
24
+ subject.optimize
25
+ end
26
+ end
27
+
28
+ context 'with identify option on' do
29
+ let(:image_magick_data) do
30
+ {
31
+ :output => 'rose.jpg JPEG 640x480 sRGB 87kb 0.050u 0:01',
32
+ :command => " -ping -quiet #{image_path}"
33
+ }
34
+ end
35
+ let(:graphics_magick_data) do
36
+ {
37
+ :output => "Image: images/aquarium.jpg\nclass: PseudoClass\ncolors: 256\n" +
38
+ "signature: eb5dca81dd93ae7e6ffae99a527eb5dca8...\nmatte: False\ngeometry: 640x480\ndepth: 8\nbytes: 308135" +
39
+ "format: JPEG\ncomments:\nImported from MTV raster image: aquarium.mtv",
40
+ :command => " -ping #{image_path}"
41
+ }
42
+ end
43
+
44
+ subject { ImageOptimizer.new(File.join(image_path), options.merge(:identify => true)) }
45
+
46
+ context 'with identify found thorough `which`' do
47
+ let(:identify_bin_path) { '/usr/local/bin/identify' }
48
+ before { allow(subject).to receive(:which).with('identify').and_return(identify_bin_path) }
49
+
50
+ context 'for ImageMagick' do
51
+ before { allow(subject).to receive(:which).with('mogrify').and_return('/usr/local/bin/mogrify') }
52
+
53
+ it 'detects jpegs' do
54
+ allow(subject).to receive(:run_command).and_return(image_magick_data[:output])
55
+ subject.optimize
56
+ expect(subject.options[:identified_format]).to eq('jpeg')
57
+ end
58
+
59
+ it 'calls the correct identify command' do
60
+ expect(subject).to receive(:run_command).with(identify_bin_path + image_magick_data[:command]).and_return('')
61
+ subject.optimize
62
+ end
63
+ end
64
+
65
+ context 'for GraphicsMagick' do
66
+ before { allow(subject).to receive(:which).with('mogrify').and_return(nil) }
67
+
68
+ it 'detects jpegs' do
69
+ allow(subject).to receive(:run_command).and_return(graphics_magick_data[:output])
70
+ subject.optimize
71
+ expect(subject.options[:identified_format]).to eq('jpeg')
72
+ end
73
+
74
+ it 'calls the correct identify command' do
75
+ expect(subject).to receive(:run_command).with(identify_bin_path + graphics_magick_data[:command]).and_return('')
76
+ subject.optimize
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'with identify found in ENV' do
82
+ let(:identify_bin_path) { '~/bin/identify' }
83
+ before { ENV['IDENTIFY_BIN'] = identify_bin_path }
84
+ after { ENV['IDENTIFY_BIN'] = nil}
85
+
86
+ context 'for ImageMagick' do
87
+ before { allow(subject).to receive(:which).with('mogrify').and_return('/usr/local/bin/mogrify') }
88
+
89
+ it 'detects jpegs' do
90
+ allow(subject).to receive(:run_command).and_return(image_magick_data[:output])
91
+ subject.optimize
92
+ expect(subject.options[:identified_format]).to eq('jpeg')
93
+ end
94
+
95
+ it 'calls the correct identify command' do
96
+ expect(subject).to receive(:run_command).with(identify_bin_path + image_magick_data[:command]).and_return('')
97
+ subject.optimize
98
+ end
99
+ end
100
+
101
+ context 'for GraphicsMagick' do
102
+ before { allow(subject).to receive(:which).with('mogrify').and_return(nil) }
103
+
104
+ it 'detects jpegs' do
105
+ allow(subject).to receive(:run_command).and_return(graphics_magick_data[:output])
106
+ subject.optimize
107
+ expect(subject.options[:identified_format]).to eq('jpeg')
108
+ end
109
+
110
+ it 'calls the correct identify command' do
111
+ expect(subject).to receive(:run_command).with(identify_bin_path + graphics_magick_data[:command]).and_return('')
112
+ subject.optimize
113
+ end
114
+ end
115
+ end
116
+
117
+ context 'with identify not installed' do
118
+ it 'warns the user' do
119
+ allow(subject).to receive(:which).with('identify').and_return(nil)
120
+ allow(subject).to receive(:identify_bin?).and_return(false)
121
+ expect(subject).to receive(:warn).with('Attempting to retrieve image format without identify installed.' +
122
+ ' Using file name extension instead...')
123
+ subject.optimize
124
+ end
125
+ end
126
+
9
127
  end
10
128
  end
11
129
  end
metadata CHANGED
@@ -1,110 +1,105 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: image_optimizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Tescher
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
- - !binary |-
12
- LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLakNDQWhLZ0F3SUJB
13
- Z0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREE3TVEwd0N3WURWUVFEREFSNWIz
14
- VnkKTVJVd0V3WUtDWkltaVpQeUxHUUJHUllGWlcxaGFXd3hFekFSQmdvSmtp
15
- YUprL0lzWkFFWkZnTmpiMjB3SGhjTgpNVE13TmpFME1Ua3hNalE0V2hjTk1U
16
- UXdOakUwTVRreE1qUTRXakE3TVEwd0N3WURWUVFEREFSNWIzVnlNUlV3CkV3
17
- WUtDWkltaVpQeUxHUUJHUllGWlcxaGFXd3hFekFSQmdvSmtpYUprL0lzWkFF
18
- WkZnTmpiMjB3Z2dFaU1BMEcKQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dF
19
- S0FvSUJBUUM5V2p2SmluV1Y3aDlWZUxsZjQreUh4cjFMRi84LwpISEZDS1lF
20
- cy9aclVKTHJwbXVVV1Vya2dwd0liVjVGVXZxa1hvQ2NDdlIyejY1bEFPTlp0
21
- ZHZnM3lnQkJYZmw3CnJRYU5iL0VNTXp1bG1mMjZ6dEF0VVAwSXBhejBwWC9x
22
- bHpETGtEa2hYeFVCMXJVY3h1WjJSaWYwSHNPdFFPNWQKTXpRZlJFc1lEdFdN
23
- aWxlTHhjSW1DeHRvRTVyK3RHMnNiSjcyZ3hQMFF5Z0F3TCtta2UvL0Mwd1BW
24
- Q0JDOXpJMgpmd2habVREMmRteXgwSlc4QzBZUiszOGtxdE1sZENjSVFPUFJI
25
- NnVlL0pBeWZ4YW9zWXlOTEs1enVVb1cxTVNSCmwxUE1XYjNmRURYcHJibmt1
26
- NDk2ZjAyNkZBZ0RuOFRGc1dERncrS2hId1RnSVlBU2Jnb3BZcVdUQWdNQkFB
27
- R2oKT1RBM01Ba0dBMVVkRXdRQ01BQXdIUVlEVlIwT0JCWUVGTTBLQ1FMTWlP
28
- am5zTDFURXU1SUZGUkNhcjRDTUFzRwpBMVVkRHdRRUF3SUVzREFOQmdrcWhr
29
- aUc5dzBCQVFVRkFBT0NBUUVBc2NXMzNxOGcwakxrQUU4alpuSVlqYk8zCmho
30
- TnBTeVhPMUptSkVibTVxOXY1ckRxaGo4UlRiZGQxMDB0RndHYzJ0SVZpUjll
31
- ZFE4WjcyczlnRUFkVTZONFAKSHBvWWNOT3FFVDhGcXMrbzE2bGJrNzRvbjZH
32
- djlTNUxaakJRMVV1SXFEYkVOdVR6b2d4WTI1WXg1ZElHSHlJbwo3cnpvcmY0
33
- ZTRLQ05GdzE5Qkc1TTNpamxNdmNpU0d4SVBibUpvYVNhN202MnN1ZEdyM0Ny
34
- RXBSZ01aQnZwMUVhCklMYVBpSTFQaFZ1cmZvdjJ5MCtZVDByYk9ydjRjV29C
35
- V3NaK2F3dzJpU05DNVhGaEEvOHhzSzBCbHRZUkY5blAKSEE0MVV0RHhySmtI
36
- TDNOMXo4Z1BNWFNyRlQ0MUZSMndnazgrbDE0UCs3ZzFVVFBpZDJFSXdmdDJ4
37
- T2JGZUE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
38
- date: 2013-12-30 00:00:00.000000000 Z
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDdDCCAlygAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMRIwEAYDVQQDDAlqYXRl
14
+ c2NoZXIxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
15
+ bTAeFw0xNDA5MjkyMTIzNDhaFw0xNTA5MjkyMTIzNDhaMEAxEjAQBgNVBAMMCWph
16
+ dGVzY2hlcjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
17
+ Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAshN+oQWZWrd06HAk
18
+ Ym6hJrg3ILAaF/BVUhsiw5Pi1Z8+4UrCY1dQKSkoU8rcpAyKlozbiAyiTgpy3rwG
19
+ s9K+++4c3Nq3n4U+TrziwdLYR6O6CceA39HYXgo8sdJNQp/dTrN/UJ9i5XjGVsj5
20
+ EZ/GxVjzFcfaxGhOtRRSxxV8cML2xPO4jdj7s1i2PdD2W8E199pZo6aQGmoViTku
21
+ AtmDOhJBi3RUUtrYPkC2ts74zdrIiRs4sPnqRAwg88ssWHBAInaqskxe8T9JMGhG
22
+ DxQEOU1cI2f6WtngbM3Grqz4zsinXaN5UNJug4MIeMw0ufVS2n9x33tl5TQbqEFE
23
+ R4lgOQIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
24
+ iZKdXYDw8pqTJRPmIgL+1fiLQ2YwHgYDVR0RBBcwFYETamF0ZXNjaGVyQGdtYWls
25
+ LmNvbTAeBgNVHRIEFzAVgRNqYXRlc2NoZXJAZ21haWwuY29tMA0GCSqGSIb3DQEB
26
+ BQUAA4IBAQBOhrOaKUTe9WSuIdWMT0EwyKa5nuBGOW+TvbZ722RFb1m/t53JrhZk
27
+ e9fcuBPqP3OP4Sm1zuJApG54g4MfVRoH4VSVXIME8SCVix2AA40Wo/kuKkpusk9o
28
+ DI8YB1wuKHvxz5Dp9TqUhW6U0xflFdBIvMxDYW4cBhBCXMNGIORi1vX2IqpMmTB/
29
+ H1OPGmibxwLAMvjJ9zmMX0JTeNl4vrOMwrqntPCN7wifzRWQQjDpr7FlR35P30jd
30
+ g//+Q17/DxaA78vyZM5fABBBpCg/ds7axx7I2n/CG+4WzyGUK2Lgn5kF5aRY3Ugh
31
+ at/y9WkZyjaptzzmD0bwLUxK3brbGZsC
32
+ -----END CERTIFICATE-----
33
+ date: 2014-09-29 00:00:00.000000000 Z
39
34
  dependencies:
40
35
  - !ruby/object:Gem::Dependency
41
36
  name: rspec
42
37
  requirement: !ruby/object:Gem::Requirement
43
38
  requirements:
44
- - - ! '>='
39
+ - - ">="
45
40
  - !ruby/object:Gem::Version
46
41
  version: '0'
47
42
  type: :development
48
43
  prerelease: false
49
44
  version_requirements: !ruby/object:Gem::Requirement
50
45
  requirements:
51
- - - ! '>='
46
+ - - ">="
52
47
  - !ruby/object:Gem::Version
53
48
  version: '0'
54
49
  - !ruby/object:Gem::Dependency
55
50
  name: rake
56
51
  requirement: !ruby/object:Gem::Requirement
57
52
  requirements:
58
- - - ! '>='
53
+ - - ">="
59
54
  - !ruby/object:Gem::Version
60
55
  version: '0'
61
56
  type: :development
62
57
  prerelease: false
63
58
  version_requirements: !ruby/object:Gem::Requirement
64
59
  requirements:
65
- - - ! '>='
60
+ - - ">="
66
61
  - !ruby/object:Gem::Version
67
62
  version: '0'
68
63
  - !ruby/object:Gem::Dependency
69
64
  name: simplecov
70
65
  requirement: !ruby/object:Gem::Requirement
71
66
  requirements:
72
- - - ! '>='
67
+ - - ">="
73
68
  - !ruby/object:Gem::Version
74
69
  version: '0'
75
70
  type: :development
76
71
  prerelease: false
77
72
  version_requirements: !ruby/object:Gem::Requirement
78
73
  requirements:
79
- - - ! '>='
74
+ - - ">="
80
75
  - !ruby/object:Gem::Version
81
76
  version: '0'
82
77
  - !ruby/object:Gem::Dependency
83
78
  name: coveralls
84
79
  requirement: !ruby/object:Gem::Requirement
85
80
  requirements:
86
- - - ! '>='
81
+ - - ">="
87
82
  - !ruby/object:Gem::Version
88
83
  version: '0'
89
84
  type: :development
90
85
  prerelease: false
91
86
  version_requirements: !ruby/object:Gem::Requirement
92
87
  requirements:
93
- - - ! '>='
88
+ - - ">="
94
89
  - !ruby/object:Gem::Version
95
90
  version: '0'
96
91
  - !ruby/object:Gem::Dependency
97
92
  name: mime-types
98
93
  requirement: !ruby/object:Gem::Requirement
99
94
  requirements:
100
- - - ~>
95
+ - - "~>"
101
96
  - !ruby/object:Gem::Version
102
97
  version: 1.25.1
103
98
  type: :development
104
99
  prerelease: false
105
100
  version_requirements: !ruby/object:Gem::Requirement
106
101
  requirements:
107
- - - ~>
102
+ - - "~>"
108
103
  - !ruby/object:Gem::Version
109
104
  version: 1.25.1
110
105
  description: A simple image optimizer
@@ -114,20 +109,23 @@ executables: []
114
109
  extensions: []
115
110
  extra_rdoc_files: []
116
111
  files:
117
- - .gitignore
118
- - .travis.yml
112
+ - ".gitignore"
113
+ - ".travis.yml"
119
114
  - Gemfile
120
115
  - LICENSE.txt
121
116
  - README.md
122
117
  - Rakefile
123
- - gem-public_cert.pem
118
+ - certs/jtescher.pem
124
119
  - image_optimizer.gemspec
125
120
  - lib/image_optimizer.rb
121
+ - lib/image_optimizer/image_optimizer_base.rb
126
122
  - lib/image_optimizer/jpeg_optimizer.rb
127
123
  - lib/image_optimizer/png_optimizer.rb
124
+ - lib/image_optimizer/shell.rb
128
125
  - lib/image_optimizer/version.rb
129
126
  - spec/image_optimizer/jpeg_optimizer_spec.rb
130
127
  - spec/image_optimizer/png_optimizer_spec.rb
128
+ - spec/image_optimizer/shell_spec.rb
131
129
  - spec/image_optimizer/version_spec.rb
132
130
  - spec/image_optimizer_spec.rb
133
131
  - spec/spec_helper.rb
@@ -141,23 +139,24 @@ require_paths:
141
139
  - lib
142
140
  required_ruby_version: !ruby/object:Gem::Requirement
143
141
  requirements:
144
- - - ! '>='
142
+ - - ">="
145
143
  - !ruby/object:Gem::Version
146
144
  version: '0'
147
145
  required_rubygems_version: !ruby/object:Gem::Requirement
148
146
  requirements:
149
- - - ! '>='
147
+ - - ">="
150
148
  - !ruby/object:Gem::Version
151
149
  version: '0'
152
150
  requirements: []
153
151
  rubyforge_project:
154
- rubygems_version: 2.1.11
152
+ rubygems_version: 2.2.1
155
153
  signing_key:
156
154
  specification_version: 4
157
155
  summary: Simply optimize images via jpegoptim or OptiPNG
158
156
  test_files:
159
157
  - spec/image_optimizer/jpeg_optimizer_spec.rb
160
158
  - spec/image_optimizer/png_optimizer_spec.rb
159
+ - spec/image_optimizer/shell_spec.rb
161
160
  - spec/image_optimizer/version_spec.rb
162
161
  - spec/image_optimizer_spec.rb
163
162
  - spec/spec_helper.rb
metadata.gz.sig CHANGED
Binary file
data/gem-public_cert.pem DELETED
@@ -1,19 +0,0 @@
1
- -----BEGIN CERTIFICATE-----
2
- MIIDKjCCAhKgAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQ0wCwYDVQQDDAR5b3Vy
3
- MRUwEwYKCZImiZPyLGQBGRYFZW1haWwxEzARBgoJkiaJk/IsZAEZFgNjb20wHhcN
4
- MTMwNjE0MTkxMjQ4WhcNMTQwNjE0MTkxMjQ4WjA7MQ0wCwYDVQQDDAR5b3VyMRUw
5
- EwYKCZImiZPyLGQBGRYFZW1haWwxEzARBgoJkiaJk/IsZAEZFgNjb20wggEiMA0G
6
- CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9WjvJinWV7h9VeLlf4+yHxr1LF/8/
7
- HHFCKYEs/ZrUJLrpmuUWUrkgpwIbV5FUvqkXoCcCvR2z65lAONZtdvg3ygBBXfl7
8
- rQaNb/EMMzulmf26ztAtUP0Ipaz0pX/qlzDLkDkhXxUB1rUcxuZ2Rif0HsOtQO5d
9
- MzQfREsYDtWMileLxcImCxtoE5r+tG2sbJ72gxP0QygAwL+mke//C0wPVCBC9zI2
10
- fwhZmTD2dmyx0JW8C0YR+38kqtMldCcIQOPRH6ue/JAyfxaosYyNLK5zuUoW1MSR
11
- l1PMWb3fEDXprbnku496f026FAgDn8TFsWDFw+KhHwTgIYASbgopYqWTAgMBAAGj
12
- OTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFM0KCQLMiOjnsL1TEu5IFFRCar4CMAsG
13
- A1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEAscW33q8g0jLkAE8jZnIYjbO3
14
- hhNpSyXO1JmJEbm5q9v5rDqhj8RTbdd100tFwGc2tIViR9edQ8Z72s9gEAdU6N4P
15
- HpoYcNOqET8Fqs+o16lbk74on6Gv9S5LZjBQ1UuIqDbENuTzogxY25Yx5dIGHyIo
16
- 7rzorf4e4KCNFw19BG5M3ijlMvciSGxIPbmJoaSa7m62sudGr3CrEpRgMZBvp1Ea
17
- ILaPiI1PhVurfov2y0+YT0rbOrv4cWoBWsZ+aww2iSNC5XFhA/8xsK0BltYRF9nP
18
- HA41UtDxrJkHL3N1z8gPMXSrFT41FR2wgk8+l14P+7g1UTPid2EIwft2xObFeA==
19
- -----END CERTIFICATE-----