# FTP File Downloader

This utility connects to an FTP server to list directory contents and download files. It uses the standard `ftplib` module, which implements the client side of the FTP protocol.

**Modules Used:**
*   [[programming/python/modules/ftplib-module|ftplib]]: To handle FTP connections and data transfer.
*   [[programming/python/modules/argparse-module|argparse]]: To handle command-line arguments.
*   `os`: To handle local file paths.

## The Code

Save this as `ftp_tool.py`.

```python
import ftplib
import argparse
import os
import sys

def ftp_client(host, user, password, remote_dir, file_to_download):
    ftp = None
    try:
        # 1. Connect and Login
        print(f"Connecting to {host}...")
        ftp = ftplib.FTP(host)
        ftp.login(user, password)
        print(f"Logged in as {user}")

        # 2. Change Directory (if specified)
        if remote_dir:
            try:
                ftp.cwd(remote_dir)
                print(f"Changed directory to: {remote_dir}")
            except ftplib.error_perm as e:
                print(f"Error changing directory: {e}")
                return

        # 3. List Files
        print("\n--- Directory Listing ---")
        ftp.retrlines('LIST')
        print("-------------------------\n")

        # 4. Download File (if specified)
        if file_to_download:
            print(f"Attempting to download '{file_to_download}'...")
            
            # Check if file exists in current listing (simple check)
            files = ftp.nlst()
            if file_to_download in files:
                local_filename = os.path.basename(file_to_download)
                
                with open(local_filename, 'wb') as f:
                    # RETR is the FTP command to retrieve a file
                    # retrbinary is used for binary files (images, zips, etc.)
                    ftp.retrbinary('RETR ' + file_to_download, f.write)
                
                print(f"Success! Saved to {os.path.abspath(local_filename)}")
            else:
                print(f"Error: File '{file_to_download}' not found in current directory.")

    except ftplib.all_errors as e:
        print(f"FTP Error: {e}")
    finally:
        if ftp:
            try:
                ftp.quit()
                print("Connection closed.")
            except:
                pass

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Simple FTP Client")
    parser.add_argument("host", help="FTP Server Address")
    parser.add_argument("-u", "--user", default="anonymous", help="Username (default: anonymous)")
    parser.add_argument("-p", "--password", default="", help="Password (default: empty)")
    parser.add_argument("-d", "--dir", help="Remote directory to navigate to")
    parser.add_argument("-f", "--file", help="Specific file to download")
    
    args = parser.parse_args()
    
    ftp_client(args.host, args.user, args.password, args.dir, args.file)
```

## Usage

```bash
# List files on a public FTP server
python ftp_tool.py ftp.debian.org -d /debian

# Download a specific file
python ftp_tool.py ftp.example.com -u myuser -p mypass -f report.pdf
```

[[programming/python/python]]