Class: Uniword::Ooxml::PackageFile
- Inherits:
-
Object
- Object
- Uniword::Ooxml::PackageFile
- Defined in:
- lib/uniword/ooxml/package_file.rb
Overview
Abstract base class for Office Open XML package files
Provides common functionality for ZIP-based Office formats:
-
Extraction to temporary directory
-
Packaging from temporary directory to ZIP
-
File reading/writing within extracted package
-
Cleanup of temporary files
Subclasses must implement:
-
load_content: Parse package contents into domain model
-
save_content: Serialize domain model into package files
Instance Attribute Summary collapse
-
#extracted_dir ⇒ Object
readonly
Temporary extraction directory.
-
#path ⇒ Object
readonly
Package file path.
Class Method Summary collapse
-
.create_empty_package_path ⇒ String
Create an empty package template.
-
.load_from_file(path) ⇒ Object
Convenience method: Load from file.
-
.save_to_file(model, output_path, template_path: nil) ⇒ String
Convenience method: Save to file.
Instance Method Summary collapse
-
#cleanup ⇒ void
Clean up temporary extraction directory.
-
#extract ⇒ String
Extract package contents to temporary directory.
-
#file_exists?(relative_path) ⇒ Boolean
Check if file exists in extracted package.
-
#initialize(path:) ⇒ PackageFile
constructor
Initialize package.
-
#load_content ⇒ Object
Load package content into domain model.
-
#package(output_path) ⇒ String
Package temporary directory contents into ZIP file.
-
#read_file(relative_path) ⇒ String
Read file from extracted package.
-
#save_content(content) ⇒ void
Save domain model content into package.
-
#write_file(relative_path, content) ⇒ void
Write file to extracted package.
Constructor Details
#initialize(path:) ⇒ PackageFile
Initialize package
44 45 46 47 |
# File 'lib/uniword/ooxml/package_file.rb', line 44 def initialize(path:) @path = path @extracted_dir = nil end |
Instance Attribute Details
#extracted_dir ⇒ Object (readonly)
Temporary extraction directory
39 40 41 |
# File 'lib/uniword/ooxml/package_file.rb', line 39 def extracted_dir @extracted_dir end |
#path ⇒ Object (readonly)
Package file path
36 37 38 |
# File 'lib/uniword/ooxml/package_file.rb', line 36 def path @path end |
Class Method Details
.create_empty_package_path ⇒ String
Create an empty package template
Subclasses may override to provide specific empty templates.
224 225 226 227 |
# File 'lib/uniword/ooxml/package_file.rb', line 224 def self.create_empty_package_path raise NotImplementedError, "#{name} must implement create_empty_package_path or provide template_path" end |
.load_from_file(path) ⇒ Object
Convenience method: Load from file
Extracts package, loads content, and returns the loaded model. Does NOT clean up automatically - caller must call cleanup.
193 194 195 196 |
# File 'lib/uniword/ooxml/package_file.rb', line 193 def self.load_from_file(path) package = new(path: path) package.load_content end |
.save_to_file(model, output_path, template_path: nil) ⇒ String
Convenience method: Save to file
Creates package from model, writes to file, and cleans up.
206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/uniword/ooxml/package_file.rb', line 206 def self.save_to_file(model, output_path, template_path: nil) # Determine source package source = template_path || create_empty_package_path package = new(path: source) package.extract package.save_content(model) package.package(output_path) package.cleanup output_path end |
Instance Method Details
#cleanup ⇒ void
This method returns an undefined value.
Clean up temporary extraction directory
Removes the temporary directory and all its contents. Safe to call multiple times.
112 113 114 115 116 117 |
# File 'lib/uniword/ooxml/package_file.rb', line 112 def cleanup return unless @extracted_dir FileUtils.rm_rf(@extracted_dir) @extracted_dir = nil end |
#extract ⇒ String
Extract package contents to temporary directory
Creates a temporary directory and extracts all ZIP contents. The extracted_dir attribute is set to the temp directory path.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/uniword/ooxml/package_file.rb', line 56 def extract unless File.exist?(@path) raise ArgumentError, "File not found: #{@path}" end @extracted_dir = Dir.mktmpdir("uniword-package-") Zip::File.open(@path) do |zip_file| zip_file.each do |entry| target_path = File.join(@extracted_dir, entry.name) FileUtils.mkdir_p(File.dirname(target_path)) entry.extract(target_path) end end @extracted_dir end |
#file_exists?(relative_path) ⇒ Boolean
Check if file exists in extracted package
152 153 154 155 156 157 |
# File 'lib/uniword/ooxml/package_file.rb', line 152 def file_exists?(relative_path) return false unless @extracted_dir full_path = File.join(@extracted_dir, relative_path) File.exist?(full_path) end |
#load_content ⇒ Object
Load package content into domain model
This is an abstract method that must be implemented by subclasses. Should extract the package and parse its contents into the appropriate domain model object.
167 168 169 170 |
# File 'lib/uniword/ooxml/package_file.rb', line 167 def load_content raise NotImplementedError, "#{self.class} must implement load_content" end |
#package(output_path) ⇒ String
Package temporary directory contents into ZIP file
Creates a new ZIP file at output_path containing all files from the extracted temporary directory.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/uniword/ooxml/package_file.rb', line 83 def package(output_path) raise "Must extract before packaging" unless @extracted_dir # Ensure output directory exists FileUtils.mkdir_p(File.dirname(output_path)) Zip::File.open(output_path, Zip::File::CREATE) do |zipfile| Dir.glob(File.join(@extracted_dir, "**", "*")).each do |file_path| next if File.directory?(file_path) # Calculate relative path within package relative_path = file_path.sub("#{@extracted_dir}/", "") # Skip if entry already exists (prevents duplicates) next if zipfile.find_entry(relative_path) zipfile.add(relative_path, file_path) end end output_path end |
#read_file(relative_path) ⇒ String
Read file from extracted package
125 126 127 128 129 130 |
# File 'lib/uniword/ooxml/package_file.rb', line 125 def read_file(relative_path) raise "Must extract before reading files" unless @extracted_dir full_path = File.join(@extracted_dir, relative_path) File.read(full_path) end |
#save_content(content) ⇒ void
This method returns an undefined value.
Save domain model content into package
This is an abstract method that must be implemented by subclasses. Should serialize the domain model and write necessary files to the extracted directory.
181 182 183 184 |
# File 'lib/uniword/ooxml/package_file.rb', line 181 def save_content(content) raise NotImplementedError, "#{self.class} must implement save_content(content)" end |
#write_file(relative_path, content) ⇒ void
This method returns an undefined value.
Write file to extracted package
Creates parent directories if needed.
140 141 142 143 144 145 146 |
# File 'lib/uniword/ooxml/package_file.rb', line 140 def write_file(relative_path, content) raise "Must extract before writing files" unless @extracted_dir full_path = File.join(@extracted_dir, relative_path) FileUtils.mkdir_p(File.dirname(full_path)) File.write(full_path, content) end |