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 +5 -13
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +13 -0
- data/certs/jtescher.pem +21 -0
- data/image_optimizer.gemspec +1 -1
- data/lib/image_optimizer.rb +35 -1
- data/lib/image_optimizer/image_optimizer_base.rb +44 -0
- data/lib/image_optimizer/jpeg_optimizer.rb +9 -33
- data/lib/image_optimizer/png_optimizer.rb +9 -33
- data/lib/image_optimizer/shell.rb +36 -0
- data/lib/image_optimizer/version.rb +1 -1
- data/spec/image_optimizer/jpeg_optimizer_spec.rb +57 -32
- data/spec/image_optimizer/png_optimizer_spec.rb +43 -21
- data/spec/image_optimizer/shell_spec.rb +25 -0
- data/spec/image_optimizer/version_spec.rb +1 -1
- data/spec/image_optimizer_spec.rb +121 -3
- metadata +44 -45
- metadata.gz.sig +0 -0
- data/gem-public_cert.pem +0 -19
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ODc5MzY0MzA4NjY2YTgzZTYzZDUzZTA2MDBmMzBmY2Q2OGZhZGVkMA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 970982e519567a730a3feb024bbed88cfbb837b6
|
4
|
+
data.tar.gz: 92198c8d8fbaa3ce8caa6ef2e270f6872a7b1829
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
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
|
|
data/certs/jtescher.pem
ADDED
@@ -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-----
|
data/image_optimizer.gemspec
CHANGED
@@ -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 = ['
|
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) }
|
data/lib/image_optimizer.rb
CHANGED
@@ -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
|
-
|
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
|
50
|
-
|
21
|
+
def extensions
|
22
|
+
%w[jpeg jpg]
|
23
|
+
end
|
24
|
+
|
25
|
+
def type
|
26
|
+
'jpeg'
|
51
27
|
end
|
52
28
|
|
53
|
-
def
|
54
|
-
|
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
|
45
|
-
|
16
|
+
def type
|
17
|
+
'png'
|
18
|
+
end
|
19
|
+
|
20
|
+
def extensions
|
21
|
+
%w[png gif]
|
46
22
|
end
|
47
23
|
|
48
|
-
def
|
49
|
-
|
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
|
@@ -2,43 +2,68 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe ImageOptimizer::JPEGOptimizer do
|
4
4
|
describe '#optimize' do
|
5
|
-
let(:
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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(:
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
@@ -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.
|
7
|
-
ImageOptimizer::PNGOptimizer.
|
8
|
-
|
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.
|
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
|
-
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
-
-
|
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
|
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-----
|