Last active
August 30, 2023 16:21
-
-
Save masukomi/9c820dccbb6d9535536ab9945153b48c to your computer and use it in GitHub Desktop.
[ruby] how to recursively process a zip file containing zip files in memory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Note this doesn't deal with directories in zip files. | |
# That's documented elsewhere. The recursive processing of | |
# zip files in zip files was the tricky bit. | |
require 'zip' | |
def recursive_zip_reader(input) | |
if input.is_a? String | |
zip_file = Zip::File.open(input) | |
recursive_zip_file_reader(zip_file) | |
elsif input.is_a? Zip::File | |
recursive_zip_file_reader(input) | |
elsif input.is_a? Zip::Entry | |
recursive_zip_entry_reader(input) | |
elsif input.is_a? File | |
recursive_zip_file_reader(Zip::File.open(input.path)) | |
else | |
"unknown input type (#{input.class}): #{input}" | |
end | |
end | |
def recursive_zip_file_reader(zip_file) | |
file_names = [] | |
zip_file.entries.each do | zip_entry | | |
# nobody wants macOS's bs finder metadata files | |
next if zip_entry.name.start_with?("__MACOSX") | |
file_names << recursive_zip_entry_reader(zip_entry) | |
end | |
file_names | |
end | |
def recursive_zip_entry_reader(zip_entry) | |
name = zip_entry.name | |
return name unless name.end_with?(".zip") | |
entry_contents = zip_entry.get_input_stream.read | |
nested_entry = Zip::File.open_buffer(entry_contents) | |
{name => recursive_zip_reader(nested_entry)} | |
end | |
puts recursive_zip_reader("multizip.zip").inspect | |
# output should look like this | |
# [ | |
# { | |
# "subzip.zip": [ | |
# "pass.json", | |
# "manifest.json", | |
# "signature" | |
# ] | |
# } | |
# ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment