zip-container 2.0.0 → 2.1.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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjRlNjYzODNiZDM4MDBjYjQyZDMyODIzODdmYjlhNzRkYTNmNjA4NQ==
4
+ ZmM2M2M1M2YyMWUwOTk2NWRkNjllMjU0MDc0ZjQ4NGU3OWRiNTFlMg==
5
5
  data.tar.gz: !binary |-
6
- MGRmMzVkNTI4NjI0NmVhMGNmNDZiMTIwZTNjM2FlM2E3YWIxZmY4OA==
6
+ OWFjNzFmYjM4NTliZjc4ZGE0NTZjYzNhMjBiMjJjY2Q3NGVmZjdmMw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NTk3MzMyYjM0M2U5NDgwZTYxNjE3ZDQ5YTIxMzA5NDk0YmQxMWVlOGI4ZmI4
10
- ZmI3MDFkMGNjN2NjNDZlMTA2NDk2YTIwNTU2MjA4OWNkMzBlYjRlODYyYTNk
11
- YThiMjNmODA4NjU1OGMzMjgxY2U1ZDhkMjkxMTQ4YmU1NDc5YzY=
9
+ ZmQxZTFjNzY2NjEyZGIzM2IzOTc2ZGU1ZjlkM2IwMzljZmM4NmUyN2JmNWYx
10
+ ZGU4YWU0ZjYzOTU3MjU3ZWVhZjdlNzI4MjY3MzhkYTEyNmNkOGFjNWNkZjFh
11
+ NmE1YWU3YWFjMzM0ODI0YTM2YTc4NzU3MDYyYzE2MTVjMDZjMTc=
12
12
  data.tar.gz: !binary |-
13
- NjI4YmU4MTkwY2QzNjJiYmQ5MGQ3MmJkOTA2YzRlMDc5OWQyMDA0NTBmNDcx
14
- ZDAwMWVlMzk4ZGVlYWYyZmUyMjc5MmRkN2UzOTAyZGZhZmUxZDIwZmRmM2Ew
15
- ZmE4Njk3YmQ2ODczMjNmZmE0OTlhNTc5MTZhMTM0YjVhOGExN2U=
13
+ MDBmMWJmMjE2YzY4ZjkxYWZiOWU2NzNhOTU3Njk4MDViYWIzOGYyMDEzZDlk
14
+ NTNiYTM4YmFmMjAwNDZmZGVlMjYxMTAxMDU3YTcyYWVmMmE1NjFjMGY5MGFm
15
+ YmE0MjQwOTFkZjk1MGM2ZDQyY2ZhMDViYTA0NWYyM2ZlMjk3YTU=
data/.ruby-env ADDED
@@ -0,0 +1 @@
1
+ RUBYLIB=./lib:../lib
data/.travis.yml CHANGED
@@ -1,10 +1,16 @@
1
1
  language: ruby
2
+
2
3
  rvm:
3
4
  - 1.9.3
4
5
  - 2.0.0
5
- - 2.1.2
6
+ - 2.1.5
6
7
  - ruby-head
7
8
  - rbx-2
9
+
10
+ sudo: false
11
+
12
+ cache: bundler
13
+
8
14
  matrix:
9
15
  allow_failures:
10
16
  - rvm: ruby-head
data/Changes.rdoc CHANGED
@@ -1,5 +1,22 @@
1
1
  = Changes log for the ZIP Container Ruby Gem
2
2
 
3
+ == Version 2.1.0
4
+
5
+ * Set up the Container superclass.
6
+ * Open the container from the superclass.
7
+ * Check and read the mimetype file in the superclass.
8
+ * Initialize reserved names and managed entries in the superclass.
9
+ * Refactor mimetype verification.
10
+ * Move container verification into the superclass.
11
+ * Update the example scripts to the new API.
12
+ * Move ::open to the Container superclass.
13
+ * Move ::verify and ::verify! to the superclass.
14
+ * Add the ZipContainer::Dir class.
15
+ * Add a test for a mimetype entry that is a directory.
16
+ * Add a test for an unreadable mimetype file.
17
+ * Update dependencies.
18
+ * Disambiguate the two test classes for File and Dir.
19
+
3
20
  == Version 2.0.0
