Rails, i need to decode Base64 ziped pdf file - ruby-on-rails

I need to decode base64 ziped pdf file and write decoded data to a tempfile . And need to save it on over local file system.in rails.

decoded_data=Base64.decode64(encoded_data)
file_name = "test.zip"
temp_file = Tempfile.new("filename-#{Time.now}")
File.open(temp_file, 'wb') {|f| f.write(decoded_data)}
send_file temp_file.path, :type => 'application/zip', :filename => file_name

Related

batch jpg images in string blob not all written to file with ruby file open write barby gem rmagick

I am using barby gem to generate barcodes. I am doing it a batch at a time and then save all of them in a file to be viewed by the user. I am not trying to print one at a time.
def generate_barcode
number_of_instances = params[:times].to_i
value = 12.times.map{rand(10)}.join
barcodes = 10.times.collect { Barby::EAN13.new(value) } #collects ten barcodes in an array
processed_barcodes = barcodes.map {|barcode| barcode.to_jpg_2(:height => 60)} #returns an array and each element is a string of jpeg file
File.open('code.jpg', 'wb') do |f|
processed_barcodes.each {|barcode| f.write(barcode)} #stuck here
#f.puts(processed_barcodes) #tried this
end
send_file('code.jpg',
:type => 'image/jpeg',
:disposition => 'inline'
)
end
the view
<%= image_tag(url_for({:controller => 'business_partners', :action => 'generate_barcode', :format => 'jpg' })) %>
processed_barcodes.count came back with 10.
My code.jpg got processed but I only have 1 image.
each image in jpg string blob format looks like this
>> processed_barcodes.first
=> "\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xFF\xDB\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\b\x06\x06\x05\x06\t\b\n\n\t\b\t\t\n\f\x0F\f\n\v\x0E\v\t\t\r\x11\r\x0E\x0F\x10\x10\x11\x10\n\f\x12\x13\x12\x10\x13\x0F\x10\x10\x10\xFF\xC0\x00\v\b\x00P\x00s\x01\x01\x11\x00\xFF\xC4\x00\e\x00\x01\x01\x01\x01\x01\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\b\x06\x05\x02\x03\t\xFF\xC4\x009\x10\x00\x00\x05\x03\x01\x05\x05\x03\f\x03\x01\x00\x00\x00\x00\x00\x01\x02\x03\x04\x06\x00\x05\a\b\x11\x12\x13\x14w\"79\xB6\xB7\x158\x87\t\x16\x18!#3FI\x85\xB5\xC4\xC5\x17$B%\xFF\xDA\x00\b\x01\x01\x00\x00?\x00\xFDS\xA5)JR\x94\xA5)JR\x95\x8F\xF2\xA6{\xCB\x11\xB9\xA6q\xB4\xD9e|\xBBH|>mt\xB2\xA7\xC8\xB6?*\xE9\x85\x82&\xED\xA2\x9BL\x98\x89\xF7\x17\xBA\xBF>\xC3\x89\x8An>\xC3\x01\x8AB\x01h\x1A`\xCAS\xBC\x89\xECo\x9E7\xDFhsx~\x01)[\xFDTR\xDE\xBA\\\xBD\xAB\xCE\xAF\xF6d.\xCE'*\x87`;\x05\xDC\xEC\x14\xBBM\xB6\x7F\xA4\xAC\xF7\x962l\xD25i\x9CJ\xFD\xA4\xD2\xE1\x0FR\xE8\xE1>E\xB2;\xEE\x82\xC1\tv\nmI2\x88}\xBD\xEA\xE6}\x80 _\xF66l\xDDM0$\x02\xC1\xAC\xCDI\xBD\x85\xE8\xAA\xEC\xEB$o\xBB\xCBs\v\xAD\xAEb\xA7\xB1\xD8\a\xB4\xDA\xA3\x7Fl\xD14\xF6\x02\e\x11\xD8\x82\x87&\xD4#\x86\x1D\xBBDD\xC0\x03W\xFCi\x9E\xF2\xC4\x83G9c*\xDD\xE5|\xC4\xA63\x0Fmt\xB5\xBF\xE4[\x13\x97tx5\xA6\xE8e8eL\x13>\xD7\xAE\xDC+\xB0\xC5\x12\xF6\xF76n\x14\xA5\b\x064\xD6f\xA4\xE4\x1A\xC6\xCB\x18\xAA\xEF\x929\x88\xB4f`\xDA\xD7ka\xECv\x04\xE5\xDA\x9Esi\xB5\x99>!P\x05\x0F\xB5\x93\xB7\tm1\x84\xDD\xBD\xFD\xBB\xE5)\x82\xFF\x00\xA4\xAC\xF7\x962l\xD25i\x9CJ\xFD\xA4\xD2\xE1\x0FR\xE8\xE1>E\xB2;\xEE\x82\xC1\tv\nmI2\x88}\xBD\xEA\xE6}\x80 _\xF66l\xDDM0\"!\x9E\xF2\xC5\xD2\x17\x15\xBB>\x95\xF1]\xDC\xA1\xF8R\xE8\xE9NE\xB1x\x8E\xAF\xD7\xF5\x9A]\x94\xD8\t\x80\a\x1D\x02\x14\x9B\x00\x00\xA9\xEC\xDA\x98\x10\xDF]p\x1A\x90\xD5\x1Ev\x81}1>i\xCEy\x1F\xF1_\xF8\xFB\xE6\x97\xFEc5}\x9B\xED>\x0F;\xF7\x89\e\x8D\xC4\xDF7\xDE\xEF\xEE\xED\xECn\xD25\xAA<\xEDp\xD7\xD68\xC2\x8E\xE7<He\xFB\xE7\xAF\xB4-\x9E\xCCf\x1CnB\xF5&l\xD3\xED\x81.)w\x11\xB6\xB2/d\xE1\xBD\xC1\xDAm\xE19\xC4\xDD\xFEK\xCFyb?\xA3\x9CO\x95m\x12\xBE^S&\x87\xB9\xBA]\x1F\xF2-\x8F\xCC:$\x1A\xEDt*\x9C3&)\x93c\xD6\x8D\xD5\xD8R\x81{\e\x9B7\fb\x8F\x01\x85uG\x9D\xA5\xB8_\x01K$3\x9En\xEB5\xE7=\xBA\xE3\xD9\x8C\xD3\xE6\xF8s\xE8\xFD\xA8\x9D\x92$\x05Oc\x17\xEE\xD1\xEC\x01~\xF7|{e!\xCB\xAF\xF4\xF5)\xBE\xCEp\x164\x9A\xCA_s\xB7\xA9\x04>\xCDt\xB8\xB9\xE1\x11>;\xA5\xD9$\xA2\xAAn\x10\nB\xEF\x1C\xE6\x1D\x85\x00(m\xD8\x00\x01\xF5U\x02\x95\x803\x87x\xBA\x97\xE9\xFEH\xF2\xAC\x16\xAA\xBA+\xFC=\xD0\fY\xFD\xE5J\xB4\e\xDE,;\xA7\xEA\xF9W\e\xD6U\x8Bwu\xF2qu\x02\xF9\xE6\xA6u\xAA\xB0\xDF\x87\xBEv\xE9\xFB?L\xEC5\x95p\xDF\x88Fv\xEA\x03?S,5\xAA\xB4\e\xDE,;\xA7\xEA\xF9W\e\xD2\x03\xDD\xD4\e\xA7\xFAq\xF3S\x8A\x95j\xFF\x00\xF3\x05\xF8Q\xFCzC|Sq\x0F\xC4\x7F1\xCC\xAA\xAB\x99<=\xF0OO\xDEzg~\xA9V\x9C}\xDDt\xB1\xFA\x8F\xAAqZ\xDF\xFAN\xF7X\xC3}?\x8F~\xDC\x85UiX\x038w\x8B\xA9~\x9F\xE4\x8F*\xC1j\xAB\xA2\xBF\xC3\xDD\x00\xC5\x9F\xDET\xABA\xBD\xE2\xC3\xBA~\xAF\x95q\xBDeX\xB7w_'\x17P/\x9EjgZ\xAB\r\xF8{\xE7n\x9F\xB3\xF4\xCE\xC3YW\r\xF8\x84gn\xA03\xF52\xC3Z\xABA\xBD\xE2\xC3\xBA~\xAF\x95q\xBD =\xDDA\xBA\x7F\xA7\x1F58\xA9V\xAF\xFF\x000_\x85\x1F\xC7\xA47\xC57\x10\xFCG\xF3\x1C\xCA\xAA\xB9\x93\xC3\xDF\x04\xF4\xFD\xE7\xA6w\xEA\x95i\xC7\xDD\xD7K\x1F\xA8\xFA\xA7\x15\xAD\xFF\x00\xA4\xEFu\x8C7\xD3\xF8\xF7\xED\xC8UV\x95\x803\x87x\xBA\x97\xE9\xFEH\xF2\xAC\x16\xAA\xBA+\xFC=\xD0\fY\xFD\xE5J\xB4\e\xDE,;\xA7\xEA\xF9W\e\xD6U\x8Bwu\xF2qu\x02\xF9\xE6\xA6u\xAA\xB0\xDF\x87\xBEv\xE9\xFB?L\xEC5\x95p\xDF\x88Fv\xEA\x03?S,5\xAA\xB4\e\xDE,;\xA7\xEA\xF9W\e\xD2\x03\xDD\xD4\e\xA7\xFAq\xF3S\x8A\x95j\xFF\x00\xF3\x05\xF8Q\xFCzC|Sq\x0F\xC4\x7F1\xCC\xAA\xAB\x99<=\xF0OO\xDEzg~\xA9V\x9C}\xDDt\xB1\xFA\x8F\xAAqZ\xDF\xFAN\xF7X\xC3}?
You open one file using File.open('code.jpg', 'wb') and write into it processed_barcodes times. If you want processed_barcodes files then you need to loop around File.open with unique names.
Instead of:
File.open('code.jpg', 'wb') do |f|
processed_barcodes.each {|barcode| f.write(barcode)} #stuck here
#f.puts(processed_barcodes) #tried this
end
Use this untested code:
processed_barcodes.each_with_index do |barcode, i|
File.open("code_#{i + 1}.jpg", 'wb') do |f|
f.write(barcode)
end
end
You'll need to figure out how to modify:
send_file('code.jpg',
:type => 'image/jpeg',
:disposition => 'inline'
)

