The approach that I took with a Rails 2.3.8 app was to spawn a new thread to handle the csv parsing and then use an AJAX call to check the server to see if the file was ready (I relied on File.mtime).
Just ripped it out of the app to post here so I've removed alot of the csv parsing code, and haven't included all of the views
sorry end of the day rush :D
controllers/exports_controller.rb
class ExportsController < ApplicationController
require 'fastercsv'
require 'generic_agent'
require 'generic_record'
def listing
@this_filepath = "../html/whatever/" << Time.now.strftime("%I:%M:%S_%d:%m:%y") << ".csv"
@spawn_id = spawn(:nice => 1) do
FasterCSV.open(@this_filepath, "w") do |csv|
csv << [ "outbreak_id"]
end
end
render :update do |page|
page.replace_html 'export_status', :partial => 'export_status_partial'
end
end
def send_export
@this_filepath = params[:with]
csv_file = File.open(@this_filepath.to_s, 'r')
csv_string = ""
csv_file.each_line do |line|
csv_string << line
end
send_data csv_string, :filename => "export.csv",
:type => 'text/csv; charset=iso-8859-1; header=present',
:disposition => "attachment; filename=export.csv"
#send_file @this_filepath.to_s, :stream => false, :type=>"text/csv", :x_sendfile=>true
#send_data csv_string, :filename => export.csv
#File.delete(@this_filepath.to_s)
end
def export_checker
filename_array = params['filename'].split(/\//)
@file_found = 0
@file_ready = 0
@file_size = File.size(params['filename'])
@this_filepath = params['filename']
if File.exists?(params['filename'])
release_time = Time.now - 5.seconds
if File.mtime(params['filename']).utc < release_time.utc
@file_found = 1
@file_ready = 1
@file_access_time = File.mtime(params['filename'])
@file_release_time = release_time
@file_size = File.size(params['filename'])
else
@file_found = 1
@file_ready = 0
@file_size = File.size(params['filename'])
end
else
@file_found = 0
@file_ready = 0
@file_size = File.size(params['filename'])
end
render :action => "export_checker"
end
end
views/exports/export_checker.rjs
if @file_found == 1 && @file_ready == 1 && @file_size > 0
page.replace_html 'link_to_file', :partial => "export_ready"
if @file_release_time
page.replace_html 'notice', "<div>Completed #{@file_release_time.strftime("%I:%M:%S %A %d %B %Y")} :: file size #{@file_size.to_s}</div>"
end
page.visual_effect :highlight, 'link_to_file', :endcolor => '#D3EDAB'
elsif @file_found == 1
page.replace_html 'link_to_file', "<div> File found, but still being constructed.</div><div>#{@this_filepath.to_s}</div>"
page.visual_effect :highlight, 'link_to_file', :endcolor => '#FF9900'
else
page.replace_html 'link_to_file', "<div> File not found @file_found #{@file_found.to_s} @file_ready #{@file_ready.to_s}</div>"
page.visual_effect :highlight, 'link_to_file', :endcolor => '#FF0000'
end