FTP Download nach Datum

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Hallo zusammen,

kann mir einer bei folgendem Problem helfen:

Ich muss von einem anderen Rechner via FTP die zuletzt dort abgespeicherte Datei mit der Endung .dat auf meinen Rechner holen.
Es sind dort mehrere hundert .dat Dateien. Ich brauch aber nur die letzte.

FTP Verbindung hab ich schon mal.

Code: Alles auswählen

from ftplib import FTP
ftp = FTP("blabla")   # connect to host, default port
ftp.login("pasu","dada")               # user anonymous, passwd anonymous@

ftp.cwd("/dateien")
#ftp.retrlines('LIST')     # list directory contents

# Define the local directory name to put data in
ddir="C:\\datadir"

# If directory doesn't exist make it
if not os.path.isdir(ddir):
    os.mkdir(ddir)

# Change the local directory to where you want to put the data
os.chdir(ddir)
Nergal
User
Beiträge: 72
Registriert: Montag 6. Oktober 2008, 14:02

Hi,

schau dir mal die Funktionen os.path.getmtime(<Pfad>) bzw. os.path.getctime(<Pfad>) an: http://docs.python.org

Damit solltest du dein Problem lösen können.

Gruß
Nergal
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Und das soll auch für Dateien gehen, die man via FTP von einem Server holt? Er will sich ja vermutlich nicht erst alle runterladen, sondern vorab gucken, welches die neueste ist.
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Ich bekomme dann eine Zahl heraus.

Code: Alles auswählen

# If directory doesn't exist make it
if not os.path.isdir(ddir):
    os.mkdir(ddir)

# Change the local directory to where you want to put the data
os.chdir(ddir)

#date=os.stat(ddir)
time=os.path.getmtime(ddir)
print time

>>> ================================ RESTART ================================
>>>
1241509813.8

was mach ich jetzt damit??? :roll:
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Jetzt hast du einen Timestamp von dem lokalen Pfad, wo die Dateien hinsollen. Das bringt dir aber rein gar nichts. :)
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

FTP bietet beim Verzeichnislisten ein Datum mit an (leider nur volle Tage). Das könntest Du auswerten.

Code: Alles auswählen

l = []
ftp.retrlines('LIST', l.append)
# dann: gehe durch Liste l und suche neueste .dat Datei
Keine Ahnung, ob man via FTP auch an einen richtigen Timestamp kommt.
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Die Uhrzeit und das Datum wird auf jeden Fall auch ausgegeben.

Apr 14 09:49
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Update:
Zumindest die mtime kann man holen mit "MDTM dateiname". Ich weiß allerdings nicht, ob das alle FTP-Server unterstützen.

Hiermit wirds einfacher:

Code: Alles auswählen

ftp.nlst() # gibt dir eine Dateinliste zurück
ftp.sendcmd('MDTM dateiname') # gibts dir die mtime zurück (nicht für Verz!)
Zuletzt geändert von jerch am Dienstag 5. Mai 2009, 13:32, insgesamt 1-mal geändert.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich bin auf das Modul ftpparse gestoßen. Allerdings ist das schon älter und wirft bei mir einen Fehler, wenn ich's installieren will. Ansonsten müsste man die Ausgabe halt selber parsen. Problematisch dabei ist, dass LIST offenbar kein einheitliches Format ausgibt.

@Manne_Manta: Kannst du mal so ein List machen und sagen wie die Ausgabe ist und ob sie einheitlich ist?
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Hier mal ein kurzes Schnipsel:

Code: Alles auswählen

for i in ftp.nlst('dein/verz/*.dat'): # wildcards, vorher testen
    try:
        t = ftp.sendcmd('MDTM ' + i)
        print i, t
    except:
        pass
Das "except" fängt erstmal alles ab, welche Fehler das alles sind, kannst Du ja selber rausfinden.

Edit: Typos und Wildcard
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier eine simple Klasse, die ftplib.FTP() um Datumssortierung erweitert. Einsetzbar wie das Original, nur eben mit der Zusatzfunktion. Noch nicht sehr schön, aber das kannst du ja ausbessern, wenn du willst. :)

Code: Alles auswählen

import ftplib
from operator import itemgetter


class Sorter(ftplib.FTP):

    def __init__(self, host='', user='', passwd='', acct=''):
        """
        Behaves like ftplib.FTP()
        """
        ftplib.FTP.__init__(self, host, user, passwd, acct)

    def datesort_files(self):
        """
        Return a date-sorted file list from the current
        ftp directory with the latest file on top
        """ 
        files = []
        for filename in self.nlst():
            try:
                mdtm = self.sendcmd('MDTM %s' % filename)
                date = mdtm.split()[1]
                files.append((filename, date))
            except ftplib.error_perm:
                pass
        return sorted(files, key=itemgetter(1), reverse=True)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

@snafu: deine __init__-Methode ist hier überflüssig.
Das Leben ist wie ein Tennisball.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ja, man kann auch einbauen, dass die Sortierfunktion als Argument eine offene FTP-Session erwartet, aber ich fand es so einfacher.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Das war nicht gemeint: wenn du deine __init__-Methode weglässt wird statt dessen eh die von ftplib.FTP aufgerufen. Die Signatur unterscheidet sich nur unwesentlich von deiner:

Code: Alles auswählen

__init__(self, host='', user='', passwd='', acct='', timeout=<object object at 0x7f6473210080>)
Das Leben ist wie ein Tennisball.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Sie lautet wohl wahrscheinlich

Code: Alles auswählen

__init__(self, host='', user='', passwd='', acct='', timeout=object())
Das, was du entdeckt hast, war lediglich die Ausgabe von der __repr__ Methode.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ich hatte es mir über help(ftplib.FTP) ausgeben lassen und mich an der Ausgabe nicht weiter gestört.
Das Leben ist wie ein Tennisball.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich muss aber die optionalen Login-Argumente doch irgendwie an ftplib.FTP() übergeben. Wenn ich dafür keine __init__()-Methode mache, kann die Klasse auch schlecht was annehmen. Oder gibt es da einen anderen, besseren Weg für?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Wenn du kein `__init__` definierst, erbst du die der Elternklasse. Und du machst nichts anderes als die aufzurufen ;)
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Achsooooooooooooo (ausprobieren soll ja zwischendurch hilfreich sein). Nee, so herum hatte ich tatsächlich nicht gedacht. Okay, dann kann sie natürlich weg.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Antworten