require 'rubygems'
# 0.9.0だとエラーが出るので
gem 'mechanize', '= 0.8.5'
require 'mechanize'
# log表示用テキストの準備
$message = {
'{js,css}' => 'Javascripts & css compressed by YUIcompressor.',
'gif' => 'gif images optimized by gifsicle.',
'png' => 'png images optimized by pngcrush.',
'{jpg,jpeg}' => 'jpeg images optimized by jpegoptim.'
}
# 圧縮を行う
def do_compress(dir, file_type)
if Dir.glob('./'+dir+'/**/*.' + file_type).length > 0
puts $message[file_type]
puts '--------------------------------------------------------------------'
Dir.glob('./'+dir+'/**/*.' + file_type).each{ |i|
# 比較用の圧縮前サイズを取得
size_before = File::stat(i).size.to_s
# ファイルタイプごとに処理
case file_type
when '{js,css}'
system('java -jar yuicompressor.jar -o '+i+' '+i+' > /dev/null')
when '{jpg,jpeg}'
system('jpegoptim -f -o --strip-all ' + i + ' > /dev/null')
when 'gif'
system('gifsicle -O2 ' + i + '>> dest.gif')
File.delete(i)
File.rename('dest.gif', i)
when 'png'
system('pngcrush -rem alla -brute -reduce ' + i + ' dest.png' + ' > /dev/null')
File.delete(i)
File.rename('dest.png', i)
else
puts 'unknown file type...'
end
# 比較用の圧縮後サイズを取得
size_after = File::stat(i).size.to_s
# 取得したサイズから圧縮率を算出
comp_rate = ((size_after.to_f/size_before.to_f)*100).floor.to_s
# 圧縮率100%だったら圧縮済み
(comp_rate == '100')?(comp_rate = 'same size. already compressed ?'):(comp_rate = 'compressed to ' + comp_rate + '%')
# 圧縮log出力
puts File.basename(i) + "\t" + size_before + " byte\t=>\t" + size_after + " byte\t" + comp_rate
}
puts
end
end
# 圧縮前準備
def compressor(url)
# エスケープ
url = URI.escape(url)
# 不正なURLかどうか
return 'Failed! "' + url + '" is invalid URL...' unless url =~ URI.regexp
puts 'target : ' + url + "\n"
# mechanizeの準備
agent = WWW::Mechanize.new
# ページを取得
begin
page = agent.get(url)
rescue
# ページ取得に失敗した場合
puts '
Failed! This URL cannot be solved...'
return
end
# 作業用ディレクトリ unixタイムスタンプ
dir = DateTime.now.strftime('%s')
# ページ内で読み込まれているjs,css,画像を全て取得
files = []
page.root.search('script').each{ |js| files << js[:src] if js[:src] =~ /\.js\??.*/i }
page.root.search('link').each{ |css| files << css[:href] if css[:href] =~ /\.css\??.*/i && css[:type] == 'text/css' }
page.root.search('img').each{ |img| files << img[:src] if img[:src] =~ /\.(jpeg|jpg|png|gif)/i && files.index(img[:src]) == nil }
# filesが空なら失敗
unless files.length > 0
puts '
Failed! There are neither a script nor an image in this URL...'
return
end
# ファイル取得
files.each{ |f|
if f
# フレームワークなどで付加されるtimestampを除去
f.sub!(/\?(.*)/, "")
if f =~ URI.regexp
# 絶対パスならそのまま
src_url = f
else
# 相対パスならURLの生成
u = URI.parse(url)
src_url = URI.join(u.scheme + '://' + u.host, u.path, f).to_s
end
# 拡張子でフォルダ分けする
ext = File.extname(f).sub(/^\./, "").downcase
# スクリプトか画像か判定
type = (ext=~/js|css/)?(ext):('img')
# ダウンロードして保存
system('wget -q --directory-prefix=./' + dir + '/' + type + ' ' + src_url + ' > /dev/null') if src_url != nil
end
}
# 全体圧縮率保存用
total_before = 0
total_after = 0
# 圧縮前サイズ計測
Dir.glob('./'+dir+'/**/*.{js,css,gif,png,jpg,jpeg}').each{ |i|
total_before += File::stat(i).size
}
# 圧縮
do_compress(dir, '{js,css}')
do_compress(dir, 'gif')
do_compress(dir, 'png')
do_compress(dir, '{jpg,jpeg}')
# 圧縮後サイズ計測
Dir.glob('./'+dir+'/**/*.{js,css,gif,png,jpg,jpeg}').each{ |i|
total_after += File::stat(i).size
}
puts '--------------------------------------------------------------------'
# 全体圧縮率の算出
total_comp_rate = (total_after.to_f/total_before.to_f*100).floor.to_s
# 100%かどうか
(total_comp_rate == '100')?(total_comp_rate = 'same size. already compressed ?'):(total_comp_rate = 'compressed to ' + total_comp_rate + '%')
puts "Total size :\t" + total_before.to_s + " byte\t=>\t" + total_after.to_s + " byte\t" + total_comp_rate + "\n"
# zipアーカイブ化
system('zip -r ./'+dir+' ./'+dir+'.zip '+dir+'/ > /dev/null')
# 作業用ディレクトリ削除
system('rm -r ./'+dir) if File.directory?(dir)
return dir
end