Class: MultiZip

Inherits:
Object
  • Object
show all
Defined in:
lib/multi_zip.rb,
lib/multi_zip/errors.rb,
lib/multi_zip/version.rb

Defined Under Namespace

Modules: Backend Classes: ArchiveError, ArchiveNotFoundError, BaseError, InvalidArchiveError, InvalidBackendError, MemberError, MemberNotFoundError, NoSupportedBackendError, UnknownError

Constant Summary collapse

BACKEND_PREFERENCE =
[ :rubyzip, :archive_zip, :zipruby, :cli ]
BACKENDS =
{
  :rubyzip => {
    :fingerprints => [
      ['constant', lambda { defined?(Zip::File) } ],
      [nil, lambda { defined?(Zip::Archive) }]
    ],
    :constant => lambda { MultiZip::Backend::Rubyzip }
  },
  :archive_zip => {
    :fingerprints => [
      ['constant', lambda { defined?(Archive::Zip) } ]
    ],
    :constant => lambda { MultiZip::Backend::ArchiveZip }
  },
  :zipruby => {
    :fingerprints => [
      ['constant', lambda { defined?(Zip::File) } ],
      ['constant', lambda { defined?(Zip::Archive) }]
    ],
    :constant => lambda { MultiZip::Backend::Zipruby }
  },
  :cli => {
    :fingerprints => [
      [true, lambda { MultiZip::Backend::Cli.strategy_available? } ]
    ],
    :constant => lambda { MultiZip::Backend::Cli.strategy.extend_class.call }
  }
}
VERSION =
"0.1.6"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename, options = {}) ⇒ MultiZip

Returns a new instance of MultiZip.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/multi_zip.rb', line 36

def initialize(filename, options = {})
  @filename = filename

  self.backend = if b_end = options.delete(:backend)
    b_end
  else
    begin
      default_backend
    rescue NoSupportedBackendError => e
      if !!options[:allow_no_backends] # TODO: Fix this test mode hack
        nil
      else
        raise e
      end
    end
  end

  if block_given?
    yield(self)
  end
end

Instance Attribute Details

#filenameObject (readonly)

Returns the value of attribute filename.



4
5
6
# File 'lib/multi_zip.rb', line 4

def filename
  @filename
end

Class Method Details

.available_backendsObject



78
79
80
81
82
83
84
85
86
# File 'lib/multi_zip.rb', line 78

def self.available_backends
  available = []
  BACKENDS.each do |name, opts|
    if opts[:fingerprints].all?{|expectation, lmb| lmb.call == expectation }
      available << name
    end
  end
  available
end

.supported_backendsObject



74
75
76
# File 'lib/multi_zip.rb', line 74

def self.supported_backends
  BACKENDS.keys
end

Instance Method Details

#backendObject



58
59
60
# File 'lib/multi_zip.rb', line 58

def backend
  @backend ||= default_backend
end

#backend=(backend_name) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/multi_zip.rb', line 62

def backend=(backend_name)
  return @backend if backend_name.nil?
  if BACKENDS.keys.include?(backend_name.to_sym)
    @backend = backend_name.to_sym
    require "multi_zip/backend/#{@backend}"
    extend BACKENDS[@backend][:constant].call
    return @backend
  else
    raise InvalidBackendError.new(backend_name)
  end
end

#closeObject

Close the archive, if the archive is open. If the archive is already closed, behave as though it was open. Expected to always return true.

This is currently a non-op since the archives are not kept open between method calls. It is here so users can write code using it to prepare for when we do keep the archives open.

Currently, this method MUST NOT be overridden.



97
98
99
# File 'lib/multi_zip.rb', line 97

def close
  return true
end

#extract_member(member_path, destination_path, options = {}) ⇒ Object

Intended to write the contents of a zip member to a filesystem path.

This SHOULD be overridden by a backend module because this default will try to read the whole file in to memory before outputting to disk and that can be memory-intensive if the file is large.



121
122
123
124
# File 'lib/multi_zip.rb', line 121

def extract_member(member_path, destination_path, options={})
  warn "Using default #extract_member which may be memory-inefficient"
  default_extract_member(member_path, destination_path, options)
end

#list_members(prefix = nil, options = {}) ⇒ Object

List members of the zip file. Optionally can specify a prefix.

This method MUST be overridden by a backend module.

Raises:

  • (NotImplementedError)


129
130
131
# File 'lib/multi_zip.rb', line 129

def list_members(prefix = nil, options={})
  raise NotImplementedError
end

#member_exists?(member_path, options = {}) ⇒ Boolean

Boolean, does a given member path exist in the zip file?

This method MAY be overridden by backend module for the sake of efficiency. Otherwise it will use #list_members.

Returns:

  • (Boolean)


137
138
139
# File 'lib/multi_zip.rb', line 137

def member_exists?(member_path, options={})
  list_members(nil, options).include?(member_path)
end

#member_info(member_path, options = {}) ⇒ Object

Returns a hash of information about the member file. At a minimum, the hash MUST contain these keys:

:path  the full path of the member file (should equal `member_path` arg)
:size  the UNCOMPRESSED file size, in bytes

Optionally, it MAY contain these keys:

:created_at  creation timestamp of the file as an instance of Time
:compressed_size size of the COMPRESSED file
:type        Filesystem type of the member (:directory, :file, :symlink, etc)
:original    The original member info object as returned from the backend
             gem. Ex: using rubyzip, it would be an instace of Zip::Entry.

This method MUST be overridden by a backend module.

Raises:

  • (NotImplementedError)


154
155
156
# File 'lib/multi_zip.rb', line 154

def member_info(member_path, options={})
  raise NotImplementedError
end

#read_member(member_path, options = {}) ⇒ Object

Intended to return the contents of a zip member as a string.

This method MUST be overridden by a backend module.

Raises:

  • (NotImplementedError)


104
105
106
# File 'lib/multi_zip.rb', line 104

def read_member(member_path, options={})
  raise NotImplementedError
end

#read_members(member_paths, options = {}) ⇒ Object

Intended to return the contents of zip members as array of strings.

This method MAY be overridden by backend module for the sake of efficiency, or will call #read_member for each entry in member_paths.



112
113
114
# File 'lib/multi_zip.rb', line 112

def read_members(member_paths, options={})
  member_paths.map{|f| read_member(f, options) }
end

#remove_member(member_path, options = {}) ⇒ Object

Remove a zip member from the archive. Expected to raise MemberNotFoundError if the member_path was not found in the archive

This method MUST be overridden by a backend module.

Raises:

  • (NotImplementedError)


168
169
170
# File 'lib/multi_zip.rb', line 168

def remove_member(member_path, options={})
  raise NotImplementedError
end

#remove_members(member_paths, options = {}) ⇒ Object

Remove multiple zip member from the archive. Expected to raise MemberNotFoundError if the member_path was not found in the archive

This method MAY be overridden by backend module for the sake of efficiency. Otherwise it will use #remove_member.



178
179
180
# File 'lib/multi_zip.rb', line 178

def remove_members(member_paths, options={})
  member_paths.map{|f| remove_member(f, options) }.all?
end

#write_member(member_path, member_content, options = {}) ⇒ Object

Write string contents to a zip member file

Raises:

  • (NotImplementedError)


159
160
161
# File 'lib/multi_zip.rb', line 159

def write_member(member_path, member_content, options={})
  raise NotImplementedError
end