How to download file from google drive using paperclip-googledrive? - ruby-on-rails

I have done file uploading on google drive but at the time of downloading got error:
ActionController::MissingFile: Cannot read file original_22_Wages372-817339(wages).pdf
I think it didn't get google drive path.
Attachment model:
has_attached_file :doc,
storage: :google_drive,
google_drive_credentials: "#{Rails.root}/config/google_drive.yml",
google_drive_options: {
public_folder_id: '0BwCp_aK6VhiaQmh5TG9Qbm0zcDQ',
path: proc { |style| "#{style}_#{id}_#{doc.original_filename}" }
}
Controller:
attachment = Attachment.find(params[:id])
send_file attachment.doc.path(:original),
filename: attachment.doc_file_name,
type: attachment.doc_content_type,
stream: 'true',
x_sendfile: true
Thanks in advance

You should read file first from your application. And then make it available for download.
attachment = Attachment.find(params[:id])
data = open(attachment.doc.url).read
send_file data,
:filename => attachment.doc_file_name,
type: attachment.doc_content_type, stream: 'true',
:x_sendfile => true
You can also make it available like :
redirect_to attachment.doc.url
But this is not a right way to do so. Because you directly opening your resources to end user.

Dinesh, try the below code it will solve your problem.
attachment = Attachment.find(params[:id])
data = attachment.doc.url(:original)
data = open(attachment.doc.url(:original))
send_file data, filename: attachment.doc_file_name,
type: attachment.doc_content_type

Related

Paperclip not saving image because of wrong content type

I am having issues uploading an image from Node js app to a remote server.
The remote server app is Rails 5 and using paperclip to save the file.
When I upload the image through Postman , the image is saved successfully and everything works fine. But the issue is when I upload from front end Node app, The image is not saved and this is what I see in the logs
begin transaction Command :: file -b --mime '/var/folders/90/d3rv8dkd3t1g9wwz90dtk_dx41mg3d/T/b5e7d988cfdb78bc3be1a9c221a8f74420171114-33517-11gthzp.png'
[paperclip] Content Type Spoof: Filename image1.png (text/plain from
Headers, ["image/png"] from Extension), content type discovered from
file command: text/plain. See documentation to allow this combination.
rollback transaction
After researching online, it seems like I am not encoding the file correctly in the front end node app.Here is my code
var FormData = require('form-data');
var fetch = require('node-fetch');
var form = new FormData();
form.append('name', req.body.name);
form.append('image', req.body.attachment, req.body.filename);
fetch('http://localhost:3000/slides', { method: 'POST', body: form,headers: form.getHeaders()})
.then(function(res) {
return res.json();
}).then(function(json) {
console.log(json);
});
res.json(resp)
})
Can someone guide me how to fix this?
I have even tried to override content type validation in my backend app, but still doesn't work.
class Slide < ApplicationRecord
has_attached_file :image, styles: { small: "64x64", med: "100x100", large: "200x200" }
validates_attachment_content_type :image, :content_type => ["image/jpg", "text/plain","image/jpeg", "image/png", "image/gif"]
end
config/initializer/paperclip_spoof.rb
require 'paperclip/media_type_spoof_detector'
module Paperclip
class MediaTypeSpoofDetector
def spoofed?
false
end
end
end
Please I need your help.Thank you in advance
I just had to decode the base64 before sending the file to the server
var buff = new
Buffer(req.body.attachment.replace(/^data:image\/\w+;base64,/, ""), 'base64');
fs.writeFileSync('image.png', buff);
var form = new FormData();
form.append('name', "some name");
form.append('image', buff, req.body.filename);

Streaming Large (7 GB) S3 gz file in Rails 3.x to the Browser

I'm trying to stream a large Amazon S3 file to the browser using the Rails send_data method, however because the file is so large, the server runs out of memory and cannot complete the request.
The code looks something like this:
def download
s3_obj.read
end
def download_file
send_data(file.download, :filename => filename, :type => 'application/gzip', :disposition => 'attachment')
end
Is there a way to stream the chunks of the file with send_data so that it's a single file in the browser? the way I understand it is that send_data has to load the entire file into memory, then send all of that at once.
You should use send_file instead of send_data as it allow you to set the buffer and more option.
More information here.
UPDATE
If you want to download from S3, you can do this:
def download
data = open("S3_OBJECT_URL")
send_file data.read, filename: filename, type: "application/gzip", disposition: 'attachment', stream: 'true', buffer_size: '4096'
end
or
redirect_to s3_object.file.url

OpenURI::HTTPError in ArticlesController#download 403 Forbidden - S3 - Rails

I'm simply trying to allow my app to download files that are stored on s3. This seems straight forward but I keep getting this error OpenURI::HTTPError in ArticlesController#download
403 Forbidden
Here is my controller:
def download
article = Article.find_by(id: params[:id])
data = File.read(open("https://s3.us-east-2.amazonaws.com/theranostics-bucket/uploads/DMS-OctoberSocialMedia.pdf"))
send_data data, filename: "file.pdf", type: "application/pdf", disposition: 'inline', stream: 'true', buffer_size: '4096'
end
It fails on the File.read line. What am I missing? I'm using Carrierwave to upload the files which is working just fine. It's only when I try to download I'm having issues.

Rails send_data streaming PDF as bytes, unless route accessed directly

I've got a simple Rails app that downloads a PDF from a (private) S3 bucket and serves it to the browser.
# app/controllers/file_controller.rb
class FileController < ApplicationController
def send_pdf
s3_file = Aws::S3::Resource.new(
region: "us-east-1",
access_key_id: S3_ACCESS_KEY_ID,
secret_access_key: S3_SECRET_ACCESS_KEY
).bucket('bucket-name').objects({prefix: "file_name"}).first.get.body.string
send_data s3_file, filename: "FileName.pdf", type: 'application/pdf', disposition: 'inline'
end
end
# config/routes.rb
Rails.application.routes.draw do
get 'file', to: 'file#send_pdf', defaults: { format: 'pdf' }
end
When accessing the route directly via URL, it displays the PDF fine.
When opening a link to the route in a new tab, it displays the PDF fine.
When opening a link in the same tab, the PDF data streams as text to the browser instead.
The same behavior occurs in Rails 4 and 5.
I'm probably missing something annoyingly minor here, but how can I get the open in the same tab behavior to properly display the PDF instead of streaming bytes as text?
Update 1:
Chrome gives a Failed to load PDF document error when send_pdf is modified to use send_file instead of send_data. (This error happens regardless of link click or direct route request.)
def send_pdf
# S3 download
temp_file = "#{Rails.root}/tmp/file.pdf"
File.open(temp_file,"wb") do |f|
f.write(s3_file)
f.close
end
send_file temp_file, filename: "FileName.pdf", type: 'application/pdf', disposition: 'inline'
File.delete(temp_file)
end
Have you tried send_file instead of send_data?
http://apidock.com/rails/v4.2.1/ActionController/DataStreaming/send_file

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