ruby reading files from S3 with open-URI

I'm having some problems reading a file from S3. I want to be able to load the ID3 tags remotely, but using open-URI doesn't work, it gives me the following error:

ruby-1.8.7-p302 > c=TagLib2::File.new(open(URI.parse("http://recordtemple.com.s3.amazonaws.com/music/745/original/The%20Stranger.mp3?1292096514")))
TypeError: can't convert Tempfile into String
    from (irb):8:in `initialize'
    from (irb):8:in `new'
    from (irb):8

However, if i download the same file and put it on my desktop (ie no need for open-URI), it works just fine.

c=TagLib2::File.new("/Users/momofwombie/Desktop/blah.mp3")

is there something else I should be doing to read a remote file?

UPDATE: I just found this link, which may explain a little bit, but surely there must be some way to do this...

Read header data from files on remote server

Answers


Might want to check out AWS::S3, a Ruby Library for Amazon's Simple Storage Service

Do an AWS::S3:S3Object.find for the file and then an use about to retrieve the metadata

This solution assumes you have the AWS credentials and permission to access the S3 bucket that contains the files in question.


TagLib2::File.new doesn't take a file handle, which is what you are passing to it when you use open without a read.

Add on read and you'll get the contents of the URL, but TagLib2::File doesn't know what to do with that either, so you are forced to read the contents of the URL, and save it.

I also noticed you are unnecessarily complicating your use of OpenURI. You don't have to parse the URL using URI before passing it to open. Just pass the URL string.

require 'open-uri'

fname = File.basename($0) << '.' << $$.to_s
File.open(fname, 'wb') do |fo|
  fo.print open("http://recordtemple.com.s3.amazonaws.com/music/745/original/The%20Stranger.mp3?1292096514").read
end

c = TagLib2::File.new(fname)

# do more processing...

File.delete(fname)

I don't have TagLib2 installed but I ran the rest of the code and the mp3 file downloaded to my disk and is playable. The File.delete would clean up afterwards, which should put you in the state you want to be in.


This solution isn't going to work much longer. Paperclip > 3.0.0 has removed to_file. I'm using S3 & Heroku. What I ended up doing was copying the file to a temporary location and parsing it from there. Here is my code:

dest = Tempfile.new(upload.spreadsheet_file_name)
dest.binmode
upload.spreadsheet.copy_to_local_file(:default_style, dest.path)
file_loc = dest.path 

...

CSV.foreach(file_loc, :headers => true, :skip_blanks => true) do |row|}

This seems to work instead of open-URI:

Mp3Info.open(mp3.to_file.path) do |mp3info|
  puts mp3info.tag.artist
end

Paperclip has a to_file method that downloads the file from S3.


Need Your Help

MySQL Select Last 10 Rows Using WHERE AVG()

mysql group-by average

I am trying to pull a list of last 10 rows whose average rating is above 4. Right now this is done by selecting from the first table and then checking the average if its above 4 then it gets added ...

drag image from TileList and drop on Canvas in Flex 3

actionscript-3 flex canvas drag-and-drop flex3

i'm working on a Flex project where i will have to use the drag &amp; drop functionality.