Ruby upload file error - ruby

I am trying to create a form that will upload files to AWS S3. I have searched all around for an answer but I am getting the error "TypeError at /upload can't convert Symbol into Integer"
Here is the block of code
post '/upload' do
s3 = AWS::S3.new(
:access_key_id => 'X',
:secret_access_key => 'X')
bucket = s3.buckets['X']
title = params['title']
desc = params['desc']
file = params['file'][:tempfile]
s3.buckets['indio'].objects[title].write(:file => file)
end
I get the error on the line
file = params['file'][:tempfile]
Can someone point out what I am doing wrong?

Typically the error can't convert Symbol into Integer hints to the fact that you are trying to access an array with a non-integer.
From this I suspect the params['file'] is an array or a string, and not whatever you think it is.
Find out exactly what you got in params['file'] and continue from there.

Related

'Extract-Name' error while loading AWS S3 Bucket

I'm attempting to upload files into my S3 bucket, but I'm receiving this error when I call my script.
Accounting::Datev::Utils::ExcelUtil.new(bucket: nil, object_key:nil, input_file_path: nil).call
ArgumentError: missing required option :name
from /Users/conhdss/.rvm/gems/ruby-2.5.1/gems/aws-sdk-s3-1.9.1/lib/aws-sdk-s3/bucket.rb:666:in `extract_name'
I have my bucket address defined in my local.yml, so I'm unsure exactly what's being asked of me? I'll attach some more code that perhaps is relevant, I'm not sure what exactly I need to pass in, in order to get this code to work.
I've attempted to use the bucket name and file name.
def initialize(bucket:, object_key:, input_file_path:)
#bucket = bucket
#object_key = object_key
#input_file_path = input_file_path
end
def call
# return unless input_file_path.end_with?('.xslx')
object = s3_resource.bucket(bucket).object(object_key)
object.upload_file(input_file_path)
end

Can't 'file.open.read' a url within a ruby if-block

I want to create a ruby script which will take barcodes from a text file, search a webservice for that barcode and download the result.
First I tried to test the webservice download. In a file when I hardcode the query things work fine:
result_download = open('http://webservice.org/api/?query=barcode:78686112327', 'User-Agent' => 'UserAgent email#gmail.com').read
It all works fine.
When I try to take the barcode from a textfile and run the query I run into problems.
IO.foreach(filename) {|barcode| barcode
website = "'http://webservice.org/api/?query=barcode:"+barcode.to_str.chomp + "', 'User-Agent' => 'UserAgent email#gmail.com'"
website = website.to_s
mb_metadata = open(website).read
}
The result of this is:
/home/user/.rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/open-uri.rb:37:in `initialize': No such file or directory # rb_sysopen - http://webservice.org/api/?query=barcode:78686112327', 'User-Agent' => 'UserAgent email#gmail.com' (Errno::ENOENT)
I can't figure out if this problem occurs because the string I generate somehow isn't a valid url and ruby is trying to open a non-existent file, or is the issue that I am doing all this in a for loop and the file/url doesn't exist there. I have tried using open(website).write instead of open(website).read but that produces the same error.
Any help would be much appreciated.
The error message you get explicitly states, that there is no such file:
http://webservice.org/api/?query=barcode:78686112327', 'User-Agent' => 'UserAgent email#gmail.com'.
You try to pass all the parameters to open method using 1 big string (website), which is wrong. You should do it like that.
IO.foreach(filename) do |barcode|
website = "http://webservice.org/api/?query=barcode:#{barcode.to_str.chomp}"
mb_metadata = open(website, 'User-Agent' => 'UserAgent email#gmail.com').read
end

How to upload an image to Amazon S3 into a folder in ruby?

I am trying to do it like this:
AWS.config(
:access_key_id => '...',
:secret_access_key => '...'
)
s3 = AWS::S3.new
bucket_name = 'bucket_name'
key = "#{File.basename(avatar_big)}"
s3.buckets[bucket_name].objects[key].write(:file => avatar_big_path)
This working well for a file, the file is uploaded to the root of the set up bucket.
However, how to upload it into the foloder photos that is located in root?
I've tried
key = "photos/#{File.basename(avatar_big)}"
but this doesn't work.
EDIT: error message
Thank you
I had the same issue as the OP. This is what worked for me:
key = "photos/example.jpg"
bucket = s3.buckets[bucket_name]
filepath = Pathname.new("path/to/example.jpg")
o = bucket.objects[key]
o.write(filepath)
Something I would check out would be the object key you are trying to use. There's not much documentation on what are the restrictions are (see this and this) but the one shown in error message looks suspicious to me.
Try including the the path in the file key:
s3.buckets[bucket_name].objects[key].write(:file => "photos/#{avatar_big_path}")

