image_optimizer 1.2.1 → 1.3.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 +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-----
|