4
21
 
5
22
  * Change API: Container => File.
data/ReadMe.rdoc CHANGED
@@ -19,16 +19,22 @@ This is a Ruby library for working with ZIP Container files. See the
19
19
  {UDF}[https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format]
20
20
  specifications for more details.
21
21
 
22
+ We follow the principles of {Semantic Versioning}[http://semver.org/] for our
23
+ releases.
24
+
22
25
  == Backwards incompatibility warnings!
23
26
 
24
27
  === ZipContainer
25
28
 
26
- The ZipContainer::Container class is deprecated in favour of
27
- ZipContainer::File. These classes are functionally identical; it is just a
28
- change of name. The new name brings this API into closer alignment with the
29
- underlying rubyzip API (Zip::File).
29
+ The ZipContainer::Container class is now a common superclass of
30
+ ZipContainer::Dir and ZipContainer::File. You can use ZipContainer::File as a
31
+ direct replacement for ZipContainer::Container as the functionality is
32
+ preserved. The new names bring this API into closer alignment with the
33
+ underlying rubyzip API (Zip::File) and allows this library to work with
34
+ "exploded" or unpacked containers directly.
30
35
 
31
- ZipContainer::Container is unavailable from version 2.0.0 onwards.
36
+ ZipContainer::Container should not be used directly from version 2.0.0
37
+ onwards.
32
38
 
33
39
  === Rubyzip
34
40
 
@@ -49,7 +49,7 @@ if File.exists?(container_file)
49
49
  end
50
50
 
51
51
  begin
52
- ZipContainer::Container.create(container_file, "application/epub+zip") do |c|
52
+ ZipContainer::File.create(container_file, "application/epub+zip") do |c|
53
53
 
54
54
  # Add a cheery greeting file from a string.
55
55
  c.file.open("greeting.txt", "w") do |f|
@@ -44,7 +44,7 @@ usage unless ARGV.length == 1
44
44
  container_file = ARGV[0]
45
45
 
46
46
  begin
47
- ZipContainer::Container.verify!(container_file)
47
+ ZipContainer::File.verify!(container_file)
48
48
  rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
49
49
  puts err.to_s
50
50
  exit 1
@@ -44,7 +44,7 @@ usage unless ARGV.length == 1
44
44
  container_file = ARGV[0]
45
45
 
46
46
  begin
47
- container = ZipContainer::Container.open(container_file)
47
+ container = ZipContainer::File.open(container_file)
48
48
  rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
49
49
  puts err.to_s
50
50
  exit 1
data/lib/zip-container.rb CHANGED
@@ -43,7 +43,9 @@ require 'zip-container/entries/managed'
43
43
  require 'zip-container/entries/entry'
44
44
  require 'zip-container/entries/file'
45
45
  require 'zip-container/entries/directory'
46
+ require 'zip-container/container'
46
47
  require 'zip-container/file'
48
+ require 'zip-container/dir'
47
49
 
48
50
  # This is a ruby library to read and write ZIP Container Format files. See the
49
51
  # ZipContainer::Container class for more information.
@@ -0,0 +1,131 @@
1
+ # Copyright (c) 2014 The University of Manchester, UK.
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # * Neither the names of The University of Manchester nor the names of its
16
+ # contributors may be used to endorse or promote products derived from this
17
+ # software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # Author: Robert Haines
32
+
33
+ #
34
+ module ZipContainer
35
+
36
+ # The superclass of anything that represents a Zip Container. That
37
+ # representation could be as a Zip file (most commonly), as a directory or
38
+ # something else.
39
+ class Container
40
+ include ReservedNames
41
+ include ManagedEntries
42
+
43
+ private_class_method :new
44
+
45
+ # The mime-type of this ZipContainer.
46
+ attr_reader :mimetype
47
+
48
+ # :stopdoc:
49
+ # The reserved mimetype file name for standard ZipContainers.
50
+ MIMETYPE_FILE = "mimetype"
51
+
52
+ def initialize(location)
53
+ @container = open_container(location)
54
+
55
+ check_mimetype!
56
+ @mimetype = read_mimetype
57
+
58
+ # Reserved entry names. Just the mimetype file by default.
59
+ register_reserved_name(MIMETYPE_FILE)
60
+
61
+ # Initialize the managed entry tables.
62
+ initialize_managed_entries
63
+ end
64
+ # :startdoc:
65
+
66
+ # :call-seq:
67
+ # open(filename) -> container
68
+ # open(filename) {|container| ...}
69
+ #
70
+ # Open an existing ZipContainer. It will be checked for conformance upon
71
+ # first access.
72
+ def self.open(filename, &block)
73
+ c = new(filename)
74
+
75
+ if block_given?
76
+ begin
77
+ yield c
78
+ ensure
79
+ c.close
80
+ end
81
+ end
82
+
83
+ c
84
+ end
85
+
86
+ # :call-seq:
87
+ # verify(filename) -> boolean
88
+ #
89
+ # Verify that the specified ZipContainer conforms to the specification.
90
+ # This method returns +false+ if there are any problems at all with the
91
+ # container (including if it cannot be found).
92
+ def self.verify(filename)
93
+ begin
94
+ new(filename).verify!
95
+ rescue
96
+ return false
97
+ end
98
+
99
+ true
100
+ end
101
+
102
+ # :call-seq:
103
+ # verify!(filename)
104
+ #
105
+ # Verify that the specified ZipContainer conforms to the specification.
106
+ # This method raises exceptions when errors are found or if there is
107
+ # something fundamental wrong with the container itself (e.g. it cannot be
108
+ # found).
109
+ def self.verify!(filename)
110
+ new(filename).verify!
111
+ end
112
+
113
+ # :call-seq:
114
+ # verify!
115
+ #
116
+ # Verify the contents of this ZipContainer file. All managed files and
117
+ # directories are checked to make sure that they exist, if required.
118
+ def verify!
119
+ verify_managed_entries!
120
+ end
121
+
122
+ private
123
+
124
+ def check_mimetype!
125
+ message = verify_mimetype
126
+ raise MalformedContainerError.new(message) unless message.nil?
127
+ end
128
+
129
+ end
130
+
131
+ end
@@ -0,0 +1,192 @@
1
+ # Copyright (c) 2014 The University of Manchester, UK.
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # * Neither the names of The University of Manchester nor the names of its
16
+ # contributors may be used to endorse or promote products derived from this
17
+ # software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # Author: Robert Haines
32
+
33
+ require 'forwardable'
34
+
35
+ module ZipContainer
36
+
37
+ # This class represents a ZipContainer in directory format. See the
38
+ # {OCF}[http://www.idpf.org/epub/30/spec/epub30-ocf.html] and
39
+ # {UCF}[https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format]
40
+ # specifications for more details.
41
+ #
42
+ # This class provides most of the facilities of the standard <tt>::Dir</tt>
43
+ # class. Please also consult the
44
+ # {ruby Dir documentation}[http://ruby-doc.org/core-1.9.3/Dir.html]
45
+ # alongside these pages.
46
+ #
47
+ # There are code examples available with the source code of this library.
48
+ class Dir < Container
49
+
50
+ extend Forwardable
51
+ def_delegators :@container, :close, :each, :path, :pos, :pos=, :read,
52
+ :rewind, :seek, :tell
53
+
54
+ private_class_method :new
55
+
56
+ # :stopdoc:
57
+ def initialize(location)
58
+ super(location)
59
+ end
60
+ # :startdoc:
61
+
62
+ # :call-seq:
63
+ # create(pathname, mimetype) -> document
64
+ # create(pathname, mimetype) {|document| ...}
65
+ #
66
+ # Create a new (or convert an existing) directory as a ZipContainer with
67
+ # the specified mimetype.
68
+ def self.create(pathname, mimetype, &block)
69
+ ::Dir.mkdir(pathname) unless ::File.directory?(pathname)
70
+ ::File.write(full_path(MIMETYPE_FILE), mimetype)
71
+
72
+ # Now open the newly created container.
73
+ c = new(pathname)
74
+
75
+ if block_given?
76
+ begin
77
+ yield c
78
+ ensure
79
+ c.close
80
+ end
81
+ end
82
+
83
+ c
84
+ end
85
+
86
+ private
87
+
88
+ # Prepend the full path of the directory name to whatever is passed in
89
+ # here. This is for internal use to ensure we are always operating on
90
+ # files within our container directory.
91
+ def full_path(path)
92
+ ::File.join(@container.path, path)
93
+ end
94
+
95
+ def open_container(location)
96
+ ::Dir.new(location)
97
+ end
98
+
99
+ def verify_mimetype
100
+ mime_path = full_path(MIMETYPE_FILE)
101
+ if ::File.exist?(mime_path)
102
+ return "'mimetype' is not a regular file" unless ::File.file?(mime_path)
103
+ return "'mimetype' is not readable." unless ::File.readable?(mime_path)
104
+ else
105
+ return "'mimetype' file is missing."
106
+ end
107
+ end
108
+
109
+ def read_mimetype
110
+ ::File.read(full_path(MIMETYPE_FILE))
111
+ end
112
+
113
+ public
114
+
115
+ # Lots of extra docs out of the way at the end here...
116
+
117
+ ##
118
+ # :method: close
119
+ # :call-seq:
120
+ # close -> nil
121
+ #
122
+ # Equal to
123
+ # {::Dir.close}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-close]
124
+
125
+ ##
126
+ # :method: each
127
+ # :call-seq:
128
+ # each { |filename| ... } -> dir
129
+ # each -> an_enumerator
130
+ #
131
+ # Equal to
132
+ # {::Dir.each}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-each]
133
+
134
+ ##
135
+ # :method: path
136
+ # :call-seq:
137
+ # path -> string or nil
138
+ #
139
+ # Equal to
140
+ # {::Dir.path}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-path]
141
+
142
+ ##
143
+ # :method: pos
144
+ # :call-seq:
145
+ # pos -> integer
146
+ #
147
+ # Equal to
148
+ # {::Dir.pos}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-pos]
149
+
150
+ ##
151
+ # :method: pos=
152
+ # :call-seq:
153
+ # pos = integer -> integer
154
+ #
155
+ # Equal to
156
+ # {::Dir.pos=}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-pos-3D]
157
+
158
+ ##
159
+ # :method: read
160
+ # :call-seq:
161
+ # read -> string or nil
162
+ #
163
+ # Equal to
164
+ # {::Dir.read}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-read]
165
+
166
+ ##
167
+ # :method: rewind
168
+ # :call-seq:
169
+ # rewind -> dir
170
+ #
171
+ # Equal to
172
+ # {::Dir.rewind}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-rewind]
173
+
174
+ ##
175
+ # :method: seek
176
+ # :call-seq:
177
+ # seek(integer) -> dir
178
+ #
179
+ # Equal to
180
+ # {::Dir.seek}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-seek]
181
+
182
+ ##
183
+ # :method: tell
184
+ # :call-seq:
185
+ # tell -> integer
186
+ #
187
+ # Equal to
188
+ # {::Dir.tell}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-tell]
189
+
190
+ end
191
+
192
+ end
@@ -45,36 +45,20 @@ module ZipContainer
45
45
  # alongside these pages.
46
46
  #
47
47
  # There are code examples available with the source code of this library.
48
- class File
49
- include ReservedNames
50
- include ManagedEntries
48
+ class File < Container
51
49
 
52
50
  extend Forwardable
53
- def_delegators :@zipfile, :comment, :comment=, :commit_required?, :each,
51
+ def_delegators :@container, :comment, :comment=, :commit_required?, :each,
54
52
  :entries, :extract, :get_input_stream, :name, :read, :size
55
53
 
56
54
  private_class_method :new
57
55
 
58
- # The mime-type of this ZipContainer file.
59
- attr_reader :mimetype
60
-
61
56
  # :stopdoc:
62
- # The reserved mimetype file name for standard ZipContainer documents.
63
- MIMETYPE_FILE = "mimetype"
64
-
65
- def initialize(document)
66
- @zipfile = open_document(document)
67
- check_mimetype!
57
+ def initialize(location)
58
+ super(location)
68
59
 
69
- @mimetype = read_mimetype
70
60
  @on_disk = true
71
61
 
72
- # Reserved entry names. Just the mimetype file by default.
73
- register_reserved_name(MIMETYPE_FILE)
74
-
75
- # Initialize the managed entry tables.
76
- initialize_managed_entries
77
-
78
62
  # Here we fake up the connection to the rubyzip filesystem classes so
79
63
  # that they also respect the reserved names that we define.
80
64
  mapped_zip = ::Zip::FileSystem::ZipFileNameMapper.new(self)
@@ -131,53 +115,6 @@ module ZipContainer
131
115
  c.each
132
116
  end
133
117
 
134
- # :call-seq:
135
- # File.open(filename) -> document
136
- # File.open(filename) {|document| ...}
137
- #
138
- # Open an existing ZipContainer file from disk. It will be checked for
139
- # conformance upon first access.
140
- def self.open(filename, &block)
141
- c = new(filename)
142
-
143
- if block_given?
144
- begin
145
- yield c
146
- ensure
147
- c.close
148
- end
149
- end
150
-
151
- c
152
- end
153
-
154
- # :call-seq:
155
- # File.verify(filename) -> boolean
156
- #
157
- # Verify that the specified ZipContainer file conforms to the
158
- # specification. This method returns +false+ if there are any problems at
159
- # all with the file (including if it cannot be found).
160
- def self.verify(filename)
161
- begin
162
- new(filename).verify!
163
- rescue
164
- return false
165
- end
166
-
167
- true
168
- end
169
-
170
- # :call-seq:
171
- # File.verify!(filename)
172
- #
173
- # Verify that the specified ZipContainer file conforms to the
174
- # specification. This method raises exceptions when errors are found or if
175
- # there is something fundamental wrong with the file itself (e.g. it
176
- # cannot be found).
177
- def self.verify!(filename)
178
- new(filename).verify!
179
- end
180
-
181
118
  # :call-seq:
182
119
  # add(entry, src_path, &continue_on_exists_proc)
183
120
  #
@@ -193,7 +130,7 @@ module ZipContainer
193
130
  raise ReservedNameClashError.new(entry.to_s)
194
131
  end
195
132
 
196
- @zipfile.add(entry, src_path, &continue_on_exists_proc)
133
+ @container.add(entry, src_path, &continue_on_exists_proc)
197
134
  end
198
135
 
199
136
  # :call-seq:
@@ -207,7 +144,7 @@ module ZipContainer
207
144
  return false unless commit_required?
208
145
 
209
146
  if on_disk?
210
- @zipfile.commit
147
+ @container.commit
211
148
  end
212
149
  end
213
150
 
@@ -251,7 +188,7 @@ module ZipContainer
251
188
  return if hidden_entry?(entry_name)
252
189
  end
253
190
 
254
- @zipfile.find_entry(entry_name)
191
+ @container.find_entry(entry_name)
255
192
  end
256
193
 
257
194
  # :call-seq:
@@ -268,7 +205,7 @@ module ZipContainer
268
205
  raise Errno::ENOENT, entry if hidden_entry?(entry)
269
206
  end
270
207
 
271
- @zipfile.get_entry(entry)
208
+ @container.get_entry(entry)
272
209
  end
273
210
 
274
211
  # :call-seq:
@@ -286,7 +223,7 @@ module ZipContainer
286
223
  raise ReservedNameClashError.new(entry.to_s)
287
224
  end
288
225
 
289
- @zipfile.get_output_stream(entry, permission, &block)
226
+ @container.get_output_stream(entry, permission, &block)
290
227
  end
291
228
 
292
229
  # :call-seq:
@@ -347,7 +284,7 @@ module ZipContainer
347
284
  raise ReservedNameClashError.new(name)
348
285
  end
349
286
 
350
- @zipfile.mkdir(name, permission)
287
+ @container.mkdir(name, permission)
351
288
  end
352
289
 
353
290
  # :call-seq:
@@ -366,7 +303,7 @@ module ZipContainer
366
303
  # method will do nothing.
367
304
  def remove(entry)
368
305
  return if reserved_entry?(entry)
369
- @zipfile.remove(entry)
306
+ @container.remove(entry)
370
307
  end
371
308
 
372
309
  # :call-seq:
@@ -383,7 +320,7 @@ module ZipContainer
383
320
  return if reserved_entry?(entry)
384
321
  raise ReservedNameClashError.new(new_name) if reserved_entry?(new_name)
385
322
 
386
- @zipfile.rename(entry, new_name, &continue_on_exists_proc)
323
+ @container.rename(entry, new_name, &continue_on_exists_proc)
387
324
  end
388
325
 
389
326
  # :call-seq:
@@ -395,7 +332,7 @@ module ZipContainer
395
332
  # nothing.
396
333
  def replace(entry, src_path)
397
334
  return if reserved_entry?(entry)
398
- @zipfile.replace(entry, src_path)
335
+ @container.replace(entry, src_path)
399
336
  end
400
337
 
401
338
  # :call-seq:
@@ -403,41 +340,30 @@ module ZipContainer
403
340
  #
404
341
  # Return a textual summary of this ZipContainer file.
405
342
  def to_s
406
- @zipfile.to_s + " - #{@mimetype}"
407
- end
408
-
409
- # :call-seq:
410
- # verify!
411
- #
412
- # Verify the contents of this ZipContainer file. All managed files and
413
- # directories are checked to make sure that they exist, if required.
414
- def verify!
415
- verify_managed_entries!
343
+ @container.to_s + " - #{@mimetype}"
416
344
  end
417
345
 
418
346
  private
419
347
 
420
- def open_document(document)
348
+ def open_container(document)
421
349
  ::Zip::File.new(document)
422
350
  end
423
351
 
424
- def check_mimetype!
352
+ def verify_mimetype
425
353
  # Check mimetype file is present and correct.
426
- entry = @zipfile.find_entry(MIMETYPE_FILE)
354
+ entry = @container.find_entry(MIMETYPE_FILE)
427
355
 
428
- raise MalformedContainerError.new("'mimetype' file is missing.") if entry.nil?
356
+ return "'mimetype' file is missing." if entry.nil?
429
357
  if entry.local_header_offset != 0
430
- raise MalformedContainerError.new("'mimetype' file is not at offset 0 in the archive.")
358
+ return "'mimetype' file is not at offset 0 in the archive."
431
359
  end
432
360
  if entry.compression_method != ::Zip::Entry::STORED
433
- raise MalformedContainerError.new("'mimetype' file is compressed.")
361
+ return "'mimetype' file is compressed."
434
362
  end
435
-
436
- true
437
363
  end
438
364
 
439
365
  def read_mimetype
440
- @zipfile.read(MIMETYPE_FILE)
366
+ @container.read(MIMETYPE_FILE)
441
367
  end
442
368
 
443
369
  public
@@ -0,0 +1 @@
1
+ This "mimetype" directory needs to be preserved by git.
@@ -0,0 +1 @@
1
+ application/epub+zip
@@ -0,0 +1 @@
1
+ This dir should be "empty", which in this case just means no "mimetype" file.
@@ -0,0 +1,59 @@
1
+ # Copyright (c) 2014 The University of Manchester, UK.
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # * Neither the names of The University of Manchester nor the names of its
16
+ # contributors may be used to endorse or promote products derived from this
17
+ # software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # Author: Robert Haines
32
+
33
+ require 'test/unit'
34
+ require 'tmpdir'
35
+ require 'zip-container'
36
+
37
+ class TestCreateDir < Test::Unit::TestCase
38
+
39
+ # Check that a mimetype which is not readable does not verify. We have to
40
+ # build this fixture programmatically as there's no way to add a file
41
+ # without read permissions into git.
42
+ def test_verify_unreadable_mimetype
43
+ Dir.mktmpdir do |dir|
44
+ container = File.join(dir, "unreadable")
45
+ Dir.mkdir(container)
46
+ mime_path = File.join(container, ZipContainer::Container::MIMETYPE_FILE)
47
+ File.open(mime_path, "w") { |file| file.write "MIMETYPE" }
48
+ File.chmod(0000, mime_path)
49
+
50
+ refute File.readable?(mime_path)
51
+ assert_raise(ZipContainer::MalformedContainerError) do
52
+ ZipContainer::Dir.verify!(container)
53
+ end
54
+
55
+ refute(ZipContainer::Dir.verify(container))
56
+ end
57
+ end
58
+
59
+ end
@@ -34,7 +34,7 @@ require 'test/unit'
34
34
  require 'tmpdir'
35
35
  require 'zip-container'
36
36
 
37
- class TestCreation < Test::Unit::TestCase
37
+ class TestCreateFile < Test::Unit::TestCase
38
38
 
39
39
  # Check creation of standard empty container files.
40
40
  def test_create_standard_file
@@ -0,0 +1,65 @@
1
+ # Copyright (c) 2014 The University of Manchester, UK.
2
+ #
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # * Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # * Neither the names of The University of Manchester nor the names of its
16
+ # contributors may be used to endorse or promote products derived from this
17
+ # software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+ # Author: Robert Haines
32
+
33
+ require 'test/unit'
34
+ require 'zip-container'
35
+
36
+ class TestReadDir < Test::Unit::TestCase
37
+
38
+ # Check that the empty directory does not verify.
39
+ def test_verify_empty_directory
40
+ assert_raise(ZipContainer::MalformedContainerError) do
41
+ ZipContainer::Dir.verify!($dir_null)
42
+ end
43
+
44
+ refute(ZipContainer::Dir.verify($dir_null))
45
+ end
46
+
47
+ # Check that the empty container directory does verify.
48
+ def test_verify_empty_container
49
+ assert_nothing_raised(ZipContainer::MalformedContainerError) do
50
+ ZipContainer::Dir.verify!($dir_empty)
51
+ end
52
+
53
+ assert(ZipContainer::Dir.verify($dir_empty))
54
+ end
55
+
56
+ # Check that a mimetype entry that is a directory does not verify.
57
+ def test_verify_mimetype_directory
58
+ assert_raise(ZipContainer::MalformedContainerError) do
59
+ ZipContainer::Dir.verify!($dir_dir_mimetype)
60
+ end
61
+
62
+ refute(ZipContainer::Dir.verify($dir_dir_mimetype))
63
+ end
64
+
65
+ end
@@ -33,7 +33,7 @@
33
33
  require 'test/unit'
34
34
  require 'zip-container'
35
35
 
36
- class TestRead < Test::Unit::TestCase
36
+ class TestReadFile < Test::Unit::TestCase
37
37
 
38
38
  # Check that the null file does not verify.
39
39
  def test_verify_null_file
data/test/ts_container.rb CHANGED
@@ -37,6 +37,9 @@ Coveralls.wear!
37
37
  $mimetype = "application/epub+zip"
38
38
 
39
39
  # Example data files
40
+ $dir_null = "test/data/dirs/null"
41
+ $dir_empty = "test/data/dirs/empty"
42
+ $dir_dir_mimetype = "test/data/dirs/dir-mimetype"
40
43
  $file_null = "test/data/null.file"
41
44
  $empty = "test/data/empty.container"
42
45
  $empty_zip = "test/data/empty.zip"
@@ -47,7 +50,9 @@ $subclass = "test/data/subclassed.container"
47
50
  # Run test cases.
48
51
  require 'tc_util'
49
52
  require 'tc_exceptions'
50
- require 'tc_create'
51
- require 'tc_read'
53
+ require 'tc_create_dir'
54
+ require 'tc_create_file'
55
+ require 'tc_read_dir'
56
+ require 'tc_read_file'
52
57
  require 'tc_reserved_names'
53
58
  require 'tc_managed_entries'
data/version.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 2
3
- :minor: 0
3
+ :minor: 1
4
4
  :patch: 0
@@ -55,10 +55,10 @@ Gem::Specification.new do |s|
55
55
  s.extra_rdoc_files = [ "Changes.rdoc", "Licence.rdoc", "ReadMe.rdoc" ]
56
56
  s.rdoc_options = [ "-N", "--tab-width=2", "--main=ReadMe.rdoc" ]
57
57
  s.required_ruby_version = ">= 1.9.3"
58
- s.add_development_dependency("rake", "~> 10.0.4")
59
- s.add_development_dependency("bundler", "~> 1.5")
60
- s.add_development_dependency("rdoc", "~> 4.0.1")
61
- s.add_development_dependency('coveralls')
62
- s.add_runtime_dependency("rubyzip", "~> 1.1.6")
58
+ s.add_development_dependency "bundler", "~> 1.5"
59
+ s.add_development_dependency "rake", "~> 10.1"
60
+ s.add_development_dependency "rdoc", "~> 4.1"
61
+ s.add_development_dependency "test-unit", "~> 3.0"
62
+ s.add_development_dependency "coveralls"
63
+ s.add_runtime_dependency "rubyzip", "~> 1.1.6"
63
64
  end
64
-
metadata CHANGED
@@ -1,57 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zip-container
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Haines
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-19 00:00:00.000000000 Z
11
+ date: 2014-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rake
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 10.0.4
19
+ version: '1.5'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
- version: 10.0.4
26
+ version: '1.5'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: '1.5'
33
+ version: '10.1'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: '1.5'
40
+ version: '10.1'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rdoc
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ~>
46
46
  - !ruby/object:Gem::Version
47
- version: 4.0.1
47
+ version: '4.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '4.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
66
  - - ~>
53
67
  - !ruby/object:Gem::Version
54
- version: 4.0.1
68
+ version: '3.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: coveralls
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -93,6 +107,7 @@ extra_rdoc_files:
93
107
  - ReadMe.rdoc
94
108
  files:
95
109
  - .gitignore
110
+ - .ruby-env
96
111
  - .ruby-gemset
97
112
  - .ruby-version
98
113
  - .travis.yml
@@ -105,6 +120,8 @@ files:
105
120
  - examples/verify-zip-container
106
121
  - examples/zip-container-info
107
122
  - lib/zip-container.rb
123
+ - lib/zip-container/container.rb
124
+ - lib/zip-container/dir.rb
108
125
  - lib/zip-container/entries/directory.rb
109
126
  - lib/zip-container/entries/entry.rb
110
127
  - lib/zip-container/entries/file.rb
@@ -115,16 +132,21 @@ files:
115
132
  - lib/zip-container/util.rb
116
133
  - lib/zip-container/version.rb
117
134
  - test/data/compressed_mimetype.container
135
+ - test/data/dirs/dir-mimetype/mimetype/.gitkeep
136
+ - test/data/dirs/empty/mimetype
137
+ - test/data/dirs/null/.gitkeep
118
138
  - test/data/empty.container
119
139
  - test/data/empty.zip
120
140
  - test/data/example.container
121
141
  - test/data/null.file
122
142
  - test/data/subclassed.container
123
143
  - test/helpers/entry_lists.rb
124
- - test/tc_create.rb
144
+ - test/tc_create_dir.rb
145
+ - test/tc_create_file.rb
125
146
  - test/tc_exceptions.rb
126
147
  - test/tc_managed_entries.rb
127
- - test/tc_read.rb
148
+ - test/tc_read_dir.rb
149
+ - test/tc_read_file.rb
128
150
  - test/tc_reserved_names.rb
129
151
  - test/tc_util.rb
130
152
  - test/ts_container.rb
@@ -159,16 +181,21 @@ specification_version: 4
159
181
  summary: A ZIP Container for use by OCF and UCF implementations
160
182
  test_files:
161
183
  - test/data/compressed_mimetype.container
184
+ - test/data/dirs/dir-mimetype/mimetype/.gitkeep
185
+ - test/data/dirs/empty/mimetype
186
+ - test/data/dirs/null/.gitkeep
162
187
  - test/data/empty.container
163
188
  - test/data/empty.zip
164
189
  - test/data/example.container
165
190
  - test/data/null.file
166
191
  - test/data/subclassed.container
167
192
  - test/helpers/entry_lists.rb
168
- - test/tc_create.rb
193
+ - test/tc_create_dir.rb
194
+ - test/tc_create_file.rb
169
195
  - test/tc_exceptions.rb
170
196
  - test/tc_managed_entries.rb
171
- - test/tc_read.rb
197
+ - test/tc_read_dir.rb
198
+ - test/tc_read_file.rb
172
199
  - test/tc_reserved_names.rb
173
200
  - test/tc_util.rb
174
201
  - test/ts_container.rb