Rails version: 4.2.0
Ruby version: 2.3.8
Is there any way in a Rails application to hide the absolute path displayed for the send_file method?
controller code:
def download_file(file_path)
send_file file_path, :x_sendfile => true, :type => 'application/pdf'
end
the path displayed in server logs:
Sent file /home/new_user/Project/new_project/pdfs/plan_7.pdf
Check the config/production.rb and change log level.
Try something like that:
config.log_level = :fatal
The level can be: :debug, :info, :warn, :error, :fatal, and :unknown. Choise the best option for your case.
Related
I have an API that generate png files.
The user request the generation, and I reply with a path to the generated files.
This is how I generate the URL:
url_for(:controller => :anaction, :action => :download, :path => "#{#relative_dir}/face", :format => 'png'
This yeild an URL that looks like:
http://0.0.0.0:3000/anaction/aging/download/%2FTMP_20161128204315_346482_695%2Fface.png
That should be handled by
def download
send_file "#{Rails.public_path}/#{params[:path]}.#{params[:format]}"
end
According to my route
get '/anaction/aging/download/:path' => 'mpsynthesizer_aging#download'
It works like a charm on my dev environment, on my nginx server, but fail on my apache server.
I get a plain apache HTTP400 error, it seems that the request is never forwarded to rails.
I use rails 4.2.6
Is there something i misunderstood ?
I ended up using
render body: IO.binread(result_file), content_type: "image/png"
I have wkhtmltopdf binaries in my bin folder and my initializer is as follows:
PDFKit.configure do |config|
# if ["development"].include?(Rails.env)
if ENV["TRIPCIPE_ENV"] == "local"
config.wkhtmltopdf = Rails.root.join('bin', 'wkhtmltopdf').to_s
else
config.wkhtmltopdf = Rails.root.join('bin', 'wkhtmltopdf-amd64').to_s
end
end
my controller code looks like this
html = render_to_string(:action => "pdf", :layout => false)
kit = PDFKit.new(html)
send_data(kit.to_pdf, :filename => 'report.pdf', :type => 'application/pdf', :disposition => 'inline')
And it works fine locally but when I deploy on heroku I just get an empty 1 page pdf file.
Any ideas or help would be appreciated, thanks.
I also noticed in my logs it says this:
Unable to load library icui18n "Cannot load library icui18n: (icui18n: cannot open shared object file: No such file or directory)"
Anyone seen this before?
UPDATE
So i removed the initializer code and added the gem 'wkhtmltopdf-heroku', which makes the error go away but it's still returning a blank page.
I wrote the following code.
def help_doc
pdf_filename = File.join(Rails.root, "/public/doc.pdf")
send_file(pdf_filename, :filename => "doc.pdf" :type => "application/pdf", :diposition => "inline")
end
It's working, but not as I want. I'd like to view in the browser the pdf, but it's doing download of the document.
I thought that just writing :disposition => "inline" and I could see on the browser the pdf.
Try removing the content disposition. You have a typo in your code, deposition vs disposition, and you're missing a comma after filename.
what is the best way of configuring Logging features on a rails project? I'm looking for something like Log4J which is available to Rails. I have found log4r and it's conflicting built in Logger class and also tried 'Logging' gem and It has some issues configuring as a audit logger. Please let me know your suggestions on this topic since I'm a beginner on the subject.
I have used below code block in logging.rb and included in environment.rb
But I'm receiving a error on 'returning' keyword as it's deprecated on rails 2.8
config/environment.rb
# Logging
require File.join(File.dirname(__FILE__), 'logging')
Rails::Initializer.run do |config|
config/logging.rb
require 'logging'
# Logging.init is required to avoid
# unknown level was given 'info' (ArgumentError)
# or
# uninitialized constant Logging::MAX_LEVEL_LENGTH (NameError)
# when an Appender or Layout is created BEFORE any Logger is instantiated:
Logging.init :debug, :info, :warn, :error, :fatal
layout = Logging::Layouts::Pattern.new :pattern => "[%d] [%-5l] %m\n"
# Default logfile, history kept for 10 days
default_appender = Logging::Appenders::RollingFile.new 'default', \
:filename => 'log/default.log', :age => 'daily', :keep => 10, :safe => true, :layout => layout
# Audit logfile, history kept forever
audit_appender = Logging::Appenders::RollingFile.new 'audit', \
:filename => 'log/audit.log', :age => 'daily', :safe => true, :layout => layout
# Production logfile, history kept forever
prod_appender = Logging::Appenders::RollingFile.new 'prod', \
:filename => 'log/production.log', :age => 'daily', :safe => true, :layout => layout
DEFAULT_LOGGER = returning Logging::Logger['server'] do |l|
l.add_appenders default_appender
end
Have a look at the following threads:
Rails Logging API
logging in rails app
What's a good logging replacement for rails?
It should be like this:
config/logging.rb
require 'logging'
# Logging.init is required to avoid
# unknown level was given 'info' (ArgumentError)
# or
# uninitialized constant Logging::MAX_LEVEL_LENGTH (NameError)
# when an Appender or Layout is created BEFORE any Logger is instantiated:
Logging.init :debug, :info, :warn, :error, :fatal
layout = Logging::Layouts::Pattern.new :pattern => "[%d] [%-5l] %m\n"
# Default logfile, history kept for 30 days
default_appender = Logging::Appenders::RollingFile.new 'default', \
:filename => "log/#{Rails.env}.log", :age => 'daily', :keep => 30, :safe => true, :layout => layout
log = Logging::Logger[:root]
log.add_appenders default_appender
log.level = :info
Rails.logger = log
I have a function in a controller that takes in some specifications and generates a report on them. This function user_report is called in a view:
< %= submit_to_remote 'submit-button', "Export Report to Excel", :url => { :controller => :reports, :action => :user_report, :print_state => 'print'} % >
In reports_controller I use the Spreadsheet plugin to generate an Excel file within the user_report function. I want to use send_data to stream the file to the user without creating it on the server first. The research I've done shows that using StringIO is the way to go, as shown below. Frustratingly, nothing happens when I call send_data. The plugin seems to work well creating a file and saving it on the server, but does nothing when I use send_file, suggesting that the problem doesn't lie in the plugin. But then what am I doing wrong with send_file/send_data?
The function itself looks like this:
def user_report
if request.post?
unless params[:reports][:userid].blank?
#userid=params[:reports][:userid]
end
if params[:print_state]=='print'
report = Spreadsheet::Workbook.new
info = report.create_worksheet :name => 'User Information'
info.row(1).push 'User ID', #userid
#outfile = "Report_for_#{#userid}.xls"
require 'stringio'
data = StringIO.new ''
report.write data
send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => #outfile
end
respond_to do |format|
format.js { }
end
end
end
The log file reads
2010-10-18 14:13:59 INFO -- Sending data Report_for_jjohnson.xls
but no download begins in-browser. I've succeed in using send_data on this app before, which is confusing.
I'm using Rails v2.3, Ruby v1.8.7, and Spreadsheet v6.4.1 at spreadsheet.rubyforge.org.
Just change the line:
send_data data.string, :type=>"application/excel", :disposition=>'attachment', :filename => #outfile
to:
send_data data.string.bytes.to_a.pack("C*"), :type=>"application/excel", :disposition=>'attachment', :filename => #outfile
Even though I dont like to write and delete , but with spreadsheet seems like the only solution.
# write the file
book.write "Employee_History_#{ params[:id]}.xls"
# send the file
send_file "Employee_History_#{ params[:id]}.xls", :type => "application/vnd.ms-excel", :filename => "data.xls", :stream => false
# and then delete the file
File.delete("Employee_History_#{ params[:id]}.xls")
For someone looking at this in (or after) 2022, a possible solution to this would be to use Axlsx Gem. The interface provides a method for converting it to a StringIO object. (From Axlsx Documentation)
#serialize to a file
p = Axlsx::Package.new
# ......add cool stuff to your workbook......
# Serialize to a stream
s = p.to_stream()
send_data(
s.read,
:type => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
:disposition => 'attachment',
:filename => #filename
)