tags:

views:

304

answers:

5

How can i check if a file on a remote ftp is a folder or not using ftplib?

Best way i have right now is to do a nlst, and iterate through calling size on each of the files, if the file errors out then it is a folder?

Is there a better way? I cannot parse the output of list, since there is about a dozen different ftp servers(many extremely old.)

What should i do?

+2  A: 

FTP.dir returns a directory listing, that you can parse with a callback function to find out whether it's a directory. For example, like this:

def parse(line):
    if line[0] == 'd':
        print(line.rpartition(' ')[2])   # gives you the name of a directory

ftp.dir(parse)
SilentGhost
But the output is not standard, so its useless.
UberJumper
well, parse it with a different function then. surely there isn't as many types of responses.
SilentGhost
Well considering right now at count there is 57 different remote ftp servers, some running linux/windows/HPUX/solaris/BSD ftp clients, + the random plethora of 3rd party ftp clients. Its a pain.
UberJumper
why do you think that there will be as many response formats? as long as some form of drwxrwxrwx is there, you can split string and use regexp or other technique to find out what field contains permission.
SilentGhost
A: 
def is_file(filename):
    return ftp.size(filename) is not None

This works because ftp.size returns None if it is a directory.

Evan Fosmark
The problem is i just noticed that one of the ftp servers, actually returns the filesize of a folder. Which shouldnt happen, but it does. Jolly.
UberJumper
raises `error_reply` on directories in py3k
SilentGhost
@uberjumper, I have one more idea to try that I'll post soon. That's really surprising that it returns the folder size.@SilentGhost, I did it in 2.6, but thanks for the note. If I share it with someone using 3.x I'll be sure to give them a modified version.
Evan Fosmark
Yes i know, also it returns the MDTM date also. I've seen one or two other ftp servers that dump folder sizes, but don't dump file modification dates. I eagrly await your solution.
UberJumper
A: 
def is_file(filename):
    current = ftp.pwd()
    try:
        ftp.cwd(filename)
    except:
        ftp.cwd(current)
        return True
    ftp.cwd(current)
    return False

Here is another solution. Half way writing it out I realized it has a problem. If you don't have permission to change to a folder, it'll read it as a file instead. It'll work if you have access to any folder.

I still posted it because maybe it'll give some ideas.

Evan Fosmark
+3  A: 

FTP is quite a rudimentary protocol and there's no built-in protocol query allowing you to get the type (file, dir) of each node, so a heuristic like the one you found is the only solution.

If getting the size of each node doesn't work, perhaps you should consider calling FTP.nlst() on each of those nodes: those that error out will be files rather than dirs.

Antoine P.
A: 

I'm running into this concern now too. I suppose no more progress has been made? Also I'm wondering if an sftp solution is available yet.

iJames
see Antoine's new addition
Matt Joiner
Yeah thats pretty much what i ended up doing. There is no decent way. The best ways ive found have basically been ether asking for the SIZE or MDTM date. On certain systems size, command works, on others MDTM works. I ended up just doing both. That worked on everything i ever ran into.
UberJumper