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.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hast du inzwischen zumindest ein bißchen im Tutorial gelesen? Es macht echt keinen Spass, wenn man das Gefühl hat, dass sich die Leute alles vorkauen lassen wollen...

Code: Alles auswählen

In [10]: ftp = TimeFTP('ftp.gimp.org', 'anonymous')

In [11]: ftp.cwd('pub/pango/1.21')
Out[11]: '250 Directory successfully changed.'

In [12]: latest3 = sorted(ftp.last_modified('*.md5'))[-3:]

In [13]: latest3
Out[13]: 
[('pango-1.21.4.tar.gz.md5',
  time.struct_time(tm_year=2008, tm_mon=8, tm_mday=11, tm_hour=23, tm_min=58, tm_sec=36, tm_wday=0, tm_yday=224, tm_isdst=-1)),
 ('pango-1.21.5.tar.bz2.md5',
  time.struct_time(tm_year=2008, tm_mon=8, tm_mday=26, tm_hour=21, tm_min=59, tm_sec=10, tm_wday=1, tm_yday=239, tm_isdst=-1)),
 ('pango-1.21.5.tar.gz.md5',
  time.struct_time(tm_year=2008, tm_mon=8, tm_mday=26, tm_hour=21, tm_min=59, tm_sec=10, tm_wday=1, tm_yday=239, tm_isdst=-1))]

In [14]: for name, time in latest3: print name
   ....: 
pango-1.21.4.tar.gz.md5
pango-1.21.5.tar.bz2.md5
pango-1.21.5.tar.gz.md5
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Sorry wenn ich dir lästig bin. Ich hab natürlich angefangen das Tutorial zu lesen. Ich habe das Tool ja eigentlich auch schon lauffähig, nur leider keinen Quellcode mehr (sogar mit Tkinter GUI).

Durch "sorted" werden die Daten ja in eine Liste geschrieben. Wie können die Datensätze aus der Liste gespeichert werden?

Code: Alles auswählen

ftp.retrbinary("RETR %s" % latestx_dat, open(latestx_dat,"wb").write)
liefert ja nur den letzten Datensatz aus der Liste. Wie komme ich an die anderen Datensätze?

Hier der Gesammte Code:

Code: Alles auswählen

#Import Bibliotheken
from timeftp import TimeFTP




ftp = TimeFTP('kkkk, 'pppp,'tttt') # Aufbau FTP Verbindung
ftp.cwd('/dat3') #In Quellverzeichnis wechseln
x=-2
latest_dat, last1 = max(ftp.last_modified('*.dat'))

latestx = sorted(ftp.last_modified('*.dat'))[x:]


for latestx_dat, time in latestx: latestx_dat
for name, time in latest3: print name


ftp.retrbinary("RETR %s" % latestx_dat, open(latestx_dat,"wb").write)
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

http://paste.pocoo.org/show/165367/

Code: Alles auswählen

In [1]: import timeftp

In [2]: ftp_addr = "ftp://ftp.gimp.org/pub/pango/1.21/"

In [3]: timeftp.get_last_modified(ftp_addr, '*.md5', 3, 'testdir', 'anonymous')
Die Funktion könnte natürlich auch `save_*` oder `download_*` heißen. Dies möge der geneigte Leser sich bei Bedarf verbessern. :)
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Ich hab mein ganzes Tool jetzt wieder fertiggeschrieben.

Leider ist mir jetzt aufgefallen das get_last_modified nicht das aktuelleste File vom Server holt, sondern das ganze nach dem Filenamen auflöst.
Ist das bei Dir auch so?

Ich hab das Script 1:1 von Dir übernommen und nur meine Parameter eingesetzt.
Die timeftp hab ich 1:1 übernommen.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Bei mir gehts. Zeig doch mal die Ausgabe von `TimeFTP.last_modified()` im Vergleich zu `TimeFTP.dir()`. Oder woran erkennst du, dass es nicht funktioniert?
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

TimeFTP.last_modified liefert einen Timestamp:0x026828F0 was nicht passen kann (13.04.1971, 09:50:56 Uhr).

TimeFTP.dir() liefert ja die ganze Directory. Die Directory ist aber komplett durcheinander. Wenn ich das richtig verstehe, mussten nach Datum sortierte Werte ausgespuckt werden, oder?
Ich hab hier Werte vom Dezember, danach welche aus dem September und dann kommt mal was aus dem Januar.

