Class: Scorm::Package
- Inherits:
-
Object
- Object
- Scorm::Package
- Defined in:
- lib/scorm/package.rb
Constant Summary collapse
- DEFAULT_LOAD_OPTIONS =
{ :strict => false, :dry_run => false, :cleanup => true, :force_cleanup => false, :name => nil, :repository => nil }
Instance Attribute Summary collapse
-
#manifest ⇒ Object
An instance of
Scorm::Manifest
. -
#name ⇒ Object
Name of the package.
-
#options ⇒ Object
The options hash supplied when opening the package.
-
#package ⇒ Object
The file name of the package file.
-
#path ⇒ Object
Path to the extracted course.
-
#repository ⇒ Object
The directory to which the packages is extracted.
Class Method Summary collapse
Instance Method Summary collapse
-
#cleanup ⇒ Object
Cleans up by deleting all extracted files.
-
#close ⇒ Object
Closes the package.
-
#exists?(filename) ⇒ Boolean
Returns
true
if the specified file (or directory) exists in the package. -
#extract!(force = false) ⇒ Object
Extracts the content of the package to the course repository.
-
#file(filename) ⇒ Object
Reads a file from the package.
-
#files ⇒ Object
Returns an array with the paths to all the files in the package.
-
#initialize(filename, options = {}, &block) ⇒ Package
constructor
This method will load a SCORM package and extract its content to the directory specified by the
:repository
option. -
#package? ⇒ Boolean
This will only return
true
if what was opened was an actual zip file. -
#path_to(relative_filename, relative = false) ⇒ Object
Computes the absolute path to a file in an extracted package given its relative path.
Constructor Details
#initialize(filename, options = {}, &block) ⇒ Package
This method will load a SCORM package and extract its content to the directory specified by the :repository
option. The manifest file will be parsed and made available through the manifest
instance variable. This method should be called with an associated block as it yields the opened package and then auto-magically closes it when the block has finished. It will also do any necessary cleanup if an exception occur anywhere in the block. The available options are:
:+strict+: If +false+ the manifest will be parsed in a nicer way. Default: +true+.
:+dry_run+: If +true+ nothing will be written to the file system. Default: +false+.
:+cleanup+: If +false+ no cleanup will take place if an error occur. Default: +true+.
:+name+: The name to use when extracting the package to the
repository. Default: will use the filename of the package
(minus the .zip extension).
:+repository+: Path to the course repository. Default: the same directory as the package.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/scorm/package.rb', line 53 def initialize(filename, = {}, &block) @options = DEFAULT_LOAD_OPTIONS.merge() @package = filename.respond_to?(:path) ? filename.path : filename # Check if package is a directory or a file. if File.directory?(@package) @name = File.basename(@package) @repository = File.dirname(@package) @path = File.(@package) else i = nil begin # Decide on a name for the package. @name = [(@options[:name] || File.basename(@package, File.extname(@package))), i].flatten.join # Set the path for the extracted package. @repository = @options[:repository] || File.dirname(@package) @path = File.(File.join(@repository, @name)) # First try is nil, subsequent tries sets and increments the value with # one starting at zero. i = (i || 0) + 1 # Make sure the generated path is unique. end while File.exists?(@path) end # Extract the package extract! # Detect and read imsmanifest.xml if exists?('imsmanifest.xml') @manifest = Manifest.new(self, file('imsmanifest.xml')) else raise InvalidPackage, "#{File.basename(@package)}: no imsmanifest.xml, maybe not SCORM compatible?" end # Yield to the caller. yield(self) # Make sure the package is closed when the caller has finished reading it. self.close # If an exception occur the package is auto-magically closed and any # residual data deleted in a clean way. rescue Exception => e self.close self.cleanup raise e end |
Instance Attribute Details
#manifest ⇒ Object
An instance of Scorm::Manifest
.
14 15 16 |
# File 'lib/scorm/package.rb', line 14 def manifest @manifest end |
#name ⇒ Object
Name of the package.
13 14 15 |
# File 'lib/scorm/package.rb', line 13 def name @name end |
#options ⇒ Object
The options hash supplied when opening the package.
17 18 19 |
# File 'lib/scorm/package.rb', line 17 def @options end |
#package ⇒ Object
The file name of the package file.
18 19 20 |
# File 'lib/scorm/package.rb', line 18 def package @package end |
#path ⇒ Object
Path to the extracted course.
15 16 17 |
# File 'lib/scorm/package.rb', line 15 def path @path end |
#repository ⇒ Object
The directory to which the packages is extracted.
16 17 18 |
# File 'lib/scorm/package.rb', line 16 def repository @repository end |
Class Method Details
.open(filename, options = {}, &block) ⇒ Object
33 34 35 |
# File 'lib/scorm/package.rb', line 33 def self.open(filename, = {}, &block) Package.new(filename, , &block) end |
.set_default_load_options(options = {}) ⇒ Object
29 30 31 |
# File 'lib/scorm/package.rb', line 29 def self.( = {}) DEFAULT_LOAD_OPTIONS.merge!() end |
Instance Method Details
#cleanup ⇒ Object
Cleans up by deleting all extracted files. Called when an error occurs.
114 115 116 |
# File 'lib/scorm/package.rb', line 114 def cleanup FileUtils.rmtree(@path) if @options[:cleanup] && !@options[:dry_run] && @path && File.exists?(@path) && package? end |
#close ⇒ Object
Closes the package.
105 106 107 108 109 110 111 |
# File 'lib/scorm/package.rb', line 105 def close @zipfile.close if @zipfile # Make sure the extracted package is deleted if force_cleanup_on_close # is enabled. self.cleanup if @options[:force_cleanup_on_close] end |
#exists?(filename) ⇒ Boolean
Returns true
if the specified file (or directory) exists in the package.
165 166 167 168 169 170 171 172 173 174 |
# File 'lib/scorm/package.rb', line 165 def exists?(filename) if File.exists?(@path) File.exists?(path_to(filename)) else Zip::ZipFile::foreach(@package) do |entry| return true if entry.name == filename end false end end |
#extract!(force = false) ⇒ Object
Extracts the content of the package to the course repository. This will be done automatically when opening a package so this method will rarely be used. If the dry_run
option was set to true
when the package was opened nothing will happen. This behavior can be overridden with the force
parameter.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/scorm/package.rb', line 123 def extract!(force = false) return if @options[:dry_run] && !force # If opening an already extracted package; do nothing. if not package? return end # Create the path to the course FileUtils.mkdir_p(@path) Zip::ZipFile::foreach(@package) do |entry| entry_path = File.join(@path, entry.name) entry_dir = File.dirname(entry_path) FileUtils.mkdir_p(entry_dir) unless File.exists?(entry_dir) entry.extract(entry_path) end end |
#file(filename) ⇒ Object
Reads a file from the package. If the file is not extracted yet (all files are extracted by default when opening the package) it will be extracted to the file system and its content returned. If the dry_run
option was set to true
when opening the package the file will not be extracted to the file system, but read directly into memory.
154 155 156 157 158 159 160 161 162 |
# File 'lib/scorm/package.rb', line 154 def file(filename) if File.exists?(@path) File.read(path_to(filename)) else Zip::ZipFile.foreach(@package) do |entry| return entry.get_input_stream {|io| io.read } if entry.name == filename end end end |
#files ⇒ Object
Returns an array with the paths to all the files in the package.
195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/scorm/package.rb', line 195 def files if File.directory?(@package) Dir.glob(File.join(File.join(File.(@package), '**'), '*')).reject {|f| File.directory?(f) }.map {|f| f.sub(/^#{File.(@package)}\/?/, '') } else entries = [] Zip::ZipFile::foreach(@package) do |entry| entries << entry.name unless entry.name[-1..-1] == '/' end entries end end |
#package? ⇒ Boolean
This will only return true
if what was opened was an actual zip file. It returns false
if what was opened was a filesystem directory.
144 145 146 147 |
# File 'lib/scorm/package.rb', line 144 def package? return false if File.directory?(@package) return true end |
#path_to(relative_filename, relative = false) ⇒ Object
Computes the absolute path to a file in an extracted package given its relative path. The argument relative
can be used to get the path relative to the course repository.
Ex.
<tt>pkg.path => '/var/lms/courses/MyCourse/'</tt>
<tt>pkg.course_repository => '/var/lms/courses/'</tt>
<tt>path_to('images/myimg.jpg') => '/var/lms/courses/MyCourse/images/myimg.jpg'</tt>
<tt>path_to('images/myimg.jpg', true) => 'MyCourse/images/myimg.jpg'</tt>
186 187 188 189 190 191 192 |
# File 'lib/scorm/package.rb', line 186 def path_to(relative_filename, relative = false) if relative File.join(@name, relative_filename) else File.join(@path, relative_filename) end end |