Skip to content

Commit

Permalink
Raise new error if GS execution fails
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan González committed May 18, 2016
1 parent 91efd6a commit 806982c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 48 deletions.
62 changes: 26 additions & 36 deletions lib/pdf_cover/converter.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
require "open3"

module PdfCover
class Converter
# NOTE: Update the generate_jpegs.sh script when changing these values
DEFAULT_FORMAT = "jpeg"
DEFAULT_QUALITY = 85
DEFAULT_RESOLUTION = 300

class CommandFailedError < StandardError
def initialize(stdout_str, stderr_str)
super("PDF conversion failed:\nSTDOUT: #{stdout_str}\nSTDERR: #{stderr_str}")
end
end

class CommandNotFoundError < StandardError
def initialize
super("Could not run the `gs` command. Make sure that GhostScript is in your PATH.")
Expand All @@ -23,15 +31,19 @@ def initialize(file, options = {})
end

# @raises PdfCover::Converter::CommandNotFoundError if GhostScript is not found
# @raises PdfCover::Converter::CommandFailedError if GhostScript returns a non-zero status
def converted_file
case convert_file
when :ok
destination_file
when :command_failed
@file
when :command_not_found
fail CommandNotFoundError
parameters = build_parameters(file_path, device)
stdout_str, stderr_str, status = execute_command("gs #{parameters}")

case status
when 0 then destination_file
when 127 then fail CommandNotFoundError
else fail CommandFailedError.new(stdout_str, stderr_str)
end
rescue => e
destination_file.close
raise e
end

private
Expand All @@ -40,38 +52,31 @@ def basename
@basename ||= File.basename(@file.path, File.extname(@file.path))
end

def build_parameters(source, device, destination)
%W(-sOutputFile='#{destination}' -dNOPAUSE
def build_parameters(source, device)
%W(-sOutputFile='#{destination_path}' -dNOPAUSE
-sDEVICE='#{device}' -dJPEGQ=#{@quality}
-dFirstPage=1 -dLastPage=1
-r#{@resolution} -q '#{source}'
-c quit
).join(" ")
end

def convert_file
parameters = build_parameters(file_path, device, File.expand_path(destination_file.path))
result = execute_command("gs #{parameters}")

if result
:ok
else
failed_result(result)
end
end

def destination_file
@destination_file ||= Tempfile.new([basename, ".#{@format}"]).tap do |file|
file.binmode
end
end

def destination_path
File.expand_path(destination_file.path)
end

def device
@format.to_s == "jpg" ? "jpeg" : @format.to_s
end

def execute_command(command)
Kernel.system(command)
Open3.capture3(command)
end

def extract_options(options)
Expand All @@ -84,23 +89,8 @@ def extract_options(options)
fail InvalidOption.new(:resolution, @resolution) unless @resolution > 1
end

def failed_result(result)
destination_file.close

if result == false
logger.warn("GhostScript execution failed: #{$CHILD_STATUS}")
:command_failed
else
:command_not_found
end
end

def file_path
@file_path ||= File.expand_path(@file.path)
end

def logger
@logger ||= defined?(Rails) ? Rails.logger : Logger.new(STDERR)
end
end
end
17 changes: 5 additions & 12 deletions spec/xing/pdf_cover/converter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
end

context "the conversion goes fine" do
let(:execution_result) { true }
let(:execution_result) { ["", "", 0] }

it "returns the generated file" do
expect(subject.converted_file).to eq(destination_file)
Expand All @@ -93,23 +93,16 @@
end

context "because the command execution failed" do
let(:execution_result) { false }
let(:execution_result) { ["", "", 1] }
let(:logger) { double(Logger) }

const_set(:CHILD_STATUS, "something went wrong")

before do
expect(subject).to receive(:logger).and_return(logger)
expect(logger).to receive(:warn)
end

it "returns the original file" do
expect(subject.converted_file).to eq(source_file)
it "generates an error" do
expect { subject.converted_file }.to raise_error(PdfCover::Converter::CommandFailedError)
end
end

context "because the GhostScript command is not found" do
let(:execution_result) { nil }
let(:execution_result) { ["", "", 127] }

it "generates an error" do
expect { subject.converted_file }.to raise_error(PdfCover::Converter::CommandNotFoundError)
Expand Down

0 comments on commit 806982c

Please sign in to comment.