Синхронизация каталогов с помощью ftplib Python
-
14-11-2019 - |
Вопрос
Я изучаю Python и пытаюсь написать код для синхронизации двух каталогов:один находится на ftp-сервере, другой — на моем локальном диске.На данный момент я написал рабочий код, но у меня есть пара вопросов по этому поводу :)
import os
from ftplib import FTP
h_local_files = [] # create local dir list
h_remote_files = [] # create remote dir list
h_local = 'C:\\something\\bla\\' # local dir
ftp = FTP('ftp.server.com')
ftp.login('user', 'pass')
if os.listdir(h_local) == []:
print 'LOCAL DIR IS EMPTY'
else:
print 'BUILDING LOCAL DIR FILE LIST...'
for file_name in os.listdir(h_local):
h_local_files.append(file_name) # populate local dir list
ftp.sendcmd('CWD /some/ftp/directory')
print 'BUILDING REMOTE DIR FILE LIST...\n'
for rfile in ftp.nlst():
if rfile.endswith('.jpg'): # i need only .jpg files
h_remote_files.append(rfile) # populate remote dir list
h_diff = sorted(list(set(h_remote_files) - set(h_local_files))) # difference between two lists
for h in h_diff:
with open(os.path.join(h_local,h), 'wb') as ftpfile:
s = ftp.retrbinary('RETR ' + h, ftpfile.write) # retrieve file
print 'PROCESSING', h
if str(s).startswith('226'): # comes from ftp status: '226 Transfer complete.'
print 'OK\n' # print 'OK' if transfer was successful
else:
print s # if error, print retrbinary's return
Этот фрагмент кода должен создать два списка Python:список файлов в локальном каталоге и список файлов в каталоге FTP.После удаления дубликатов из списков скрипт должен загрузить «недостающие» файлы в мой локальный каталог.
На данный момент этот фрагмент кода делает то, что мне нужно, но я заметил, что когда я его запускаю, мои выходные данные ведут себя не так, как я себе представляю :)
Например, мой текущий вывод:
PROCESSING 2012-01-17_07.05.jpg
OK
# LONG PAUSE HERE
PROCESSING 2012-01-17_07.06.jpg
OK
# LONG PAUSE HERE
PROCESSING 2012-01-17_07.06.jpg
OK
etc...
но я предполагаю, что это должно работать так:
PROCESSING 2012-01-17_07.05.jpg
# LONG PAUSE HERE (WHILE DOWNLOADING)
OK
PROCESSING 2012-01-17_07.06.jpg
# LONG PAUSE HERE (WHILE DOWNLOADING)
OK
PROCESSING 2012-01-17_07.06.jpg
# LONG PAUSE HERE (WHILE DOWNLOADING)
OK
etc...
Как я уже сказал, я только начал изучать Python и, возможно, я что-то делаю здесь совершенно неправильно (if str(s).startswith('226')
????).Может быть, я не могу добиться этого сftplib
только?Итак, в итоге мои вопросы:
Что я здесь делаю не так?:)
Как создать «правильный» вывод и есть ли способ напечатать какой-то статус при загрузке файла (хотя бы строку точек), например:
PROCESSING 2012-01-17_07.05.jpg
..........
OK
PROCESSING 2012-01-17_07.06.jpg
......
OK
PROCESSING 2012-01-17_07.06.jpg
...............
OK
etc...
Большое спасибо за помощь!
Решение
ретрибинарные блоки до завершения.Вот почему вы видите Processing ZZZ\n OK
немедленно, поскольку это происходит после завершения вызова retrbinary.
Если вы хотите распечатать .
для каждого вызова вам необходимо предоставить функцию обратного вызова для этого.вот строка документации для ретрбинария:
"""Retrieve data in binary mode. A new port is created for you.
Args:
cmd: A RETR command.
callback: A single parameter callable to be called on each
block of data read.
blocksize: The maximum number of bytes to read from the
socket at one time. [default: 8192]
rest: Passed to transfercmd(). [default: None]
Returns:
The response code.
"""
Итак, вам нужно предоставить другой обратный вызов, который одновременно записывает файл и печатает '.'
import sys # At the top of your module.
# Modify your retrbinary
ftp.retrbinary('RETR ' + h, lambda s: ftpfile.write(s) and sys.stdout.write('.'))
Возможно, вам придется отредактировать этот фрагмент кода, но он должен дать вам представление о том, что делать.