omnizip 0.3.51 → 0.3.52
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 +27 -0
- data/lib/omnizip/archive_handlers/seven_zip_handler.rb +1 -1
- data/lib/omnizip/cli/output_formatter.rb +16 -8
- data/lib/omnizip/cli.rb +1 -7
- data/lib/omnizip/commands/archive_create_command.rb +1 -10
- data/lib/omnizip/commands/archive_extract_command.rb +4 -13
- data/lib/omnizip/commands/archive_list_command.rb +1 -18
- data/lib/omnizip/commands/metadata_command.rb +21 -26
- data/lib/omnizip/commands/parity_create_command.rb +1 -7
- data/lib/omnizip/extraction/selective_extractor.rb +16 -4
- data/lib/omnizip/models/conversion_result.rb +1 -7
- data/lib/omnizip/parity/par2_creator.rb +0 -34
- data/lib/omnizip/parity/par2_verifier.rb +5 -0
- data/lib/omnizip/profiler/report_generator.rb +1 -12
- data/lib/omnizip/profiler.rb +1 -12
- data/lib/omnizip/temp/safe_extract.rb +3 -43
- data/lib/omnizip/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8002bf03f99715929f352dfb92a91a10d02f6dac7152006a6cb87ca20b3647ae
|
|
4
|
+
data.tar.gz: b095258b0b0af358ae9c0a21482a6f8b29de1620bb2162d64dd8794f29eb8f59
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 527be0108ee0fa63b6e7ebafdeaafd05430a17c08e0d59b0f731db7a3b76401da96daec205947c7c3b5baa07aba886515959513ef3d4b31438889761219e958d
|
|
7
|
+
data.tar.gz: e1f8665f545fc81a4459cbdffbb9e5d5aca219a177a5b2d2ac3bd47c589a2ceb11b02d8cfdc748ac39381417f12682bf53cf14105dcbcd3d04bd59b77d7f9e87
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.51] - 2026-09-01
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Profile resolution lives in one place: `Omnizip::Profile` gains
|
|
14
|
+
`resolve`, `apply`, and `first_file_among`, and the convenience
|
|
15
|
+
methods plus the `archive create` command collapse onto them. The
|
|
16
|
+
two prior copies had drifted — the command only accepted `"auto"`
|
|
17
|
+
strings and could not pass a `CompressionProfile` through.
|
|
18
|
+
- Both direct converter strategies (ZIP↔7z) now extract through
|
|
19
|
+
`Omnizip.extract_archive` and write through a shared
|
|
20
|
+
`ConversionStrategy#repack_tree` on the Archive facade — they were
|
|
21
|
+
the last library code instantiating format readers/writers
|
|
22
|
+
directly, and the 7z→ZIP path required `#open` against the
|
|
23
|
+
reader-always-usable invariant.
|
|
24
|
+
- `create_rar` routes through the RAR handler (unrar-verified) with
|
|
25
|
+
the generic writer block interface; its stale "requires RAR
|
|
26
|
+
license" docstring is gone. `decompress_file`'s three-arm case
|
|
27
|
+
with magic `:xz`/`:zstandard` markers becomes a
|
|
28
|
+
`SINGLE_FILE_DECOMPRESSORS` table mirroring the compressor table.
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- macOS CI failed at setup from 2026-09-01: Homebrew disabled the
|
|
32
|
+
`rar` cask (Gatekeeper check), breaking `brew install rar`. The
|
|
33
|
+
workflow now installs it separately and non-fatally, like the
|
|
34
|
+
Windows branch already did for winrar; RAR interop specs skip
|
|
35
|
+
when unrar is absent.
|
|
36
|
+
|
|
10
37
|
## [0.3.50] - 2026-08-31
|
|
11
38
|
|
|
12
39
|
### Added
|
|
@@ -44,19 +44,27 @@ module Omnizip
|
|
|
44
44
|
].join("\n")
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
# Format file size in human-readable format.
|
|
47
|
+
# Format file size in human-readable format. This is THE byte
|
|
48
|
+
# formatter — commands, the CLI, and display-oriented models
|
|
49
|
+
# delegate here instead of carrying private copies.
|
|
48
50
|
#
|
|
49
|
-
# @param bytes [Integer] Size in bytes
|
|
50
|
-
# @return [String] Formatted size
|
|
51
|
+
# @param bytes [Integer, nil] Size in bytes
|
|
52
|
+
# @return [String] Formatted size ("512 B", "1.5 KB", "2.0 MB")
|
|
51
53
|
def format_size(bytes)
|
|
54
|
+
return "0 B" if bytes.nil? || bytes.zero?
|
|
55
|
+
|
|
52
56
|
units = %w[B KB MB GB TB]
|
|
53
|
-
|
|
57
|
+
size = bytes.to_f
|
|
58
|
+
unit_index = 0
|
|
59
|
+
|
|
60
|
+
while size >= 1024.0 && unit_index < units.size - 1
|
|
61
|
+
size /= 1024.0
|
|
62
|
+
unit_index += 1
|
|
63
|
+
end
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
exp = [exp, units.length - 1].min
|
|
65
|
+
return format("%d B", bytes) if unit_index.zero?
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
"#{size} #{units[exp]}"
|
|
67
|
+
format("%.1f %s", size, units[unit_index])
|
|
60
68
|
end
|
|
61
69
|
|
|
62
70
|
# Format error message for display.
|
data/lib/omnizip/cli.rb
CHANGED
|
@@ -60,13 +60,7 @@ module Omnizip
|
|
|
60
60
|
# @param bytes [Integer] the byte count
|
|
61
61
|
# @return [String] human-readable size (e.g. "1.5 MB")
|
|
62
62
|
def format_bytes(bytes)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
units = %w[B KB MB GB TB]
|
|
66
|
-
exp = (Math.log(bytes) / Math.log(1024)).to_i
|
|
67
|
-
exp = [exp, units.size - 1].min
|
|
68
|
-
|
|
69
|
-
"%.1f %s" % [bytes.to_f / (1024**exp), units[exp]]
|
|
63
|
+
Omnizip::CliOutputFormatter.format_size(bytes)
|
|
70
64
|
end
|
|
71
65
|
end
|
|
72
66
|
|
|
@@ -201,16 +201,7 @@ module Omnizip
|
|
|
201
201
|
end
|
|
202
202
|
|
|
203
203
|
def format_bytes(bytes)
|
|
204
|
-
|
|
205
|
-
size = bytes.to_f
|
|
206
|
-
unit_idx = 0
|
|
207
|
-
|
|
208
|
-
while size >= 1024 && unit_idx < units.length - 1
|
|
209
|
-
size /= 1024.0
|
|
210
|
-
unit_idx += 1
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
format("%.2f %s", size, units[unit_idx])
|
|
204
|
+
Omnizip::CliOutputFormatter.format_size(bytes)
|
|
214
205
|
end
|
|
215
206
|
|
|
216
207
|
def parse_volume_size(size_str)
|
|
@@ -135,17 +135,10 @@ module Omnizip
|
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
def extract_with_patterns(archive_file, output_dir, verbose)
|
|
138
|
-
#
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
when ".rar"
|
|
143
|
-
Formats::Rar::Reader.new(archive_file).open
|
|
144
|
-
when ".tar"
|
|
145
|
-
Formats::Tar::Reader.new(archive_file).read
|
|
146
|
-
else
|
|
147
|
-
Formats::SevenZip::Reader.new(archive_file).open
|
|
148
|
-
end
|
|
138
|
+
# Route through the facade: the extension routes pick each
|
|
139
|
+
# format's reader, and the reader session holds no open
|
|
140
|
+
# resources to close
|
|
141
|
+
archive = Omnizip::Archive.open(archive_file)
|
|
149
142
|
|
|
150
143
|
# Build filter chain
|
|
151
144
|
filter = Extraction::FilterChain.new
|
|
@@ -193,8 +186,6 @@ module Omnizip
|
|
|
193
186
|
end
|
|
194
187
|
|
|
195
188
|
extracted.size
|
|
196
|
-
ensure
|
|
197
|
-
archive.close if archive.is_a?(Omnizip::Zip::File)
|
|
198
189
|
end
|
|
199
190
|
|
|
200
191
|
def extract_gzip(archive_file, output_dir, verbose)
|
|
@@ -157,24 +157,7 @@ module Omnizip
|
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
def format_bytes(bytes)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
units = %w[B KB MB GB]
|
|
163
|
-
size = bytes.to_f
|
|
164
|
-
unit_idx = 0
|
|
165
|
-
|
|
166
|
-
while size >= 1024 && unit_idx < units.length - 1
|
|
167
|
-
size /= 1024.0
|
|
168
|
-
unit_idx += 1
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
if size < 10
|
|
172
|
-
format("%.2f %s", size, units[unit_idx])
|
|
173
|
-
elsif size < 100
|
|
174
|
-
format("%.1f %s", size, units[unit_idx])
|
|
175
|
-
else
|
|
176
|
-
format("%.0f %s", size, units[unit_idx])
|
|
177
|
-
end
|
|
160
|
+
Omnizip::CliOutputFormatter.format_size(bytes)
|
|
178
161
|
end
|
|
179
162
|
|
|
180
163
|
# Helper methods to handle different entry types. Each delegates
|
|
@@ -54,7 +54,8 @@ module Omnizip
|
|
|
54
54
|
%i[comment set_mtime chmod set_attribute].none? { |key| options[key] }
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
# Read-only view for 7z archives
|
|
57
|
+
# Read-only view for 7z archives through the handler registry;
|
|
58
|
+
# the edit path is zip-only
|
|
58
59
|
def show_seven_zip_metadata(archive_path, pattern)
|
|
59
60
|
if options[:comment] || options[:set_mtime] ||
|
|
60
61
|
options[:chmod] || options[:set_attribute]
|
|
@@ -62,37 +63,37 @@ module Omnizip
|
|
|
62
63
|
"Metadata editing is only supported for ZIP archives"
|
|
63
64
|
end
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
reader.open
|
|
66
|
+
entries = Omnizip.list_archive(archive_path, details: true)
|
|
67
67
|
|
|
68
68
|
if pattern
|
|
69
|
-
entries =
|
|
70
|
-
File.fnmatch(pattern,
|
|
69
|
+
entries = entries.select do |entry|
|
|
70
|
+
File.fnmatch(pattern, entry[:name])
|
|
71
71
|
end
|
|
72
72
|
if entries.empty?
|
|
73
73
|
warn "No entries match pattern: #{pattern}"
|
|
74
74
|
return
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
entries.each
|
|
78
|
-
puts "Entry: #{entry.name}"
|
|
79
|
-
puts " Type: #{entry.is_dir ? 'Directory' : 'File'}"
|
|
80
|
-
puts " Size: #{format_size(entry.size)}"
|
|
81
|
-
# Per-entry packed sizes are not tracked by the parser
|
|
82
|
-
if entry.compressed_size&.positive?
|
|
83
|
-
puts " Compressed: #{format_size(entry.compressed_size)}"
|
|
84
|
-
end
|
|
85
|
-
puts " Modified: #{entry.mtime}" if entry.mtime
|
|
86
|
-
puts " CRC32: 0x#{entry.crc.to_s(16).upcase}" if entry.crc
|
|
87
|
-
end
|
|
77
|
+
entries.each { |entry| show_seven_zip_entry(entry) }
|
|
88
78
|
else
|
|
89
|
-
|
|
90
|
-
files = entries.reject(&:is_dir)
|
|
79
|
+
files = entries.reject { |entry| entry[:directory] }
|
|
91
80
|
puts "Archive: #{archive_path}"
|
|
92
81
|
puts "Entries: #{entries.size} " \
|
|
93
82
|
"(#{files.size} files, #{entries.size - files.size} dirs)"
|
|
94
|
-
puts "Total size: #{format_size(files.sum
|
|
83
|
+
puts "Total size: #{format_size(files.sum { |entry| entry[:size] })}"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def show_seven_zip_entry(entry)
|
|
88
|
+
puts "Entry: #{entry[:name]}"
|
|
89
|
+
puts " Type: #{entry[:directory] ? 'Directory' : 'File'}"
|
|
90
|
+
puts " Size: #{format_size(entry[:size])}"
|
|
91
|
+
# Per-entry packed sizes are not tracked by the parser
|
|
92
|
+
if entry[:compressed_size]&.positive?
|
|
93
|
+
puts " Compressed: #{format_size(entry[:compressed_size])}"
|
|
95
94
|
end
|
|
95
|
+
puts " Modified: #{entry[:mtime]}" if entry[:mtime]
|
|
96
|
+
puts " CRC32: 0x#{entry[:crc].to_s(16).upcase}" if entry[:crc]
|
|
96
97
|
end
|
|
97
98
|
|
|
98
99
|
def show_metadata(archive, pattern)
|
|
@@ -199,13 +200,7 @@ module Omnizip
|
|
|
199
200
|
end
|
|
200
201
|
|
|
201
202
|
def format_size(bytes)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
units = %w[B KB MB GB TB]
|
|
205
|
-
exp = (Math.log(bytes) / Math.log(1024)).to_i
|
|
206
|
-
exp = [exp, units.size - 1].min
|
|
207
|
-
|
|
208
|
-
"%.1f %s" % [bytes.to_f / (1024**exp), units[exp]]
|
|
203
|
+
Omnizip::CliOutputFormatter.format_size(bytes)
|
|
209
204
|
end
|
|
210
205
|
end
|
|
211
206
|
end
|
|
@@ -107,13 +107,7 @@ module Omnizip
|
|
|
107
107
|
# @param bytes [Integer] Size in bytes
|
|
108
108
|
# @return [String] Formatted size
|
|
109
109
|
def format_size(bytes)
|
|
110
|
-
|
|
111
|
-
"#{bytes} B"
|
|
112
|
-
elsif bytes < 1024 * 1024
|
|
113
|
-
"#{(bytes / 1024.0).round(1)} KB"
|
|
114
|
-
else
|
|
115
|
-
"#{(bytes / (1024.0 * 1024)).round(1)} MB"
|
|
116
|
-
end
|
|
110
|
+
Omnizip::CliOutputFormatter.format_size(bytes)
|
|
117
111
|
end
|
|
118
112
|
end
|
|
119
113
|
end
|
|
@@ -33,7 +33,10 @@ module Omnizip
|
|
|
33
33
|
FileUtils.mkdir_p(dest)
|
|
34
34
|
extracted = []
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
# Directory entries carry no content to extract
|
|
37
|
+
entries_to_extract = list_matches.reject do |entry|
|
|
38
|
+
entry_filename(entry).end_with?("/")
|
|
39
|
+
end
|
|
37
40
|
total = entries_to_extract.size
|
|
38
41
|
current = 0
|
|
39
42
|
|
|
@@ -162,7 +165,7 @@ module Omnizip
|
|
|
162
165
|
entry.get_input_stream.read
|
|
163
166
|
# allowed: some archives read entry content from the archive
|
|
164
167
|
elsif @archive.respond_to?(:read)
|
|
165
|
-
@archive.read(entry)
|
|
168
|
+
@archive.read(entry_filename(entry))
|
|
166
169
|
else
|
|
167
170
|
raise Error, "Cannot read entry content"
|
|
168
171
|
end
|
|
@@ -191,10 +194,19 @@ module Omnizip
|
|
|
191
194
|
|
|
192
195
|
# Get filename from entry
|
|
193
196
|
#
|
|
194
|
-
# @param entry [#entry_name] Entry (Omnizip::Entry
|
|
197
|
+
# @param entry [#entry_name, #name] Entry (legacy Omnizip::Entry,
|
|
198
|
+
# Archive::Entry from a reader session, or compatible)
|
|
195
199
|
# @return [String] Filename
|
|
196
200
|
def entry_filename(entry)
|
|
197
|
-
|
|
201
|
+
# allowed: entries come from a caller-supplied archive
|
|
202
|
+
if entry.respond_to?(:entry_name)
|
|
203
|
+
entry.entry_name
|
|
204
|
+
# allowed: reader-session entries expose name, not entry_name
|
|
205
|
+
elsif entry.respond_to?(:name)
|
|
206
|
+
entry.name
|
|
207
|
+
else
|
|
208
|
+
entry.to_s
|
|
209
|
+
end
|
|
198
210
|
end
|
|
199
211
|
|
|
200
212
|
# Update progress tracker
|
|
@@ -122,13 +122,7 @@ module Omnizip
|
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
def format_size(bytes)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
units = %w[B KB MB GB TB]
|
|
128
|
-
exp = (Math.log(bytes) / Math.log(1024)).to_i
|
|
129
|
-
exp = [exp, units.size - 1].min
|
|
130
|
-
|
|
131
|
-
"%.1f %s" % [bytes.to_f / (1024**exp), units[exp]]
|
|
125
|
+
Omnizip::CliOutputFormatter.format_size(bytes)
|
|
132
126
|
end
|
|
133
127
|
end
|
|
134
128
|
end
|
|
@@ -161,40 +161,6 @@ progress: nil)
|
|
|
161
161
|
Digest::MD5.digest("#{Time.now.to_f}#{rand}")
|
|
162
162
|
end
|
|
163
163
|
|
|
164
|
-
# Analyze file and calculate hashes
|
|
165
|
-
#
|
|
166
|
-
# @param file_path [String] Path to file
|
|
167
|
-
# @return [FileInfo] File information
|
|
168
|
-
def analyze_file(file_path)
|
|
169
|
-
File.open(file_path, "rb") do |io|
|
|
170
|
-
file_size = io.size
|
|
171
|
-
|
|
172
|
-
# Calculate hash of first 16KB
|
|
173
|
-
first_16k = io.read(16384) || ""
|
|
174
|
-
hash_16k = Digest::MD5.digest(first_16k)
|
|
175
|
-
|
|
176
|
-
# Calculate full file hash
|
|
177
|
-
io.rewind
|
|
178
|
-
hash_full = Digest::MD5.file(file_path).digest
|
|
179
|
-
|
|
180
|
-
# Generate file ID
|
|
181
|
-
file_id = Digest::MD5.digest("#{File.basename(file_path)}#{file_size}")
|
|
182
|
-
|
|
183
|
-
# Read file blocks
|
|
184
|
-
io.rewind
|
|
185
|
-
blocks = read_file_blocks(io)
|
|
186
|
-
|
|
187
|
-
FileInfo.new(
|
|
188
|
-
path: file_path,
|
|
189
|
-
file_id: file_id,
|
|
190
|
-
hash_16k: hash_16k,
|
|
191
|
-
hash_full: hash_full,
|
|
192
|
-
size: file_size,
|
|
193
|
-
blocks: blocks,
|
|
194
|
-
)
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
|
|
198
164
|
# Read file data into blocks
|
|
199
165
|
#
|
|
200
166
|
# @param io [IO] File IO object
|
|
@@ -69,6 +69,11 @@ module Omnizip
|
|
|
69
69
|
# @param par2_file [String] Path to .par2 index file
|
|
70
70
|
# @raise [ArgumentError] if file doesn't exist
|
|
71
71
|
def initialize(par2_file)
|
|
72
|
+
if par2_file.nil?
|
|
73
|
+
raise ArgumentError,
|
|
74
|
+
"PAR2 file is nil — no index .par2 was produced for this set"
|
|
75
|
+
end
|
|
76
|
+
|
|
72
77
|
raise ArgumentError, "PAR2 file not found: #{par2_file}" unless
|
|
73
78
|
File.exist?(par2_file)
|
|
74
79
|
|
|
@@ -145,18 +145,7 @@ module Omnizip
|
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
def format_bytes(bytes)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
units = %w[B KB MB GB]
|
|
151
|
-
size = bytes.to_f
|
|
152
|
-
unit_index = 0
|
|
153
|
-
|
|
154
|
-
while size >= 1024.0 && unit_index < units.size - 1
|
|
155
|
-
size /= 1024.0
|
|
156
|
-
unit_index += 1
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
format("%.2f %s", size, units[unit_index])
|
|
148
|
+
Omnizip::CliOutputFormatter.format_size(bytes)
|
|
160
149
|
end
|
|
161
150
|
|
|
162
151
|
def truncate(string, max_length)
|
data/lib/omnizip/profiler.rb
CHANGED
|
@@ -186,18 +186,7 @@ module Omnizip
|
|
|
186
186
|
end
|
|
187
187
|
|
|
188
188
|
def format_bytes(bytes)
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
units = %w[B KB MB GB]
|
|
192
|
-
size = bytes.to_f
|
|
193
|
-
unit_index = 0
|
|
194
|
-
|
|
195
|
-
while size >= 1024.0 && unit_index < units.size - 1
|
|
196
|
-
size /= 1024.0
|
|
197
|
-
unit_index += 1
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
format("%.2f %s", size, units[unit_index])
|
|
189
|
+
Omnizip::CliOutputFormatter.format_size(bytes)
|
|
201
190
|
end
|
|
202
191
|
end
|
|
203
192
|
end
|
|
@@ -79,37 +79,9 @@ module Omnizip
|
|
|
79
79
|
private
|
|
80
80
|
|
|
81
81
|
def extract_to_temp(temp_dir)
|
|
82
|
-
#
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
extract_zip(temp_dir)
|
|
86
|
-
when :seven_zip
|
|
87
|
-
extract_7z(temp_dir)
|
|
88
|
-
else
|
|
89
|
-
raise Omnizip::UnsupportedFormatError,
|
|
90
|
-
"Unknown archive format: #{@archive_path}"
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def extract_zip(dest)
|
|
95
|
-
Omnizip::Zip::File.open(@archive_path) do |zip|
|
|
96
|
-
zip.each do |entry|
|
|
97
|
-
entry_path = File.join(dest, entry.name)
|
|
98
|
-
|
|
99
|
-
if entry.directory?
|
|
100
|
-
FileUtils.mkdir_p(entry_path)
|
|
101
|
-
else
|
|
102
|
-
FileUtils.mkdir_p(File.dirname(entry_path))
|
|
103
|
-
zip.extract(entry, entry_path)
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def extract_7z(dest)
|
|
110
|
-
# Placeholder for 7z extraction
|
|
111
|
-
# Would use Omnizip::SevenZip::File when available
|
|
112
|
-
raise NotImplementedError, "7z extraction not yet implemented"
|
|
82
|
+
# Every routed format extracts through the handler registry,
|
|
83
|
+
# same as the convenience API
|
|
84
|
+
Omnizip.extract_archive(@archive_path, temp_dir)
|
|
113
85
|
end
|
|
114
86
|
|
|
115
87
|
def move_to_destination(temp_dir)
|
|
@@ -147,18 +119,6 @@ module Omnizip
|
|
|
147
119
|
end
|
|
148
120
|
count
|
|
149
121
|
end
|
|
150
|
-
|
|
151
|
-
def detect_format
|
|
152
|
-
File.open(@archive_path, "rb") do |f|
|
|
153
|
-
magic = f.read(4)
|
|
154
|
-
case magic
|
|
155
|
-
when "PK\x03\x04"
|
|
156
|
-
:zip
|
|
157
|
-
when "7z\xBC\xAF"
|
|
158
|
-
:seven_zip
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
122
|
end
|
|
163
123
|
end
|
|
164
124
|
end
|
data/lib/omnizip/version.rb
CHANGED