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