IMGKit returning corrupted image - ruby-on-rails

I have the following code in Rails 3 application's controller:
respond_to do |format|
format.html
format.jpeg do
image = IMGKit.new("http://www.google.com").to_img(:jpg)
send_data(image, type: "image/jpeg", filename: "data.jpeg", disposition: "inline")
end
end
I expect that when I ask for a jpeg I get back a jpeg of the Google home page. However, I get back an image that looks like this. What am I doing wrong?
I'm on Windows 7, and the wkhtmltoimage command works fine from the command line. I have ruby verion ruby 1.9.3p125 (2012-02-16) [i386-mingw32].

Related

Rails 4, disposition: 'attachment' is not downloading in iOS

I am passing disposition: 'attachment' in send_data method to download image and it works flawlessly on all the platforms but iOS. In iOs it is behaving as if disposition: 'inline' was passed. I am stuck and unable to figure it out. It would be really appreciable if any one could help.
I am using Rails 4.2.6 with Ruby 2.3.4
My code in view is
<%= link_to "Download", blog_blogs_download_image_path, data: {turbolinks: false} %>
and in controller
require 'open-uri'
url = 'resource_path'
data = open(url).read
send_data data, filename: "test_photo.jpg", disposition: 'attachment'
AFAIU, that's the way it is. There's no concept of "downloads" in iOS.

Problem with generate pdf and display images

