Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if a listing is a directory or file in Python over FTP

Tags:

python

ftp

Python has a standard library module ftplib to run FTP communications. It has two means of getting a listing of directory contents. One, FTP.nlst(), will return a list of the contents of a directory given a directory name as an argument. (It will return the name of a file if given a file name instead.) This is a robust way to list the contents of a directory but does not give any indication whether each item in the list is a file or directory. The other method is FTP.dir(), which gives a string formatted listing of the directory contents of the directory given as an argument (or of the file attributes, given a file name).

According to a previous question on Stack Overflow, parsing the results of dir() can be fragile (different servers may return different strings). I'm looking for some way to list just the directories contained within another directory over FTP, though. To the best of my knowledge, scraping for a d in the permissions part of the string is the only solution I've come up with, but I guess I can't guarantee that the permissions will appear in the same place between different servers. Is there a more robust solution to identifying directories over FTP?

like image 952
gotgenes Avatar asked Feb 25 '09 05:02

gotgenes


3 Answers

Unfortunately FTP doesn't have a command to list just folders so parsing the results you get from ftp.dir() would be 'best'.

A simple app assuming a standard result from ls (not a windows ftp)

from ftplib import FTP

ftp = FTP(host, user, passwd)
for r in ftp.dir():
    if r.upper().startswith('D'):
        print r[58:]  # Starting point

Standard FTP Commands

Custom FTP Commands

like image 132
Christian Witts Avatar answered Oct 02 '22 14:10

Christian Witts


If the FTP server supports the MLSD command, then please check that answer for a couple of useful classes (FTPDirectory and FTPTree).

like image 27
tzot Avatar answered Oct 02 '22 12:10

tzot


Another way is to assume everything is a directory and try and change into it. If this succeeds it is a directory, but if this throws an ftplib.error_perm it is probably a file. You can catch then catch the exception. Sure, this isn't really the safest, but neither is parsing the crazy string for leading 'd's.

Example

def processRecursive(ftp,directory):
    ftp.cwd(directory)
    #put whatever you want to do in each directory here
    #when you have called processRecursive with a file, 
    #the command above will fail and you will return


    #get the files and directories contained in the current directory
    filenames = []
    ftp.retrlines('NLST',filenames.append)
    for name in filenames:
        try:
            processRecursive(ftp,name)
        except ftplib.error_perm:
            #put whatever you want to do with files here

    #put whatever you want to do after processing the files 
    #and sub-directories of a directory here
like image 29
Cara Monical Avatar answered Oct 02 '22 12:10

Cara Monical