Вопрос

Я изучаю 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('.'))

Возможно, вам придется отредактировать этот фрагмент кода, но он должен дать вам представление о том, что делать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top