image_optim_tolerance 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +0 -0
- data/LICENSE +16 -0
- data/README.md +33 -0
- data/VERSION +1 -0
- data/bin/image_optim_tolerance +3 -0
- data/lib/image_optim_tolerance/executor.rb +62 -0
- data/lib/image_optim_tolerance/image_optim_tolerance.rb +90 -0
- data/lib/image_optim_tolerance/version.rb +3 -0
- metadata +67 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cc3fcc0b514deaa80ade949a9ac3d9ba7425eefa
|
4
|
+
data.tar.gz: 20aa1f1e9cb06a616f489f56dcc465146a8056be
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7c7b0ae401482f733fd5cecc3abc023c37222106353e17702cfbd1e5423ffdfd0324138821fb6447ddfc819ef7a45c4d93ad43f724c4c18e8e13d2666c32c3d5
|
7
|
+
data.tar.gz: 468ec21bfd083103f71596e494ec44695c184a415213a67a8ad02c995fc63451632833c18093ad814059112c8328722034e47bc610f3a6e350c13c9511aadc44
|
data/CHANGELOG.md
ADDED
File without changes
|
data/LICENSE
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
ImageOptimTolerance
|
2
|
+
Copyright (c) 2014 LinkedIn Corp. All rights reserved.
|
3
|
+
Apache Software License 2.0
|
4
|
+
|
5
|
+
|
6
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
you may not use this file except in compliance with the License.
|
8
|
+
You may obtain a copy of the License at
|
9
|
+
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
|
12
|
+
Unless required by applicable law or agreed to in writing, software
|
13
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
See the License for the specific language governing permissions and
|
16
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# image\_optim\_tolerance
|
2
|
+
|
3
|
+
Tests that an image is compressed within a specified tolerance. [image_optim](https://github.com/toy/image_optim) does all the heavy lifting.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
### Install the gem
|
8
|
+
|
9
|
+
```sh
|
10
|
+
[sudo] gem install image\_optim\_tolerance
|
11
|
+
```
|
12
|
+
|
13
|
+
Instead of installing the gem directly via the command line, we recommend using [Bundler](http://gembundler.com/) to manage your gem dependencies.
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
```
|
18
|
+
Usage: image\_optim\_tolerance path [, path2 [, pathN]]
|
19
|
+
|
20
|
+
Examples:
|
21
|
+
image\_optim\_tolerance /path/to/image.png /path/to/other/image.jpg
|
22
|
+
image\_optim\_tolerance -t 5 /path/to/image.png /path/to/other/image.jpg
|
23
|
+
|
24
|
+
@options:
|
25
|
+
-t, --tolerance NUMBER the maximum allowed compression tolerance (in percentage)
|
26
|
+
-a, --[no-]aggressive if aggressive, also return the non-failing (acceptable) offenders if there are other offenders
|
27
|
+
-v, --[no-]verbose run verbosely
|
28
|
+
-h, --help shows this help message
|
29
|
+
```
|
30
|
+
|
31
|
+
## Configuration
|
32
|
+
|
33
|
+
See [image_optim](https://github.com/toy/image_optim) for configuration options. e.g. use a `.image_optim.yml` file.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.3
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
require "#{File.join(File.dirname(__FILE__), 'image_optim_tolerance')}"
|
4
|
+
|
5
|
+
# allow ImageOptim.app path to be discoverable if it exists
|
6
|
+
image_optim_app_path = '/Applications/ImageOptim.app/Contents/MacOS'
|
7
|
+
ENV['PATH'] = "#{image_optim_app_path}:#{ENV['PATH']}" if File.exist?(image_optim_app_path)
|
8
|
+
|
9
|
+
# defaults
|
10
|
+
options = {}
|
11
|
+
|
12
|
+
opts = OptionParser.new do |opts|
|
13
|
+
opts.banner = "Tests that an image is compressed within a specified tolerance\n\n"
|
14
|
+
opts.define_head "Usage: image_optim_tolerance path [, path2 [, pathN]]"
|
15
|
+
opts.separator ""
|
16
|
+
opts.separator "Examples:"
|
17
|
+
opts.separator " image_optim_tolerance /path/to/image.png /path/to/other/image.jpg"
|
18
|
+
opts.separator " image_optim_tolerance -t 5 /path/to/image.png /path/to/other/image.jpg"
|
19
|
+
opts.separator ""
|
20
|
+
opts.separator "@options:"
|
21
|
+
|
22
|
+
opts.on('-t', '--tolerance NUMBER', Float, 'the maximum allowed compression tolerance (in percentage)') do |v|
|
23
|
+
options[:tolerance] = v
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on("-a", "--[no-]aggressive", "if aggressive, also return the non-failing (acceptable) offenders if there are other offenders") do |v|
|
27
|
+
options[:aggressive] = v
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("-v", "--[no-]verbose", "run verbosely") do |v|
|
31
|
+
options[:verbose] = v
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on('-h', '--help', 'shows this help message') do
|
35
|
+
puts opts
|
36
|
+
exit
|
37
|
+
end
|
38
|
+
end
|
39
|
+
opts.parse!
|
40
|
+
|
41
|
+
if not ARGV.empty?
|
42
|
+
image_optim_tolerance = ImageOptimTolerance.new(options)
|
43
|
+
offenders = image_optim_tolerance.offenders(ARGV)
|
44
|
+
if offenders && offenders.count > 0
|
45
|
+
$stderr << <<-TEXT.gsub(/^\s*\|/, '')
|
46
|
+
|the following images are not optimized:
|
47
|
+
|
|
48
|
+
| #{offenders.join("\n ")}
|
49
|
+
|
|
50
|
+
|FAILED
|
51
|
+
TEXT
|
52
|
+
exit 1
|
53
|
+
else
|
54
|
+
puts "PASSED"
|
55
|
+
exit 0
|
56
|
+
end
|
57
|
+
else
|
58
|
+
puts opts
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
exit
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'image_optim'
|
3
|
+
|
4
|
+
class ImageOptimTolerance
|
5
|
+
|
6
|
+
attr_accessor :options
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
self.options = DEFAULTS.merge(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def is_valid_image(path)
|
13
|
+
return false if path.nil? or path.empty?
|
14
|
+
valid_pattern = /.*\.(gif|png|jpeg|jpg|svg)$/
|
15
|
+
return ((valid_pattern =~ path.to_s.strip) && File.exist?(path))
|
16
|
+
end
|
17
|
+
|
18
|
+
def log(msg, type = nil)
|
19
|
+
if self.options[:verbose]
|
20
|
+
puts (type && MARKS[type]) ? " #{MARKS[type]} #{msg}" : msg
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def offenders(paths)
|
25
|
+
offenders = {
|
26
|
+
:terrible => [],
|
27
|
+
:acceptable => []
|
28
|
+
}
|
29
|
+
paths = [paths] if paths.is_a?(String)
|
30
|
+
paths.each do |path|
|
31
|
+
if self.is_valid_image(path)
|
32
|
+
self.log "checking optimization of #{path}..."
|
33
|
+
optimized = image_optim.optimize_image(path)
|
34
|
+
if optimized
|
35
|
+
size = {}
|
36
|
+
size[:original] = File.size(path)
|
37
|
+
size[:optimized] = File.size?(optimized) || size[:original]
|
38
|
+
size[:saved] = size[:original] - size[:optimized]
|
39
|
+
size[:percentage] = size[:saved].to_f / size[:original].to_f * 100
|
40
|
+
|
41
|
+
if size[:saved] > 0
|
42
|
+
self.log "could have saved #{size[:saved]} bytes (#{size[:percentage].ceil}%)!", :sad
|
43
|
+
if size[:percentage] > self.options[:tolerance]
|
44
|
+
self.log "exceeds tolerance threshold by #{(size[:percentage] - self.options[:tolerance]).ceil}%", :bad
|
45
|
+
offenders[:terrible] << path
|
46
|
+
else
|
47
|
+
offenders[:acceptable] << path
|
48
|
+
self.log "within acceptable tolerance", :good
|
49
|
+
end
|
50
|
+
next
|
51
|
+
end
|
52
|
+
else
|
53
|
+
self.log "nothing to see here", :happy
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# if there are terrible offenders that are above the threshold
|
59
|
+
if offenders[:terrible].count > 0
|
60
|
+
# return both the terrible and acceptable, if we're being aggressive
|
61
|
+
return offenders[:terrible] + offenders[:acceptable] if self.options[:aggressive]
|
62
|
+
return offenders[:terrible]
|
63
|
+
end
|
64
|
+
|
65
|
+
return nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def verify(paths)
|
69
|
+
return self.offenders(paths).nil?
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
MARKS = {
|
74
|
+
# Ruby < 1.9 has bad unicode support, so we're doing it this way
|
75
|
+
:good => ['2714'.to_i(16)].pack('U*'),
|
76
|
+
:bad => ['2717'.to_i(16)].pack('U*'),
|
77
|
+
:happy => ['263A'.to_i(16)].pack('U*'),
|
78
|
+
:sad => ['2639'.to_i(16)].pack('U*')
|
79
|
+
}
|
80
|
+
|
81
|
+
DEFAULTS = {
|
82
|
+
:tolerance => 0,
|
83
|
+
:aggressive => true,
|
84
|
+
:verbose => false
|
85
|
+
}
|
86
|
+
|
87
|
+
def image_optim
|
88
|
+
@image_optim ||= ImageOptim.new()
|
89
|
+
end
|
90
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: image_optim_tolerance
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eugene ONeill
|
8
|
+
- LinkedIn
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-04-08 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: image_optim
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.12'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0.12'
|
28
|
+
description: verifies that images are within an acceptable compression tolerance
|
29
|
+
email: oneill.eugene@gmail.com
|
30
|
+
executables:
|
31
|
+
- image_optim_tolerance
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- CHANGELOG.md
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
38
|
+
- VERSION
|
39
|
+
- bin/image_optim_tolerance
|
40
|
+
- lib/image_optim_tolerance/executor.rb
|
41
|
+
- lib/image_optim_tolerance/image_optim_tolerance.rb
|
42
|
+
- lib/image_optim_tolerance/version.rb
|
43
|
+
homepage:
|
44
|
+
licenses:
|
45
|
+
- Apache License (2.0)
|
46
|
+
metadata: {}
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 2.2.2
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: verifies that images are within an acceptable compression tolerance
|
67
|
+
test_files: []
|