Class: Zipping::ZipBuilder
- Inherits:
-
Object
- Object
- Zipping::ZipBuilder
- Defined in:
- lib/zipping.rb
Instance Method Summary collapse
- #abs_path_for(name) ⇒ Object
- #abs_path_for_entity(entity) ⇒ Object
- #cd(dir) ⇒ Object
-
#close ⇒ Object
Create central directories.
- #current_dir ⇒ Object
- #current_dir_entity ⇒ Object
- #fix_current_dir_entity ⇒ Object
-
#fix_entity(entity) ⇒ Object
Fix an entity: time -> DOSTime object, name -> abs path in zip & encoded.
- #has_dir? ⇒ Boolean
-
#initialize(output_stream, file_division_size = 1048576, encoding = :utf8) ⇒ ZipBuilder
constructor
Initialize ZipBuilder.
- #next_dir ⇒ Object
-
#pack(files) ⇒ Object
Pack file and directory entities and output to stream.
-
#pack_current_dir ⇒ Object
Pack a directory.
- #pack_current_directory_entity ⇒ Object
-
#pack_entities(entities) ⇒ Object
Pack file entities.
- #pack_entity(entity) ⇒ Object
- #pack_file_entity(entity) ⇒ Object
- #pack_symbolic_link_entity(entity) ⇒ Object
-
#pack_symlinks ⇒ Object
Pack symlinks if its link path exists in zip.
- #postpone_dir(dir) ⇒ Object
- #postpone_symlink(link) ⇒ Object
- #queue_entity(entity, queue) ⇒ Object
-
#reset_state ⇒ Object
Attr controls.
- #root_dir? ⇒ Boolean
-
#string_to_bytes(str) ⇒ Object
Create ASCII-8bits string.
-
#subdir_entities(dir = @current_dir) ⇒ Object
Get entities of files in dir.
Constructor Details
#initialize(output_stream, file_division_size = 1048576, encoding = :utf8) ⇒ ZipBuilder
Initialize ZipBuilder. ‘files’ must be a String(file or directory path), a Hash(entity), or an Array of Strings and/or Hashes.
94 95 96 97 98 |
# File 'lib/zipping.rb', line 94 def initialize(output_stream, file_division_size = 1048576, encoding = :utf8) @w = Writer.new output_stream, file_division_size @e = encoding @l = [] end |
Instance Method Details
#abs_path_for(name) ⇒ Object
144 145 146 |
# File 'lib/zipping.rb', line 144 def abs_path_for(name) root_dir? ? name : (@current_dir[:abs_path] + '/' + name) end |
#abs_path_for_entity(entity) ⇒ Object
148 149 150 |
# File 'lib/zipping.rb', line 148 def abs_path_for_entity(entity) abs_path_for entity[:name] || File.basename(entity[:path]) end |
#cd(dir) ⇒ Object
128 129 130 |
# File 'lib/zipping.rb', line 128 def cd(dir) @current_dir = dir end |
#close ⇒ Object
Create central directories
224 225 226 227 |
# File 'lib/zipping.rb', line 224 def close pack_symlinks @w.close end |
#current_dir ⇒ Object
136 137 138 |
# File 'lib/zipping.rb', line 136 def current_dir root_dir? ? '' : @current_dir[:abs_path] end |
#current_dir_entity ⇒ Object
140 141 142 |
# File 'lib/zipping.rb', line 140 def current_dir_entity @current_dir end |
#fix_current_dir_entity ⇒ Object
169 170 171 172 173 174 175 176 |
# File 'lib/zipping.rb', line 169 def fix_current_dir_entity fix_entity(@current_dir).merge!( { binary_name: string_to_bytes(@current_dir[:abs_path] + '/'), zip_path: @current_dir[:abs_path] } ) end |
#fix_entity(entity) ⇒ Object
Fix an entity: time -> DOSTime object, name -> abs path in zip & encoded
160 161 162 163 164 165 166 167 |
# File 'lib/zipping.rb', line 160 def fix_entity(entity) { path: entity[:path], filetime: Zip::DOSTime.at(entity[:time] || File.mtime(entity[:path])), binary_name: string_to_bytes(abs_path_for_entity(entity)), zip_path: abs_path_for_entity(entity) } end |
#has_dir? ⇒ Boolean
107 108 109 |
# File 'lib/zipping.rb', line 107 def has_dir? ! @pending_dirs.empty? end |
#next_dir ⇒ Object
111 112 113 |
# File 'lib/zipping.rb', line 111 def next_dir @pending_dirs.shift end |
#pack(files) ⇒ Object
Pack file and directory entities and output to stream.
194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/zipping.rb', line 194 def pack(files) entities = Entity.entities_from files return if entities.empty? reset_state pack_entities entities while has_dir? cd next_dir pack_current_dir end end |
#pack_current_dir ⇒ Object
Pack a directory
207 208 209 210 |
# File 'lib/zipping.rb', line 207 def pack_current_dir pack_current_directory_entity pack_entities subdir_entities end |
#pack_current_directory_entity ⇒ Object
258 259 260 261 |
# File 'lib/zipping.rb', line 258 def pack_current_directory_entity @w.load_entity fix_current_dir_entity @w.write_directory_entry end |
#pack_entities(entities) ⇒ Object
Pack file entities. Directory entities are queued, not packed in this method.
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/zipping.rb', line 230 def pack_entities(entities) entities.each do |entity| # ignore bad entities next unless entity.is_a?(Hash) && entity[:path] path = entity[:path] if File.symlink? path postpone_symlink entity elsif File.directory? path postpone_dir entity elsif File.file? path pack_file_entity entity end end end |
#pack_entity(entity) ⇒ Object
263 264 265 266 |
# File 'lib/zipping.rb', line 263 def pack_entity(entity) @w.load_entity fix_entity entity yield end |
#pack_file_entity(entity) ⇒ Object
246 247 248 249 250 |
# File 'lib/zipping.rb', line 246 def pack_file_entity(entity) pack_entity entity do @w.write_file_entry end end |
#pack_symbolic_link_entity(entity) ⇒ Object
252 253 254 255 256 |
# File 'lib/zipping.rb', line 252 def pack_symbolic_link_entity(entity) pack_entity entity do @w.write_symbolic_link_entry end end |
#pack_symlinks ⇒ Object
Pack symlinks if its link path exists in zip
213 214 215 216 217 218 219 220 221 |
# File 'lib/zipping.rb', line 213 def pack_symlinks reset_state @l.each do |link| if @w.path_exists? Entity.linked_path(link[:abs_path], File.readlink(link[:path])) link[:name] = link[:abs_path] pack_symbolic_link_entity link end end end |
#postpone_dir(dir) ⇒ Object
115 116 117 |
# File 'lib/zipping.rb', line 115 def postpone_dir(dir) queue_entity dir, @pending_dirs end |
#postpone_symlink(link) ⇒ Object
119 120 121 |
# File 'lib/zipping.rb', line 119 def postpone_symlink(link) queue_entity link, @l end |
#queue_entity(entity, queue) ⇒ Object
123 124 125 126 |
# File 'lib/zipping.rb', line 123 def queue_entity(entity, queue) entity[:abs_path] = abs_path_for entity[:name] || File.basename(entity[:path]) queue << entity end |
#reset_state ⇒ Object
Attr controls
102 103 104 105 |
# File 'lib/zipping.rb', line 102 def reset_state @pending_dirs = [] @current_dir = {name: '', time: Time.now} end |
#root_dir? ⇒ Boolean
132 133 134 |
# File 'lib/zipping.rb', line 132 def root_dir? @current_dir.nil? || @current_dir[:abs_path].nil? end |
#string_to_bytes(str) ⇒ Object
Create ASCII-8bits string. Also convert encoding if needed.
179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/zipping.rb', line 179 def string_to_bytes(str) unless @e.nil? || @e == :utf8 if @e == :shift_jis begin str = str.encode 'Shift_JIS', :invalid => :replace, :undef => :replace, :replace => '??' rescue => e end end end [str].pack('a*') end |
#subdir_entities(dir = @current_dir) ⇒ Object
Get entities of files in dir
155 156 157 |
# File 'lib/zipping.rb', line 155 def subdir_entities(dir = @current_dir) Dir.glob(dir[:path] + '/*').map!{|path| {path: path, time: File.mtime(path), name: File.basename(path)}} end |