0

I am trying to retrieve files (.csv) from an ftp site and save them all locally in the same folder. My code looks like this:

#! /usr/bin/ruby

require 'logger'
require 'fileutils'
require 'net/ftp'
require 'rubygems'
require 'mysql2'
require 'roo'
require 'date'

# logging setup
log = Logger.new("/path_to_logs/ftp_log.log", 10, 1024000)
log.level = Logger::INFO

export_ftp_path = '/Receive/results/'
export_work_path ='/Users/pierce/results_exports/'

Net::FTP.open('host', 'username', 'password') do |ftp|
    log.info("Logged into FTP")
    ftp.passive = true
    ftp.chdir("#{export_ftp_path}")
      ftp.list.each do |file|
        log.info("Found file #{file}")
        new_file = file[56..115]  #take part of the file name and remove spaces and periods
        new_file = new_file.gsub(/[.]+/, "") 
        new_file = new_file.gsub(/\s/, "0") 
        ftp.gettextfile(file,"#{new_file}")
        log.info("Downloaded file #{new_file}")
      end
end

And here is the error I receive:

/Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/1.9.1/net/ftp.rb:560:in `initialize': No such file or directory -  (Errno::ENOENT)
    from /Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/1.9.1/net/ftp.rb:560:in `open'
    from /Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/1.9.1/net/ftp.rb:560:in `gettextfile'
    from ftp_test.rb:44:in `block (2 levels) in <main>'
    from ftp_test.rb:33:in `each'
    from ftp_test.rb:33:in `block in <main>'
    from /Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/1.9.1/net/ftp.rb:116:in `open'

As suggested, here are the values I have for puts file and puts new_file.

file = -rwxr-xr-x    1 1130419  114727       9546 May 17 08:11 results_Wed. 16 May 2012.csv
new_file = results_Wed0230May02012csv

Any suggestions on what to change in gettextfile or within my script to get the files saved correctly?

analyticsPierce
  • 2,979
  • 9
  • 57
  • 81
  • You need to at least start by fixing the file you are downloading. It should be `ftp.gettextfile("#{file}","#{new_file}")`. You can't have `new_file` as the source name. – Casper Jun 23 '12 at 10:21
  • Thanks for the suggestion. I made that change and got the same error as the first error message above. Any other suggestions. – analyticsPierce Jun 23 '12 at 10:34
  • How about just `ftp.gettextfile(file, "testfile")`. Also you should debug (print out) what `new_file` is before you use it. – Casper Jun 23 '12 at 22:21
  • @Casper I made some edits to my question and tried the direction you suggested. However, I received a 'No such file or directory' error. I think it has to do with the extra spaces in the file name which is why I was removing them and creating a new variable. I added the actual values of these variables into my question. – analyticsPierce Jun 24 '12 at 06:56

1 Answers1

1

You should use nlst instead of list when you just need a list of files in a directory. The output of list needs to be properly parsed otherwise.

When you request the file it has to be the original filename, including all spaces. When you save the file it can be anything you want (including spaces or not). The error was because you were requesting the wrong file. Use nlst in your case instead. It will make it much easier (no conversion or parsing needed).

Casper
  • 33,403
  • 4
  • 84
  • 79
  • this looks like it is returning a good filename. However, the . and .. files are not able to be processed by gettextfile. How can I eliminate them from the returned nest array? – analyticsPierce Jun 24 '12 at 23:22
  • @analyticsPierce - There are many ways. You could add this to the first line of the loop for example: `next if file.match(/^\.\.?$/)`. That will cause the loop to jump to the next element if the file is either `.` or `..`. Or if you like more verbose code then: `next if file == "." || file == ".."`. – Casper Jun 24 '12 at 23:28
  • Nice, perfect. Thanks so much for your help, I learned so much from this. – analyticsPierce Jun 25 '12 at 04:59