4 Stimmen

Synchronisierung von Verzeichnissen mit der ftplib von Python

Ich lerne gerade Python und versuche, einen Code zu schreiben, um zwei Verzeichnisse zu synchronisieren: eines liegt auf einem FTP-Server, das andere auf meiner lokalen Festplatte. Bis jetzt habe ich einen funktionierenden Code geschrieben, aber ich habe ein oder zwei Fragen dazu :)

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

Dieses Codestück sollte zwei Python-Listen erstellen: eine Liste der Dateien im lokalen Verzeichnis und eine Liste der Dateien im FTP-Verzeichnis. Nachdem Duplikate aus den Listen entfernt wurden, sollte das Skript "fehlende" Dateien in mein lokales Verzeichnis herunterladen.

Für jetzt, dieses Stück Code tut, was ich brauche, aber ich habe bemerkt, dass, wenn ich es ausführen meine Ausgabe ist nicht handeln, wie ich mir vorstellen, es handeln würde :)

Meine aktuelle Ausgabe lautet zum Beispiel:

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...

aber ich kann mir vorstellen, dass es so funktionieren sollte:

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...

Wie ich schon sagte, habe ich gerade angefangen, Python zu lernen, und vielleicht mache ich hier einiges völlig falsch ( if str(s).startswith('226') ????). Vielleicht kann ich dies nicht erreichen mit ftplib nur? Meine Fragen lauten also letztlich:

Was mache ich hier falsch? :)
Wie kann man eine "richtige" Ausgabe erzeugen und gibt es eine Möglichkeit, eine Art von Status zu drucken, während eine Datei heruntergeladen wird (zumindest eine Zeile mit Punkten), zum Beispiel:

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...

Vielen Dank für Ihre Hilfe!

3voto

jaime Punkte 2176

Binärblöcke wiederholen, bis er vollständig ist. Aus diesem Grund sehen Sie Processing ZZZ\n OK sofort, da sie nach dem Aufruf von retrbinary erfolgt.

Wenn Sie drucken möchten . für jeden Aufruf, dann müssen Sie eine Callback-Funktion zur Verfügung stellen, um dies zu tun. hier ist die docstring für 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.
    """

Sie müssen also einen anderen Callback bereitstellen, der sowohl die Datei schreibt als auch '.' ausgibt.

import sys # At the top of your module.

# Modify your retrbinary    
ftp.retrbinary('RETR ' + h, lambda s: ftpfile.write(s) and sys.stdout.write('.'))

Möglicherweise müssen Sie diesen Codeschnipsel bearbeiten, aber er sollte Ihnen eine Vorstellung davon vermitteln, was zu tun ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X