ftplib: ftp.retrbinary-Callback

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
to.ni
User
Beiträge: 24
Registriert: Dienstag 6. Januar 2004, 15:52

Hallo zusammen,

schon fast peinlich, hier schon wieder das Forum bemühen zu müssen... :oops:

Aber ich habe eine Frage zur Callback-Funktionalität der retrbinary-Methode:
In der Dokumentation steht:

Code: Alles auswählen

retrbinary(command, callback[, maxblocksize[, rest]])
In den meisten Beispielen, die ich gefunden habe wird als Callback einfach fh.write angegeben, um die empfangenen Daten zu speichern. Ich würde aber gerne eine Fortschrittsanzeige realisieren, die anzeigt wie viele Daten schon empfangen wurden.
Dazu hätte ich eine eigene Funktion definiert und diese als Callback angegeben:

Code: Alles auswählen

ftp.retrbinary("RETR test.jpg", transfer_callback)
Leider kann ich da aber ja keine Argumente übergeben... z.B. den Filehandler, der zu speichernden Datei?

wieder mal danke für eure hilfe...
Mephisto
User
Beiträge: 28
Registriert: Mittwoch 17. Januar 2007, 15:52

Hi,

Wenn du Python 2.5 benutzt kannst du das so machen:

Code: Alles auswählen

from functools import partial

def transfer_callback(fileobj, block):
    pass

fileobj = open('test.jpg', 'wb')
ftp.retrbinary("RETR test.jpg", partial(transfer_callback, fileobj))
partial gibt eine Funktion zurück, die sich genau wie transfer_callback verhält, ausser dass sie vor dem eigentlichen Aufruf von "transfer_callback" als ersten Parameter das "fileobj" einfuegt. (Ich hoffe das konnte man verstehen, ansonsten steht in der Doku mehr dazu :))

Vor Python2.5 kann man "lambda"s verwenden

Code: Alles auswählen


def transfer_callback(fileobj, block):
    pass

fileobj = open('test.jpg', 'wb')
ftp.retrbinary("RETR test.jpg", lambda block: transfer_callback(fileobj, block))
HTH

Grüsse, Mephisto
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Und hier eine etwas längere Version. :-)

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

import ftplib
from StringIO import StringIO


class ByteContainer(StringIO):
   
    def __init__(self, buf = ""):
        StringIO.__init__(self, buf)
        self.bytecounter = 0
   
    def write(self, bytestring):
        self.bytecounter += len(bytestring)
        print "%i Bytes transfered." % self.bytecounter
        file.write(self, bytestring)

f = ByteContainer()
ftp = ftplib.FTP()
ftp.connect("host", 21)
ftp.login("user", "pass")
ftp.set_pasv(True)
ftp.retrbinary("RETR bild.jpg", f.write)
ftp.quit()

print repr(f.getvalue())
mfg
Gerold
:-)
Zuletzt geändert von gerold am Dienstag 23. Januar 2007, 23:27, insgesamt 2-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

...das geht natürlich auch direkt mit dem ``file``-Objekt.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

import ftplib
import time


class ByteContainer(file):
    
    def __init__(self, name, mode = "wb"):
        file.__init__(self, name, mode)
        self.bytecounter = 0
    
    def write(self, bytestring):
        self.bytecounter += len(bytestring)
        print "%i Bytes transfered." % self.bytecounter
        file.write(self, bytestring)
    

f = ByteContainer("bild.jpg", "wb")
ftp = ftplib.FTP()
ftp.connect("host", 21)
time.sleep(0.2)
ftp.login("user", "pass")
time.sleep(0.2)
ftp.retrbinary("RETR bild.jpg", f.write)
ftp.quit()

f.close()
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
to.ni
User
Beiträge: 24
Registriert: Dienstag 6. Januar 2004, 15:52

Nochmal hallo,

merci für eure Vorschläge. Inzwischen klappt der Download mit Übertragungsanzeige ;-)

Grüße tobi
Antworten