image_optim 0.1.0 → 0.2.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.
- data/image_optim.gemspec +2 -2
- data/lib/image_optim/worker.rb +2 -7
- data/lib/image_optim.rb +22 -7
- data/spec/image_optim_spec.rb +48 -2
- metadata +7 -7
data/image_optim.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'image_optim'
|
5
|
-
s.version = '0.
|
5
|
+
s.version = '0.2.0'
|
6
6
|
s.summary = %q{Optimize images (jpeg, png, gif) using external utilities (advpng, gifsicle, jpegoptim, jpegtran, optipng, pngcrush, pngout)}
|
7
7
|
s.homepage = "http://github.com/toy/#{s.name}"
|
8
8
|
s.authors = ['Ivan Kuchin']
|
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
16
|
s.require_paths = %w[lib]
|
17
17
|
|
18
|
-
s.add_dependency 'fspath', '~> 2.0.
|
18
|
+
s.add_dependency 'fspath', '~> 2.0.3'
|
19
19
|
s.add_dependency 'image_size', '~> 1.0.4'
|
20
20
|
s.add_dependency 'progress', '~> 2.4.0'
|
21
21
|
s.add_dependency 'in_threads', '~> 1.1.1'
|
data/lib/image_optim/worker.rb
CHANGED
@@ -44,13 +44,8 @@ class ImageOptim
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# Optimize file, return new path or nil if optimization failed
|
47
|
-
def optimize(src)
|
48
|
-
dst
|
49
|
-
if Util.run bin, *command_args(src, dst)
|
50
|
-
if dst.size? && dst.size < src.size
|
51
|
-
dst
|
52
|
-
end
|
53
|
-
end
|
47
|
+
def optimize(src, dst)
|
48
|
+
Util.run(bin, *command_args(src, dst)) && dst.size? && dst.size < src.size
|
54
49
|
end
|
55
50
|
|
56
51
|
# Name of binary determined from class name
|
data/lib/image_optim.rb
CHANGED
@@ -43,11 +43,11 @@ class ImageOptim
|
|
43
43
|
end
|
44
44
|
worker = klass.new(worker_options)
|
45
45
|
klass.image_formats.each do |format|
|
46
|
-
workers_by_format[format] ||= []
|
47
|
-
workers_by_format[format] << worker
|
46
|
+
@workers_by_format[format] ||= []
|
47
|
+
@workers_by_format[format] << worker
|
48
48
|
end
|
49
49
|
end
|
50
|
-
workers_by_format.each do |format, workers|
|
50
|
+
@workers_by_format.each do |format, workers|
|
51
51
|
workers.replace workers.sort_by(&:run_priority)
|
52
52
|
end
|
53
53
|
|
@@ -64,14 +64,29 @@ class ImageOptim
|
|
64
64
|
assert_options_empty!(options)
|
65
65
|
end
|
66
66
|
|
67
|
+
# Get workers for image
|
68
|
+
def workers_for_image(path)
|
69
|
+
@workers_by_format[ImagePath.new(path).format]
|
70
|
+
end
|
71
|
+
|
67
72
|
# Optimize one file, return new path or nil if optimization failed
|
68
73
|
def optimize_image(original)
|
69
74
|
original = ImagePath.new(original)
|
70
|
-
if workers =
|
71
|
-
result =
|
72
|
-
|
75
|
+
if workers = workers_for_image(original)
|
76
|
+
result = nil
|
77
|
+
ts = [original, original.temp_path]
|
78
|
+
workers.each do |worker|
|
79
|
+
if result && ts.length < 3
|
80
|
+
ts << original.temp_path
|
81
|
+
end
|
82
|
+
if worker.optimize(*ts.last(2))
|
83
|
+
result = ts.last
|
84
|
+
if ts.length == 3
|
85
|
+
ts[-2, 2] = ts[-1], ts[-2]
|
86
|
+
end
|
87
|
+
end
|
73
88
|
end
|
74
|
-
result
|
89
|
+
result
|
75
90
|
end
|
76
91
|
end
|
77
92
|
|
data/spec/image_optim_spec.rb
CHANGED
@@ -17,26 +17,68 @@ def temp_copy_path(original)
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
Tempfile.class_eval do
|
21
|
+
alias_method :initialize_orig, :initialize
|
22
|
+
|
23
|
+
def initialize(*args, &block)
|
24
|
+
self.class.initialize_called
|
25
|
+
initialize_orig(*args, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.initialize_called
|
29
|
+
@@call_count ||= 0
|
30
|
+
@@call_count += 1
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.reset_call_count
|
34
|
+
@@call_count = 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.call_count
|
38
|
+
@@call_count
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
Fixnum.class_eval do
|
43
|
+
def in_range?(range)
|
44
|
+
range.include?(self)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
20
48
|
describe ImageOptim do
|
21
49
|
image_dir.glob('*') do |original|
|
22
50
|
describe "optimizing #{original}" do
|
23
51
|
it "should optimize image" do
|
24
52
|
temp_copy_path(original) do |unoptimized|
|
25
|
-
|
53
|
+
Tempfile.reset_call_count
|
54
|
+
io = ImageOptim.new
|
55
|
+
optimized = io.optimize_image(unoptimized)
|
26
56
|
optimized.should be_a(FSPath)
|
27
57
|
unoptimized.read.should == original.read
|
28
58
|
optimized.size.should > 0
|
29
59
|
optimized.size.should < unoptimized.size
|
30
60
|
optimized.read.should_not == unoptimized.read
|
61
|
+
if io.workers_for_image(unoptimized).length > 1
|
62
|
+
Tempfile.call_count.should be_in_range(1..2)
|
63
|
+
else
|
64
|
+
Tempfile.call_count.should === 1
|
65
|
+
end
|
31
66
|
end
|
32
67
|
end
|
33
68
|
|
34
69
|
it "should optimize image in place" do
|
35
70
|
temp_copy_path(original) do |path|
|
36
|
-
|
71
|
+
Tempfile.reset_call_count
|
72
|
+
io = ImageOptim.new
|
73
|
+
io.optimize_image!(path).should be_true
|
37
74
|
path.size.should > 0
|
38
75
|
path.size.should < original.size
|
39
76
|
path.read.should_not == original.read
|
77
|
+
if io.workers_for_image(path).length > 1
|
78
|
+
Tempfile.call_count.should be_in_range(2..3)
|
79
|
+
else
|
80
|
+
Tempfile.call_count.should === 2
|
81
|
+
end
|
40
82
|
end
|
41
83
|
end
|
42
84
|
|
@@ -58,7 +100,9 @@ describe ImageOptim do
|
|
58
100
|
|
59
101
|
it "should ignore" do
|
60
102
|
temp_copy_path(original) do |unoptimized|
|
103
|
+
Tempfile.reset_call_count
|
61
104
|
optimized = ImageOptim.optimize_image(unoptimized)
|
105
|
+
Tempfile.call_count.should == 0
|
62
106
|
optimized.should be_nil
|
63
107
|
unoptimized.read.should == original.read
|
64
108
|
end
|
@@ -66,7 +110,9 @@ describe ImageOptim do
|
|
66
110
|
|
67
111
|
it "should ignore in place" do
|
68
112
|
temp_copy_path(original) do |unoptimized|
|
113
|
+
Tempfile.reset_call_count
|
69
114
|
ImageOptim.optimize_image!(unoptimized).should_not be_true
|
115
|
+
Tempfile.call_count.should == 0
|
70
116
|
unoptimized.read.should == original.read
|
71
117
|
end
|
72
118
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_optim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ivan Kuchin
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-01-
|
18
|
+
date: 2012-01-10 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: fspath
|
@@ -25,12 +25,12 @@ dependencies:
|
|
25
25
|
requirements:
|
26
26
|
- - ~>
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
hash:
|
28
|
+
hash: 9
|
29
29
|
segments:
|
30
30
|
- 2
|
31
31
|
- 0
|
32
|
-
-
|
33
|
-
version: 2.0.
|
32
|
+
- 3
|
33
|
+
version: 2.0.3
|
34
34
|
type: :runtime
|
35
35
|
version_requirements: *id001
|
36
36
|
- !ruby/object:Gem::Dependency
|