I have been working on this for a while. Tried many many different things, I'm totally stumped.
I'm trying to download a series of mp3 files from Amazon s3, then store them in Heroku's tmp dir, zip them, then download the file.
It works locally, but when its pushed to Heroku the zip file gets created but is corrupted/empty (0 Bytes). Heroku doesn't throw any errors (see log file below). The individual files seem be getting written fine. I can write them to tmp then send them. So it appears to be something with the zipfile getting created?
I'm really new to heroku so even tips on how to debug would also be helpful.
Any help would be much appreciated! I can't seem to get this solved for the life of me.
Code:
def download_album
require 'rubygems'
require 'zip/zip'
if(params.has_key?(:album_url_slug))
@artist = Artist.find_by_url_slug(params[:url_slug])
find_album(@artist,params[:album_url_slug])
else
@album = album
@artist = artist
end
#Sets Directory Path
directory_path = "#{Rails.root}/tmp/#{Process.pid}_mp3"
directory_artist_path = directory_path+"/"+@artist.url_slug
directory = directory_artist_path+"/"+@album.album_url_slug
zipfile = @album.al_name+".zip"
zipfile_name = directory_artist_path+"/"+zipfile
FileUtils.mkdir_p directory
#zips files
Zip::ZipFile.open(zipfile_name, Zip::ZipFile::CREATE) do |zipfile|
#gets mp3's from S3 and writes them into the zip directory
@album.songs.uniq.each do |songs|
#sets the name of the file to be loaded
name = songs.song_name+".mp3"
@song_file = AWS::S3::S3Object.value(songs.s3_id, BUCKET)
# create the file path
path = File.join(directory,name)
File.open(path, 'wb') { |f| f.write(@song_file) }
zipfile.add(name, path)
end
end
send_file(directory_artist_path+"/"+zipfile,
:filename => @album.al_name+".zip")
Log File:
2012-08-17T02:32:03+00:00 heroku[web.1]: State changed from starting to up
2012-08-17T02:32:04+00:00 app[web.1]: => Booting WEBrick
2012-08-17T02:32:04+00:00 app[web.1]: => Rails 3.0.7 application starting in production on http://0.0.0.0:40764
2012-08-17T02:32:04+00:00 app[web.1]: => Call with -d to detach
2012-08-17T02:32:04+00:00 app[web.1]:
2012-08-17T02:32:04+00:00 app[web.1]: Started GET "/tedkennedy/album/download/testalbum6" for 216.58.66.202 at 2012-08-17 02:32:04 +0000
2012-08-17T02:32:04+00:00 app[web.1]:
2012-08-17T02:32:04+00:00 app[web.1]: => Ctrl-C to shutdown server
2012-08-17T02:32:05+00:00 app[web.1]: Zipping files!
2012-08-17T02:32:06+00:00 app[web.1]: Parameters: {"url_slug"=>"tedkennedy", "album_url_slug"=>"testalbum6"}
2012-08-17T02:32:06+00:00 app[web.1]: Processing by AlbumsController#download_album as HTML
2012-08-17T02:32:06+00:00 app[web.1]: Sent file /app/tmp/tedkennedy/Test album 6.zip (0.1ms)
2012-08-17T02:32:06+00:00 app[web.1]: Completed 200 OK in 1809ms
2012-08-17T02:32:06+00:00 heroku[router]: GET mighty-refuge-6115.herokuapp.com/tedkennedy/album/download/testalbum6 dyno=web.1 queue=0 wait=0ms service=1922ms status=200 bytes=0
So after much debugging. Turns out sendfile was the problem...not sure on the details but more can be found here.
My solution is to zip the files, then store the zip file on s3 then download zip file from s3. Admittedly not the most elegant, but in my case the files only have to be zipped once then I just download from s3 from then on.