# WordPress Backup Tool (FTP & SSH)

This utility automates the backup of a WordPress site. It uses a hybrid approach for efficiency:
1.  **SSH (`paramiko`)**: Connects to the server to run `mysqldump` (for the database) and `tar` (to compress site files into a single archive).
2.  **FTP (`ftplib`)**: Connects to download the large backup files.
3.  **SSH**: Connects again to delete the temporary backup files from the server.

**Modules Used:**
*   `paramiko`: For SSH connections and command execution.
*   [[programming/python/modules/ftplib-module|ftplib]]: For downloading files via FTP.
*   [[programming/python/modules/argparse-module|argparse]]: To handle command-line arguments.

## Prerequisites

1.  **SSH Access**: You must have SSH access enabled on your hosting account.
2.  **Database Credentials**: You need the DB name, user, and password (found in `wp-config.php`).

## Installation

```bash
pip install paramiko
```

## The Code

Save this as `wp_backup.py`.

```python
import paramiko
import ftplib
import argparse
import sys
import time
from datetime import datetime

def ssh_exec(ssh, command):
    """Executes a command via SSH and checks for errors."""
    print(f"  [SSH] Executing: {command.split()[0]}...") # Print command name only for brevity
    stdin, stdout, stderr = ssh.exec_command(command)
    exit_status = stdout.channel.recv_exit_status()
    
    if exit_status != 0:
        print(f"  [Error] Command failed: {command}")
        print(stderr.read().decode())
        return False
    return True

def perform_backup(args):
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    sql_file = f"db_{args.db_name}_{timestamp}.sql"
    archive_file = f"files_{timestamp}.tar.gz"
    
    # 1. SSH: Create Backups
    print(f"--- Step 1: Creating Backups on Server ({args.host}) ---")
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(args.host, username=args.ssh_user, password=args.ssh_pass)
        
        # Dump Database
        # Note: -p{password} (no space) is required for mysqldump
        dump_cmd = f"mysqldump -u {args.db_user} -p'{args.db_pass}' {args.db_name} > {sql_file}"
        if not ssh_exec(ssh, dump_cmd): return

        # Compress Site Files
        # tar -czf archive.tar.gz folder_to_backup
        tar_cmd = f"tar -czf {archive_file} {args.remote_dir}"
        if not ssh_exec(ssh, tar_cmd): return
        
        ssh.close()
    except Exception as e:
        print(f"SSH Connection Error: {e}")
        return

    # 2. FTP: Download Files
    print(f"\n--- Step 2: Downloading via FTP ---")
    try:
        ftp = ftplib.FTP(args.host)
        ftp.login(args.ftp_user, args.ftp_pass)
        
        for filename in [sql_file, archive_file]:
            print(f"  [FTP] Downloading {filename}...")
            with open(filename, 'wb') as f:
                ftp.retrbinary(f"RETR {filename}", f.write)
        
        ftp.quit()
        print("  Downloads complete.")
    except Exception as e:
        print(f"FTP Error: {e}")
        return

    # 3. SSH: Cleanup
    print(f"\n--- Step 3: Cleaning up Remote Files ---")
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(args.host, username=args.ssh_user, password=args.ssh_pass)
        
        ssh_exec(ssh, f"rm {sql_file}")
        ssh_exec(ssh, f"rm {archive_file}")
        ssh.close()
        print("  Cleanup complete.")
    except Exception as e:
        print(f"Cleanup Error: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="WordPress Backup Tool (FTP & SSH)")
    
    # Server Credentials
    parser.add_argument("--host", required=True, help="Server Hostname/IP")
    parser.add_argument("--ssh-user", required=True, help="SSH Username")
    parser.add_argument("--ssh-pass", required=True, help="SSH Password")
    parser.add_argument("--ftp-user", required=True, help="FTP Username")
    parser.add_argument("--ftp-pass", required=True, help="FTP Password")
    
    # Site Details
    parser.add_argument("--db-name", required=True, help="Database Name")
    parser.add_argument("--db-user", required=True, help="Database User")
    parser.add_argument("--db-pass", required=True, help="Database Password")
    parser.add_argument("--remote-dir", default="public_html", help="Remote directory to backup (default: public_html)")

    args = parser.parse_args()
    perform_backup(args)
```

## Usage

```bash
python wp_backup.py \
  --host example.com \
  --ssh-user myuser --ssh-pass "ssh_password" \
  --ftp-user myuser --ftp-pass "ftp_password" \
  --db-name wp_database --db-user wp_user --db-pass "db_password" \
  --remote-dir public_html
```

[[programming/python/python]]