Class: CbzTools::CbrConverter

Inherits:
Object
  • Object
show all
Defined in:
lib/cbz_tools/cbr_converter.rb,
sig/cbz_tools.rbs

Overview

Converts a CBR (Comic Book RAR) archive into a CBZ (Comic Book ZIP) archive.

The CBR extraction step is delegated to an injectable extractor — anything that responds to call(cbr_path, destination_dir) and raises ExtractionError on failure. Callers (not this gem) own the extractor; this class is deliberately agnostic about which binary, library, or pure-Ruby implementation is used to expand the source.

Examples:

Single-shot conversion with an explicit extractor

extractor = MyApp::UnrarExtractor.new
CbzTools::CbrConverter.convert("path/to/comic.cbr",
  to: "path/to/comic.cbz",
  extractor: extractor)

Reusing one extractor across many conversions

extractor = MyApp::UnrarExtractor.new
converter = CbzTools::CbrConverter.new(extractor: extractor)
paths.each { |p| converter.convert(p, to: p.sub(/\.cbr\z/i, ".cbz")) }

Defined Under Namespace

Classes: ArchiveError, ExtractionError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(extractor: nil) ⇒ CbrConverter

Returns a new instance of CbrConverter.

Parameters:

  • extractor (#call, nil) (defaults to: nil)

    anything responding to call(cbr_path, destination_dir) that raises ExtractionError on failure. Required — #convert raises ArchiveError if left as nil.

  • extractor: (Object) (defaults to: nil)


68
69
70
# File 'lib/cbz_tools/cbr_converter.rb', line 68

def initialize(extractor: nil)
  @extractor = extractor
end

Instance Attribute Details

#extractor#call? (readonly)

Returns the configured extractor, or nil if none was supplied. Read-only; there is no corresponding writer.

Returns:

  • (#call, nil)

    the configured extractor, or nil if none was supplied. Read-only; there is no corresponding writer.



44
45
46
# File 'lib/cbz_tools/cbr_converter.rb', line 44

def extractor
  @extractor
end

Class Method Details

.convert(cbr_path, to:, overwrite: true, work_in: nil, extractor: nil) ⇒ String

Returns the destination CBZ path.

Parameters:

  • cbr_path (String)

    source CBR path

  • to (String)

    destination CBZ path

  • overwrite (Boolean) (defaults to: true)

    when false, raise ArchiveError if to already exists; default true

  • work_in (String, nil) (defaults to: nil)

    work directory; when nil (default), a fresh Dir.mktmpdir is created and cleaned up. When set, the converter uses that directory and leaves cleanup to the caller (useful when batching many conversions).

  • extractor (#call) (defaults to: nil)

    extractor backend; required.

Returns:

  • (String)

    the destination CBZ path

Raises:

See Also:



60
61
62
# File 'lib/cbz_tools/cbr_converter.rb', line 60

def self.convert(cbr_path, to:, overwrite: true, work_in: nil, extractor: nil)
  new(extractor: extractor).convert(cbr_path, to: to, overwrite: overwrite, work_in: work_in)
end

Instance Method Details

#convert(cbr_path, to:, overwrite: true, work_in: nil) ⇒ String

Returns the destination CBZ path.

Parameters:

  • cbr_path (String)

    source CBR path

  • to (String)

    destination CBZ path

  • overwrite (Boolean) (defaults to: true)

    when false, raise ArchiveError if to already exists; default true

  • work_in (String, nil) (defaults to: nil)

Returns:

  • (String)

    the destination CBZ path

Raises:

See Also:



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/cbz_tools/cbr_converter.rb', line 82

def convert(cbr_path, to:, overwrite: true, work_in: nil)
  ensure_extractor!
  ensure_target_slot!(to, overwrite: overwrite)
  File.delete(to) if overwrite && File.exist?(to)

  in_workdir(work_in) do |temp_dir|
    @extractor.call(cbr_path, temp_dir)
    repack(temp_dir, to)
  end

  to
end

#ensure_extractor!void

This method returns an undefined value.

Raises:



97
98
99
100
# File 'lib/cbz_tools/cbr_converter.rb', line 97

def ensure_extractor!
  raise ArchiveError,
    "No extractor configured; pass `extractor:` to CbrConverter.convert or CbrConverter.new" unless @extractor
end

#ensure_target_slot!(to, overwrite:) ⇒ void

This method returns an undefined value.

Parameters:

  • to (String)
  • overwrite: (Boolean)

Raises:



102
103
104
105
106
# File 'lib/cbz_tools/cbr_converter.rb', line 102

def ensure_target_slot!(to, overwrite:)
  return if overwrite || !File.exist?(to)

  raise ArchiveError, "Target #{to} already exists (pass overwrite: true to replace)"
end

#in_workdir(work_in) {|arg0| ... } ⇒ void

This method returns an undefined value.

Parameters:

  • work_in (String, nil)

Yields:

Yield Parameters:

  • arg0 (String)

Yield Returns:

  • (void)


108
109
110
111
112
113
114
115
# File 'lib/cbz_tools/cbr_converter.rb', line 108

def in_workdir(work_in, &block)
  if work_in
    FileUtils.mkdir_p(work_in)
    yield work_in
  else
    Dir.mktmpdir(&block)
  end
end

#repack(source_dir, target_path) ⇒ void

This method returns an undefined value.

Parameters:

  • source_dir (String)
  • target_path (String)


117
118
119
120
121
122
123
# File 'lib/cbz_tools/cbr_converter.rb', line 117

def repack(source_dir, target_path)
  Zip::File.open(target_path, create: true) do |zipfile|
    each_file_in(source_dir) { |file| add_to_zip(zipfile, source_dir, file) }
  end
rescue Zip::Error, SystemCallError => e
  raise ArchiveError, "Failed to write CBZ #{target_path}: #{e.class}: #{e.message}"
end