Seite 1 von 4

FTP Download nach Datum

Verfasst: Dienstag 5. Mai 2009, 11:40
von Manne_Manta
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)

Verfasst: Dienstag 5. Mai 2009, 12:23
von Nergal
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

Verfasst: Dienstag 5. Mai 2009, 12:31
von snafu
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.

Verfasst: Dienstag 5. Mai 2009, 12:35
von Manne_Manta
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:

Verfasst: Dienstag 5. Mai 2009, 12:54
von snafu
Jetzt hast du einen Timestamp von dem lokalen Pfad, wo die Dateien hinsollen. Das bringt dir aber rein gar nichts. :)

Verfasst: Dienstag 5. Mai 2009, 13:03
von jerch
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.

Verfasst: Dienstag 5. Mai 2009, 13:25
von Manne_Manta
Die Uhrzeit und das Datum wird auf jeden Fall auch ausgegeben.

Apr 14 09:49

Verfasst: Dienstag 5. Mai 2009, 13:28
von jerch
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!)

Verfasst: Dienstag 5. Mai 2009, 13:28
von snafu
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?

Verfasst: Dienstag 5. Mai 2009, 13:45
von jerch
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

Verfasst: Dienstag 5. Mai 2009, 14:49
von snafu
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)

Verfasst: Dienstag 5. Mai 2009, 15:06
von EyDu
@snafu: deine __init__-Methode ist hier überflüssig.

Verfasst: Dienstag 5. Mai 2009, 15:21
von snafu
Ja, man kann auch einbauen, dass die Sortierfunktion als Argument eine offene FTP-Session erwartet, aber ich fand es so einfacher.

Verfasst: Dienstag 5. Mai 2009, 15:29
von EyDu
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>)

Verfasst: Dienstag 5. Mai 2009, 15:35
von derdon
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.

Verfasst: Dienstag 5. Mai 2009, 15:46
von EyDu
Ich hatte es mir über help(ftplib.FTP) ausgeben lassen und mich an der Ausgabe nicht weiter gestört.

Verfasst: Dienstag 5. Mai 2009, 15:59
von snafu
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?

Verfasst: Dienstag 5. Mai 2009, 16:01
von cofi
Wenn du kein `__init__` definierst, erbst du die der Elternklasse. Und du machst nichts anderes als die aufzurufen ;)

Verfasst: Dienstag 5. Mai 2009, 16:06
von snafu
Achsooooooooooooo (ausprobieren soll ja zwischendurch hilfreich sein). Nee, so herum hatte ich tatsächlich nicht gedacht. Okay, dann kann sie natürlich weg.

Verfasst: Dienstag 5. Mai 2009, 17:38
von snafu