File Upload with Sinatra

File upload with Sinatra

I've had good luck with the example code found on this thread.

Including it here in case the link ever disappears:

post '/upload' do
unless params[:file] &&
(tmpfile = params[:file][:tempfile]) &&
(name = params[:file][:filename])
@error = "No file selected"
return haml(:upload)
end
STDERR.puts "Uploading file, original name #{name.inspect}"
while blk = tmpfile.read(65536)
# here you would write it to its final location
STDERR.puts blk.inspect
end
"Upload complete"
end

Then your view would look like this. This uses HAML, but the important part is not to forget to set the enctype in your form element, otherwise you will just get the filename instead of an object:

%form{:action=>"/upload",:method=>"post"   ,:enctype=>"multipart/form-data"}
%input{:type=>"file",:name=>"file"}
%input{:type=>"submit",:value=>"Upload"}

Multiple file upload with ruby & sinatra

this is my solution

puts params['images'].map{ |f| f[:filename] }.join(";")
k = params['images'].map{ |f| f[:filename] }.join(";")
$param = k.chomp.split(";")
array_length = $param.length # or $param.size
array_lengthx = array_length - 1
puts "length of $param is : #{array_length}"

i = 0
i = i - 1
puts array_lengthx
puts i
while i.to_i < array_lengthx do
i =i+1
puts i
@filename = params[:images][i][:filename]
file = params[:images][i][:tempfile]
path = "/home/user/Descargas/sinatra_ajax-master/#{@filename}"
File.open("/home/user/Descargas/sinatra_ajax-master/#{@filename}", 'wb') do |f|
f.write file.read
end
end

this is html code:

<form action="/upload2" method="post" enctype="multipart/form-data">  <input type="file" name="images[]" multiple />  <input type="submit" /></form>

how to upload file using ajax request with sinatra?

It's a safe bet that params['cfile'] is nil. Have you actually logged your request parameters to ensure you are posting what you think you're posting?

Furthermore, I believe that you're trying to upload these files using JSON - you will most likely need to base64 encode the body of the file to do this.

Multiple file uploads in Sinatra

The only thing that puts me off here is that you don't use the POST method – maybe your issue has to do with that. Anyway, the following code works perfectly for me. I hope this will give you a hint how to fix your code.

require 'sinatra'

get '/' do
<<-HTML
<html>
<head><title>Multi file upload</title></head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="images[]" multiple />
<input type="submit" />
</form>
</body>
</html>
HTML
end

post '/upload' do
content_type :text

res = "I received the following files:\n"
res << params['images'].map{|f| f[:filename] }.join("\n")
res
end

Sinatra, progress bar in upload form

I think i got what the problem is:

tmp = params[:file][:tempfile] doesn't return until the file has been fully received.

How to upload multiple files via Sinatra and avoid NoMethodError - undefined method `read' for # File:0x0000000xxxxxx0 :String

When you run join() on your tempfiles:

mz= params['images'].map{|f| f[:tempfile] }.join(";")

You're taking a a bunch of File objects and forcing them into strings using to_s(). But the default to_s for a File is to create this generally useless thing:

"#<File:0x0000000xxxxxx0>"

Which is why you're getting the error message that you are.


As for how to fix it, the solution is simply to not turn your files into strings. I don't entirely understand why you're taking an array, joining it into a string, then immediately splitting the string back into an array. I would just not do any of that:

post '/upload2' do
puts params

filename = params["images"][0][:filename]
puts filename

tempfile = params["images"][0][:tempfile]
puts tempfile

path = "/home/user/Descargas/sinatra_ajax-master/#{filename}"

File.open(path, 'wb') do |f|
f.write(tempfile.read)
end

erb :index

end


Related Topics



Leave a reply



Submit