5

The attached script loops through the features of a polygon featureclass and uses that attribute information to download particular files via a ftp server. The script works great for downloading files as long as all of the files on the ftp server are contained within one folder (example).

Now, I need to download imagery via a ftp server with a different file structure (example) where files are contained within multiple folders. How can I tweak the code so that the following actions occur?:

  1. Use polygon features to identify the necessary file to download (completed)
  2. Access the correct folder and download the imagery

I suspect that I need to utilize the os.path module, however, I cannot seem to put the pieces together.


# Download data via a ftp server

import arcpy, ftplib, os, socket

HOST = 'ftp.agrc.utah.gov'
DIRN = '/Imagery/NAIP2011_4-band/'
#FILE = ''     # Defined later in for loop
workspace = r'F:\my\workspace'  # This is where the downloads go
quads = r'F:\path\to\polygon\shapefile' # Used to define which files to download

# Get current working directory
print 'The current working directory is %s' % os.getcwd()

# Change the current working directory to a download folder
os.chdir(workspace)
print 'The workspace has been changed to %s' % workspace 

try:
    f = ftplib.FTP(HOST)
except (socket.error, socket.gaierror), e:
    print 'ERROR: cannot reach "%s"' % HOST
print '*** Connected to host "%s"' % HOST

try:     
    f.login()
except ftplib.error_perm:
    print 'Error: cannot login anonymously'
    f.quit()
print '*** Logged in as "anonymous"'

try:
    f.cwd(DIRN)
except ftplib.error_perm:
    print 'ERROR: cannot CD to "%s"' % DIRN
    f.quit()
print '*** Changed to "%s" folder' % DIRN

# Use search cursor to loop through download polygons,
# get the name of the required file and use that name to download file on ftp site
with arcpy.da.SearchCursor(quads, ("TILE_NAME", "QUADID")) as cursor:
    for row in cursor:
        print row[0]
        FILE = row[0] + ".tif"
        name = row[1]

        try:
            f.retrbinary('RETR %s' % FILE, open(FILE, 'wb').write)
            arcpy.Rename_management(os.path.join(workspace, FILE), os.path.join(workspace, name + ".tif"))
        except ftplib.error_perm:
            print 'ERROR: cannot read file "%s"' % FILE
            os.unlink(FILE)
        else:
            print '*** Downloaded "%s" to CWD' % FILE
f.quit()
6

In your example you have a root folder containing many numbered folders.

Can you simply:

1) Use python to list the numbered folders:

    files = ftp.dir()
    print files

2) Match your polygon feature to the correct folder

3) Open the correct directory

ftp.cwd("/numbered_folder")

4) Use your existing code to download the files.

  • 1
    Thanks for the help Radar. The specific implementation is included below. – Aaron Jan 15 '14 at 22:15
2

The answer is a two-liner:

Add a folder name from the polygon attribute table

folder = row[0][:5] + "/"

And then change the directory within every iteration

f.cwd(DIRN + folder)

To put it all together starting with the with statement:

with arcpy.da.SearchCursor(quads, ("TILE_NAME", "QUADID")) as cursor:
    for row in cursor:
        print row[0]
        FILE = row[0] + ".tif"
        name = row[1]
        folder = row[0][:5] + "/"

        try:
            f.cwd(DIRN + folder)
            f.retrbinary('RETR %s' % FILE, open(FILE, 'wb').write)
            arcpy.Rename_management(os.path.join(workspace, FILE), os.path.join(workspace, name + ".tif"))
        except ftplib.error_perm:
            print 'ERROR: cannot read file "%s"' % FILE
            os.unlink(FILE)
        else:
            print '*** Downloaded "%s" to CWD' % FILE

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.