ruby reading files from S3 with open-URI

时光总嘲笑我的痴心妄想 提交于 2019-12-08 07:31:04

问题


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


回答1:


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.




回答2:


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.




回答3:


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|}



回答4:


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.



来源:https://stackoverflow.com/questions/4422956/ruby-reading-files-from-s3-with-open-uri

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!