Выгрузка на сервер целого каталога симметрична загрузке с сервера: в основном требуется поменять местами локальные и удаленные компьютеры и операции в только что рассмотренной программе. Сценарий в примере 13.11, используя протокол FTP, копирует все файлы из каталога на локальном компьютере, в котором он был запущен, в каталог на удаленном компьютере.
Я действительно пользуюсь этим сценарием, чаще всего для выгрузки одним махом всех файлов, которые я поддерживаю на своем ноутбуке, на сервер моего интернет-провайдера. Иногда я также с его помощью копирую свой сайт с моего ПК на сервер зеркала или с сервера зеркала обратно на сервер провайдера. Этот сценарий выполняется на любом компьютере, где есть Python и сокеты, благодаря чему он может копировать каталог с любого компьютера, подключенного к Сети, на любой компьютер, где работает FTP-сервер. Чтобы осуществить требуемую пересылку, достаточно лишь поменять соответствующим образом начальные настройки в этом модуле.
Пример 13.11. PP4E\Internet\Ftp\Mirror\uploadflat.py
#!/bin/env python
############################################################################ использует FTP для выгрузки всех файлов из локального каталога на удаленный сайт/каталог; например, сценарий можно использовать для копирования файлов веб/FTP сайта с вашего ПК на сервер провайдера; выполняет выгрузку плоского каталога: вложенные каталоги можно копировать с помощью сценария uploadall.py. дополнительные примечания смотрите в комментариях в downloadflat.py: этот сценарий является его зеркальным отражением.
############################################################################
import os, sys, ftplib
from getpass import getpass
from mimetypes import guess_type
nonpassive = False # пассивный режим FTP по умолчанию
remotesite = ‘learning-python.com’ # выгрузить на этот сайт
remotedir = ‘books‘ # с компьютера, где выполняется сценарий
remoteuser = ‘lutz’
remotepass = getpass(‘Password for %s on %s: ‘ % (remoteuser, remotesite)) localdir = (len(sys.argv) > 1 and sys.argv[1]) or ‘.’
cleanall = input(‘Clean remote directory first? ‘)[:1] in [‘y’, ‘Y’]
print(‘connecting…’)
connection = ftplib.FTP(remotesite) # соединиться с FTP—сайтом connection.login(remoteuser, remotepass) # зарегистрироваться
# с именем/паролем
connection.cwd(remotedir) # перейти в каталог копирования
if nonpassive: # принудительный переход в активный режим FTP
connection.set_pasv(False) # большинство серверов работают # в ‘.м режиме
if cleanall:
for remotename in connection.nlst(): # уничтожить все удаленные
try: # файлы, чтобы избавиться
print(‘deleting remote’, remotename) # от устаревших копий connection.delete(remotename) # пропустить . и ..
except:
print(‘cannot delete remote’, remotename)
count = 0 # выгрузить все локальные файлы
localfiles = os.listdir(localdir) # listdir() отбрасывает путь к каталогу
# любая ошибка завершит сценарий for localname in localfiles:
mimetype, encoding = guess_type(localname) # например,
# (‘text/plain’,’gzip’)
mimetype = mimetype or ‘?/?’ # допускается (None, None)
maintype = mimetype.split(‘/’)[0] # .jpg (‘image/jpeg’, None’)
localpath = os.path.join(localdir, localname)
print(‘uploading’, localpath, ‘to’, localname, end=’ ‘) print(‘as’, maintype, encoding or »)
if maintype == ‘text’ and encoding == None:
# использовать двоичный файл и режим передачи ascii
# для поддержки логики обработки символов конца строки
# требуется использовать режим rb
localfile = open(localpath, ‘rb’)
connection.storlines(‘STOR ‘ + localname, localfile)
else:
# использовать двоичный файл и двоичный режим предачи
localfile = open(localpath, ‘rb’)
connection.storbinary(‘STOR ‘ + localname, localfile)
localfile.close() count += 1
connection.quit()
print(‘Done:’, count, ‘files uploaded.’)
Как и сценарий загрузки каталога с сервера, эта программа иллюстрирует ряд новых интерфейсов и приемов написания сценариев FTP:
Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, II том, 2011