Class: Sprout::ArchiveUnpacker
- Inherits:
-
Object
- Object
- Sprout::ArchiveUnpacker
- Includes:
- Archive::Tar
- Defined in:
- lib/sprout/archive_unpacker.rb
Overview
Unpack downloaded files from a variety of common archive types. This library should efficiently extract archived files on OS X, Win XP, Vista, DOS, Cygwin, and Linux.
It will attempt to infer the archive type by standard mime-type file extensions, but if there is a file with no extension, the unpack_archive method can be provided with an @archive_type symbol argument that is one of the following values:
:exe
:zip
:targz
:gzip
:swc
:rb
:dmg
Instance Method Summary collapse
- #inferred_archive_type(file_name) ⇒ Object
- #is_dmg?(file) ⇒ Boolean
- #is_exe?(file) ⇒ Boolean
- #is_gzip?(file) ⇒ Boolean
- #is_rb?(file) ⇒ Boolean
- #is_swc?(file) ⇒ Boolean
- #is_targz?(file) ⇒ Boolean
- #is_zip?(file) ⇒ Boolean
- #suffix_for_archive_type(type) ⇒ Object
- #unpack_archive(file_name, dir, force = false, archive_type = nil) ⇒ Object
-
#unpack_dmg(dmg_file, dir) ⇒ Object
This is actually not unpacking the FlashPlayer Binary file as expected…
- #unpack_tar_zip(tgz_file, dir, ext) ⇒ Object
- #unpack_targz(tgz_file, dir) ⇒ Object
- #unpack_tbz2(tgz_file, dir) ⇒ Object
- #unpack_zip(zip_file, dir) ⇒ Object
- #unpacked_file_name(file, dir, suffix = nil) ⇒ Object
Instance Method Details
#inferred_archive_type(file_name) ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/sprout/archive_unpacker.rb', line 184 def inferred_archive_type(file_name) if is_zip?(file_name) return :zip elsif is_targz?(file_name) return :targz elsif is_gzip?(file_name) return :gz elsif is_swc?(file_name) return :swc elsif is_rb?(file_name) return :rb elsif is_dmg?(file_name) return :dmg elsif is_exe?(file_name) return :exe else return nil end end |
#is_dmg?(file) ⇒ Boolean
227 228 229 |
# File 'lib/sprout/archive_unpacker.rb', line 227 def is_dmg?(file) return (file.split('.').pop == 'dmg') end |
#is_exe?(file) ⇒ Boolean
231 232 233 |
# File 'lib/sprout/archive_unpacker.rb', line 231 def is_exe?(file) return (file.split('.').pop == 'exe') end |
#is_gzip?(file) ⇒ Boolean
215 216 217 |
# File 'lib/sprout/archive_unpacker.rb', line 215 def is_gzip?(file) return (file.split('.').pop == 'gz') end |
#is_rb?(file) ⇒ Boolean
223 224 225 |
# File 'lib/sprout/archive_unpacker.rb', line 223 def is_rb?(file) return (file.split('.').pop == 'rb') end |
#is_swc?(file) ⇒ Boolean
219 220 221 |
# File 'lib/sprout/archive_unpacker.rb', line 219 def is_swc?(file) return (file.split('.').pop == 'swc') end |
#is_targz?(file) ⇒ Boolean
209 210 211 212 213 |
# File 'lib/sprout/archive_unpacker.rb', line 209 def is_targz?(file) parts = file.split('.') part = parts.pop return (part == 'tgz' || part == 'gz' && parts.pop == 'tar') end |
#is_zip?(file) ⇒ Boolean
205 206 207 |
# File 'lib/sprout/archive_unpacker.rb', line 205 def is_zip?(file) return (file.split('.').pop == 'zip') end |
#suffix_for_archive_type(type) ⇒ Object
176 177 178 179 180 181 182 |
# File 'lib/sprout/archive_unpacker.rb', line 176 def suffix_for_archive_type(type) if(type == :targz) return '.tar.gz' else return ".#{type.to_s}" end end |
#unpack_archive(file_name, dir, force = false, archive_type = nil) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/sprout/archive_unpacker.rb', line 24 def unpack_archive(file_name, dir, force=false, archive_type=nil) archive_type ||= inferred_archive_type(file_name) suffix = suffix_for_archive_type(archive_type) unpacked = unpacked_file_name(file_name, dir, suffix) if(File.exists?(unpacked) && force) FileUtils.rm_rf(unpacked) end if(!File.exists?(unpacked)) case archive_type.to_s when 'zip' unpack_zip(file_name, dir) when 'targz' unpack_targz(file_name, dir) when 'tbz2' unpack_tbz2(file_name, dir) when 'dmg' unpack_dmg(file_name, dir) when 'exe' FileUtils.mkdir_p(dir) FileUtils.move(file_name, dir) when 'swc' || 'rb' return else raise ArchiveUnpackerError.new("ArchiveUnpacker does not know how to unpack files of type: #{archive_type} for file_name: #{file_name}") end end end |
#unpack_dmg(dmg_file, dir) ⇒ Object
This is actually not unpacking the FlashPlayer Binary file as expected… OSX is treated the player binary as if it is a regular text file, but if it is copied manually, the command works fine!?
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/sprout/archive_unpacker.rb', line 143 def unpack_dmg(dmg_file, dir) # 1) Mount the dmg in place # 2) Recursively Copy its contents to asproject_home # 3) Unmount the dmg if(mounted_path.nil?) raise StandardError.new('DMG file downloaded, but the RemoteFileTask needs a mounted_path in order to mount it') end if(!File.exists?(full_mounted_path)) system("hdiutil mount #{dmg_file}") end begin mounted_target = File.join(full_mounted_path, extracted_file) # Copy the DMG contents using system copy rather than ruby utils # Because OS X does something special with .app files that the # Ruby FileUtils and File classes break... from = mounted_target # from = File.join(full_mounted_path, extracted_file) to = File.join(@user.downloads, @name.to_s, extracted_file) FileUtils.makedirs(File.dirname(to)) if(File.exists?(from)) `ditto '#{from}' '#{to}'` end rescue StandardError => e if(File.exists?(full_mounted_path)) system("hdiutil unmount -force \"#{full_mounted_path}\"") end end end |
#unpack_tar_zip(tgz_file, dir, ext) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/sprout/archive_unpacker.rb', line 121 def unpack_tar_zip(tgz_file, dir, ext) if(!File.exists?(dir)) FileUtils.makedirs(dir) end tar = Zlib::GzipReader.new(File.open(tgz_file, 'rb')) Minitar.unpack(tar, dir) # Recurse and unpack gzipped children (Adobe did this double # gzip with the Linux FlashPlayer for some reason) Dir.glob("#{dir}/**/*.#{ext}").each do |child| if(child != tgz_file && dir != File.dirname(child)) unpack_targz(child, File.dirname(child)) end end end |
#unpack_targz(tgz_file, dir) ⇒ Object
117 118 119 |
# File 'lib/sprout/archive_unpacker.rb', line 117 def unpack_targz(tgz_file, dir) unpack_tar_zip tgz_file, dir, 'tar.gz' end |
#unpack_tbz2(tgz_file, dir) ⇒ Object
113 114 115 |
# File 'lib/sprout/archive_unpacker.rb', line 113 def unpack_tbz2(tgz_file, dir) unpack_tar_zip tgz_file, dir, 'tar.bz2' end |
#unpack_zip(zip_file, dir) ⇒ Object
54 55 56 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 103 104 105 |
# File 'lib/sprout/archive_unpacker.rb', line 54 def unpack_zip(zip_file, dir) # Avoid the rubyzip Segmentation Fault bug # at least on os x... if(RUBY_PLATFORM =~ /darwin/) # Unzipping on OS X FileUtils.makedirs(dir) zip_dir = File.(File.dirname(zip_file)) zip_name = File.basename(zip_file) output = File.(dir) # puts ">> zip_dir: #{zip_dir} zip_name: #{zip_name} output: #{output}" %x(cd #{zip_dir};unzip #{zip_name} -d #{output}) else retries = 0 begin retries += 1 Zip::ZipFile::open(zip_file) do |zf| zf.each do |e| fpath = File.join(dir, e.name) FileUtils.mkdir_p(File.dirname(fpath)) # Disgusting, Gross Hack to fix DOS/Ruby Bug # That makes the zip library throw a ZipDestinationFileExistsError # When the zip archive includes two files whose names # differ only by extension. # This bug actually appears in the File.exists? implementation # throwing false positives! # If you're going to use this code, be sure you extract # into a new, empty directory as existing files will be # clobbered... begin if(File.exists?(fpath) && !File.directory?(fpath)) hackpath = fpath + 'hack' zf.extract(e, hackpath) File.copy(hackpath, fpath) File.delete(hackpath) else zf.extract(e, fpath) end rescue NotImplementedError => ni_err puts "[WARNING] #{ni_err} for: #{e}" end end end rescue StandardError => err FileUtils.rm_rf(dir) if(retries < 3) FileUtils.makedirs(dir) retry end raise err end end end |
#unpacked_file_name(file, dir, suffix = nil) ⇒ Object
107 108 109 110 111 |
# File 'lib/sprout/archive_unpacker.rb', line 107 def unpacked_file_name(file, dir, suffix=nil) basename = File.basename(file, suffix) path = File.(dir) return File.join(path, basename) end |