# -*- coding: utf-8 -*- # frozen_string_literal: true # # from http://d.hatena.ne.jp/alunko/20071021 # require 'kconv' require 'zip/filesystem' require 'fileutils' module ZipFileUtils # src file or directory # dest zip filename # options :fs_encoding=[UTF-8,Shift_JIS,EUC-JP] def self.zip(src, dest, options = {}) src = File.expand_path(src) dest = File.expand_path(dest) FileUtils.rm_f(dest) Zip::File.open(dest, Zip::File::CREATE) do |zf| if File.file?(src) zf.add(encode_path(File.basename(src), options[:fs_encoding]), src) break else each_dir_for(src) do |path| if File.file?(path) zf.add(encode_path(relative(path, src), options[:fs_encoding]), path) elsif File.directory?(path) zf.mkdir(encode_path(relative(path, src), options[:fs_encoding])) end end end end FileUtils.chmod(0o644, dest) end # src zip filename # dest destination directory # options :fs_encoding=[UTF-8,Shift_JIS,EUC-JP] def self.unzip(src, dest, options = {}) FileUtils.makedirs(dest) Zip::InputStream.open(src) do |is| loop do entry = is.get_next_entry break unless entry dir = File.dirname(entry.name) FileUtils.makedirs(dest + '/' + dir) path = encode_path(dest + '/' + entry.name, options[:fs_encoding]) if entry.file? File.open(path, File::CREAT | File::WRONLY | File::BINARY) do |w| w.puts(is.read) end else FileUtils.makedirs(path) end end end end def self.each_dir_for(dir_path, &block) each_file_for(dir_path, &block) end def self.each_file_for(path, &block) if File.file?(path) yield(path) return true end dir = Dir.open(path) file_exist = false dir.each do |file| next if ['.', '..'].include?(file) file_exist = true if each_file_for(path + "/" + file, &block) end yield(path) unless file_exist file_exist end def self.relative(path, base_dir) path[base_dir.length + 1..path.length] if path.index(base_dir) == 0 end def self.encode_path(path, encode_s) return path unless encode_s case encode_s when 'UTF-8' path.toutf8 when 'Shift_JIS' path.tosjis when 'EUC-JP' path.toeuc else path end end end