Python Forum

Full Version: FTP Download of Last File
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
The goal of the script is to grab the last file on the ftp site and save it in a network folder. I am not familiar with debugging the code to see where issues are, and I pulled this code from another article but it seems like it should have been straight forward. Also wondering if my values are in the correct place also, if I am using this example do I enter my values for the ftp host, user, pw, etc. on just the first line "def...."? I inputted my values for the ftp credentials everywhere in the code it had those statements, which I don't think hurts but probably not efficient. When I ran the script, something fired off and the command black screen showed for a milisecond. All of this is really new to me and only had some success writing my own code that called a SQL DB and outputted files, this FTP stuff is racking my head.
from ftplib import FTP
import os
import datetime

def download_most_recent_file('ftp.example.com', 'your_username', 'your_password', '/remote/directory', '/local/directory'):
    try:
        # Connect to FTP server
        ftp = FTP(ftp_host)
        ftp.login(your_username, your_password)
        
        # Change to the specified directory
        ftp.cwd(/remote/directory)
        
        # List files and get the most recent one
        files = ftp.nlst()
        files_with_dates = [(file, ftp.voidcmd(f'MDTM {file}')[4:]) for file in files]
        most_recent_file = max(files_with_dates, key=lambda x: datetime.datetime.strptime(x[1], "%Y%m%d%H%M%S")[0])
        
        # Download the most recent file
        file_name = most_recent_file[0]
        local_file_path = os.path.join(/local/directory, file_name)
        with open(local_file_path, 'wb') as local_file:
            ftp.retrbinary('RETR ' + file_name, local_file.write)
        
        print(f"Downloaded most recent file: {file_name}")
    except Exception as e:
        print(f"Error: {e}")
    finally:
        ftp.quit()

# Example usage
ftp_host = 'ftp.example.com'
ftp_user = 'your_username'
ftp_password = 'your_password'
ftp_directory = '/remote/directory'
local_directory = '/local/directory'

download_most_recent_file(ftp_host, ftp_user, ftp_password, ftp_directory, local_directory)
The datetime strings returned by ftp MDTM are formatted in a way that they can be sorted without having to convert them to datetime objects. You can replace this:
files = ftp.nlst()
files_with_dates = [(file, ftp.voidcmd(f'MDTM {file}')[4:]) for file in files]
most_recent_file = max(files_with_dates, key=lambda x: datetime.datetime.strptime(x[1], "%Y%m%d%H%M%S")[0])
file_name = most_recent_file[0]
with this:
file_name = max(ftp.nlst(), key=lambda x: ftp.voidcmd(f'MDTM {x}')[4:])
(Mar-15-2024, 06:30 PM)deanhystad Wrote: [ -> ]The datetime strings returned by ftp MDTM are formatted in a way that they can be sorted without having to convert them to datetime objects. You can replace this:
files = ftp.nlst()
files_with_dates = [(file, ftp.voidcmd(f'MDTM {file}')[4:]) for file in files]
most_recent_file = max(files_with_dates, key=lambda x: datetime.datetime.strptime(x[1], "%Y%m%d%H%M%S")[0])
file_name = most_recent_file[0]
with this:
file_name = max(ftp.nlst(), key=lambda x: ftp.voidcmd(f'MDTM {x}')[4:])
so just this part could be causing the script to not run?
No, that just an observation.

If I were you, I would remove the try/except/finally. Maybe you'll get some useful information about what causes the script to fail.

I don't understand this:
Quote:When I ran the script, something fired off and the command black screen showed for a milisecond
How do you run the script? I would run from the command line. Maybe error information is getting displayed in the window that shows for a millisecond. Try opening your favorite command shell and typing
Output:
python whatevethisscripteiscalled.py
Not Python, but very handy!

Assuming you can ssh into your server, a bash script is good for doing file things like you want.

This lovely little 1-liner from stackoverflow 2010 gets you the name of the newest file in path1:

newest=`ls $path1 | sort -n -t _ -k 2 | tail -1`
Pay attention to the back-ticks!

Quote:ssh -p 22 -i ~/.ssh/my_cloud_ed25519 pedro@123.123.123.123
user="pedro"
path1="/var/www/mywebpage.com/public_html/contact/messages/"
putpath="/var/www/mywebpage.com/public_html/contact/save_newest/"
# get the name of the newest file
newest=ls $path1 | sort -n -t _ -k 2 | tail -1
mv -v $path1$newest $putpath

Save this as movefile.sh, make it executable, then run it. Only 6 lines!