copy_to in s3 using ruby

Am trying to copy an image from bucket to another bucket in s3.
AWS.config(
:access_key_id => 'Bucket one key',
:secret_access_key => 'bucket one secret key'
)
s3 = AWS::S3.new
bucket1 = s3.buckets["Bucket_one"]
bucket2 = s3.buckets["Bucket_two"]
obj1 = bucket1.objects["source_key"]
obj2 = bucket2.objects["destination_key"]
obj1.copy_to(obj2)
Can you guide me as to how to retrieve the source key of a file already uploaded in S3? I have the destination_key,bucket_one and bucket_two.
Image on S3 is not a single file but a number of files names of which starts from the name of your image.
Thus you need to know the name of your image.
Once you get it, the could should look like:
bucket1 = s3.buckets["Bucket_one"]
bucket2 = s3.buckets["Bucket_two"]
bucket1.objects.with_prefix(image_name).each do |source_object|
source_object.copy_to(bucket2.objects[source_object.key])
end

Multipart File Upload in Ruby

I simply want to upload an image to a server with POST. As simple as this task sounds, there seems to be no simple solution in Ruby.
In my application I am using WWW::Mechanize for most things so I wanted to use it for this too, and had a source like this:
f = File.new(filename, File::RDWR)
reply = agent.post(
'http://rest-test.heroku.com',
{
:pict => f,
:function => 'picture2',
:username => #username,
:password => #password,
:pict_to => 0,
:pict_type => 0
}
)
f.close
This results in a totally garbage-ready file on the server that looks scrambled all over:
alt text http://imagehub.org/f/1tk8/garbage.png
My next step was to downgrade WWW::Mechanize to version 0.8.5. This worked until I tried to run it, which failed with an error like "Module not found in hpricot_scan.so". Using the Dependency Walker tool I could find out that hpricot_scan.so needed msvcrt-ruby18.dll. Yet after I put that .dll into my Ruby/bin-folder it gave me an empty error box from where on I couldn't debug very much further. So the problem here is that Mechanize 0.8.5 has a dependency on Hpricot instead of Nokogiri (which works flawlessly).
The next idea was to use a different gem, so I tried using Net::HTTP. After short research I could find out that there is no native support for multipart forms in Net::HTTP and instead you have to build a class that encodes etc. for you. The most helpful I could find was the Multipart-class by Stanislav Vitvitskiy. This class looked good so far, but it does not do what I need, because I don't want to post only files, I also want to post normal data, and that is not possible with his class.
My last attempt was to use RestClient. This looked promising, as there have been examples on how to upload files. Yet I can't get it to post the form as multipart.
f = File.new(filename, File::RDWR)
reply = RestClient.post(
'http://rest-test.heroku.com',
:pict => f,
:function => 'picture2',
:username => #username,
:password => #password,
:pict_to => 0,
:pict_type => 0
)
f.close
I am using http://rest-test.heroku.com which sends back the request to debug if it is sent correctly, and I always get this back:
POST http://rest-test.heroku.com/ with a 101 byte payload,
content type application/x-www-form-urlencoded
{
"pict" => "#<File:0x30d30c4>",
"username" => "s1kx",
"pict_to" => "0",
"function" => "picture2",
"pict_type" => "0",
"password" => "password"
}
This clearly shows that it does not use multipart/form-data as content-type but the standard application/x-www-form-urlencoded, although it definitely sees that pict is a file.
How can I upload a file in Ruby to a multipart form without implementing the whole encoding and data aligning myself?
Long problem, short answer: I was missing the binary mode for reading the image under Windows.
f = File.new(filename, File::RDWR)
had to be
f = File.new(filename, "rb")
Another method is to use Bash and Curl. I used this method when I wanted to test multiple file uploads.
bash_command = 'curl -v -F "file=#texas.png,texas_reversed.png"
http://localhost:9292/fog_upload/upload'
command_result = `#{bash_command}` # the backticks are important <br/>
puts command_result

Resources