class MdsFileUtils::ZipSplitter

Constants

COMPONENTS_DIR
EXTRACTED_DIR
FILES_PER_ZIP

Public Class Methods

new(path, original_filename=path) click to toggle source
# File lib/mds_file_utils/zip_splitter.rb, line 10
def initialize(path, original_filename=path)
  @path = path
  @original_filename = original_filename
end

Public Instance Methods

split(tmp_storage_path='/tmp') click to toggle source
# File lib/mds_file_utils/zip_splitter.rb, line 15
def split(tmp_storage_path='/tmp')
  splitter_path = File.join(tmp_storage_path, self.class.name)

  zip_base_name = base_file_name

  # Create a directory in which to place the contents of the zip file
  extracted_path = File.join(splitter_path, EXTRACTED_DIR, zip_base_name)
  mkdir_p extracted_path

  # Extract the contents of the zip file to the extracted path
  %x{unzip -d #{extracted_path} '#{@path}'}
  raise "Error extracting ZIP file '#{@path}' to '#{extracted_path}'" if $? != 0

  entries = directory_entries(extracted_path)

  puts "Number of entries: #{entries}"

  if entries.size > FILES_PER_ZIP
    result_zip_file = create_composite_zip_from_entries(zip_base_name, entries, splitter_path, extracted_path)
  else
    # The file is fine as is; just copy the file to the storage
    # location and return the path
    result_zip_file = File.join(splitter_path, File.basename(@path))
    cp @path, result_zip_file
  end

  result_zip_file
end

Private Instance Methods

base_file_name() click to toggle source
# File lib/mds_file_utils/zip_splitter.rb, line 90
def base_file_name
  basename = File.basename(@original_filename)
  if index = basename.rindex('.')
    basename = basename[0...index]
  end
  basename
end
create_composite_zip_from_entries(zip_base_name, entries, splitter_path, extracted_path) click to toggle source
# File lib/mds_file_utils/zip_splitter.rb, line 46
def create_composite_zip_from_entries(zip_base_name, entries, splitter_path, extracted_path)
  components_path = File.join(splitter_path, COMPONENTS_DIR)
  mkdir_p components_path
  index = 0

  entries.each_slice(FILES_PER_ZIP) do |files|
    new_partial_name = "#{zip_base_name}_#{index}"
    partial_path = File.join(splitter_path, new_partial_name)
    component_path = File.join(components_path, "#{new_partial_name}.zip")
    mkdir_p partial_path
    # Move all the files in this slice to the new partial path
    files.each { |f| mv File.join(extracted_path, f), partial_path }
    # Now, zip up all the files into it's own component zip file
    %x{cd #{partial_path}; zip #{component_path} *}
    raise "Error zipping up files in '#{partial_path}' into '#{component_path}'" if $? != 0
    # Delete the partial dir
    rm_rf partial_path
    index += 1
  end

  # Once we get here, all the component files have been built. Package up the
  # components into a new zip
  result_zip_file = File.join(splitter_path, "CMP_#{File.basename(@path)}")
  %x{cd #{components_path}; zip #{result_zip_file} *}
  raise "Error zipping up the components of the composite file: #{result_zip_file}" if $? != 0

  # Some housekeeping
  rm_rf File.dirname(extracted_path)
  rm_rf components_path

  result_zip_file
end
directory_entries(path) click to toggle source

Return the entries in the directory (without the '.' and '..'

# File lib/mds_file_utils/zip_splitter.rb, line 82
def directory_entries(path)
  Dir.entries(path).tap do |entries|
    # Get rid of the directory entries
    entries.delete('.')
    entries.delete('..')
  end
end