Das tatsächliche Datum des zuletzt geschriebenen Files, laut normalem FTP Programm ist der 20.01.2010 um 10:21.
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Hat keiner nen Tip? :?: :(

Code: Alles auswählen

import timeftp

ftp_addr = "ftp://testserver/tst3"
timeftp.get_last_modified(ftp_addr, '*.dat', 2, 'C:\user', 'login','pass')


Code: Alles auswählen

import ftplib
import os.path
import time
import urlparse

class TimeFTP(ftplib.FTP):
    def last_modified(self, pattern):
        for filename in self.nlst(pattern):
            retcode, timestamp = self.sendcmd('MDTM ' + filename).split()
            timestruct = time.strptime(timestamp, '%Y%m%d%H%M%S')
            yield filename, timestruct

def get_last_modified(ftp_addr, pattern='*', no=1, dest='.', user='', pw=''):
    parsed = urlparse.urlparse(ftp_addr)
    ftp = TimeFTP(parsed.netloc, user, pw)
    if parsed.path:
        ftp.cwd(parsed.path)
    for filename, timestruct in sorted(ftp.last_modified(pattern))[-no:]:
        with open(os.path.join(dest, filename), 'wb') as outfile:
            ftp.retrbinary('RETR ' + filename, outfile.write)
liefert bei mir nicht die zuletzt auf den Server geschriebene Datei, sondern die mit dem "höchsten" Filenamen
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich glaube wir haben es auch so verstanden... Das Datum kommt halt in einem Format zurück, bei dem nicht klar ist, wie es geparst werden soll. Du siehst ja am Gimp-Beispiel selbst, dass normalerweise etwas anderes erwartet wird. Ich hab mich danach gerichtet:
MDTM
Syntax: MDTM remote-filename

Returns the last-modified time of the given file on the remote host in the format "YYYYMMDDhhmmss": YYYY is the four-digit year, MM is the month from 01 to 12, DD is the day of the month from 01 to 31, hh is the hour from 00 to 23, mm is the minute from 00 to 59, and ss is the second from 00 to 59.
Wenn du mal die Seite nennen würdest und falls sie öffentlich zugänglich ist, dann könnte man mal ein bißchen rumprobieren. Andernfalls: Was gibt denn ein `ftp.sendcmd('syst')` zurück?

Hier übrigens nochmal eine Verbesserung, da `sorted()` entgegen meiner Vermutung doch nicht mit `struct_time` zurecht kommt. Und bitte tu mir und dem Forum den Gefallen und kopier den Quelltext nicht nochmal hier rein. Die Teilnehmer hier sind nämlich zum größten Teil fähig, einen Link anzuklicken. :)

EDIT: `get_last_modified()` heißt jetzt `download_datesorted()`.
Zuletzt geändert von snafu am Donnerstag 21. Januar 2010, 10:29, insgesamt 2-mal geändert.
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Die Seite ist leider nicht öffentlich. Habs mal ausprobiert.

Code: Alles auswählen

>>> ftp.cwd('/dat3')
'250 OK. Current directory is /dat3'
>>> ftp.sendcmd('PWD')
'257 "/dat3" is your current location'
>>> ftp.sendcmd('SYST')
'215 UNIX Type: L8'
>>> 
Super. Danke!!!
Deine Verbesserung war der Knackpunkt. Jetzt gehts.
Super. Danke!!! :D
Zuletzt geändert von Manne_Manta am Donnerstag 21. Januar 2010, 09:44, insgesamt 1-mal geändert.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Und jetzt, nur um Missverständnissen vorzubeugen, bitte ein `ftp.mdtm(dateiname)` (neuen Quelltext benutzen) für eine beliebige Datei aus dem FTP-Verzeichnis, wo du bist und Ausgabe posten.
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Code: Alles auswählen

>>> ftp.sendcmd('MDTM ' + 'test.dat')
'213 20100119140243'
>>> 
Wie gesagt mit Deinem überarbeiteten Code gehts.
Danke.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Achso, weil du halt vorher sowas komisches gepostet hast. Naja, schwere Geburt. ;)
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Hallo zusammen,

ich hab jetzt noch ein kleines Problem. Ich wollte das Programm dahingegen optimieren, dass die Files den Timestap vom Server haben.
dazu hab ich get_last_modified so angepasst:

Code: Alles auswählen

def get_last_modified(ftp_addr, pattern='*', no=1, dest='.', user='', pw=''):
    parsed = urlparse.urlparse(ftp_addr)
    ftp = TimeFTP(parsed.netloc, user, pw)


    if parsed.path:
        ftp.cwd(parsed.path)
    for filename, timestruct in list(ftp.last_modified(pattern))[-no:]:
        with open(os.path.join(dest, filename), 'wb') as outfile:
            ftp.retrbinary('RETR ' + filename, outfile.write)



    strptime=timestruct
    atime= time.mktime(strptime)
    pfad=os.path.join(dest, filename)
    print pfad
    times = (atime,atime)
    print times
    os.utime(pfad,times)
