How get pdf file from httparty get response - ruby-on-rails

I would like render a PDF with wicked_pdf or download it from GET response with httparty,
I succeed to do it with curl -o filename url but i dont know how do it with Rails

You can do it like this:
filename = "tmp/test.pdf"
File.open(filename, "w") do |file|
file.binmode
HTTParty.get(URL_TO_PDF, stream_body: true) do |fragment|
file.write(fragment)
end
end
Replace URL_TO_PDF with your pdf url

Related

How to combine pdf when one pdf file is stored on s3 bucket using combine pdf gem

In my task table I can access pdf file #task&.assignable&.pdf_file that is stored on s3 bucket.
I can access to its url using #task&.assignable&.pdf_file.file.url
I want to add a new page in the same pdf file so I am using combine_pdf gem. It is getting path of file1 that I have generated with wicked_pdf but on line
pdf << CombinePDF.load(#task&.assignable&.pdf_file.file.url)
It is showing error:
No such file or directory # rb_sysopen - https://patientiq1.s3-us-east-2.amazonaws.com/uploads/ < hashed_path >.pdf? < access_key >
file1_path = Rails.root.join('tmp', filename)
pdf = WickedPdf.new.pdf_from_string(
render_to_string('patient_engagements/signed_page', layout: 'pdf', locals: { :#signed_pdf => #signed_pdf })
)
File.open(file1_path, 'wb') do |file|
file << pdf
end
pdf = CombinePDF.new
pdf << CombinePDF.load(file1_path) # one way to combine, very fast.
pdf << CombinePDF.load(#task&.assignable&.pdf_file.file.url)
pdf.save "combined.pdf"
You can not use load with remote files, use parse instead
require 'combine_pdf'
require 'net/http'
url = "https://example.com/my.pdf"
pdf = CombinePDF.parse Net::HTTP.get_response(URI.parse(url)).body
Extracted from Loading and parsing DPF data at CombinePDF docs.

download and extract remote zip file using rubyzip

I am trying to download a zip file, extract the zip and read the files. Below is my code snippet:
url = "http://localhost/my.zip"
response = RestClient::Request.execute({:url => url, :method => :get, :content_type => 'application/zip'})
zipfile = Tempfile.new("downloaded")
zipfile.binmode #someone suggested to use binary for tempfile
zipfile.write(response)
Zip::ZipFile.open(zipfile.path) do |file|
file.each do |content|
data = file.read(content)
end
end
When I run this script, I see below error:
zip_central_directory.rb:97:in `get_e_o_c_d': Zip end of central directory signature not found (Zip::ZipError)
I am not able to understand what this error is for ? I can download and view the zip from the zip file url.
Couldn't get the download to work with Restclient so I used net/http instead, tested and works. Working with tempfiles and Zip gave me trouble in the past so I rather use a normal file. You can delete it afterwards.
require 'net/http'
require 'uri'
require 'zip/zip'
url = "http://localhost/my.zip"
uri = URI.parse(url)
req = Net::HTTP::Get.new(uri.path)
filename = './test.zip'
# download the zip
File.open(filename,"wb") do |file|
Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass).start(uri.host, uri.port) do |http|
http.get(uri.path) do |str|
file.write str
end
end
end
# and show it's contents
Zip::ZipFile.open(filename) do |zip|
# zip.each { |entry| p entry.get_input_stream.read } # show contents
zip.each { |entry| p entry.name } # show the name of the files inside
end
I suspect you have a corrupted zip.
Unzip cannot find the line of code that mark the end of the archive, so either:
The archive is corrupt.
It is not a .zip archive.
There are more than one parts to the archive.

Rails saving a pdf to Amazon S3

I have a Rails 3.2 app that uses gem 'wicked_pdf', and gem 'combine_pdf'.
They both work and I can create PDFs which get emailed.
But, I have run into a situation where the email would be too big.
So, I'm trying to save the created pdf to Amazon S3. The app already has the gem 'aws-sdk'.
This is my code:
def self.saveallpdf
#costprojects = Costproject.where("client_id = 2")
pdf = CombinePDF.new
#costprojects.each do |costproject|
#costproject = costproject
controller = CostprojectsController.new
controller.instance_variable_set(:"#costproject", #costproject)
pdf2 = controller.render_to_string(pdf: "Captital Projects.pdf",
template: "costprojects/viewproject",
encoding: "UTF-8")
pdf << CombinePDF.parse(pdf2)
end
#s3 = AWS::S3.new
#bucket = #s3.buckets['ndeavor3-pdf']
#obj = #bucket.objects['filename'].write(pdf, acl: :public_read)
end
The error I'm getting is:
:data must be provided as a String, Pathname, File, or an object that responds to #read and #eof?
/app/vendor/bundle/ruby/1.9.1/gems/aws-sdk-1.8.3.1/lib/aws/s3/data_options.rb:125:in `validate_data!'
/app/vendor/bundle/ruby/1.9.1/gems/aws-sdk-1.8.3.1/lib/aws/s3/data_options.rb:32:in `compute_write_options'
/app/vendor/bundle/ruby/1.9.1/gems/aws-sdk-1.8.3.1/lib/aws/s3/s3_object.rb:594:in `write'
/app/app/models/costproject.rb:167:in `saveallpdf
'
I guess was-sdk doesn't like the "pdf" as the file??
PS - I can email the "pdf" - if it was smaller in size.
Thanks for your help!
At this point in time:
#obj = #bucket.objects['filename'].write(pdf, acl: :public_read)
pdf is a CombinePDF object and not a File, String, or Pathname
pdf.to_s might work, or you will have to create a new file from the CombinePDF object
File.new(CombinePDF) # pseduo code only

Ruby on Rails - How to Save Remote File over HTTPS and Basic Authentication

I am using a supplier's api and the response they send to our server includes a url to a file, upon trying to save this file locally I fail miserably.
def self.create_file_new(filename, ext, url)
require 'open-uri'
file = Tempfile.new(filename + ext)
file.binmode
# data = open(url).read
# data = open(url, :http_basic_authentication => [username, password])
file << open(url, :http_basic_authentication => [username, password]).read
# file.write CGI::unescape(data)
file.close
file = File.open(file.path)
return file
end
I was originally getting a OpenURI::HTTPError (401 Unauthorised): but I have since created a file named bypass_ssl_verification_for_open_uri in app/initializers containing the following:
# Make open-uri work with https
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
which I found whilst Googling on how to fix it.
I then started to get this error message: NoMethodError (undefined method 'tr' for #<StringIO:0xb5b728c4>):, I tried creating another file (cgi_escape_fix.rb in app/initializers) containing this:
require 'cgi'
class << CGI
alias_method :orig_escape, :escape
def escape(str)
orig_escape(str.to_str)
end
end
Which I also found on my Google travels but that doesn't seem to have solved anything, so I commented out the file.write CGI::unescape(data) to try a different way but still no joy.
Now in the log I am just getting a plain 500 Internal Server Error with no useful information.
The file I'm attempting to save will always be a pdf.
Ruby 1.8.7
Rails 2.3.14
Got it to work with the following (two new initializer scripts removed):
file = Tempfile.new(filename + ext)
file.binmode
file << open(url, :http_basic_authentication => [username, password]).read
file.close
file = File.open(file.path)
return file
Should also mention that this is being passed to the attachment_fu plugin incase anyone else has problems with it.

Generating a PDF With Images from Base64 with Prawn

I am trying to save multiple pngs in one pdf. I'm receiving the PNGs from an API Call to the Endicia Label Server, which is giving me a Base64 Encoded Image as response.
Based on this Question:
How to convert base64 string to PNG using Prawn without saving on server in Rails
def batch_order_labels
#orders = Spree::Order.ready_to_ship.limit(1)
dt = Date.current.strftime("%d %b %Y ")
title = "Labels - #{dt} - #{#orders.count} Orders"
Prawn::Document.generate("#{title}.pdf") do |pdf|
#orders.each do |order|
label = order.generate_label
if order.international?
#image = label.response_body.scan(/<Image PartNumber=\"1\">([^<>]*)<\/Image>/imu).flatten.last
else
#image = label.image
end
file = Tempfile.new('labelimg', :encoding => 'utf-8')
file.write Base64.decode64(#image)
file.close
pdf.image file
pdf.start_new_page
end
end
send_data("#{title}.pdf")
end
But I'm receiving following error:
"\x89" from ASCII-8BIT to UTF-8
Any Idea?
There's no need to write the image data to a tempfile, Prawn::Document#image can accept a StringIO.
Try replacing this:
file = Tempfile.new('labelimg', :encoding => 'utf-8')
file.write Base64.decode64(#image)
file.close
pdf.image file
With this:
require 'stringio'
.....
image_data = StringIO.new( Base64.decode64(#image) )
pdf.image(image_data)
The Problem is, that the Api is returning this thing in UTF-8 - So I dont have a great choice.
Anyhow, I found this solution to be working
file = Tempfile.new('labelimg', :encoding => 'utf-8')
File.open(file, 'wb') do |f|
f.write Base64.decode64(#image)
end
you can't convert the Base64 to UTF-8.
Leave it as plain ASCII:
file = Tempfile.new('labelimg', :encoding => 'ascii-8bit')
file.write Base64.decode64(#image)
file.close
or even better - leave it as binary:
file = Tempfile.new('labelimg')
file.write Base64.decode64(#image)
file.close
UTF-8 is multibite format and it's not usable for transferring binary data such as pics.

Resources