Class: PdfTools
- Inherits:
-
Object
- Object
- PdfTools
- Defined in:
- lib/pdf_tools.rb
Overview
High-level PDF helpers built on top of PdfCombinator. Accepts a
heterogeneous list of inputs (URIs, file paths, Upload records,
raw PDF blobs, or anything that responds to #path), normalises
them onto disk, then merges and optionally re-orients the result.
Class Method Summary collapse
-
.combine(files = [], output_mode: :file, raw_pdf_data: false, output_file_path: nil, remove_originals: false, fix_rotation: nil, orientation: nil) ⇒ Object
files can be a an array of - URI - File Path - Upload - Anything that responds to .path alternatives, if you specify raw_pdf_data true then files is interpreted as an array of pdf blobs.
Class Method Details
.combine(files = [], output_mode: :file, raw_pdf_data: false, output_file_path: nil, remove_originals: false, fix_rotation: nil, orientation: nil) ⇒ Object
files can be a an array of
- URI
- File Path
- Upload
- Anything that responds to .path
alternatives, if you specify raw_pdf_data true then files is interpreted as an array of pdf blobs
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/pdf_tools.rb', line 13 def self.combine(files = [], output_mode: :file, raw_pdf_data: false, output_file_path: nil, remove_originals: false, fix_rotation: nil, orientation: nil) raise 'Invalid orientation specified' if orientation && !orientation.in?(%i[portrait landscape]) output_file_path ||= Upload.temp_location("combined_#{Time.current.to_i}.pdf") pdfs = [] files.compact.each do |f| if raw_pdf_data # Store blob in a temp location temp_file = Tempfile.new(%w[combined pdf], binmode: true) temp_file.write(f) temp_file.flush temp_file.fsync pdfs << temp_file.path elsif f.is_a? String # Url or Filepath? if f&.match?(URI::DEFAULT_PARSER.make_regexp) # URI remote file tmp_f = Down::Http.download(f) { |client| client.timeout(read: 120) } pdfs << tmp_f.path else # FilePath pdfs << f end elsif f.is_a? Upload # Use our new convenient method pdfs << f.to_file elsif f.respond_to? :path pdfs << f.path end end # Only combine file that exist pdfs = pdfs.compact.select { |f| File.exist?(f) }.map(&:to_s) Rails.logger.debug { "PdfTools.combine: pdfs: #{pdfs.inspect}, after pdfs.select{|f| f and File.exist?f }" } new_pdf = PdfCombinator.new pdfs.select { |f| f && File.exist?(f) }.each do |pdf_file_path| new_pdf << PdfCombinator.load(pdf_file_path) rescue HexaPDF::Error => e # Carrier sometimes returns a corrupt label PDF (no trailer, truncated, etc.). # Skip the bad file and keep batching so one bad shipment doesn't kill the # entire batched combo PDF (AppSignal #5196). ErrorReporting.warning(e, pdf_file_path: pdf_file_path, message: 'PdfTools.combine skipping malformed PDF') end # If you specify the orientation and the orientation mode does not match, fix it new_pdf.fix_orientation(orientation) if orientation || fix_rotation return_result = nil if output_mode == :file new_pdf.save output_file_path return_result = output_file_path else # Return a blob return_result = new_pdf.to_pdf end if remove_originals && File.exist?(output_file_path) # Remove all originals pdfs.each { |f| FileUtils.rm(f) } end return_result end |