Es gibt keine Fehlermeldung aber die Files haben weiterhin das aktuelle Datum des Clients.
Geht das gar nicht mit os.time?
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn du das für jede Datei machen willst, dann solltest du es natürlich auch in einen Ebene unterhalb der For-Schleife machen, denn sonst arbeitest du nur mit den Werten, die nach dem letzten Durchlauf der Schleife rauskommen.
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Kaum macht mans richtig, schon gehts. :oops:
Vielen Dank.
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Hallo zusammen,

nach langer Zeit habe ich die Aufgabe bekommen mein FTP-Programm auf SFTP umzustellen.
Hierzu habe ich den Code mal teilweise angepasst:

Code: Alles auswählen

import pysftp
from operator import itemgetter
import os.path
import time
import urlparse

class TimeFTP(pysftp.Connection):

    def mdtm(self, filename):
        retcode, timestamp = self.sendcmd('MDTM ' + filename).split()
        return timestamp

    def last_modified(self, pattern):
        results = []
        for filename in self.nlst(pattern):
            timestamp = self.mdtm(filename)
            results.append((filename, timestamp))
        for filename, timestamp in sorted(results, key=itemgetter(1)):
            timestruct = time.strptime(timestamp, '%Y%m%d%H%M%S')
            yield filename, timestruct


def get_last_modified(ftp_addr, pattern='*', no=1, dest='.', user='', pw=''):
    parsed = urlparse.urlparse(ftp_addr)
    FTP = TimeFTP(parsed.netloc, user, pw)
    if parsed.path:
        ftp.cwd(parsed.path)
    for filename, timestruct in list(ftp.last_modified(pattern))[-no:]:
        with open(os.path.join(dest, filename), 'wb') as outfile:
            ftp.retrbinary('RETR ' + filename, outfile.write)
Das das so natürlich noch nicht funktioniert ist mir schon klar, da dass pysftp z.B. retrbinary nicht kennt.

Was mir jetzt nicht klar ist,was will mir die Fehlermeldung sagen:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:/Python_Test/Sourcecode/testmini", line 4, in <module>
    timeftpx.get_last_modified(ftp_addr, '*.dat', 2, 'C:\user', 'login','pass')
  File "C:\Python27\lib\timeftpx.py", line 25, in get_last_modified
    FTP = TimeFTP(parsed.netloc, user, pw)
  File "build\bdist.win32\egg\pysftp.py", line 74, in __init__
    xSx_key = paramiko.RSAKey.from_private_key_file(private_key_file,private_key_pass)
  File "build\bdist.win32\egg\paramiko\pkey.py", line 198, in from_private_key_file
    key = cls(filename=filename, password=password)
  File "build\bdist.win32\egg\paramiko\rsakey.py", line 51, in __init__
    self._from_private_key_file(filename, password)
  File "build\bdist.win32\egg\paramiko\rsakey.py", line 163, in _from_private_key_file
    data = self._read_private_key_file('RSA', filename, password)
  File "build\bdist.win32\egg\paramiko\pkey.py", line 279, in _read_private_key_file
    f = open(filename, 'r')
IOError: [Errno 2] No such file or directory: 'pass'
Für mich sieht das so aus, wie wenn er unter "def get_last_modified" andere Parameter erwarten würde,bzw. in anderer Reihenfolge.
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Ein

Code: Alles auswählen

help(timeftpx.get_last_modified)
an der entsprechenden Stelle wird dir sicherlich die entsprechenden Parameter zeigen, die erwartet werden.
Zuletzt geändert von sparrow am Montag 4. Februar 2013, 13:11, insgesamt 1-mal geändert.
BlackJack

@Manne_Manta: Vielleicht ja nicht die `get_last_modified()`, wobei ich jetzt mal davon ausgehe, dass die a) von Dir ist und b) nicht verändert wurde. Aber was *hast* Du denn verändert und wo betrifft das die genannte Funktion. Das ist doch eigentlich ziemlich offensichtlich.
Manne_Manta
User
Beiträge: 39
Registriert: Dienstag 5. Mai 2009, 11:26

Die timeftp wurde von Snafu in einem der älteren Posts geschrieben.
Ich habe anstelle der ftplib die pysftp importiert.

@sparrow: Wenn ich

Code: Alles auswählen

help(timeftpx.get_last_modified
vor

Code: Alles auswählen

def get_last_modified
einfüge bringt er mir

Code: Alles auswählen

    import timeftpx
  File "C:\Python27\lib\timeftpx.py", line 24
    def get_last_modified(ftp_addr, pattern='*', no=1, dest='.', user='', pw=''):
      ^
SyntaxError: invalid syntax
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Schließen die Klammer du musst!
Antworten