Python FTP retrieves the most recent file by date

I use ftplib to connect to the ftp site. I want to get the last downloaded file and upload it. I can connect to the ftp server and list the files, I also put them on the list and got the datefield conversion. Is there any function / module that can get the latest date and print the entire line from the list?

 #!/usr/bin/env python import ftplib import os import socket import sys HOST = 'test' def main(): try: f = ftplib.FTP(HOST) except (socket.error, socket.gaierror), e: print 'cannot reach to %s' % HOST return print "Connect to ftp server" try: f.login('anonymous',' al@ge.com ') except ftplib.error_perm: print 'cannot login anonymously' f.quit() return print "logged on to the ftp server" data = [] f.dir(data.append) for line in data: datestr = ' '.join(line.split()[0:2]) orig-date = time.strptime(datestr, '%d-%m-%y %H:%M%p') f.quit() return if __name__ == '__main__': main() 

RESOLVED:

 data = [] f.dir(data.append) datelist = [] filelist = [] for line in data: col = line.split() datestr = ' '.join(line.split()[0:2]) date = time.strptime(datestr, '%m-%d-%y %H:%M%p') datelist.append(date) filelist.append(col[3]) combo = zip(datelist,filelist) who = dict(combo) for key in sorted(who.iterkeys(), reverse=True): print "%s: %s" % (key,who[key]) filename = who[key] print "file to download is %s" % filename try: f.retrbinary('RETR %s' % filename, open(filename, 'wb').write) except ftplib.err_perm: print "Error: cannot read file %s" % filename os.unlink(filename) else: print "***Downloaded*** %s " % filename return f.quit() return 

One of the problems is, is it possible to extract the first element from the dictionary? what I did here is that the for loop only works once and exits, thereby giving me the first sorted value, which is good, but I don't think it's good practice to do it this way.

+5
source share
4 answers

If you have all the dates in time.struct_time ( strptime will give you this) in the list, then all you have to do is sort list.

Here is an example:

 #!/usr/bin/python import time dates = [ "Jan 16 18:35 2012", "Aug 16 21:14 2012", "Dec 05 22:27 2012", "Jan 22 19:42 2012", "Jan 24 00:49 2012", "Dec 15 22:41 2012", "Dec 13 01:41 2012", "Dec 24 01:23 2012", "Jan 21 00:35 2012", "Jan 16 18:35 2012", ] def main(): datelist = [] for date in dates: date = time.strptime(date, '%b %d %H:%M %Y') datelist.append(date) print datelist datelist.sort() print datelist if __name__ == '__main__': main() 
+1
source

Why don't you use the following dir option?

 ftp.dir('-t',data.append) 

With this option, the list of files is ordered by time from the newest to the oldest. Then just upload the first file to the list to upload it.

+6
source

For those who are looking for a complete solution to find the last file in a folder:

If your FTP server supports the MLSD command, the solution is easy:

 entries = list(ftp.mlsd()) entries.sort(key = lambda entry: entry[1]['modify'], reverse = True) latest_name = entries[0][0] print(latest_name) 

If you need to rely on the legacy LIST command, you need to parse the listing that it returns.

General list * nix:

 -rw-r--r-- 1 user group 4467 Mar 27 2018 file1.zip -rw-r--r-- 1 user group 124529 Jun 18 15:31 file2.zip 

With such a list, this code will do:

 from dateutil import parser # ... lines = [] ftp.dir("", lines.append) latest_time = None latest_name = None for line in lines: tokens = line.split(maxsplit = 9) time_str = tokens[5] + " " + tokens[6] + " " + tokens[7] time = parser.parse(time_str) if (latest_time is None) or (time > latest_time): latest_name = tokens[8] latest_time = time print(latest_name) 

This is a rather fragile approach.


A more reliable but less efficient way is to use the MDTM to retrieve the timestamps of individual files / folders:

 names = ftp.nlst() latest_time = None latest_name = None for name in names: time = ftp.sendcmd("MDTM " + name) if (latest_time is None) or (time > latest_time): latest_name = name latest_time = time print(latest_name) 

Some FTP servers support their own custom -t switch for the NLST (or LIST ) command.

 lines = ftp.nlst("-t") latest_name = lines[-1] 

See Section How to get files in FTP folder sorted by modification time .


No matter which approach you use, as soon as you have the latest_name , you upload it like any other file:

 file = open(latest_name, 'wb') ftp.retrbinary('RETR '+ latest_name, file.write) 

See Also Getting the Last FTP Folder Name in Python .

+2
source

I do not know how this is your ftp, but your example did not work for me. I changed some lines related to date sorting:

  import sys from ftplib import FTP import os import socket import time # Connects to the ftp ftp = FTP(ftpHost) ftp.login(yourUserName,yourPassword) data = [] datelist = [] filelist = [] ftp.dir(data.append) for line in data: col = line.split() datestr = ' '.join(line.split()[5:8]) date = time.strptime(datestr, '%b %d %H:%M') datelist.append(date) filelist.append(col[8]) combo = zip(datelist,filelist) who = dict(combo) for key in sorted(who.iterkeys(), reverse=True): print "%s: %s" % (key,who[key]) filename = who[key] print "file to download is %s" % filename try: ftp.retrbinary('RETR %s' % filename, open(filename, 'wb').write) except ftplib.err_perm: print "Error: cannot read file %s" % filename os.unlink(filename) else: print "***Downloaded*** %s " % filename ftp.quit() 
+1
source

Source: https://habr.com/ru/post/1392733/


All Articles