I have a problem with displaying the images in pdf. 5 out of 100 attempts work. After saving all data to database, there is opened a new site with pdf generated by gem wkhtmltopdf. During getting the image from path /rails/active_storage/blobs/... service is stopped and report isn't generated. There are no errors on consoles .Only solution is stopped the server ( ctrl+c ) and start again the server.
The server is stopped on request :
Started GET "/rails/active_storage/blobs/...
I display image by line :
<%= image_tag(#object.image, class: '') if #object.image.attached? %>
There is a method for generate report (above this code there are the varialbes to display in report )
respond_to do |format|
format.html do
redirect_to index
end
format.pdf do
render pdf: "Raport",
template: "myFolder/report.html.erb",
:footer => {
:font_size => '8'
}
end
end
I'm using rails 5.2.3, ruby 2.5.3
I'm expect to generate the pdf with images.

rails send_data can't handle large file (2G+)

My env:
Mac: 10.12.4
Memory: 16G
ruby: 2.1.4
rails: 3.2.22.5
web server: thin 1.7.0
When the file size is under 2G, everything goes well.
class ItemListsController < ApplicationController
...
send_data IO.read(zip_path), :type => 'application/zip',
:disposition => 'attachment',
:filename => file_name
However, when file size is larger than 2G, exception raised:
Errno::EINVAL: Invalid argument # io_fread
I tried to use rubyzip to output stream instead:
compressed_filestream = Zip::OutputStream.write_buffer do |zos|
files.each do |file|
zos.put_next_entry file[1]
zos.write File.open(file[0], 'r').read
end
end
compressed_filestream.rewind
send_data compressed_filestream.read, :type => 'application/zip',
:disposition => 'attachment',
:filename => file_name
Exception raised with further detail:
Unexpected error while processing request: integer 2206004964 too big to convert to `int'
/Users/karl/.rvm/gems/ruby-2.1.4#hcsvlab/gems/eventmachine-1.0.3/lib/em/connection.rb:328:in `send_data'
Seems send_data would read the whole file into memory then send data back.
My original plan is to find some way to provide "buffer" so send_data would read from buffer instead reading the whole file, but can't find such options in API
https://apidock.com/rails/ActionController/DataStreaming/send_data
Any idea would be greatly appreciated.
Thanks.
You might want to use send_file instead. According to the documentation:
Sends the file, by default streaming it 4096 bytes at a time. This way
the whole file doesn’t need to be read into memory at once. This makes
it feasible to send even large files. You can optionally turn off
streaming and send the whole file at once.

wickedpdf not rendering images?

i am using wickedpdf gem to generate pdf invoice from the html code.
gems:
gem 'wicked_pdf'
gem "wkhtmltopdf-binary"
gemfile.lock
wicked_pdf (1.0.6)
wkhtmltopdf-binary (0.9.9.3)
in controller:
def show_pdf_invoice
respond_to do |format|
format.html { render :layout => "pdf.pdf.erb" }
format.pdf do
render pdf: "show_pdf_invoice", :layout => 'pdf.pdf.erb'
#render :pdf => "pdf"#, :layout => 'pdf.html.erb'
end
end
end
in views/invoices/show_pdf_invoice.pdf.erb
<img id="image" src="https://www.google.co.in/logos/doodles/2016/holidays-2016-day-2-6356741311692800-scta.png" alt="logo" />
<%= wicked_pdf_image_tag 'https://www.google.co.in/logos/doodles/2016/holidays-2016-day-2-6356741311692800-scta.png' %>
pdf is getting generated. But the images are not showing. in the place of images empty boxes are coming. unable to find the issue.
I've had the same problem, mine was fixed by removing https for http. Have you tried this? and for the Amazon S3 part: You could use gsub for that as in: gsub("https", "http")
Using Rails 5.2 with Active Storage in combination with Amazon S3 storage I had the same problem.
In development on my local machine the images rendered perfectly, but on Heroku
they were presented as small empty rectangles.
To get the url from the logo uploaded to Active Storage I used: #my_object.logo.service_url.
Which used the standard url with https. As mentioned before, replacing this with http resolved the issue.
Full code used in my pdf generator view:
<%= wicked_pdf_image_tag #my_object.logo.service_url.gsub("https", "http") %>
Two Options
1. Upgrade to wkhtmltopdf 0.12.5.
-or-
2. Install libssl1.0-dev with apt-get install libssl1.0-dev.
See this issue for more information: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3001

Rails 3 Wicked PDF - include Paperclip S3 pdf files

I have a Rails 3 app that uses these gems:
gem 'paperclip'
gem 'wicked_pdf'
gem 'combine_pdf'
I'm using wicked_pdf to open a pdf for a costproject. The costproject has an HTML page called viewproject.pdf.erb.
I'm trying to combine the wicked pdf with the costproject attachments into a single pdf.
This is my controller code:
def viewproject
#costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf = CombinePDF.new
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
pdf << CombinePDF.new(pdf2)
#costproject.attachments.each do |attachment|
pdf << CombinePDF.new(attachment.attach.path)
end
send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf"
end
end
end
The line pdf << CombinePDF.new(pdf2) is giving me:
string contains null byte
If I look at pdf2, it starts like this - so it looks like a pdf:
>> pdf2
=> "%PDF-1.4\n1 0 obj\n<<\n/Title (\xFE\xFF)\n/Producer (wkhtmltopdf)\n/CreationDate (D:20150405202628)\n>>\nendobj\n4 0 obj\n<<\n/Type /ExtGState\n/SA true\n/SM 0.02\n/ca 1.0\n/CA 1.0\n/AIS false\n/SMask /None>>\nendobj\n5 0 obj\n[/Pattern /DeviceRGB]\nendobj\n8 0 obj\n<<\n/Type /XObject\n/Subtype /Image\n/Width 71\n/Height 75\n/BitsPerComponent 8\n/ColorSpace /DeviceRGB\n/Length 9 0 R\n/Filter
I also tried pdf << CombinePDF.new(pdf2.to_pdf)
Thanks for the help!
UPDATE1
As a test, to see if pdf2 is working, I did this successfully:
def viewproject
#costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
send_data pdf2, :disposition => 'inline', :type => "application/pdf"
end
end
end
UPDATE2
Myst was correct about using parse. Thanks!
I am now using this line in the controller code:
pdf << CombinePDF.new(attachment.attach.url)
I get this error:
No such file or directory - http://s3.amazonaws.com/ ...
But, if I copy the http address and paste into the browser the pdf shows up.
I am editing this answer to reflect the issue of remotely stored PDF files.
I should point out that without a persistent connection to the S3 storage and without using the S3 API, the following solution WILL effect performance*.
As I pointed out, the CombinePDF.new method is the same as the CombinePDF.load method. It accepts a file name and attempts to open the file. The CombinePDF.parse method will accept raw PDF data and parses it into a PDF Object.
In the following code I use Net::HTTP.get(URI.parse(url)) to get the raw PDF data.
I recommend replacing this solution with a S3 native solution, so that the whole application can share one or more persistent connections. This is a performance issue that may or may not be important for you.
require 'net/http'
def viewproject
#costproject = Costproject.find(params[:costproject_id])
respond_to do |format|
format.html
format.pdf do
pdf = CombinePDF.new
pdf2 = render_to_string pdf: "Costproject.pdf", template: "costprojects/viewproject", encoding: "UTF-8"
pdf << CombinePDF.parse(pdf2)
#costproject.attachments.each do |attachment|
pdf << CombinePDF.parse( Net::HTTP.get( URI.parse( attachment.attach.url ) ) )
end
send_data pdf.to_pdf, :disposition => 'inline', :type => "application/pdf"
end
end
end
* The performance hit is dependent on the amount of PDF attachments you have, on the number of users your app has, on network traffic, on your framework (single/multi-thread) and other factors.
A persistent connection should reduce the performance hit in a dramatic way, mainly due to the fact that establishing connections is an expensive action.

Resources