ucf 0.0.1
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.
- data/Changes.rdoc +7 -0
- data/Licence.rdoc +29 -0
- data/Rakefile +83 -0
- data/ReadMe.rdoc +36 -0
- data/examples/create_ucf.rb +58 -0
- data/examples/verify_ucf.rb +44 -0
- data/lib/ucf/container.rb +344 -0
- data/lib/ucf.rb +61 -0
- data/test/data/compressed_mimetype.ucf +0 -0
- data/test/data/empty.ucf +0 -0
- data/test/data/empty.zip +0 -0
- data/test/data/example.ucf +0 -0
- data/test/data/null.file +0 -0
- data/test/tc_create.rb +104 -0
- data/test/tc_read.rb +99 -0
- data/test/ts_ucf.rb +44 -0
- data/ucf.gemspec +68 -0
- data/version.yml +4 -0
- metadata +135 -0
data/Changes.rdoc
ADDED
data/Licence.rdoc
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Copyright (c) 2013 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.
|
data/Rakefile
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# Copyright (c) 2013 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 'rubygems'
|
34
|
+
require 'rake'
|
35
|
+
require 'rake/clean'
|
36
|
+
require 'rake/testtask'
|
37
|
+
require 'rdoc/task'
|
38
|
+
require 'jeweler'
|
39
|
+
|
40
|
+
# we need to add lib to the path because we're not installed yet!
|
41
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), "lib")
|
42
|
+
require 'ucf'
|
43
|
+
|
44
|
+
task :default => [:test]
|
45
|
+
|
46
|
+
Jeweler::Tasks.new do |s|
|
47
|
+
s.name = "ucf"
|
48
|
+
s.version = UCF::Version::STRING
|
49
|
+
s.authors = ["Robert Haines"]
|
50
|
+
s.email = ["support@mygrid.org.uk"]
|
51
|
+
s.homepage = "http://www.taverna.org.uk/"
|
52
|
+
s.platform = Gem::Platform::RUBY
|
53
|
+
s.summary = "Universal Container Format (UCF) Ruby Library"
|
54
|
+
s.description = "A Ruby library for working with Universal Container "\
|
55
|
+
"Format files. See "\
|
56
|
+
"https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format "\
|
57
|
+
"for the specification."
|
58
|
+
s.require_path = "lib"
|
59
|
+
s.test_file = "test/ts_ucf.rb"
|
60
|
+
s.has_rdoc = true
|
61
|
+
s.extra_rdoc_files = ["ReadMe.rdoc", "Licence.rdoc", "Changes.rdoc"]
|
62
|
+
s.rdoc_options = ["-N", "--tab-width=2", "--main=ReadMe.rdoc"]
|
63
|
+
s.add_development_dependency('rake', '~> 10.0.4')
|
64
|
+
s.add_development_dependency('rdoc', '~> 4.0.1')
|
65
|
+
s.add_development_dependency('jeweler', '~> 1.8.4')
|
66
|
+
s.add_runtime_dependency('rubyzip', '~> 0.9.9')
|
67
|
+
end
|
68
|
+
|
69
|
+
Rake::TestTask.new do |t|
|
70
|
+
t.libs << "test"
|
71
|
+
t.test_files = FileList['test/ts_ucf.rb']
|
72
|
+
t.verbose = true
|
73
|
+
end
|
74
|
+
|
75
|
+
RDoc::Task.new do |r|
|
76
|
+
r.main = "ReadMe.rdoc"
|
77
|
+
lib = Dir.glob("lib/**/*.rb")
|
78
|
+
r.rdoc_files.include("ReadMe.rdoc", "Licence.rdoc", "Changes.rdoc", lib)
|
79
|
+
r.options << "-t Universal Container Format Ruby Library version " +
|
80
|
+
"#{UCF::Version::STRING}"
|
81
|
+
r.options << "-N"
|
82
|
+
r.options << "--tab-width=2"
|
83
|
+
end
|
data/ReadMe.rdoc
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
= Universal Container Format (UCF) Ruby Library
|
2
|
+
|
3
|
+
Authors:: Robert Haines
|
4
|
+
Contact:: mailto:support@mygrid.org.uk
|
5
|
+
URL:: http://www.taverna.org.uk/
|
6
|
+
Licence:: BSD (See Licence file or http://www.opensource.org/licenses/bsd-license.php)
|
7
|
+
Copyright:: (c) 2013 The University of Manchester, UK
|
8
|
+
|
9
|
+
|
10
|
+
== Synopsis
|
11
|
+
|
12
|
+
This is a Ruby library for working with UCF files.
|
13
|
+
|
14
|
+
See https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format
|
15
|
+
|
16
|
+
This library is a work in progress!
|
17
|
+
|
18
|
+
Examples are provided in the examples directory.
|
19
|
+
|
20
|
+
== What this library can not do yet
|
21
|
+
|
22
|
+
The basic requirements of a UCF file are all implemented but there are a
|
23
|
+
number of optional features that are not yet provided.
|
24
|
+
|
25
|
+
* In memory operation. Presently all operations are performed on files that
|
26
|
+
are resident on disk.
|
27
|
+
* META-INF directory support. Everything within the META-INF directory is
|
28
|
+
optional but will supported in a near future version.
|
29
|
+
* Changing the mimetype. It is not certain that this is a sensible operation
|
30
|
+
but is being considered for a future version.
|
31
|
+
* Digital signatures (this feature has been deferred until a future revision
|
32
|
+
of the UCF specification. It will be supported by this gem when it is added
|
33
|
+
to the specification).
|
34
|
+
* Encryption (this feature has been deferred until a future revision of the
|
35
|
+
UCF specification. It will be supported by this gem when it is added to the
|
36
|
+
specification).
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Copyright (c) 2013 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 'rubygems'
|
34
|
+
require 'ucf'
|
35
|
+
|
36
|
+
ZIP_FILE = "example.zip"
|
37
|
+
file = ARGV.length > 0 ? ARGV[0] : ZIP_FILE
|
38
|
+
|
39
|
+
File.delete(file) if File.exists?(file)
|
40
|
+
|
41
|
+
begin
|
42
|
+
UCF::Container.create(file) do |c|
|
43
|
+
|
44
|
+
# Add a cheery greeting file from a string.
|
45
|
+
c.file.open("greeting.txt", "w") do |f|
|
46
|
+
f.puts "Hello, World!"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Create a subdirectory.
|
50
|
+
c.dir.mkdir("dir")
|
51
|
+
|
52
|
+
# Copy this example code in straight from a file.
|
53
|
+
c.add("dir/code.rb", __FILE__)
|
54
|
+
end
|
55
|
+
rescue UCF::MalformedUCFError, Zip::ZipError => err
|
56
|
+
puts err.to_s
|
57
|
+
exit 1
|
58
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright (c) 2013 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 'rubygems'
|
34
|
+
require 'ucf'
|
35
|
+
|
36
|
+
ZIP_FILE = "example.zip"
|
37
|
+
file = ARGV.length > 0 ? ARGV[0] : ZIP_FILE
|
38
|
+
|
39
|
+
begin
|
40
|
+
UCF::Container.verify!(file)
|
41
|
+
rescue UCF::MalformedUCFError, Zip::ZipError => err
|
42
|
+
puts err.to_s
|
43
|
+
exit 1
|
44
|
+
end
|
@@ -0,0 +1,344 @@
|
|
1
|
+
# Copyright (c) 2013 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
|
+
require 'zip/zipfilesystem'
|
35
|
+
|
36
|
+
module UCF
|
37
|
+
|
38
|
+
# This class represents a UCF file in PK Zip format. See
|
39
|
+
# https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format
|
40
|
+
# for more details.
|
41
|
+
#
|
42
|
+
# This class mostly provides all the facilities of the <tt>Zip::ZipFile</tt>
|
43
|
+
# class in the rubyzip gem. Please also consult the rubyzip documentation:
|
44
|
+
# http://rubydoc.info/gems/rubyzip/0.9.9/frames
|
45
|
+
#
|
46
|
+
# There are code examples available with the source code of this library.
|
47
|
+
class Container
|
48
|
+
|
49
|
+
extend Forwardable
|
50
|
+
def_delegators :@zipfile, :add, :close, :comment, :commit, :dir, :extract,
|
51
|
+
:file, :find_entry, :get_entry, :get_input_stream, :get_output_stream,
|
52
|
+
:glob, :mkdir, :name, :read
|
53
|
+
|
54
|
+
private_class_method :new
|
55
|
+
|
56
|
+
# The mime-type of this UCF file. By default this is
|
57
|
+
# "application/epub+zip".
|
58
|
+
attr_reader :mimetype
|
59
|
+
|
60
|
+
# :stopdoc:
|
61
|
+
DEFAULT_MIMETYPE = "application/epub+zip"
|
62
|
+
MIMETYPE_FILE = "mimetype"
|
63
|
+
|
64
|
+
ERR_MT_NONE = "Not a UCF file. 'mimetype' file is missing."
|
65
|
+
ERR_MT_BAD_OFF = "Not a UCF file. 'mimetype' file is not at offset 0."
|
66
|
+
ERR_MT_BAD_COMP = "Not a UCF file. 'mimetype' file is compressed."
|
67
|
+
|
68
|
+
def initialize(filename)
|
69
|
+
@zipfile = open_and_check_ucf(filename)
|
70
|
+
|
71
|
+
@mimetype = read_mimetype
|
72
|
+
end
|
73
|
+
# :startdoc:
|
74
|
+
|
75
|
+
# :call-seq:
|
76
|
+
# Container.create(filename, mimetype = "application/epub+zip") -> container
|
77
|
+
# Container.create(filename, mimetype = "application/epub+zip") {|container| ...}
|
78
|
+
#
|
79
|
+
# Create a new UCF file on disk with the specified mimetype.
|
80
|
+
def Container.create(filename, mimetype = DEFAULT_MIMETYPE, &block)
|
81
|
+
::Zip::ZipOutputStream.open(filename) do |stream|
|
82
|
+
stream.put_next_entry(MIMETYPE_FILE, nil, nil, ::Zip::ZipEntry::STORED)
|
83
|
+
stream.write mimetype
|
84
|
+
end
|
85
|
+
|
86
|
+
Container.open(filename, &block)
|
87
|
+
end
|
88
|
+
|
89
|
+
# :call-seq:
|
90
|
+
# Container.open(filename) -> container
|
91
|
+
# Container.open(filename) {|container| ...}
|
92
|
+
#
|
93
|
+
# Open an existing UCF file from disk. It will be checked for conformance
|
94
|
+
# to the UCF specification upon first access.
|
95
|
+
def Container.open(filename, &block)
|
96
|
+
c = new(filename)
|
97
|
+
|
98
|
+
if block_given?
|
99
|
+
begin
|
100
|
+
yield c
|
101
|
+
ensure
|
102
|
+
c.close
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
c
|
107
|
+
end
|
108
|
+
|
109
|
+
# :call-seq:
|
110
|
+
# Container.verify(filename) -> boolean
|
111
|
+
#
|
112
|
+
# Verify that the specified UCF file conforms to the UCF specification.
|
113
|
+
# This method returns +false+ if there are any problems at all with the
|
114
|
+
# file (including if it can't be found) or +true+ if it conforms.
|
115
|
+
def Container.verify(filename)
|
116
|
+
begin
|
117
|
+
Container.verify!(filename)
|
118
|
+
rescue
|
119
|
+
return false
|
120
|
+
end
|
121
|
+
|
122
|
+
true
|
123
|
+
end
|
124
|
+
|
125
|
+
# :call-seq:
|
126
|
+
# Container.verify!(filename)
|
127
|
+
#
|
128
|
+
# Verify that the specified UCF file conforms to the UCF specification.
|
129
|
+
# This method raises exceptions when errors are found or if there is
|
130
|
+
# something fundamental wrong with the file itself (e.g. not found).
|
131
|
+
def Container.verify!(filename)
|
132
|
+
new(filename)
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
|
136
|
+
# :call-seq:
|
137
|
+
# remove(entry)
|
138
|
+
#
|
139
|
+
# Removes the specified entry. If asked to remove the special mimetype
|
140
|
+
# header file this method will do nothing.
|
141
|
+
def remove(entry)
|
142
|
+
return if mimetype_entry?(entry)
|
143
|
+
@zipfile.remove(entry)
|
144
|
+
end
|
145
|
+
|
146
|
+
# :call-seq:
|
147
|
+
# rename(entry, new_name, &continueOnExistsProc)
|
148
|
+
#
|
149
|
+
# Renames the specified entry. If asked to rename the special mimetype
|
150
|
+
# header file this method will do nothing. See the rubyzip documentation
|
151
|
+
# for details of the +continue_on_exists_proc+ parameter.
|
152
|
+
def rename(entry, new_name, &continue_on_exists_proc)
|
153
|
+
return if mimetype_entry?(entry)
|
154
|
+
@zipfile.rename(entry, new_name, continue_on_exists_proc)
|
155
|
+
end
|
156
|
+
|
157
|
+
# :call-seq:
|
158
|
+
# replace(entry, src_path)
|
159
|
+
#
|
160
|
+
# Replaces the specified entry with the contents of +src_path+ (from the
|
161
|
+
# file system). If asked to replace the special mimetype header file this
|
162
|
+
# method will do nothing.
|
163
|
+
def replace(entry, src_path)
|
164
|
+
return if mimetype_entry?(entry)
|
165
|
+
@zipfile.replace(entry, src_path)
|
166
|
+
end
|
167
|
+
|
168
|
+
# :call-seq:
|
169
|
+
# to_s -> String
|
170
|
+
#
|
171
|
+
# Return a String representation of this UCF file.
|
172
|
+
def to_s
|
173
|
+
@zipfile.to_s + " - #{@mimetype}"
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
def open_and_check_ucf(filename)
|
179
|
+
file = ::Zip::ZipFile.new(filename)
|
180
|
+
|
181
|
+
# Check mimetype file is present and correct.
|
182
|
+
entry = file.find_entry(MIMETYPE_FILE)
|
183
|
+
raise MalformedUCFError.new(ERR_MT_NONE) if entry.nil?
|
184
|
+
raise MalformedUCFError.new(ERR_MT_BAD_OFF) if entry.localHeaderOffset != 0
|
185
|
+
if entry.compression_method != ::Zip::ZipEntry::STORED
|
186
|
+
raise MalformedUCFError.new(ERR_MT_BAD_COMP)
|
187
|
+
end
|
188
|
+
|
189
|
+
file
|
190
|
+
end
|
191
|
+
|
192
|
+
def read_mimetype
|
193
|
+
@zipfile.read(MIMETYPE_FILE)
|
194
|
+
end
|
195
|
+
|
196
|
+
def mimetype_entry?(entry)
|
197
|
+
name = entry.kind_of?(ZipEntry) ? entry.name : entry
|
198
|
+
name == MIMETYPE_FILE
|
199
|
+
end
|
200
|
+
|
201
|
+
public
|
202
|
+
|
203
|
+
# Lots of extra docs out of the way at the end here...
|
204
|
+
|
205
|
+
##
|
206
|
+
# :method: add
|
207
|
+
# :call-seq:
|
208
|
+
# add(entry, src_path, &continue_on_exists_proc)
|
209
|
+
#
|
210
|
+
# Convenience method for adding the contents of a file to the UCF file.
|
211
|
+
#
|
212
|
+
# See the rubyzip documentation for details of the
|
213
|
+
# +continue_on_exists_proc+ parameter.
|
214
|
+
|
215
|
+
##
|
216
|
+
# :method: close
|
217
|
+
# :call-seq:
|
218
|
+
# close
|
219
|
+
#
|
220
|
+
# Closes the UCF file committing any changes that have been made.
|
221
|
+
|
222
|
+
##
|
223
|
+
# :method: comment
|
224
|
+
# :call-seq:
|
225
|
+
# comment -> String
|
226
|
+
#
|
227
|
+
# Returns the UCF file comment, if it has one.
|
228
|
+
|
229
|
+
##
|
230
|
+
# :method: commit
|
231
|
+
# :call-seq:
|
232
|
+
# commit
|
233
|
+
#
|
234
|
+
# Commits changes that have been made since the previous commit to the
|
235
|
+
# UCF file.
|
236
|
+
|
237
|
+
##
|
238
|
+
# :method: dir
|
239
|
+
# :call-seq:
|
240
|
+
# dir -> Zip::ZipFsDir
|
241
|
+
#
|
242
|
+
# Returns an object which can be used like ruby's built in +Dir+ (class)
|
243
|
+
# object, except that it works on the UCF file on which this method is
|
244
|
+
# invoked.
|
245
|
+
#
|
246
|
+
# See the rubyzip documentation for details.
|
247
|
+
|
248
|
+
##
|
249
|
+
# :method: extract
|
250
|
+
# :call-seq:
|
251
|
+
# extract(entry, dest_path, &on_exists_proc)
|
252
|
+
#
|
253
|
+
# Extracts the specified entry to +dest_path+.
|
254
|
+
#
|
255
|
+
# See the rubyzip documentation for details of the +on_exists_proc+
|
256
|
+
# parameter.
|
257
|
+
|
258
|
+
##
|
259
|
+
# :method: file
|
260
|
+
# :call-seq:
|
261
|
+
# dir -> Zip::ZipFsFile
|
262
|
+
#
|
263
|
+
# Returns an object which can be used like ruby's built in +File+ (class)
|
264
|
+
# object, except that it works on the UCF file on which this method is
|
265
|
+
# invoked.
|
266
|
+
#
|
267
|
+
# See the rubyzip documentation for details.
|
268
|
+
|
269
|
+
##
|
270
|
+
# :method: find_entry
|
271
|
+
# :call-seq:
|
272
|
+
# find_entry(entry) -> Zip::ZipEntry
|
273
|
+
#
|
274
|
+
# Searches for entries with the specified name. Returns +nil+ if no entry
|
275
|
+
# is found. See also +get_entry+.
|
276
|
+
|
277
|
+
##
|
278
|
+
# :method: get_entry
|
279
|
+
# :call-seq:
|
280
|
+
# get_entry(entry) -> Zip::ZipEntry
|
281
|
+
#
|
282
|
+
# Searches for an entry like +find_entry+, but throws +Errno::ENOENT+ if
|
283
|
+
# no entry is found.
|
284
|
+
|
285
|
+
##
|
286
|
+
# :method: get_input_stream
|
287
|
+
# :call-seq:
|
288
|
+
# get_input_stream(entry) -> stream
|
289
|
+
# get_input_stream(entry) {|stream| ...}
|
290
|
+
#
|
291
|
+
# Returns an input stream to the specified entry. If a block is passed the
|
292
|
+
# stream object is passed to the block and the stream is automatically
|
293
|
+
# closed afterwards just as with ruby's built in +File.open+ method.
|
294
|
+
|
295
|
+
##
|
296
|
+
# :method: get_output_stream
|
297
|
+
# :call-seq:
|
298
|
+
# get_output_stream(entry, permission_int = nil) -> stream
|
299
|
+
# get_output_stream(entry, permission_int = nil) {|stream| ...}
|
300
|
+
#
|
301
|
+
# Returns an output stream to the specified entry. If a block is passed
|
302
|
+
# the stream object is passed to the block and the stream is automatically
|
303
|
+
# closed afterwards just as with ruby's built-in +File.open+ method.
|
304
|
+
#
|
305
|
+
# See the rubyzip documentation for details of the +permission_int+
|
306
|
+
# parameter.
|
307
|
+
|
308
|
+
##
|
309
|
+
# :method: glob
|
310
|
+
# :call-seq:
|
311
|
+
# glob(*args) -> Array of Zip::ZipEntry
|
312
|
+
# glob(*args) {|entry| ...}
|
313
|
+
#
|
314
|
+
# Searches for entries given a glob.
|
315
|
+
#
|
316
|
+
# See the rubyzip documentation for details of the parameters that can be
|
317
|
+
# passed in.
|
318
|
+
|
319
|
+
##
|
320
|
+
# :method: mkdir
|
321
|
+
# :call-seq:
|
322
|
+
# mkdir(entryName, permission_int = 0755)
|
323
|
+
#
|
324
|
+
# Creates a directory.
|
325
|
+
#
|
326
|
+
# See the rubyzip documentation for details of the +permission_int+
|
327
|
+
# parameter.
|
328
|
+
|
329
|
+
##
|
330
|
+
# :method: name
|
331
|
+
# :call-seq:
|
332
|
+
# name -> String
|
333
|
+
#
|
334
|
+
# Returns the filename of this UCF file.
|
335
|
+
|
336
|
+
##
|
337
|
+
# :method: read
|
338
|
+
# :call-seq:
|
339
|
+
# read(entry) -> String
|
340
|
+
#
|
341
|
+
# Returns a string containing the contents of the specified entry.
|
342
|
+
|
343
|
+
end
|
344
|
+
end
|
data/lib/ucf.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Copyright (c) 2013 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 'yaml'
|
34
|
+
require 'ucf/container'
|
35
|
+
|
36
|
+
# This is a ruby library to read and write UCF files in PK Zip format. See the
|
37
|
+
# UCF::Container class for more information.
|
38
|
+
#
|
39
|
+
# See https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format
|
40
|
+
# for more details on the UCF.
|
41
|
+
module UCF
|
42
|
+
|
43
|
+
# Library version information.
|
44
|
+
module Version
|
45
|
+
# Version information in a Hash
|
46
|
+
INFO = YAML.load_file(File.join(File.dirname(__FILE__), "..",
|
47
|
+
"version.yml"))
|
48
|
+
|
49
|
+
# Version number as a String
|
50
|
+
STRING = [:major, :minor, :patch].map {|d| INFO[d]}.compact.join('.')
|
51
|
+
end
|
52
|
+
|
53
|
+
# Exception raised when a bad UCF is detected.
|
54
|
+
class MalformedUCFError < RuntimeError
|
55
|
+
# :stopdoc:
|
56
|
+
def initialize(message = "")
|
57
|
+
super(message)
|
58
|
+
end
|
59
|
+
# :startdoc:
|
60
|
+
end
|
61
|
+
end
|
Binary file
|
data/test/data/empty.ucf
ADDED
Binary file
|
data/test/data/empty.zip
ADDED
Binary file
|
Binary file
|
data/test/data/null.file
ADDED
File without changes
|
data/test/tc_create.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# Copyright (c) 2013 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 'tmpdir'
|
34
|
+
require 'ucf'
|
35
|
+
|
36
|
+
class TestCreation < Test::Unit::TestCase
|
37
|
+
|
38
|
+
# Check creation of standard empty ucf files.
|
39
|
+
def test_create_standard_file
|
40
|
+
Dir.mktmpdir do |dir|
|
41
|
+
filename = File.join(dir, "test.ucf")
|
42
|
+
|
43
|
+
assert_nothing_raised do
|
44
|
+
UCF::Container.create(filename) do |c|
|
45
|
+
assert(c.find_entry("mimetype").localHeaderOffset == 0)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
assert_nothing_raised(UCF::MalformedUCFError, Zip::ZipError) do
|
50
|
+
UCF::Container.verify!(filename)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Check creation of empty ucf files with a different mimetype.
|
56
|
+
def test_create_mimetype_file
|
57
|
+
mimetype = "application/x-something-really-odd"
|
58
|
+
|
59
|
+
Dir.mktmpdir do |dir|
|
60
|
+
filename = File.join(dir, "test.ucf")
|
61
|
+
|
62
|
+
assert_nothing_raised do
|
63
|
+
UCF::Container.create(filename) do |c|
|
64
|
+
assert(c.find_entry("mimetype").localHeaderOffset == 0)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
assert_nothing_raised(UCF::MalformedUCFError, Zip::ZipError) do
|
69
|
+
UCF::Container.verify!(filename)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Check creation of stuff in ucf files.
|
75
|
+
def test_create_contents_file
|
76
|
+
Dir.mktmpdir do |dir|
|
77
|
+
filename = File.join(dir, "test.ucf")
|
78
|
+
|
79
|
+
assert_nothing_raised do
|
80
|
+
UCF::Container.create(filename) do |ucf|
|
81
|
+
ucf.file.open("test.txt", "w") do |f|
|
82
|
+
f.print "testing"
|
83
|
+
end
|
84
|
+
|
85
|
+
ucf.dir.mkdir("dir1")
|
86
|
+
ucf.mkdir("dir2")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
assert_nothing_raised(UCF::MalformedUCFError, Zip::ZipError) do
|
91
|
+
UCF::Container.open(filename) do |ucf|
|
92
|
+
assert(ucf.file.exists?("test.txt"))
|
93
|
+
assert(ucf.file.exists?("dir1"))
|
94
|
+
assert(ucf.file.exists?("dir2"))
|
95
|
+
assert(!ucf.file.exists?("dir3"))
|
96
|
+
|
97
|
+
text = ucf.file.read("test.txt")
|
98
|
+
assert_equal("testing", text)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
data/test/tc_read.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# Copyright (c) 2013 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 'ucf'
|
34
|
+
|
35
|
+
class TestRead < Test::Unit::TestCase
|
36
|
+
|
37
|
+
# Check that the null file does not verify.
|
38
|
+
def test_verify_null_file
|
39
|
+
assert_raise(Zip::ZipError) do
|
40
|
+
UCF::Container.verify!($file_null)
|
41
|
+
end
|
42
|
+
|
43
|
+
assert(!UCF::Container.verify($file_null))
|
44
|
+
end
|
45
|
+
|
46
|
+
# Check that the empty ucf file does verify.
|
47
|
+
def test_verify_empty_ucf
|
48
|
+
assert_nothing_raised(UCF::MalformedUCFError, Zip::ZipError) do
|
49
|
+
UCF::Container.verify!($ucf_empty)
|
50
|
+
end
|
51
|
+
|
52
|
+
assert(UCF::Container.verify($ucf_empty))
|
53
|
+
end
|
54
|
+
|
55
|
+
# Check that the empty zip file does not verify.
|
56
|
+
def test_verify_empty_zip
|
57
|
+
assert_raise(UCF::MalformedUCFError) do
|
58
|
+
UCF::Container.verify!($zip_empty)
|
59
|
+
end
|
60
|
+
|
61
|
+
assert(!UCF::Container.verify($zip_empty))
|
62
|
+
end
|
63
|
+
|
64
|
+
# Check that a compressed mimetype file is detected.
|
65
|
+
def test_verify_compressed_mimetype
|
66
|
+
assert_raise(UCF::MalformedUCFError) do
|
67
|
+
UCF::Container.verify!($ucf_compressed_mimetype)
|
68
|
+
end
|
69
|
+
|
70
|
+
assert(!UCF::Container.verify($ucf_compressed_mimetype))
|
71
|
+
end
|
72
|
+
|
73
|
+
# Check the raw mimetype bytes
|
74
|
+
def test_raw_mimetypes
|
75
|
+
empty_ucf = File.read($ucf_empty)
|
76
|
+
assert_equal("application/epub+zip", empty_ucf[38..57])
|
77
|
+
|
78
|
+
compressed_mimetype = File.read($ucf_compressed_mimetype)
|
79
|
+
assert_not_equal("application/epub+zip", compressed_mimetype[38..57])
|
80
|
+
end
|
81
|
+
|
82
|
+
# Check reading files out of a ucf file.
|
83
|
+
def test_read_files_from_ucf
|
84
|
+
assert_nothing_raised(UCF::MalformedUCFError, Zip::ZipError) do
|
85
|
+
UCF::Container.open($ucf_example) do |ucf|
|
86
|
+
assert(ucf.file.exists?("greeting.txt"))
|
87
|
+
|
88
|
+
greeting = ucf.file.read("greeting.txt")
|
89
|
+
assert_equal("Hello, World!\n", greeting)
|
90
|
+
|
91
|
+
assert(ucf.file.exists?("dir"))
|
92
|
+
assert(ucf.file.directory?("dir"))
|
93
|
+
|
94
|
+
assert(ucf.file.exists?("dir/code.rb"))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
data/test/ts_ucf.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright (c) 2013 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 'ucf'
|
35
|
+
|
36
|
+
$file_null = "test/data/null.file"
|
37
|
+
$ucf_empty = "test/data/empty.ucf"
|
38
|
+
$zip_empty = "test/data/empty.zip"
|
39
|
+
$ucf_compressed_mimetype = "test/data/compressed_mimetype.ucf"
|
40
|
+
$ucf_example = "test/data/example.ucf"
|
41
|
+
|
42
|
+
# Run test cases.
|
43
|
+
require 'tc_create'
|
44
|
+
require 'tc_read'
|
data/ucf.gemspec
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "ucf"
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Robert Haines"]
|
12
|
+
s.date = "2013-05-24"
|
13
|
+
s.description = "A Ruby library for working with Universal Container Format files. See https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format for the specification."
|
14
|
+
s.email = ["support@mygrid.org.uk"]
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"Changes.rdoc",
|
17
|
+
"Licence.rdoc",
|
18
|
+
"ReadMe.rdoc"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
"Changes.rdoc",
|
22
|
+
"Licence.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"ReadMe.rdoc",
|
25
|
+
"examples/create_ucf.rb",
|
26
|
+
"examples/verify_ucf.rb",
|
27
|
+
"lib/ucf.rb",
|
28
|
+
"lib/ucf/container.rb",
|
29
|
+
"test/data/compressed_mimetype.ucf",
|
30
|
+
"test/data/empty.ucf",
|
31
|
+
"test/data/empty.zip",
|
32
|
+
"test/data/example.ucf",
|
33
|
+
"test/data/null.file",
|
34
|
+
"test/tc_create.rb",
|
35
|
+
"test/tc_read.rb",
|
36
|
+
"test/ts_ucf.rb",
|
37
|
+
"ucf.gemspec",
|
38
|
+
"version.yml"
|
39
|
+
]
|
40
|
+
s.homepage = "http://www.taverna.org.uk/"
|
41
|
+
s.rdoc_options = ["-N", "--tab-width=2", "--main=ReadMe.rdoc"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubygems_version = "1.8.21"
|
44
|
+
s.summary = "Universal Container Format (UCF) Ruby Library"
|
45
|
+
s.test_files = ["test/ts_ucf.rb"]
|
46
|
+
|
47
|
+
if s.respond_to? :specification_version then
|
48
|
+
s.specification_version = 3
|
49
|
+
|
50
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
51
|
+
s.add_development_dependency(%q<rake>, ["~> 10.0.4"])
|
52
|
+
s.add_development_dependency(%q<rdoc>, ["~> 4.0.1"])
|
53
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
54
|
+
s.add_runtime_dependency(%q<rubyzip>, ["~> 0.9.9"])
|
55
|
+
else
|
56
|
+
s.add_dependency(%q<rake>, ["~> 10.0.4"])
|
57
|
+
s.add_dependency(%q<rdoc>, ["~> 4.0.1"])
|
58
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
59
|
+
s.add_dependency(%q<rubyzip>, ["~> 0.9.9"])
|
60
|
+
end
|
61
|
+
else
|
62
|
+
s.add_dependency(%q<rake>, ["~> 10.0.4"])
|
63
|
+
s.add_dependency(%q<rdoc>, ["~> 4.0.1"])
|
64
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
65
|
+
s.add_dependency(%q<rubyzip>, ["~> 0.9.9"])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
data/version.yml
ADDED
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ucf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Robert Haines
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 10.0.4
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 10.0.4
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rdoc
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 4.0.1
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 4.0.1
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: jeweler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.8.4
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.8.4
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rubyzip
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.9.9
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.9.9
|
78
|
+
description: A Ruby library for working with Universal Container Format files. See
|
79
|
+
https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format for the specification.
|
80
|
+
email:
|
81
|
+
- support@mygrid.org.uk
|
82
|
+
executables: []
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files:
|
85
|
+
- Changes.rdoc
|
86
|
+
- Licence.rdoc
|
87
|
+
- ReadMe.rdoc
|
88
|
+
files:
|
89
|
+
- Changes.rdoc
|
90
|
+
- Licence.rdoc
|
91
|
+
- Rakefile
|
92
|
+
- ReadMe.rdoc
|
93
|
+
- examples/create_ucf.rb
|
94
|
+
- examples/verify_ucf.rb
|
95
|
+
- lib/ucf.rb
|
96
|
+
- lib/ucf/container.rb
|
97
|
+
- test/data/compressed_mimetype.ucf
|
98
|
+
- test/data/empty.ucf
|
99
|
+
- test/data/empty.zip
|
100
|
+
- test/data/example.ucf
|
101
|
+
- test/data/null.file
|
102
|
+
- test/tc_create.rb
|
103
|
+
- test/tc_read.rb
|
104
|
+
- test/ts_ucf.rb
|
105
|
+
- ucf.gemspec
|
106
|
+
- version.yml
|
107
|
+
homepage: http://www.taverna.org.uk/
|
108
|
+
licenses: []
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options:
|
111
|
+
- -N
|
112
|
+
- --tab-width=2
|
113
|
+
- --main=ReadMe.rdoc
|
114
|
+
require_paths:
|
115
|
+
- lib
|
116
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 1.8.21
|
131
|
+
signing_key:
|
132
|
+
specification_version: 3
|
133
|
+
summary: Universal Container Format (UCF) Ruby Library
|
134
|
+
test_files:
|
135
|
+
- test/ts_ucf.rb
|