rubyzip 2.3.2 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changelog.md +538 -0
- data/LICENSE.md +24 -0
- data/README.md +235 -48
- data/Rakefile +15 -13
- data/lib/rubyzip.rb +3 -0
- data/lib/zip/central_directory.rb +194 -125
- data/lib/zip/compressor.rb +3 -1
- data/lib/zip/constants.rb +29 -21
- data/lib/zip/crypto/aes_encryption.rb +123 -0
- data/lib/zip/crypto/decrypted_io.rb +27 -15
- data/lib/zip/crypto/encryption.rb +4 -2
- data/lib/zip/crypto/null_encryption.rb +5 -13
- data/lib/zip/crypto/traditional_encryption.rb +13 -7
- data/lib/zip/decompressor.rb +4 -3
- data/lib/zip/deflater.rb +12 -8
- data/lib/zip/dirtyable.rb +32 -0
- data/lib/zip/dos_time.rb +72 -7
- data/lib/zip/entry.rb +407 -241
- data/lib/zip/entry_set.rb +11 -9
- data/lib/zip/errors.rb +152 -16
- data/lib/zip/extra_field/aes.rb +50 -0
- data/lib/zip/extra_field/generic.rb +10 -11
- data/lib/zip/extra_field/ntfs.rb +6 -4
- data/lib/zip/extra_field/old_unix.rb +5 -3
- data/lib/zip/extra_field/universal_time.rb +3 -1
- data/lib/zip/extra_field/unix.rb +7 -5
- data/lib/zip/extra_field/unknown.rb +35 -0
- data/lib/zip/extra_field/zip64.rb +19 -5
- data/lib/zip/extra_field.rb +25 -23
- data/lib/zip/file.rb +185 -226
- data/lib/zip/file_split.rb +91 -0
- data/lib/zip/filesystem/dir.rb +86 -0
- data/lib/zip/filesystem/directory_iterator.rb +48 -0
- data/lib/zip/filesystem/file.rb +263 -0
- data/lib/zip/filesystem/file_stat.rb +110 -0
- data/lib/zip/filesystem/zip_file_name_mapper.rb +81 -0
- data/lib/zip/filesystem.rb +27 -596
- data/lib/zip/inflater.rb +13 -10
- data/lib/zip/input_stream.rb +99 -47
- data/lib/zip/ioextras/abstract_input_stream.rb +146 -58
- data/lib/zip/ioextras/abstract_output_stream.rb +13 -3
- data/lib/zip/ioextras.rb +11 -8
- data/lib/zip/null_compressor.rb +3 -1
- data/lib/zip/null_decompressor.rb +6 -3
- data/lib/zip/null_input_stream.rb +3 -1
- data/lib/zip/output_stream.rb +66 -50
- data/lib/zip/pass_thru_compressor.rb +3 -1
- data/lib/zip/pass_thru_decompressor.rb +12 -9
- data/lib/zip/streamable_directory.rb +3 -1
- data/lib/zip/streamable_stream.rb +4 -1
- data/lib/zip/version.rb +4 -1
- data/lib/zip.rb +28 -4
- data/rubyzip.gemspec +39 -0
- data/samples/example.rb +8 -3
- data/samples/example_filesystem.rb +3 -2
- data/samples/example_recursive.rb +3 -1
- data/samples/gtk_ruby_zip.rb +5 -3
- data/samples/qtzip.rb +7 -6
- data/samples/write_simple.rb +2 -1
- data/samples/zipfind.rb +1 -0
- metadata +82 -49
- data/TODO +0 -15
- data/lib/zip/extra_field/zip64_placeholder.rb +0 -15
data/lib/zip/output_stream.rb
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
##
|
|
1
6
|
module Zip
|
|
2
7
|
# ZipOutputStream is the basic class for writing zip files. It is
|
|
3
8
|
# possible to create a ZipOutputStream object directly, passing
|
|
@@ -16,50 +21,58 @@ module Zip
|
|
|
16
21
|
#
|
|
17
22
|
# java.util.zip.ZipOutputStream is the original inspiration for this
|
|
18
23
|
# class.
|
|
19
|
-
|
|
20
24
|
class OutputStream
|
|
25
|
+
extend Forwardable
|
|
21
26
|
include ::Zip::IOExtras::AbstractOutputStream
|
|
22
27
|
|
|
23
|
-
|
|
28
|
+
def_delegators :@cdir, :comment, :comment=
|
|
24
29
|
|
|
25
30
|
# Opens the indicated zip file. If a file with that name already
|
|
26
31
|
# exists it will be overwritten.
|
|
27
|
-
def initialize(file_name, stream
|
|
32
|
+
def initialize(file_name, stream: false, encrypter: nil, suppress_extra_fields: false)
|
|
28
33
|
super()
|
|
29
34
|
@file_name = file_name
|
|
30
35
|
@output_stream = if stream
|
|
31
|
-
iostream = @file_name.dup
|
|
36
|
+
iostream = Zip::RUNNING_ON_WINDOWS ? @file_name : @file_name.dup
|
|
32
37
|
iostream.reopen(@file_name)
|
|
33
38
|
iostream.rewind
|
|
34
39
|
iostream
|
|
35
40
|
else
|
|
36
41
|
::File.new(@file_name, 'wb')
|
|
37
42
|
end
|
|
38
|
-
@
|
|
43
|
+
@cdir = ::Zip::CentralDirectory.new
|
|
39
44
|
@compressor = ::Zip::NullCompressor.instance
|
|
40
45
|
@encrypter = encrypter || ::Zip::NullEncrypter.new
|
|
46
|
+
@suppress_extra_fields = suppress_extra_fields
|
|
41
47
|
@closed = false
|
|
42
48
|
@current_entry = nil
|
|
43
|
-
@comment = nil
|
|
44
49
|
end
|
|
45
50
|
|
|
46
|
-
# Same as #initialize but if a block is passed the opened
|
|
47
|
-
# stream is passed to the block and closed when the block
|
|
48
|
-
# returns.
|
|
49
51
|
class << self
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
# Same as #initialize but if a block is passed the opened
|
|
53
|
+
# stream is passed to the block and closed when the block
|
|
54
|
+
# returns.
|
|
55
|
+
def open(file_name, encrypter: nil, suppress_extra_fields: false)
|
|
56
|
+
unless block_given?
|
|
57
|
+
return new(
|
|
58
|
+
file_name,
|
|
59
|
+
encrypter: encrypter,
|
|
60
|
+
suppress_extra_fields: suppress_extra_fields
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
zos = new(file_name, stream: false, encrypter: encrypter,
|
|
65
|
+
suppress_extra_fields: suppress_extra_fields)
|
|
54
66
|
yield zos
|
|
55
67
|
ensure
|
|
56
68
|
zos.close if zos
|
|
57
69
|
end
|
|
58
70
|
|
|
59
71
|
# Same as #open but writes to a filestream instead
|
|
60
|
-
def write_buffer(io = ::StringIO.new
|
|
72
|
+
def write_buffer(io = ::StringIO.new, encrypter: nil, suppress_extra_fields: false)
|
|
61
73
|
io.binmode if io.respond_to?(:binmode)
|
|
62
|
-
zos = new(io, true, encrypter
|
|
74
|
+
zos = new(io, stream: true, encrypter: encrypter,
|
|
75
|
+
suppress_extra_fields: suppress_extra_fields)
|
|
63
76
|
yield zos
|
|
64
77
|
zos.close_buffer
|
|
65
78
|
end
|
|
@@ -71,7 +84,7 @@ module Zip
|
|
|
71
84
|
|
|
72
85
|
finalize_current_entry
|
|
73
86
|
update_local_headers
|
|
74
|
-
|
|
87
|
+
@cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields)
|
|
75
88
|
@output_stream.close
|
|
76
89
|
@closed = true
|
|
77
90
|
end
|
|
@@ -82,37 +95,41 @@ module Zip
|
|
|
82
95
|
|
|
83
96
|
finalize_current_entry
|
|
84
97
|
update_local_headers
|
|
85
|
-
|
|
98
|
+
@cdir.write_to_stream(@output_stream, suppress_extra_fields: @suppress_extra_fields)
|
|
86
99
|
@closed = true
|
|
100
|
+
@output_stream.flush
|
|
87
101
|
@output_stream
|
|
88
102
|
end
|
|
89
103
|
|
|
90
104
|
# Closes the current entry and opens a new for writing.
|
|
91
105
|
# +entry+ can be a ZipEntry object or a string.
|
|
92
|
-
def put_next_entry(
|
|
106
|
+
def put_next_entry(
|
|
107
|
+
entry_name, comment = '', extra = ExtraField.new,
|
|
108
|
+
compression_method = Entry::DEFLATED, level = Zip.default_compression
|
|
109
|
+
)
|
|
93
110
|
raise Error, 'zip stream is closed' if @closed
|
|
94
111
|
|
|
95
|
-
new_entry =
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
init_next_entry(new_entry
|
|
112
|
+
new_entry =
|
|
113
|
+
if entry_name.kind_of?(Entry) || entry_name.kind_of?(StreamableStream)
|
|
114
|
+
entry_name
|
|
115
|
+
else
|
|
116
|
+
Entry.new(
|
|
117
|
+
@file_name, entry_name.to_s, comment: comment, extra: extra,
|
|
118
|
+
compression_method: compression_method, compression_level: level
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
init_next_entry(new_entry)
|
|
106
123
|
@current_entry = new_entry
|
|
107
124
|
end
|
|
108
125
|
|
|
109
|
-
def copy_raw_entry(entry)
|
|
126
|
+
def copy_raw_entry(entry) # :nodoc:
|
|
110
127
|
entry = entry.dup
|
|
111
128
|
raise Error, 'zip stream is closed' if @closed
|
|
112
129
|
raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry)
|
|
113
130
|
|
|
114
131
|
finalize_current_entry
|
|
115
|
-
@
|
|
132
|
+
@cdir << entry
|
|
116
133
|
src_pos = entry.local_header_offset
|
|
117
134
|
entry.write_local_entry(@output_stream)
|
|
118
135
|
@compressor = NullCompressor.instance
|
|
@@ -131,55 +148,54 @@ module Zip
|
|
|
131
148
|
return unless @current_entry
|
|
132
149
|
|
|
133
150
|
finish
|
|
134
|
-
@current_entry.compressed_size = @output_stream.tell -
|
|
135
|
-
@current_entry.local_header_offset -
|
|
151
|
+
@current_entry.compressed_size = @output_stream.tell -
|
|
152
|
+
@current_entry.local_header_offset -
|
|
136
153
|
@current_entry.calculate_local_header_size
|
|
137
154
|
@current_entry.size = @compressor.size
|
|
138
155
|
@current_entry.crc = @compressor.crc
|
|
139
|
-
@output_stream << @encrypter.data_descriptor(
|
|
156
|
+
@output_stream << @encrypter.data_descriptor(
|
|
157
|
+
@current_entry.crc,
|
|
158
|
+
@current_entry.compressed_size,
|
|
159
|
+
@current_entry.size
|
|
160
|
+
)
|
|
140
161
|
@current_entry.gp_flags |= @encrypter.gp_flags
|
|
141
162
|
@current_entry = nil
|
|
142
163
|
@compressor = ::Zip::NullCompressor.instance
|
|
143
164
|
end
|
|
144
165
|
|
|
145
|
-
def init_next_entry(entry
|
|
166
|
+
def init_next_entry(entry)
|
|
146
167
|
finalize_current_entry
|
|
147
|
-
@
|
|
148
|
-
entry.write_local_entry(@output_stream)
|
|
168
|
+
@cdir << entry
|
|
169
|
+
entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields)
|
|
149
170
|
@encrypter.reset!
|
|
150
171
|
@output_stream << @encrypter.header(entry.mtime)
|
|
151
|
-
@compressor = get_compressor(entry
|
|
172
|
+
@compressor = get_compressor(entry)
|
|
152
173
|
end
|
|
153
174
|
|
|
154
|
-
def get_compressor(entry
|
|
175
|
+
def get_compressor(entry)
|
|
155
176
|
case entry.compression_method
|
|
156
177
|
when Entry::DEFLATED
|
|
157
|
-
::Zip::Deflater.new(@output_stream,
|
|
178
|
+
::Zip::Deflater.new(@output_stream, entry.compression_level, @encrypter)
|
|
158
179
|
when Entry::STORED
|
|
159
180
|
::Zip::PassThruCompressor.new(@output_stream)
|
|
160
181
|
else
|
|
161
|
-
raise ::Zip::CompressionMethodError,
|
|
162
|
-
"Invalid compression method: '#{entry.compression_method}'"
|
|
182
|
+
raise ::Zip::CompressionMethodError, entry.compression_method
|
|
163
183
|
end
|
|
164
184
|
end
|
|
165
185
|
|
|
166
186
|
def update_local_headers
|
|
167
187
|
pos = @output_stream.pos
|
|
168
|
-
@
|
|
188
|
+
@cdir.each do |entry|
|
|
169
189
|
@output_stream.pos = entry.local_header_offset
|
|
170
|
-
entry.write_local_entry(@output_stream,
|
|
190
|
+
entry.write_local_entry(@output_stream, suppress_extra_fields: @suppress_extra_fields,
|
|
191
|
+
rewrite: true)
|
|
171
192
|
end
|
|
172
193
|
@output_stream.pos = pos
|
|
173
194
|
end
|
|
174
195
|
|
|
175
|
-
def write_central_directory
|
|
176
|
-
cdir = CentralDirectory.new(@entry_set, @comment)
|
|
177
|
-
cdir.write_to_stream(@output_stream)
|
|
178
|
-
end
|
|
179
|
-
|
|
180
196
|
protected
|
|
181
197
|
|
|
182
|
-
def finish
|
|
198
|
+
def finish # :nodoc:
|
|
183
199
|
@compressor.finish
|
|
184
200
|
end
|
|
185
201
|
|
|
@@ -1,26 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Zip
|
|
2
|
-
class PassThruDecompressor < Decompressor
|
|
4
|
+
class PassThruDecompressor < Decompressor # :nodoc:all
|
|
3
5
|
def initialize(*args)
|
|
4
6
|
super
|
|
5
7
|
@read_so_far = 0
|
|
6
8
|
end
|
|
7
9
|
|
|
8
|
-
def read(
|
|
9
|
-
return (
|
|
10
|
+
def read(maxlen = nil)
|
|
11
|
+
return (maxlen.nil? || maxlen.zero? ? '' : nil) if eof?
|
|
10
12
|
|
|
11
|
-
if
|
|
12
|
-
|
|
13
|
+
if maxlen.nil? || (@read_so_far + maxlen) > decompressed_size
|
|
14
|
+
maxlen = decompressed_size - @read_so_far
|
|
13
15
|
end
|
|
14
16
|
|
|
15
|
-
@read_so_far +=
|
|
16
|
-
input_stream.read(
|
|
17
|
+
@read_so_far += maxlen
|
|
18
|
+
input_stream.read(maxlen)
|
|
17
19
|
end
|
|
18
20
|
|
|
19
|
-
def eof
|
|
21
|
+
def eof?
|
|
20
22
|
@read_so_far >= decompressed_size
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
# Alias for compatibility. Remove for version 4.
|
|
26
|
+
alias eof eof?
|
|
24
27
|
end
|
|
25
28
|
|
|
26
29
|
::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Zip
|
|
2
4
|
class StreamableStream < DelegateClass(Entry) # :nodoc:all
|
|
3
5
|
def initialize(entry)
|
|
4
|
-
super
|
|
6
|
+
super
|
|
5
7
|
@temp_file = Tempfile.new(::File.basename(name))
|
|
6
8
|
@temp_file.binmode
|
|
7
9
|
end
|
|
@@ -42,6 +44,7 @@ module Zip
|
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
def clean_up
|
|
47
|
+
super
|
|
45
48
|
@temp_file.unlink
|
|
46
49
|
end
|
|
47
50
|
end
|
data/lib/zip/version.rb
CHANGED
data/lib/zip.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'English'
|
|
2
4
|
require 'delegate'
|
|
3
5
|
require 'singleton'
|
|
@@ -5,6 +7,7 @@ require 'tempfile'
|
|
|
5
7
|
require 'fileutils'
|
|
6
8
|
require 'stringio'
|
|
7
9
|
require 'zlib'
|
|
10
|
+
require 'zip/version'
|
|
8
11
|
require 'zip/constants'
|
|
9
12
|
require 'zip/dos_time'
|
|
10
13
|
require 'zip/ioextras'
|
|
@@ -27,14 +30,21 @@ require 'zip/crypto/decrypted_io'
|
|
|
27
30
|
require 'zip/crypto/encryption'
|
|
28
31
|
require 'zip/crypto/null_encryption'
|
|
29
32
|
require 'zip/crypto/traditional_encryption'
|
|
33
|
+
require 'zip/crypto/aes_encryption'
|
|
30
34
|
require 'zip/inflater'
|
|
31
35
|
require 'zip/deflater'
|
|
32
36
|
require 'zip/streamable_stream'
|
|
33
37
|
require 'zip/streamable_directory'
|
|
34
38
|
require 'zip/errors'
|
|
35
39
|
|
|
40
|
+
# Rubyzip is a ruby module for reading and writing zip files.
|
|
41
|
+
#
|
|
42
|
+
# The main entry points are File, InputStream and OutputStream. For a
|
|
43
|
+
# file/directory interface in the style of the standard ruby ::File and
|
|
44
|
+
# ::Dir APIs then `require 'zip/filesystem'` and see FileSystem.
|
|
36
45
|
module Zip
|
|
37
46
|
extend self
|
|
47
|
+
|
|
38
48
|
attr_accessor :unicode_names,
|
|
39
49
|
:on_exists_proc,
|
|
40
50
|
:continue_on_exists_proc,
|
|
@@ -44,21 +54,35 @@ module Zip
|
|
|
44
54
|
:warn_invalid_date,
|
|
45
55
|
:case_insensitive_match,
|
|
46
56
|
:force_entry_names_encoding,
|
|
47
|
-
:validate_entry_sizes
|
|
57
|
+
:validate_entry_sizes,
|
|
58
|
+
:validate_declared_number_of_entries
|
|
59
|
+
|
|
60
|
+
DEFAULT_RESTORE_OPTIONS = {
|
|
61
|
+
restore_ownership: false,
|
|
62
|
+
restore_permissions: true,
|
|
63
|
+
restore_times: true
|
|
64
|
+
}.freeze # :nodoc:
|
|
65
|
+
|
|
66
|
+
# :nodoc:
|
|
67
|
+
# Remove this when JRuby#3962 is fixed.
|
|
68
|
+
ZLIB_FLUSHING_STRATEGY = defined?(JRUBY_VERSION) ? Zlib::SYNC_FLUSH : Zlib::NO_FLUSH
|
|
48
69
|
|
|
49
|
-
def reset!
|
|
70
|
+
def reset! # :nodoc:
|
|
50
71
|
@_ran_once = false
|
|
51
72
|
@unicode_names = false
|
|
52
73
|
@on_exists_proc = false
|
|
53
74
|
@continue_on_exists_proc = false
|
|
54
75
|
@sort_entries = false
|
|
55
|
-
@default_compression =
|
|
56
|
-
@write_zip64_support =
|
|
76
|
+
@default_compression = Zlib::DEFAULT_COMPRESSION
|
|
77
|
+
@write_zip64_support = true
|
|
57
78
|
@warn_invalid_date = true
|
|
58
79
|
@case_insensitive_match = false
|
|
80
|
+
@force_entry_names_encoding = nil
|
|
59
81
|
@validate_entry_sizes = true
|
|
82
|
+
@validate_declared_number_of_entries = false # Set this to `true` in v4.0.0?
|
|
60
83
|
end
|
|
61
84
|
|
|
85
|
+
# Set options for RubyZip in one block.
|
|
62
86
|
def setup
|
|
63
87
|
yield self unless @_ran_once
|
|
64
88
|
@_ran_once = true
|
data/rubyzip.gemspec
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/zip/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = 'rubyzip'
|
|
7
|
+
s.version = Zip::VERSION
|
|
8
|
+
s.authors = ['Robert Haines', 'John Lees-Miller', 'Alexander Simonov']
|
|
9
|
+
s.email = [
|
|
10
|
+
'hainesr@gmail.com', 'jdleesmiller@gmail.com', 'alex@simonov.me'
|
|
11
|
+
]
|
|
12
|
+
s.homepage = 'http://github.com/rubyzip/rubyzip'
|
|
13
|
+
s.platform = Gem::Platform::RUBY
|
|
14
|
+
s.summary = 'rubyzip is a ruby module for reading and writing zip files'
|
|
15
|
+
s.files = Dir.glob('{samples,lib}/**/*.rb') +
|
|
16
|
+
%w[LICENSE.md README.md Changelog.md Rakefile rubyzip.gemspec]
|
|
17
|
+
s.require_paths = ['lib']
|
|
18
|
+
s.license = 'BSD-2-Clause'
|
|
19
|
+
|
|
20
|
+
s.metadata = {
|
|
21
|
+
'bug_tracker_uri' => 'https://github.com/rubyzip/rubyzip/issues',
|
|
22
|
+
'changelog_uri' => "https://github.com/rubyzip/rubyzip/blob/v#{s.version}/Changelog.md",
|
|
23
|
+
'documentation_uri' => "https://www.rubydoc.info/gems/rubyzip/#{s.version}",
|
|
24
|
+
'source_code_uri' => "https://github.com/rubyzip/rubyzip/tree/v#{s.version}",
|
|
25
|
+
'wiki_uri' => 'https://github.com/rubyzip/rubyzip/wiki',
|
|
26
|
+
'rubygems_mfa_required' => 'true'
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
s.required_ruby_version = '>= 3.0'
|
|
30
|
+
|
|
31
|
+
s.add_development_dependency 'minitest', '~> 5.25'
|
|
32
|
+
s.add_development_dependency 'rake', '~> 13.2'
|
|
33
|
+
s.add_development_dependency 'rdoc', '~> 6.11'
|
|
34
|
+
s.add_development_dependency 'rubocop', '~> 1.80.2'
|
|
35
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.26.0'
|
|
36
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.7.1'
|
|
37
|
+
s.add_development_dependency 'simplecov', '~> 0.22.0'
|
|
38
|
+
s.add_development_dependency 'simplecov-lcov', '~> 0.8'
|
|
39
|
+
end
|
data/samples/example.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
system('zip example.zip example.rb gtk_ruby_zip.rb')
|
|
@@ -20,7 +21,8 @@ end
|
|
|
20
21
|
|
|
21
22
|
zf = Zip::File.new('example.zip')
|
|
22
23
|
zf.each_with_index do |entry, index|
|
|
23
|
-
puts "entry #{index} is #{entry.name}, size = #{entry.size},
|
|
24
|
+
puts "entry #{index} is #{entry.name}, size = #{entry.size}, " \
|
|
25
|
+
"compressed size = #{entry.compressed_size}"
|
|
24
26
|
# use zf.get_input_stream(entry) to get a ZipInputStream for the entry
|
|
25
27
|
# entry can be the ZipEntry object or any object which has a to_s method that
|
|
26
28
|
# returns the name of the entry.
|
|
@@ -70,8 +72,11 @@ part_zips_count = Zip::File.split('large_zip_file.zip', 2_097_152, false)
|
|
|
70
72
|
puts "Zip file splitted in #{part_zips_count} parts"
|
|
71
73
|
|
|
72
74
|
# Track splitting an archive
|
|
73
|
-
Zip::File.split(
|
|
74
|
-
|
|
75
|
+
Zip::File.split(
|
|
76
|
+
'large_zip_file.zip', 1_048_576, true, 'part_zip_file'
|
|
77
|
+
) do |part_count, part_index, chunk_bytes, segment_bytes|
|
|
78
|
+
puts "#{part_index} of #{part_count} part splitting: " \
|
|
79
|
+
"#{(chunk_bytes.to_f / segment_bytes * 100).to_i}%"
|
|
75
80
|
end
|
|
76
81
|
|
|
77
82
|
# For other examples, look at zip.rb and ziptest.rb
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
|
|
@@ -6,9 +7,9 @@ require 'zip/filesystem'
|
|
|
6
7
|
|
|
7
8
|
EXAMPLE_ZIP = 'filesystem.zip'
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
FileUtils.rm_f(EXAMPLE_ZIP)
|
|
10
11
|
|
|
11
|
-
Zip::File.open(EXAMPLE_ZIP,
|
|
12
|
+
Zip::File.open(EXAMPLE_ZIP, create: true) do |zf|
|
|
12
13
|
zf.file.open('file1.txt', 'w') { |os| os.write 'first file1.txt' }
|
|
13
14
|
zf.dir.mkdir('dir1')
|
|
14
15
|
zf.dir.chdir('dir1')
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'zip'
|
|
2
4
|
|
|
3
5
|
# This is a simple example which uses rubyzip to
|
|
@@ -21,7 +23,7 @@ class ZipFileGenerator
|
|
|
21
23
|
def write
|
|
22
24
|
entries = Dir.entries(@input_dir) - %w[. ..]
|
|
23
25
|
|
|
24
|
-
::Zip::File.open(@output_file,
|
|
26
|
+
::Zip::File.open(@output_file, create: true) do |zipfile|
|
|
25
27
|
write_entries entries, '', zipfile
|
|
26
28
|
end
|
|
27
29
|
end
|
data/samples/gtk_ruby_zip.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
|
|
@@ -9,7 +10,7 @@ require 'zip'
|
|
|
9
10
|
|
|
10
11
|
class MainApp < Gtk::Window
|
|
11
12
|
def initialize
|
|
12
|
-
super
|
|
13
|
+
super
|
|
13
14
|
set_usize(400, 256)
|
|
14
15
|
set_title('rubyzip')
|
|
15
16
|
signal_connect(Gtk::Window::SIGNAL_DESTROY) { Gtk.main_quit }
|
|
@@ -42,7 +43,8 @@ class MainApp < Gtk::Window
|
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
class ButtonPanel < Gtk::HButtonBox
|
|
45
|
-
attr_reader :
|
|
46
|
+
attr_reader :extract_button, :open_button
|
|
47
|
+
|
|
46
48
|
def initialize
|
|
47
49
|
super
|
|
48
50
|
set_layout(Gtk::BUTTONBOX_START)
|
|
@@ -72,7 +74,7 @@ class MainApp < Gtk::Window
|
|
|
72
74
|
@zipfile.each do |entry|
|
|
73
75
|
@clist.append([entry.name,
|
|
74
76
|
entry.size.to_s,
|
|
75
|
-
|
|
77
|
+
"#{100.0 * entry.compressedSize / entry.size}%"])
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
end
|
data/samples/qtzip.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$VERBOSE = true
|
|
4
5
|
|
|
@@ -6,14 +7,14 @@ $LOAD_PATH << '../lib'
|
|
|
6
7
|
|
|
7
8
|
require 'Qt'
|
|
8
9
|
system('rbuic -o zipdialogui.rb zipdialogui.ui')
|
|
9
|
-
require 'zipdialogui
|
|
10
|
+
require 'zipdialogui'
|
|
10
11
|
require 'zip'
|
|
11
12
|
|
|
12
13
|
a = Qt::Application.new(ARGV)
|
|
13
14
|
|
|
14
15
|
class ZipDialog < ZipDialogUI
|
|
15
16
|
def initialize
|
|
16
|
-
super
|
|
17
|
+
super
|
|
17
18
|
connect(child('add_button'), SIGNAL('clicked()'),
|
|
18
19
|
self, SLOT('add_files()'))
|
|
19
20
|
connect(child('extract_button'), SIGNAL('clicked()'),
|
|
@@ -65,14 +66,14 @@ class ZipDialog < ZipDialogUI
|
|
|
65
66
|
end
|
|
66
67
|
puts "selected_items.size = #{selected_items.size}"
|
|
67
68
|
puts "unselected_items.size = #{unselected_items.size}"
|
|
68
|
-
items =
|
|
69
|
+
items = selected_items.empty? ? unselected_items : selected_items
|
|
69
70
|
puts "items.size = #{items.size}"
|
|
70
71
|
|
|
71
72
|
d = Qt::FileDialog.get_existing_directory(nil, self)
|
|
72
|
-
if
|
|
73
|
-
puts 'No directory chosen'
|
|
74
|
-
else
|
|
73
|
+
if d
|
|
75
74
|
zipfile { |zf| items.each { |e| zf.extract(e, File.join(d, e)) } }
|
|
75
|
+
else
|
|
76
|
+
puts 'No directory chosen'
|
|
76
77
|
end
|
|
77
78
|
end
|
|
78
79
|
|
data/samples/write_simple.rb
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
$LOAD_PATH << '../lib'
|
|
4
5
|
|
|
5
6
|
require 'zip'
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
Zip::OutputStream.open('simple.zip') do |zos|
|
|
8
9
|
zos.put_next_entry 'entry.txt'
|
|
9
10
|
zos.puts 'Hello world'
|
|
10
11
|
end
|