zip-container 4.0.1 → 5.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{Changes.rdoc → CHANGES.md} +53 -17
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +67 -0
- data/Gemfile +7 -0
- data/{Licence.rdoc → LICENCE} +1 -1
- data/README.md +41 -0
- data/Rakefile +8 -11
- data/bin/console +15 -0
- data/bin/setup +6 -0
- data/examples/create-zip-container +2 -2
- data/examples/verify-zip-container +2 -2
- data/examples/zip-container-info +6 -6
- data/lib/zip-container/container.rb +8 -8
- data/lib/zip-container/dir.rb +5 -15
- data/lib/zip-container/{exceptions.rb → errors.rb} +7 -9
- data/lib/zip-container/file.rb +19 -22
- data/lib/zip-container/{entries/directory.rb → managed_directory.rb} +6 -4
- data/lib/zip-container/{entries/managed.rb → managed_entries.rb} +22 -17
- data/lib/zip-container/{entries/entry.rb → managed_entry.rb} +1 -5
- data/lib/zip-container/{entries/file.rb → managed_file.rb} +3 -3
- data/lib/zip-container/{entries/reserved.rb → reserved_names.rb} +4 -5
- data/lib/zip-container/util.rb +6 -6
- data/lib/zip-container/version.rb +2 -14
- data/lib/zip-container.rb +1 -15
- data/zip-container.gemspec +30 -19
- metadata +103 -39
- data/ReadMe.rdoc +0 -73
- data/version.yml +0 -4
data/lib/zip-container/file.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013
|
1
|
+
# Copyright (c) 2013-2024 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,10 +30,13 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
+
require_relative 'container'
|
34
|
+
require_relative 'errors'
|
35
|
+
|
36
|
+
require 'zip/filesystem'
|
33
37
|
require 'forwardable'
|
34
38
|
|
35
39
|
module ZipContainer
|
36
|
-
|
37
40
|
# This class represents a ZipContainer file in PK Zip format. See the
|
38
41
|
# {OCF}[http://www.idpf.org/epub/30/spec/epub30-ocf.html] and
|
39
42
|
# {UCF}[https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format]
|
@@ -46,7 +49,6 @@ module ZipContainer
|
|
46
49
|
#
|
47
50
|
# There are code examples available with the source code of this library.
|
48
51
|
class File < Container
|
49
|
-
|
50
52
|
extend Forwardable
|
51
53
|
def_delegators :@container, :comment, :comment=, :commit_required?, :each,
|
52
54
|
:entries, :extract, :get_input_stream, :name, :read, :size
|
@@ -104,7 +106,7 @@ module ZipContainer
|
|
104
106
|
def self.each_entry(filename, &block)
|
105
107
|
c = new(filename)
|
106
108
|
|
107
|
-
if
|
109
|
+
if block
|
108
110
|
begin
|
109
111
|
c.each(&block)
|
110
112
|
ensure
|
@@ -138,12 +140,14 @@ module ZipContainer
|
|
138
140
|
# close -> boolean
|
139
141
|
#
|
140
142
|
# Commits changes that have been made since the previous commit to the
|
141
|
-
# ZipContainer file. Returns +
|
143
|
+
# ZipContainer file. Returns +false+ if no commit was required, +true+
|
142
144
|
# otherwise.
|
143
145
|
def commit
|
144
146
|
return false unless commit_required?
|
145
147
|
|
146
148
|
@container.commit if on_disk?
|
149
|
+
|
150
|
+
true
|
147
151
|
end
|
148
152
|
|
149
153
|
alias close commit
|
@@ -182,9 +186,7 @@ module ZipContainer
|
|
182
186
|
def find_entry(entry_name, options = {})
|
183
187
|
options = { include_hidden: false }.merge(options)
|
184
188
|
|
185
|
-
|
186
|
-
return if hidden_entry?(entry_name)
|
187
|
-
end
|
189
|
+
return if !options[:include_hidden] && hidden_entry?(entry_name)
|
188
190
|
|
189
191
|
@container.find_entry(entry_name)
|
190
192
|
end
|
@@ -199,9 +201,7 @@ module ZipContainer
|
|
199
201
|
def get_entry(entry, options = {})
|
200
202
|
options = { include_hidden: false }.merge(options)
|
201
203
|
|
202
|
-
|
203
|
-
raise Errno::ENOENT, entry if hidden_entry?(entry)
|
204
|
-
end
|
204
|
+
raise Errno::ENOENT, entry if !options[:include_hidden] && hidden_entry?(entry)
|
205
205
|
|
206
206
|
@container.get_entry(entry)
|
207
207
|
end
|
@@ -238,7 +238,7 @@ module ZipContainer
|
|
238
238
|
# <tt>::File::FNM_PATHNAME | ::File::FNM_DOTMATCH</tt>
|
239
239
|
# * +options+ - <tt>:include_hidden => true</tt> will include hidden
|
240
240
|
# entries in the search.
|
241
|
-
def glob(pattern, *params)
|
241
|
+
def glob(pattern, *params) # rubocop:disable Metrics/CyclomaticComplexity
|
242
242
|
flags = ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH
|
243
243
|
options = { include_hidden: false }
|
244
244
|
|
@@ -251,13 +251,13 @@ module ZipContainer
|
|
251
251
|
end
|
252
252
|
end
|
253
253
|
|
254
|
-
entries.
|
254
|
+
entries.filter_map do |entry|
|
255
255
|
next if !options[:include_hidden] && hidden_entry?(entry)
|
256
256
|
next unless ::File.fnmatch(pattern, entry.name.chomp('/'), flags)
|
257
257
|
|
258
258
|
yield(entry) if block_given?
|
259
259
|
entry
|
260
|
-
end
|
260
|
+
end
|
261
261
|
end
|
262
262
|
|
263
263
|
# :call-seq:
|
@@ -279,9 +279,7 @@ module ZipContainer
|
|
279
279
|
# permissions. The default (+0755+) is owner read, write and list; group
|
280
280
|
# read and list; and world read and list.
|
281
281
|
def mkdir(name, permission = 0o0755)
|
282
|
-
if reserved_entry?(name) || managed_file?(name)
|
283
|
-
raise ReservedNameClashError, name
|
284
|
-
end
|
282
|
+
raise ReservedNameClashError, name if reserved_entry?(name) || managed_file?(name)
|
285
283
|
|
286
284
|
@container.mkdir(name, permission)
|
287
285
|
end
|
@@ -353,13 +351,12 @@ module ZipContainer
|
|
353
351
|
def verify_mimetype
|
354
352
|
# Check mimetype file is present and correct.
|
355
353
|
entry = @container.find_entry(MIMETYPE_FILE)
|
356
|
-
|
357
354
|
return "'mimetype' file is missing." if entry.nil?
|
355
|
+
|
358
356
|
if entry.local_header_offset != 0
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
return "'mimetype' file is compressed."
|
357
|
+
"'mimetype' file is not at offset 0 in the archive."
|
358
|
+
elsif entry.compression_method != ::Zip::Entry::STORED
|
359
|
+
"'mimetype' file is compressed."
|
363
360
|
end
|
364
361
|
end
|
365
362
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013-
|
1
|
+
# Copyright (c) 2013-2024 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,9 +30,12 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
+
require_relative 'managed_entries'
|
34
|
+
require_relative 'managed_entry'
|
35
|
+
require_relative 'reserved_names'
|
36
|
+
|
33
37
|
##
|
34
38
|
module ZipContainer
|
35
|
-
|
36
39
|
# A ManagedDirectory acts as the interface to a set of (possibly) managed
|
37
40
|
# files within it and also reserves the directory name in the Container
|
38
41
|
# namespace.
|
@@ -40,7 +43,6 @@ module ZipContainer
|
|
40
43
|
# Once a ManagedDirectory is registered in a Container then only it can be
|
41
44
|
# used to write to its contents.
|
42
45
|
class ManagedDirectory < ManagedEntry
|
43
|
-
|
44
46
|
include ReservedNames
|
45
47
|
include ManagedEntries
|
46
48
|
|
@@ -77,7 +79,7 @@ module ZipContainer
|
|
77
79
|
def verify
|
78
80
|
messages = super
|
79
81
|
|
80
|
-
@files.
|
82
|
+
@files.each_value { |f| messages += f.verify }
|
81
83
|
|
82
84
|
messages
|
83
85
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013
|
1
|
+
# Copyright (c) 2013-2024 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,23 +30,25 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
+
require_relative 'errors'
|
34
|
+
require_relative 'managed_entry'
|
35
|
+
require_relative 'managed_file'
|
36
|
+
require_relative 'util'
|
37
|
+
|
33
38
|
##
|
34
39
|
module ZipContainer
|
35
|
-
|
36
40
|
# This module provides support for managed file and directory entries.
|
37
41
|
#
|
38
42
|
# <b>Note!</b> If you mix this module in you *must* call
|
39
43
|
# +initialize_managed_entries+ in your constructor to ensure that the
|
40
44
|
# internal lists of managed entries are correctly assigned.
|
41
45
|
module ManagedEntries
|
42
|
-
include Util
|
43
|
-
|
44
46
|
# :call-seq:
|
45
47
|
# managed_directories -> Array
|
46
48
|
#
|
47
49
|
# Return the list of managed directories.
|
48
50
|
def managed_directories
|
49
|
-
return @managed_directories if @managed_directories
|
51
|
+
return @managed_directories if defined?(@managed_directories)
|
50
52
|
|
51
53
|
dirs = @directories.values
|
52
54
|
@managed_directories = dirs + dirs.map(&:managed_directories).flatten
|
@@ -89,7 +91,7 @@ module ZipContainer
|
|
89
91
|
#
|
90
92
|
# Is the supplied entry/name a managed entry?
|
91
93
|
def managed_entry?(entry, list = managed_entry_names)
|
92
|
-
name = entry_name(entry)
|
94
|
+
name = Util.entry_name(entry)
|
93
95
|
list.map(&:downcase).include? name.downcase
|
94
96
|
end
|
95
97
|
|
@@ -106,7 +108,7 @@ module ZipContainer
|
|
106
108
|
#
|
107
109
|
# Is the supplied entry/name a hidden directory?
|
108
110
|
def hidden_directory?(entry)
|
109
|
-
name = entry_name(entry)
|
111
|
+
name = Util.entry_name(entry)
|
110
112
|
managed_directory?(name) ? all_managed_entries[name].hidden? : false
|
111
113
|
end
|
112
114
|
|
@@ -115,7 +117,7 @@ module ZipContainer
|
|
115
117
|
#
|
116
118
|
# Is the supplied entry/name a hidden file?
|
117
119
|
def hidden_file?(entry)
|
118
|
-
name = entry_name(entry)
|
120
|
+
name = Util.entry_name(entry)
|
119
121
|
managed_file?(name) ? all_managed_entries[name].hidden? : false
|
120
122
|
end
|
121
123
|
|
@@ -204,25 +206,28 @@ module ZipContainer
|
|
204
206
|
# the container namespace and act as an interface to the (possibly)
|
205
207
|
# managed files within it.
|
206
208
|
def register_managed_entry(entry)
|
207
|
-
unless entry.is_a?(
|
208
|
-
raise ArgumentError,
|
209
|
-
|
209
|
+
unless entry.is_a?(ManagedEntry)
|
210
|
+
raise ArgumentError,
|
211
|
+
'The supplied entry must be of type ' \
|
212
|
+
'ManagedDirectory or ManagedFile or a subclass of either.'
|
210
213
|
end
|
211
214
|
|
212
215
|
entry.parent = self
|
213
|
-
|
214
|
-
|
216
|
+
if entry.is_a?(ManagedFile)
|
217
|
+
@files[entry.name] = entry
|
218
|
+
else
|
219
|
+
@directories[entry.name] = entry
|
220
|
+
end
|
215
221
|
end
|
216
222
|
|
217
|
-
|
223
|
+
private
|
224
|
+
|
218
225
|
def all_managed_entries
|
219
|
-
return @entries
|
226
|
+
return @entries if defined?(@entries) && !@entries.nil?
|
220
227
|
|
221
228
|
all = {}
|
222
229
|
managed_entries.each { |e| all[e.full_name] = e }
|
223
230
|
@entries = all
|
224
231
|
end
|
225
|
-
# :startdoc:
|
226
|
-
|
227
232
|
end
|
228
233
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013 The University of Manchester, UK.
|
1
|
+
# Copyright (c) 2013-2024 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -32,13 +32,9 @@
|
|
32
32
|
|
33
33
|
##
|
34
34
|
module ZipContainer
|
35
|
-
|
36
35
|
# ManagedEntry is the superclass of ManagedDirectory and ManagedFile. It
|
37
36
|
# should not be used directly but may be subclassed if necessary.
|
38
37
|
class ManagedEntry
|
39
|
-
|
40
|
-
include Util
|
41
|
-
|
42
38
|
# The name of the ManagedEntry. For the full path name of this entry use
|
43
39
|
# full_name.
|
44
40
|
attr_reader :name
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013-
|
1
|
+
# Copyright (c) 2013-2024 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,12 +30,12 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
+
require_relative 'managed_entry'
|
34
|
+
|
33
35
|
##
|
34
36
|
module ZipContainer
|
35
|
-
|
36
37
|
# A ManagedFile is used to reserve a filename in a Container namespace.
|
37
38
|
class ManagedFile < ManagedEntry
|
38
|
-
|
39
39
|
# :call-seq:
|
40
40
|
# new(name, required = false, validation_proc = nil) -> ManagedFile
|
41
41
|
#
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013
|
1
|
+
# Copyright (c) 2013-2024 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,13 +30,12 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
+
require_relative 'util'
|
34
|
+
|
33
35
|
##
|
34
36
|
module ZipContainer
|
35
|
-
|
36
37
|
# This module provides support for reserved names.
|
37
38
|
module ReservedNames
|
38
|
-
include Util
|
39
|
-
|
40
39
|
# :call-seq:
|
41
40
|
# reserved_names -> Array
|
42
41
|
#
|
@@ -69,7 +68,7 @@ module ZipContainer
|
|
69
68
|
# Is the given entry in the reserved list of names? A String or a
|
70
69
|
# Zip::Entry object can be passed in here.
|
71
70
|
def reserved_entry?(entry)
|
72
|
-
name = entry_name(entry)
|
71
|
+
name = Util.entry_name(entry)
|
73
72
|
reserved_names.map(&:downcase).include? name.downcase
|
74
73
|
end
|
75
74
|
|
data/lib/zip-container/util.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014 The University of Manchester, UK.
|
1
|
+
# Copyright (c) 2014-2024 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,11 +30,14 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
+
require 'zip' # Remove this when we update to rubyzip 3.x.
|
34
|
+
require 'zip/entry'
|
35
|
+
|
33
36
|
##
|
34
37
|
module ZipContainer
|
35
|
-
|
36
38
|
# Utility methods useful throughout the rest of the ZipContainer library.
|
37
39
|
module Util
|
40
|
+
module_function
|
38
41
|
|
39
42
|
# :call-seq:
|
40
43
|
# entry_name(entry) -> String
|
@@ -48,12 +51,9 @@ module ZipContainer
|
|
48
51
|
def entry_name(entry)
|
49
52
|
name = entry.is_a?(::Zip::Entry) ? entry.name : entry
|
50
53
|
|
51
|
-
|
52
|
-
name.chop! if name.end_with?('/')
|
53
|
-
end
|
54
|
+
name.chomp!('/') if name.respond_to?(:chomp!)
|
54
55
|
|
55
56
|
name
|
56
57
|
end
|
57
|
-
|
58
58
|
end
|
59
59
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2014 The University of Manchester, UK.
|
1
|
+
# Copyright (c) 2014-2025 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,18 +30,6 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
-
require 'yaml'
|
34
|
-
|
35
33
|
module ZipContainer
|
36
|
-
|
37
|
-
# Library version information.
|
38
|
-
module Version
|
39
|
-
# Version information in a Hash
|
40
|
-
INFO = YAML.load_file(
|
41
|
-
File.join(File.dirname(__FILE__), '..', '..', 'version.yml')
|
42
|
-
)
|
43
|
-
|
44
|
-
# Version number as a String
|
45
|
-
STRING = %i[major minor patch].map { |d| INFO[d] }.compact.join('.')
|
46
|
-
end
|
34
|
+
VERSION = '5.0.0.rc1' # :nodoc:
|
47
35
|
end
|
data/lib/zip-container.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013
|
1
|
+
# Copyright (c) 2013-2024 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,20 +30,6 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
-
require 'rubygems'
|
34
|
-
require 'bundler/setup'
|
35
|
-
|
36
|
-
require 'zip/filesystem'
|
37
|
-
|
38
|
-
require 'zip-container/util'
|
39
|
-
require 'zip-container/version'
|
40
|
-
require 'zip-container/exceptions'
|
41
|
-
require 'zip-container/entries/reserved'
|
42
|
-
require 'zip-container/entries/managed'
|
43
|
-
require 'zip-container/entries/entry'
|
44
|
-
require 'zip-container/entries/file'
|
45
|
-
require 'zip-container/entries/directory'
|
46
|
-
require 'zip-container/container'
|
47
33
|
require 'zip-container/file'
|
48
34
|
require 'zip-container/dir'
|
49
35
|
|
data/zip-container.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013
|
1
|
+
# Copyright (c) 2013-2025 The University of Manchester, UK.
|
2
2
|
#
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
@@ -30,22 +30,21 @@
|
|
30
30
|
#
|
31
31
|
# Author: Robert Haines
|
32
32
|
|
33
|
-
|
34
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
35
|
-
require 'zip-container/version'
|
33
|
+
require_relative 'lib/zip-container/version'
|
36
34
|
|
37
35
|
Gem::Specification.new do |s|
|
38
36
|
s.name = 'zip-container'
|
39
|
-
s.version = ZipContainer::
|
37
|
+
s.version = ZipContainer::VERSION
|
40
38
|
s.authors = ['Robert Haines', 'Finn Bacall']
|
41
|
-
s.email = ['
|
39
|
+
s.email = ['robert.haines@manchester.ac.uk']
|
42
40
|
|
43
|
-
s.homepage = '
|
41
|
+
s.homepage = 'https://github.com/hainesr/ruby-zip-container'
|
44
42
|
s.summary = 'A ZIP Container for use by OCF and UCF implementations'
|
45
|
-
s.description =
|
46
|
-
'
|
47
|
-
'
|
48
|
-
'
|
43
|
+
s.description =
|
44
|
+
'A Ruby library for working with ZIP Container ' \
|
45
|
+
'Format files. See http://www.idpf.org/epub/30/spec/epub30-ocf.html for ' \
|
46
|
+
'the OCF specification and ' \
|
47
|
+
'https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format ' \
|
49
48
|
'for the UCF specification.'
|
50
49
|
s.license = 'BSD'
|
51
50
|
|
@@ -54,14 +53,26 @@ Gem::Specification.new do |s|
|
|
54
53
|
f.match(%r{^((test|spec|features)/|\.)})
|
55
54
|
end
|
56
55
|
|
57
|
-
s.
|
56
|
+
s.metadata = {
|
57
|
+
'bug_tracker_uri' => 'https://github.com/hainesr/ruby-zip-container/issues',
|
58
|
+
'changelog_uri' => "https://github.com/hainesr/ruby-zip-container/blob/v#{s.version}/CHANGES.md",
|
59
|
+
'documentation_uri' => 'https://hainesr.github.io/ruby-zip-container',
|
60
|
+
'source_code_uri' => "https://github.com/hainesr/ruby-zip-container/tree/v#{s.version}",
|
61
|
+
'rubygems_mfa_required' => 'true'
|
62
|
+
}
|
58
63
|
|
59
|
-
s.
|
64
|
+
s.required_ruby_version = '>= 2.7'
|
60
65
|
|
61
|
-
s.
|
62
|
-
|
63
|
-
s.add_development_dependency '
|
64
|
-
s.add_development_dependency '
|
65
|
-
s.add_development_dependency '
|
66
|
-
s.add_development_dependency '
|
66
|
+
s.add_runtime_dependency 'rubyzip', '~> 2.4'
|
67
|
+
|
68
|
+
s.add_development_dependency 'minitest', '~> 5.25'
|
69
|
+
s.add_development_dependency 'os', '~> 1.1.4'
|
70
|
+
s.add_development_dependency 'rake', '~> 13.2'
|
71
|
+
s.add_development_dependency 'rdoc', '~> 6.11'
|
72
|
+
s.add_development_dependency 'rubocop', '~> 1.50.0'
|
73
|
+
s.add_development_dependency 'rubocop-minitest', '~> 0.30.0'
|
74
|
+
s.add_development_dependency 'rubocop-performance', '~> 1.17.0'
|
75
|
+
s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
|
76
|
+
s.add_development_dependency 'simplecov', '0.22.0'
|
77
|
+
s.add_development_dependency 'simplecov-lcov', '~> 0.8'
|
67
78
|
end
|