0

I want to download a specific directory on a linux ftp server with all files and subfolders/subsubfolders...

I found this code which is only working for a linux ftp server and linux os, but my os is windows. I went over the code and it is just making a clone of the directory structure so replacing "/" with "\\" should do the job. However I failed to make the code work.

Here is my current (not working code) where I just replaced path with path.replace("/", "\\") on the relevant places:

import sys
import ftplib
import os
from ftplib import FTP
ftp=FTP("ftpserver.com")    
ftp.login('user', 'pass')

def downloadFiles(path,destination):
#path & destination are str of the form "/dir/folder/something/"
#path should be the abs path to the root FOLDER of the file tree to download
  try:
      ftp.cwd(path)
      #clone path to destination
      os.chdir(destination)
      print destination[0:len(destination)-1]+path.replace("/", "\\")
      os.mkdir(destination[0:len(destination)-1]+path.replace("/", "\\"))
      print destination[0:len(destination)-1]+path.replace("/", "\\")+" built"
  except OSError:
      #folder already exists at destination
      pass
  except ftplib.error_perm:
      #invalid entry (ensure input form: "/dir/folder/something/")
      print "error: could not change to "+path
      sys.exit("ending session")

  #list children:
  filelist=ftp.nlst()

  for file in filelist:
      try:
          #this will check if file is folder:
          ftp.cwd(path+file+"/")
          #if so, explore it:
          downloadFiles(path+file+"/",destination)
      except ftplib.error_perm:
          #not a folder with accessible content
          #download & return
          os.chdir(destination[0:len(destination)-1]+path.replace("/", "\\"))
          #possibly need a permission exception catch:
          ftp.retrbinary("RETR "+file, open(os.path.join(destination,file),"wb").write)
          print file + " downloaded"
  return

downloadFiles("/x/test/download/this/",os.path.dirname(os.path.abspath(__file__))+"\\")

Output:

Traceback (most recent call last):
  File "ftpdownload2.py", line 44, in <module>
    downloadFiles("/x/test/download/this/",os.path.dirname(os.path.abspath(__file__))+"\\")
  File "ftpdownload2.py", line 38, in downloadFiles
    os.chdir(destination[0:len(destination)-1]+path.replace("/", "\\"))
WindowsError: [Error 3] The system cannot find the path specified: 'C:\\
Users\\Me\\Desktop\\py_destination_folder\\x\\test\\download\\this\\'

Can anyone please help me get this code work? Thanks.

Community
  • 1
  • 1
Cecil
  • 119
  • 1
  • 5
  • Does this code of the author actually makes sense? I think the problem is the directory creation. Instead of creating `x`, then `test`, then `download` ... it is just creating `/x/test/download/this/` which is wrong, right? – Cecil Feb 25 '14 at 13:45

1 Answers1

0

The directory creation seems to be similar to this question that was already asked besides the change due to Windows format.

mkdir -p functionality in Python

How to run os.mkdir() with -p option in Python?

As a result, I would suggest putting in the mkdir_p function shown in the accepted answers to those questions and then seeing if the windows will create the appropriate path

os.mkdir(destination[0:len(destination)-1]+path.replace("/", "\\"))

then becomes

newpath = destination[0:len(destination)-1]+path.replace("/", "\\")
mkdir_p(newpath)

This uses the os.makedirs(path) method in order to get the full path. You could also just replace os.mkdir() with os.makedirs()

Note that if you use the replacement path in a number of places, then just keep using the newpath variable. That might be easier in the rest of your code.

Community
  • 1
  • 1
sabbahillel
  • 4,357
  • 1
  • 19
  • 36