Search code examples
ruby-on-railsrubyftpnet-ftp

How do I copy a file onto a separate server using Net::FTP?


I'm building a Rails app which creates a bookmarklet file for each user upon sign-up. I'd like to save that file onto a remote server, so I'm trying Ruby's Net::FTP, based on "Rails upload file to ftp server".

I tried this code:

  require 'net/ftp'

  FileUtils.cp('public/ext/files/script.js', 'public/ext/bookmarklets/'+resource.authentication_token )
  file = File.open('public/ext/bookmarklets/'+resource.authentication_token, 'a') {|f| f.puts("cb_bookmarklet.init('"+resource.username+"', '"+resource.authentication_token+"', '"+resource.id.to_s+"');$('<link>', {href: '//***.com/bookmarklet/cb.css',rel: 'stylesheet',type: 'text/css'}).appendTo('head');});"); return f }
  ftp = Net::FTP.new('www.***.com')
  ftp.passive = true
  ftp.login(user = '***', psswd = '***')
  ftp.storbinary("STOR " + file.original_filename, StringIO.new(file.read), Net::FTP::DEFAULT_BLOCKSIZE)
  ftp.quit()

But I'm getting an error that the file variable is nil. I may be doing several things wrong here. I'm pretty new to Ruby and Rails, so any help is welcome.


Solution

  • The block form of File.open does not return the file handle (and even if it did, it would be closed at that point). Perhaps change your code to roughly:

    require '…'
    FileUtils.cp …
    File.open('…','a') do |file|
      ftp = …
      ftp.storbinary("STOR #{file.original_filename}", StringIO.new(file.read))
      ftp.quit
    end
    

    Alternatively:

    require '…'
    FileUtils.cp …
    filename = '…'
    contents = IO.read(filename)
    ftp = …
    ftp.storbinary("STOR #{filename}", StringIO.new(contents))
    ftp.quit