Rails send_file/send_data - Cannot Read File - After web service call

My Rails 3.1 app makes a web service call to get a pdf file that I then need to send to the browser for download.
The XML response is something like this:
<RenderResponse>
<Result>blahblah this is the file info<Result>
<Extension>PDF</Extension>
<MimeType>application/pdf</MimeType>
</RenderResponse>
I am then trying to convert the "Result" tag to a file as so:
#report = #results[:render_response][:result]
#report_name = MyReport.pdf
File.open(#report_name, "w+") do |f|
f.puts #report
end
finally I try to send to the browser:
send_file File.read(#report_name), :filename => #report_name, :type => "application/pdf; charset=utf-8", :disposition => "attachment"
This yields an error the says "Cannot Read File" and it spits out all the text from the results tag.
If I use send_data as so:
send_data File.read(#report_name).force_encoding('BINARY'), :filename => #report_name, :type => "application/pdf; charset=utf-8", :disposition => "attachment"
The download works but I get a file with 0KB and an Adobe Error that says the file "MyReport.pdf" can't be opened because "its either not a supported file type or it has been damaged".
How can I take the XML response file info, create the file, and stream to the browser?
I found the solution. send_file is the correct stream mechanism to use but I needed to decode the string while writing to the file. I also need to add the 'b' parameter to the File.open call.
This works:
File.open(#report_name, "wb+") do |f|
f.puts Base64.decode64(#report)
end
#file = File.open(#report_name, 'r')
send_file #file, :filename => #report_name, :type => "application/pdf; charset=utf-8", :disposition => "attachment"

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.

How to handle csv download prompt through a post request in Rails

I have a servlet (java) returning a csv file. So in my controller I send a post request,
def handleCsvRequest
response = RestClient.post theUrlPathTotheServlet queryParams
end
Now how do I handle the response so that it prompts the user to download this csv file. I know you can do this via a form and hidden Iframe but i'd like to do it through rails. I am looking through fastercsv but i am not finding great examples. Many thanks.
I have tried the following:
i have tried the following
csv_string = RestClient.post url, json, :content_type => :json
csv_file = CSV.generate do |csv|
csv << [csv_string]
end
send_data csv_file, :type => 'text/csv; charset=iso-8859-1; header=present', :disposition => "attachment; filename=report.csv"
but i don't get prompt for a file download? any ideas?
Do have a look at
1> http://fastercsv.rubyforge.org/ - For Documenation
2> http://supriya-surve.blogspot.com/2010/02/using-fastercsv-to-import-data.html - As an e.g.
Use send_file or send_data to send the csv data back to the browser.
A typical example of send_data is something along the lines:
csv_data = CSV.generate do
# block to generate CSV text
end
send_data csv_data, :filename => 'your_data.csv'
A typical example of send_file is
#csv_filename ="#{RAILS_ROOT}/tmp/your_data.csv"
send_file #csv_filename, :filename => "your_data.csv"
This should work in development. If this does not work in production, and you are using an Apache server,
you have to comment out the following line in config/environments/production.rb
config.action_dispatch.x_sendfile_header = "X-Sendfile"
Hope this helps.

rails send_file and send_data sends out zero byte files

I'm trying to send a pdf back to the user but I'm having serious problem getting send_file and send_data to work. I created the pdf file as follows:
tmp = Tempfile.new('filled')
new_tmp_path = PDFPrint.fill_form_using_pdftk(template_path, tmp.path)
send_file (new_tmp_path, :filename => 'filled.pdf')
The browser prompts for a download, but the downloaded filled.pdf file has zero byte.
I have verified that new_tmp_path does contain a valid pdf (good, filled content)
I have tried this:
File.open(new_tmp_path, 'r') do |f|
send_data(f.read, :filename => "filled.pdf")
end
But this also gives me the same download->zero-byte problem, while the file on server (new_tmp_path) has perfect content.
Regards,
Try sending a simple file to see if it works
send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline'
Read this thread, I think it has everything you need.

Resources