2 min read

FTP Cleanup Utility (File Rotation)

This utility connects to an FTP server and deletes files in a specific directory that are older than a specified number of days. This is essential for maintaining disk space on servers by rotating old backups or log files.

Modules Used:

  • ftplib: To handle FTP commands.
  • datetime: To calculate file age.
  • argparse: To handle command-line arguments.

The Code

Save this as ftp_cleanup.py.

import ftplib
import argparse
from datetime import datetime, timedelta
import sys

def parse_mlsd_time(time_str):
    """Parses the 'modify' fact from MLSD output (format: YYYYMMDDHHMMSS)."""
    return datetime.strptime(time_str[:14], "%Y%m%d%H%M%S")

def cleanup_ftp(host, user, password, remote_dir, days):
    cutoff_date = datetime.now() - timedelta(days=days)
    print(f"Deleting files older than: {cutoff_date}")

    try:
        ftp = ftplib.FTP(host)
        ftp.login(user, password)

        # Switch to directory
        ftp.cwd(remote_dir)

        # Get file list with metadata (MLSD is supported by most modern servers like cPanel's Pure-FTPd)
        # MLSD returns an iterator of (name, facts_dict)
        try:
            files = list(ftp.mlsd())
        except ftplib.error_perm:
            print("Error: Server does not support MLSD command.")
            return

        deleted_count = 0

        for name, facts in files:
            # Skip current/parent directory pointers
            if name in ['.', '..']:
                continue

            # We only want to delete files, not directories
            if facts.get('type') == 'file':
                modify_time_str = facts.get('modify')

                if modify_time_str:
                    file_date = parse_mlsd_time(modify_time_str)

                    if file_date < cutoff_date:
                        print(f"Deleting '{name}' (Modified: {file_date})...")
                        try:
                            ftp.delete(name)
                            deleted_count += 1
                        except Exception as e:
                            print(f"Failed to delete {name}: {e}")

        print(f"\nCleanup complete. Deleted {deleted_count} files.")
        ftp.quit()

    except Exception as e:
        print(f"FTP Error: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="FTP Cleanup Utility")
    parser.add_argument("host", help="FTP Server Address")
    parser.add_argument("user", help="FTP Username")
    parser.add_argument("password", help="FTP Password")
    parser.add_argument("dir", help="Remote directory to clean")
    parser.add_argument("--days", type=int, default=30, help="Delete files older than N days (default: 30)")

    args = parser.parse_args()

    cleanup_ftp(args.host, args.user, args.password, args.dir, args.days)

Usage

# Delete files in /backups older than 7 days
python ftp_cleanup.py ftp.mysite.com myuser mypass /backups --days 7

programming/python/python