Hallo,
ich wollt mal wissen, ob/wie es möglich ist in python den status eines downloads abzufragen. mir ist eigentlich dabei recht egal, ob mir ausgegeben wird, wieviel bytes/kilobytes oder wieviel % er schon geladen hat.
Thx & Greetings
N17R0
Status von ftp/http download
Nochmal, in der Hoffnung, dass jetzt jemand Rat weiß.
Also, es geht mir darum, dass ich eine Datei mit httplib oder ftplib runterlade und Python nun in einem extra Thread mit jede Sekunde sagen soll, wieviel er/es schon runtergeladen hat (anzahl an Bytes).
*Hoff, dass jemand weiß wie's geht
*
Greetz
Also, es geht mir darum, dass ich eine Datei mit httplib oder ftplib runterlade und Python nun in einem extra Thread mit jede Sekunde sagen soll, wieviel er/es schon runtergeladen hat (anzahl an Bytes).
*Hoff, dass jemand weiß wie's geht

Greetz
Hi. Ich wollte dir irgendwann mal antworten, hatte aber keine Zeit. Jetzt fällts mir wieder ein 
Die Methoden retrlines und retrbinary einer ftplib.FTP Instanz erlauben, dass du eine Callbackfunktion angibst, an die die Werte übergeben werden. Normalerweiese ist das die write Methode einer geöffneten Datei (Bsp: ftp.retrlines("RETR xyz.txt",open("xyz.txt","r").write)), das muss aber nicht sein. Du kannst dir hier auch eine eigene Funktion (Klasse wäre vielleicht besser, da die Funktion mehrmals aufgerufen wird) basteln, mit der du zwar auch in eine Datei schreibst, gleichzeitig aber mitzählst, wieviele Bytes übertragen worden sind. Wenn man weiß wie groß die Datei auf dem FTP-Server war (size Kommando), kann man hieraus den Fortschritt errechnen.
Bei http wird das schon schwerer: der Server kann eine Dateigröße vor dem Download ansagen, muss es aber nicht. Auch implementiert Python hier keine so schöne Schnittstelle, so dass ich nicht wüsste, wie man hier vorgehen sollte. Da musst du dir die httplib vielleicht mal bis auf's Detail anschauen und eventuell eine eigene Klasse für Response-Objets schreiben, denn du kannst zwar die Header auslesen, aber den Dateiinhalt nur "mit einem Ruck" abrufen. Da musst du eine gepufferte Variante für finden, dann geht das auch.
So, nun vielleicht noch ein kleines Beispiel für die FTP-Variante:
Hier kannst du nun entweder die Methode aktualisiere mit einer Handlung überschreiben (Tk-BAlten verändern) oder einen Thread starten, der Zugriff auf f hat und somit jede Sekunde f.retrsize und f.filesize auslesen kann oder aber ... denk dir selbst was aus
Die Methode __del__ sichert, dass die Datei automatisch bei Programmende geschlossen wird, fals dies vergessen wurde.
Milan

Die Methoden retrlines und retrbinary einer ftplib.FTP Instanz erlauben, dass du eine Callbackfunktion angibst, an die die Werte übergeben werden. Normalerweiese ist das die write Methode einer geöffneten Datei (Bsp: ftp.retrlines("RETR xyz.txt",open("xyz.txt","r").write)), das muss aber nicht sein. Du kannst dir hier auch eine eigene Funktion (Klasse wäre vielleicht besser, da die Funktion mehrmals aufgerufen wird) basteln, mit der du zwar auch in eine Datei schreibst, gleichzeitig aber mitzählst, wieviele Bytes übertragen worden sind. Wenn man weiß wie groß die Datei auf dem FTP-Server war (size Kommando), kann man hieraus den Fortschritt errechnen.
Bei http wird das schon schwerer: der Server kann eine Dateigröße vor dem Download ansagen, muss es aber nicht. Auch implementiert Python hier keine so schöne Schnittstelle, so dass ich nicht wüsste, wie man hier vorgehen sollte. Da musst du dir die httplib vielleicht mal bis auf's Detail anschauen und eventuell eine eigene Klasse für Response-Objets schreiben, denn du kannst zwar die Header auslesen, aber den Dateiinhalt nur "mit einem Ruck" abrufen. Da musst du eine gepufferte Variante für finden, dann geht das auch.
So, nun vielleicht noch ein kleines Beispiel für die FTP-Variante:
Code: Alles auswählen
class downloadstate:
def __init__(self,filename,mode,filesize):
self.datei=file(filename,mode)
self.filesize=filesize
self.retrsize=0
if 'b' not in mode:
self.sep="\n"
else:
self.sep=""
def write(self,text):
text+=self.sep
self.datei.write(text)
self.retrsize+=len(text)
self.aktualisiere()
def aktualisiere(self):
pass
def close(self):
self.datei.close()
def __del__(self):
if not self.datei.closed:
self.datei.close()
import ftplib
dateiname="xyz.txt"
ftp=ftplib.FTP(...)
f=downloadstate(dateiname,"w",ftp.size(dateiname))
ftp.retrlines("RETR %s"%dateiname,f.write)
f.close()
ftp.quit()

Milan