This script filled the need to have a scheduled directory synch occur via FTP. I also realized I could use it to clean out a directory without much effort. There are probably more robust examples out there, but this one should be easily modifiable for FTP newbies. It uses Sets to speed up finding missing files from the local directory.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
def moveFTPFiles(serverName,userName,passWord,remotePath,localPath,deleteRemoteFiles=False,onlyDiff=False): """Connect to an FTP server and bring down files to a local directory""" import os from sets import Set from ftplib import FTP try: ftp = FTP(serverName) except: print "Couldn't find server" ftp.login(userName,passWord) ftp.cwd(remotePath) try: print "Connecting..." if onlyDiff: lFileSet = Set(os.listdir(localPath)) rFileSet = Set(ftp.nlst()) transferList = list(rFileSet - lFileSet) print "Missing: " + str(len(transferList)) else: transferList = ftp.nlst() delMsg = "" filesMoved = 0 for fl in transferList: # create a full local filepath localFile = localPath + fl grabFile = True if grabFile: #open a the local file fileObj = open(localFile, 'wb') # Download the file a chunk at a time using RETR ftp.retrbinary('RETR ' + fl, fileObj.write) # Close the file fileObj.close() filesMoved += 1 # Delete the remote file if requested if deleteRemoteFiles: ftp.delete(fl) delMsg = " and Deleted" print "Files Moved" + delMsg + ": " + str(filesMoved) + " on " + timeStamp() except: print "Connection Error - " + timeStamp() ftp.close() # Close FTP connection ftp = None def timeStamp(): """returns a formatted current time/date""" import time return str(time.strftime("%a %d %b %Y %I:%M:%S %p")) if __name__ == '__main__': #--- constant connection values ftpServerName = "ftpservername.com" ftpU = "ftpusername" ftpP = "ftppassword" remoteDirectoryPath = "remote/ftp/subdirectory" localDirectoryPath = """local\sub\directory""" print "\n-- Retreiving Files----\n" deleteAfterCopy = False #set to true if you want to clean out the remote directory onlyNewFiles = True #set to true to grab & overwrite all files locally moveFTPFiles(ftpServerName,ftpU,ftpP,remoteDirectoryPath,localDirectoryPath,deleteAfterCopy,onlyNewFiles)
This could stand to have a more robust synch method - just grabbing the files that don't exist locally doesn't help you with newer/changed files of the same name.
I'm also using a try/except block that covers a little too much code. More granular error handling would be nice, but might make it's readability drop.
huh? Where's the definition of ZzWw?
Rats. Sorry about that - it appears my pop-up blocking/ad munching software killed that line when I submitted (and tried to re-edit) the code.
The line has been changed to "open"
stumped. I can't get this working
this is what I get:
-- Retreiving Files----
Couldn't find server Traceback (most recent call last):
File "C:\Python24\projects\zipstuff\ftp.py", line 66, in ?
File "C:\Python24\projects\zipstuff\ftp.py", line 10, in moveFTPFiles
UnboundLocalError: local variable 'ftp' referenced before assignment
The ftpservername is correct, as is the ftpU and ftpP.
What could I be doing wrong?
got it. ah I see, you don't include the ftp:// in the address, just the address without the ftp:// duh
Thanks very much for sharing. A lot of this is beyond me at present as I just started python yesterday. I was hoping to understand why I'm getting a syntax error by looking at your code. Alas, it is far to advanced with many function calls. If you have a moment can you tell me why I can't change to a specific folder on the ftp site without getting an error message. I can upload a file directly to the root but can't get pass an error when i try to change the directory. - thanks.
(keep getting this error message: TypeError: cwd() missing 1 required positional argument: 'dirname' I have tried many variations for the directory argument; 'mychosenfolder' - '/mychosenfolder/' '//mychosenfolder//' and even assigned the string to a variable and used that in the FTP.cwd statmente (as in the code below) But still get the same error message. And YES, the folder does exist and it is writeable to.
I have issue with images named with a dash characters.... how can i still use this script and make it working?? (original file name is DJ3200-03-BX.jpg cmd 'RETR DJ3200?03?BX.jpg' resp '550 The filename, directory name, or volume label syntax is incorrect. ' Connection Error - Sun 30 Apr 2017 10:29:13 AM