Class: EPUB::OCF::PhysicalContainer::ArchiveZip

Inherits:
EPUB::OCF::PhysicalContainer show all
Defined in:
lib/epub/maker/ocf/physical_container/archive_zip.rb

Instance Method Summary collapse

Methods inherited from EPUB::OCF::PhysicalContainer

mtime, mtime=, save, write

Instance Method Details

#write(path_name, content, mtime: nil) ⇒ Object

TODO:

Write multiple files at once



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/epub/maker/ocf/physical_container/archive_zip.rb', line 8

def write(path_name, content, mtime: nil)
  ::Dir.mktmpdir do |dir|
    tmp_archive_path = ::File.join(dir, ::File.basename(@container_path) + '.tmp')
    ::File.open @container_path do |archive_in|
      ::File.open tmp_archive_path, 'w' do |archive_out|
        archive_out.binmode
        Archive::Zip.open archive_in, :r do |z_in|
          Archive::Zip.open archive_out, :w do |z_out|
            updated = false
            z_in.each do |entry|
              if entry.zip_path == path_name.force_encoding('ASCII-8BIT')
                entry.file_data = StringIO.new(content)
                updated = true
              end
              if mtime
                entry.mtime = mtime
              end
              z_out << entry
            end
            unless updated
              entry = Archive::Zip::Entry::File.new(path_name)
              entry.file_data = StringIO.new(content)
              if mtime
                entry.mtime = mtime
              end
              z_out << entry
            end
          end
        end
      end
    end
    begin
      ::File.chmod 0666 & ~::File.umask, tmp_archive_path
      ::File.rename tmp_archive_path, @container_path
    rescue Errno::EACCES, Errno::EXDEV
      # In some cases on Windows, we fail to rename the file
      # but succeed to copy although I don't know why.
      # Race condition? I don't know. But no time to dig deeper.
      ::FileUtils.copy tmp_archive_path, @container_path
    end
  end
end