File: ftp-put.py

#!/usr/bin/python
###!/usr/local/bin/python3
"""
=================================================================
Put (upload) one file by FTP in binary mode.

 (Caveat: this script may not be very useful today, because most
  ISPs no longer support its basic FTP.  To upload to websites, 
  you will likely need to use a secure SSL-based interface like 
  SFTP or scp instead.  See the web for related Python tools.)

Usage: on Unix make executable with "chmod +x ftp-put.py", store
your FTP site+rdir+user+pswd in "ftp-config.txt" (one per line) 
in this script file's own folder, and run with a file to upload:

    ftp-put.py filename

For example, as part of a general site build/update process:
    cd /MY-STUFF/Websites
    py3 _PUBLISH.PY             # generate/collect site files
    cd UNION
    ../ftp-put.py index.html    # to upload changed files only
    ../ftp-put.py photo.png

The "ftp-config.txt" file (but omit indents and "#..."):
    ftp-server-domain-name      # e.g., learning-python.com
    ftp-remote-directory        # e.g., html or . (. = no cd)
    ftp-user-name               # your account name
    ftp-user-password           # your account password

You can also run this from any IDE that supports command-line
arguments (see PyEdit: learning-python.com/pyedit.html).  On 
Windows, usage is the same but with "\" and without "chmod."

This is a variation of the first FTP upload example in the book 
PP4E; works on Python 3.X and 2.X (pick a #! above as desired); 
and uses your platform's default Unicode encoding for configs.
=================================================================
"""

from __future__ import print_function    # 2.X: standard on Mac OS
import ftplib                            # socket-based FTP tools


def putfile(file, site, rdir='.', login=(), verbose=True):
    """
    --------------------------------------------------
    Upload a file by ftp to a remote site + directory.
    Uses binary transfer, and anonymous or real login.
    login: ()=anonymous, (user, pswd)=a real account.
    rdir: "." default means no remote cwd is required.
    --------------------------------------------------
    """
    if verbose: print('Uploading', file)
    local  = open(file, 'rb')                   # local file of same name
    remote = ftplib.FTP(site)                   # connect to FTP site
    remote.login(*login)                        # anonymous or (user, pswd)
    remote.cwd(rdir)                            # goto remote dir (or '.')
    remote.storbinary('STOR ' + file, local)    # xfer with default blocksize
    remote.quit()
    local.close()
    if verbose: print('Upload done.')


if __name__ == '__main__':
    """
    --------------------------------------------------
    Script (command-line) use.
    Pass one arg = filename.  All four FTP parameters 
    are lines in file ftp-configs.txt in script's dir.
    --------------------------------------------------
    """
    import sys, os
    print('Python', sys.version.split()[0])

    # file to transfer in command-line arg (one per run: keep it simple)
    file = sys.argv[1]

    # ftp parameters from file, one per line (or getpass.getpass(prompt))
    scriptdir = os.path.dirname(__file__)
    configs = os.path.join(scriptdir, 'ftp-config.txt')
    site, rdir, user, pswd = [line.rstrip() for line in open(configs)][:4]

    # upload the target file
    putfile(file, site, rdir, login=(user, pswd), verbose=True)   # nonanonymous login



[Home page] Books Code Blog Python Author Train Find ©M.Lutz