Class: Squeezem

Inherits:
Object
  • Object
show all
Defined in:
lib/squeezem.rb

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Squeezem

Returns a new instance of Squeezem.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/squeezem.rb', line 8

def initialize(options)
  @options = options
  find_helpers
  @total_bytes = 0
  @saved_bytes = 0
  @files_seen = 0
  @files_ignored = 0
  @files_with_saving = 0
  output_dir = make_output_dir
  at_exit do
    write_cache
    FileUtils.rm_rf(output_dir)
  end
  @output_path = File.join(output_dir, 'x')
  @files = read_cache
  trap("INT") {
    summary
    exit
  }
end

Instance Method Details

#cache_filenameObject



173
174
175
# File 'lib/squeezem.rb', line 173

def cache_filename
  File.expand_path("~/.squeezem-cache")
end

#command_exists?(command) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
# File 'lib/squeezem.rb', line 39

def command_exists?(command)
  system("which #{command} >/dev/null 2>/dev/null")
  return false if $?.exitstatus == 127
  return true
end

#find_helpersObject



29
30
31
32
33
34
35
36
37
# File 'lib/squeezem.rb', line 29

def find_helpers
  @helpers = {}
  @helpers[:png] = 1 if command_exists?("pngcrush")
  @helpers[:jpg] = 1 if command_exists?("jpegtran")
  if @helpers.size == 0
    $stderr.puts "Can't find any helpers - please install at least one of pngcrush or jpegtran!"
    exit 1
  end
end

#get_file_type(path) ⇒ Object



109
110
111
112
113
114
115
116
# File 'lib/squeezem.rb', line 109

def get_file_type(path)
  extension = File.extname(path).sub('.', '')
  if extension.empty?
    return nil
  else
    return extension.to_sym
  end
end

#keep_or_remove_outputObject



145
146
147
148
149
150
151
# File 'lib/squeezem.rb', line 145

def keep_or_remove_output
  if @options.squeezem
    FileUtils.mv(@output_path, @path)
  else
    File.unlink(@output_path)
  end
end

#log(message) ⇒ Object



191
192
193
# File 'lib/squeezem.rb', line 191

def log(message)
  puts message if @options.verbose
end

#make_output_dirObject



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/squeezem.rb', line 45

def make_output_dir
  begin
    Dir.mktmpdir
  rescue NoMethodError
    # Lame fallback for 1.8.6-p369 and below
    dir = Dir.tmpdir + "/squeezem-#{$$}"
    Dir.mkdir(dir)
    FileUtils.chmod(0700, dir)
    return dir
  end
end

#process_file(path, file_type) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/squeezem.rb', line 122

def process_file(path, file_type)
  output = ''
  case file_type
  when :png
    cmd = ['pngcrush', '-quiet', '-rem', 'allb', path, @output_path]
    log("Calling #{cmd.join(' ')}")
    Open3.popen3(*cmd) do |stdin, stdout, stderr|
      output = stdout.read
      output += stderr.read
    end
  when :jpg
    File.open(@output_path, "w") do |out|
      cmd = ['jpegtran', '-copy', 'none', '-optimize', '-perfect', path]
      log("Calling #{cmd.join(' ')}")
      Open3.popen3(*cmd) do |stdin, stdout, stderr|
        out.write(stdout.read)
        output = stderr.read
      end
    end
  end
  return output
end

#read_cacheObject



177
178
179
180
181
182
183
# File 'lib/squeezem.rb', line 177

def read_cache
  begin
    return Marshal.load(File.read(cache_filename))
  rescue
    return {}
  end
end

#record_saving(saving) ⇒ Object



153
154
155
156
157
158
159
160
# File 'lib/squeezem.rb', line 153

def record_saving(saving)
  if saving > 0
    @saved_bytes += saving
    @total_bytes += @size
    @files_with_saving += 1
    puts @path
  end
end

#report_error(path, output) ⇒ Object



104
105
106
107
# File 'lib/squeezem.rb', line 104

def report_error(path, output)
  $stderr.print "Error processing #{path}"
  $stderr.puts ": #{output}" if output
end

#squeeze(path) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/squeezem.rb', line 57

def squeeze(path)
  log("Considering #{path}")
  file_type = get_file_type(path)
  unless valid_file_type?(file_type)
    log("Ignoring, #{file_type} not a valid file type")
    @files_ignored += 1
    return
  end
  @files_seen += 1
  @path = path
  @size = File.size(path)
  log("File size #{@size}")
  canonical_path = File.expand_path(path)
  unless @options.ignorecache
    cache = @files[canonical_path]
    log("Read cache #{cache}")
    if cache && cache.size == @size
      unless @options.squeezem && cache.saving > 0
        log("Skipping file, already processed")
        record_saving(cache.saving)
        return
      end
    end
  end
  output = process_file(path, file_type)
  if File.exist?(@output_path)
    new_size = File.size(@output_path)
    if new_size == 0
      report_error(path, output)
      return
    end
    saving = @size - new_size
    record_saving(saving)
    keep_or_remove_output
    if @options.squeezem
      cache_saving = 0
      cache_size = new_size
    else
      cache_saving = saving
      cache_size = @size
    end
    @files[canonical_path] = OpenStruct.new(:size => cache_size, :saving => cache_saving)
  else
    report_error(path, output)
  end
end

#summaryObject



162
163
164
165
166
167
168
169
170
171
# File 'lib/squeezem.rb', line 162

def summary
  return unless @files_with_saving > 0
  if @total_bytes > 0
    pct_saved = @saved_bytes * 100.0 / @total_bytes
  else
    pct_saved = 0
  end
  could_save_or_saved = @options.squeezem ? 'saved' : 'could save'
  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
end

#valid_file_type?(type) ⇒ Boolean

Returns:

  • (Boolean)


118
119
120
# File 'lib/squeezem.rb', line 118

def valid_file_type?(type)
  @helpers[type]
end

#write_cacheObject



185
186
187
188
189
# File 'lib/squeezem.rb', line 185

def write_cache
  File.open(cache_filename, "w") do |f|
    f.puts Marshal.dump(@files)
  end
end