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 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,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "#{File.join(File.dirname(__FILE__), '..', 'lib/image_optim_tolerance/executor')}"
@@ -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
@@ -0,0 +1,3 @@
1
+ module ImageOptimTolerance
2
+ VERSION = File.read(File.join(File.dirname(__FILE__), "..", "..", "VERSION")).strip
3
+ 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: []