Module: EPUB::Maker

Defined in:
lib/epub/maker.rb,
lib/epub/maker/task.rb,
lib/epub/maker/version.rb

Defined Under Namespace

Classes: Error, Task

Constant Summary collapse

VERSION =
"0.1.8"

Class Method Summary collapse

Class Method Details

.archive(source_dir, epub_file = nil) ⇒ Pathname

TODO:

Accept usage that epub-archive path/to/boo . generates ./book.epub

TODO:

Abstract ZIP library

TODO:

Accept compression method option

TODO:

Accept compression level option

Substance of epub-archive command

Parameters:

  • source_dir (Pathname, String)
  • epub_file (Pathname, String, nil) (defaults to: nil)

Returns:

  • (Pathname)

    Path to generated EPUB file

Raises:

  • (RuntimeError)

    if directory source_dir doesn’t exist

  • (Archive::Zip::Error)

    if something goes wrong around ZIP archive manipulation



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/epub/maker.rb', line 71

def archive(source_dir, epub_file = nil)
  source_dir = source_dir.to_s
  source_dir = source_dir.to_s[0..-2] if source_dir.to_s.end_with? "/"
  epub_file ||= source_dir + ".epub"
  source_dir = Pathname(source_dir)
  raise "source directory #{source_dir} not exist" unless source_dir.exist?

  epub_file = Pathname(epub_file)
  temp_dest_file = Tempfile.create(epub_file.basename.to_path, epub_file.dirname.to_path)
  temp_dest_file.close
  temp_dest = Pathname(temp_dest_file)
  Pathname.mktmpdir "epub-maker" do |dir|
    temp_container = dir/source_dir.basename

    temp_container.mkdir
    mimetype = temp_container/"mimetype"
    mimetype.write EPUB::MediaType::EPUB
    Archive::Zip.open temp_dest.to_path, :w do |archive|
      file = Archive::Zip::Entry.from_file(mimetype.to_path,  compression_codec: Archive::Zip::Codec::Store)
      archive.add_entry file
    end
    mimetype.delete
    temp_container.delete

    FileUtils.cp_r source_dir, temp_container
    mimetype.delete if mimetype.exist?
    Archive::Zip.archive temp_dest.to_path, temp_container.to_path + "/.", directories: false
    temp_dest.rename epub_file
  end

  epub_file
end

.make(path) ⇒ Object

TODO:

Add option whether mv blocks or not when file locked already

TODO:

Timeout when file shared-locked long time

Parameters:



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
50
51
52
53
54
55
56
57
58
59
# File 'lib/epub/maker.rb', line 23

def make(path)
  path = Pathname(path) unless path.kind_of? Pathname
  book = EPUB::Book.new
  dir = Pathname.mktmpdir 'epub-maker'
  temp_path = dir/path.basename
  mimetype = dir/'mimetype'
  mimetype.write EPUB::MediaType::EPUB
  Archive::Zip.open temp_path.to_path, :w do |archive|
    file = Archive::Zip::Entry.from_file(mimetype.to_path, compression_codec: Archive::Zip::Codec::Store)
    archive.add_entry file
  end

  book.epub_file = temp_path.to_path
  yield book if block_given?
  book.save

  path.open 'wb' do |file|
    raise Error, "File locked by other process: #{path}" unless file.flock File::LOCK_SH|File::LOCK_NB
    ($VERBOSE ? ::FileUtils::Verbose : ::FileUtils).move temp_path.to_path, path.to_path
  end
  dir.remove_entry_secure
  book.epub_file = path.to_path
  book

  # validate
  # build_xml
  # archive
rescue => error
  backtrace = error.backtrace
  error = error.exception([
            error.message,
            "[#{self}]Working directory remained at: #{dir}"
          ].join($RS))
  backtrace.unshift("#{__FILE__}:#{__LINE__}:in `rescue in #{__method__}'")
  error.set_backtrace backtrace
  raise error
end