squeezem 0.1
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/LICENSE +19 -0
- data/README +22 -0
- data/bin/squeezem +41 -0
- data/bin/squeezem.rb~ +51 -0
- data/bin/squeezem~ +52 -0
- data/lib/squeezem.rb +120 -0
- data/lib/squeezem.rb~ +2 -0
- metadata +78 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2010 Steve Woodcock
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
List pngs which are bigger than they need to be. Can optionally
|
2
|
+
compress them, but is designed mainly to keep an eye on a tree of
|
3
|
+
images to make sure they stay in good shape.
|
4
|
+
|
5
|
+
Usage
|
6
|
+
|
7
|
+
List files which could benefit from squeezing, suitable for running from cron.
|
8
|
+
|
9
|
+
squeezem .
|
10
|
+
|
11
|
+
Squeeze 'em
|
12
|
+
|
13
|
+
squeezem --squeezem
|
14
|
+
|
15
|
+
Force previously seen files to be reevaluated:
|
16
|
+
|
17
|
+
squeezem --ignore-cache
|
18
|
+
|
19
|
+
Related
|
20
|
+
|
21
|
+
http://github.com/grosser/smusher - does a similar job, but uses
|
22
|
+
online compression services.
|
data/bin/squeezem
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'squeezem'
|
4
|
+
require 'find'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
def parse_options
|
8
|
+
options = OpenStruct.new
|
9
|
+
options.squeezem = false
|
10
|
+
options.ignorecache = false
|
11
|
+
|
12
|
+
opts = OptionParser.new do |opts|
|
13
|
+
opts.banner = <<BANNER
|
14
|
+
List pngs which are bigger than they need to be, and optionally compress them.
|
15
|
+
|
16
|
+
Usage:
|
17
|
+
squeezem .
|
18
|
+
|
19
|
+
Options:
|
20
|
+
BANNER
|
21
|
+
opts.on("-s", "--squeezem", "Squeeze files") { options.squeezem = true }
|
22
|
+
opts.on("-i", "--ignore-cache", "Ignore file cache") { options.ignorecache = true }
|
23
|
+
opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
|
24
|
+
end
|
25
|
+
begin
|
26
|
+
opts.parse!
|
27
|
+
rescue
|
28
|
+
puts opts
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
return options
|
32
|
+
end
|
33
|
+
|
34
|
+
options = parse_options
|
35
|
+
squeezem = Squeezem.new(options)
|
36
|
+
ARGV.each do |file_or_dir|
|
37
|
+
Find.find(file_or_dir) do |path|
|
38
|
+
squeezem.squeeze(path) if File.file?(path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
squeezem.summary
|
data/bin/squeezem.rb~
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Like smusher but uses local tools
|
4
|
+
|
5
|
+
# report mode
|
6
|
+
# pass list of files on stdin
|
7
|
+
# save canonicalised list of files processed + state (can squeeze vs already squeezed)
|
8
|
+
# squeeze mode
|
9
|
+
# handle exception when pngcrush given a jpeg
|
10
|
+
# handle nonempty output_dir at exit
|
11
|
+
# license
|
12
|
+
|
13
|
+
require 'find'
|
14
|
+
require 'open3'
|
15
|
+
require 'tempfile'
|
16
|
+
|
17
|
+
total_bytes = 0
|
18
|
+
saved_bytes = 0
|
19
|
+
output_dir = Dir.mktmpdir
|
20
|
+
at_exit do
|
21
|
+
Dir.rmdir(output_dir)
|
22
|
+
end
|
23
|
+
output_path = File.join(output_dir, 'x')
|
24
|
+
|
25
|
+
$stdin.each_line do |file_or_dir|
|
26
|
+
puts file_or_dir
|
27
|
+
end
|
28
|
+
ARGV.each do |file_or_dir|
|
29
|
+
Find.find(file_or_dir) do |path|
|
30
|
+
next unless path =~ /\.(png)$/
|
31
|
+
original_size = File.size(path)
|
32
|
+
output = ''
|
33
|
+
Open3.popen3('pngcrush', '-quiet', path, output_path) do |stdin, stdout, stderr|
|
34
|
+
output = stdout.read
|
35
|
+
end
|
36
|
+
if File.exist?(output_path)
|
37
|
+
new_size = File.size(output_path)
|
38
|
+
if new_size < original_size
|
39
|
+
total_bytes += original_size
|
40
|
+
saving = original_size - new_size
|
41
|
+
saved_bytes += saving
|
42
|
+
puts "#{path}"
|
43
|
+
end
|
44
|
+
File.unlink(output_path)
|
45
|
+
else
|
46
|
+
puts path, output
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
pct_saved = saved_bytes * 100.0 / total_bytes
|
51
|
+
puts "#{saved_bytes} saved out of #{total_bytes} (%.2f)%" % pct_saved
|
data/bin/squeezem~
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Like smusher but uses local tools
|
4
|
+
|
5
|
+
# report mode
|
6
|
+
# pass list of files on stdin
|
7
|
+
# save canonicalised list of files processed + state (can squeeze vs already squeezed)
|
8
|
+
# squeeze mode
|
9
|
+
# handle exception when pngcrush given a jpeg
|
10
|
+
# handle nonempty output_dir at exit
|
11
|
+
# license
|
12
|
+
|
13
|
+
require 'squeezem'
|
14
|
+
require 'find'
|
15
|
+
require 'open3'
|
16
|
+
require 'tempfile'
|
17
|
+
|
18
|
+
total_bytes = 0
|
19
|
+
saved_bytes = 0
|
20
|
+
output_dir = Dir.mktmpdir
|
21
|
+
at_exit do
|
22
|
+
Dir.rmdir(output_dir)
|
23
|
+
end
|
24
|
+
output_path = File.join(output_dir, 'x')
|
25
|
+
|
26
|
+
$stdin.each_line do |file_or_dir|
|
27
|
+
puts file_or_dir
|
28
|
+
end
|
29
|
+
ARGV.each do |file_or_dir|
|
30
|
+
Find.find(file_or_dir) do |path|
|
31
|
+
next unless path =~ /\.(png)$/
|
32
|
+
original_size = File.size(path)
|
33
|
+
output = ''
|
34
|
+
Open3.popen3('pngcrush', '-quiet', path, output_path) do |stdin, stdout, stderr|
|
35
|
+
output = stdout.read
|
36
|
+
end
|
37
|
+
if File.exist?(output_path)
|
38
|
+
new_size = File.size(output_path)
|
39
|
+
if new_size < original_size
|
40
|
+
total_bytes += original_size
|
41
|
+
saving = original_size - new_size
|
42
|
+
saved_bytes += saving
|
43
|
+
puts "#{path}"
|
44
|
+
end
|
45
|
+
File.unlink(output_path)
|
46
|
+
else
|
47
|
+
puts path, output
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
pct_saved = saved_bytes * 100.0 / total_bytes
|
52
|
+
puts "#{saved_bytes} saved out of #{total_bytes} (%.2f)%" % pct_saved
|
data/lib/squeezem.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'ostruct'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
|
7
|
+
class Squeezem
|
8
|
+
def initialize(options)
|
9
|
+
@options = options
|
10
|
+
@output_path = "/tmp/x"
|
11
|
+
@total_bytes = 0
|
12
|
+
@saved_bytes = 0
|
13
|
+
@files_seen = 0
|
14
|
+
@files_ignored = 0
|
15
|
+
@files_with_saving = 0
|
16
|
+
output_dir = Dir.mktmpdir
|
17
|
+
at_exit do
|
18
|
+
write_cache
|
19
|
+
FileUtils.rm_rf(output_dir)
|
20
|
+
end
|
21
|
+
@output_path = File.join(output_dir, 'x')
|
22
|
+
@files = read_cache
|
23
|
+
@interrupted = false
|
24
|
+
trap("INT") {
|
25
|
+
@interrupted = true
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def squeeze(path)
|
30
|
+
handle_interruption
|
31
|
+
return unless valid_file?(path)
|
32
|
+
@files_seen += 1
|
33
|
+
@path = path
|
34
|
+
@size = File.size(path)
|
35
|
+
canonical_path = File.expand_path(path)
|
36
|
+
unless @options.ignorecache
|
37
|
+
cache = @files[canonical_path]
|
38
|
+
if cache && cache.size == @size
|
39
|
+
unless @options.squeezem && cache.saving > 0
|
40
|
+
record_saving(cache.saving)
|
41
|
+
return
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
output = ''
|
46
|
+
Open3.popen3('pngcrush', '-quiet', '-rem', 'alla', '-reduce', '-brute', path, @output_path) do |stdin, stdout, stderr|
|
47
|
+
output = stdout.read
|
48
|
+
end
|
49
|
+
if File.exist?(@output_path)
|
50
|
+
new_size = File.size(@output_path)
|
51
|
+
saving = @size - new_size
|
52
|
+
record_saving(saving)
|
53
|
+
@files[canonical_path] = OpenStruct.new(:size => @size, :saving => saving)
|
54
|
+
keep_or_remove_output
|
55
|
+
else
|
56
|
+
$stderr.puts "Error processing #{path}:", output
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def handle_interruption
|
61
|
+
if @interrupted
|
62
|
+
summary
|
63
|
+
exit
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def valid_file?(path)
|
68
|
+
if !(path =~ /\.(png)$/)
|
69
|
+
@files_ignored += 1
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
|
75
|
+
def keep_or_remove_output
|
76
|
+
if @options.squeezem
|
77
|
+
FileUtils.mv(@output_path, @path)
|
78
|
+
else
|
79
|
+
File.unlink(@output_path)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def record_saving(saving)
|
84
|
+
if saving > 0
|
85
|
+
@saved_bytes += saving
|
86
|
+
@total_bytes += @size
|
87
|
+
@files_with_saving += 1
|
88
|
+
puts @path
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def summary
|
93
|
+
return unless @files_with_saving > 0
|
94
|
+
if @total_bytes > 0
|
95
|
+
pct_saved = @saved_bytes * 100.0 / @total_bytes
|
96
|
+
else
|
97
|
+
pct_saved = 0
|
98
|
+
end
|
99
|
+
could_save_or_saved = @options.squeezem ? 'saved' : 'could save'
|
100
|
+
puts "#{@files_with_saving} files out of #{@files_seen} #{could_save_or_saved} #{@saved_bytes} out of #{@total_bytes} (%.2f)%%. #{@files_ignored} files ignored." % pct_saved
|
101
|
+
end
|
102
|
+
|
103
|
+
def cache_filename
|
104
|
+
File.expand_path("~/.squeezem-cache")
|
105
|
+
end
|
106
|
+
|
107
|
+
def read_cache
|
108
|
+
begin
|
109
|
+
return Marshal.load(File.read(cache_filename))
|
110
|
+
rescue
|
111
|
+
return {}
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def write_cache
|
116
|
+
File.open(cache_filename, "w") do |f|
|
117
|
+
f.puts Marshal.dump(@files)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/lib/squeezem.rb~
ADDED
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: squeezem
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: "0.1"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Steve Woodcock
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-08-22 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: |-
|
22
|
+
List pngs which are bigger than they need to be. Can optionally
|
23
|
+
compress them, but is designed mainly to keep an eye on a tree of
|
24
|
+
images to make sure they stay in good shape.
|
25
|
+
email:
|
26
|
+
- steve.woodcock@gmail.com
|
27
|
+
executables:
|
28
|
+
- squeezem
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- bin/squeezem
|
35
|
+
- bin/squeezem.rb~
|
36
|
+
- bin/squeezem~
|
37
|
+
- lib/squeezem.rb
|
38
|
+
- lib/squeezem.rb~
|
39
|
+
- LICENSE
|
40
|
+
- README
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/stevewoodcock/squeezem
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 0
|
58
|
+
version: "0"
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
hash: 23
|
65
|
+
segments:
|
66
|
+
- 1
|
67
|
+
- 3
|
68
|
+
- 6
|
69
|
+
version: 1.3.6
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project: squeezem
|
73
|
+
rubygems_version: 1.3.7
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: List pngs which are bigger than they need to be, and optionally compress them
|
77
|
+
test_files: []
|
78
|
+
|