hallo,
gibts die Möglichkeit Python also FXP Client einzusetzen, so dass zwischen 2 anderen FTP servern Files ausgetauscht werden können?
Wäre super wenn jemand eine Idee diesbezüglich hat. In der FTPlib hab ich leider nix finden können.
Python FXP Client
Hat doch nichts mit Freak-sein-oder-nicht zu tun
:Anhübschen musst Du es schon selber
.
Habe das ganze mit zwei lokalen (PyFTPdlib) FTP-Server Instanzen (einmal Port 21 und dann Port 22) getestet, welche beiden den "test"-User mitbekommen hatten.
Dabei bin ich zuerst auch in die Falle getappt und hatte vergessen, dem FTP-Server den FXP-Support freizuschalten ... "mit" klappte es auf jeden Fall deutlich besser
.
Gelernt habe ich dabei, dass ein Funktionieren von FXP nicht nur vom Client, sondern auch vom Server abhängt. Unterstützt nämlich dieser die Verbindung zu anderen FTP-Adressen nicht, so kann man das ganze knicken. Eine PyFTPdlib FTP-Server Instanz benötigt z.B. folgende FTPHandler-Einstellung:
Fazit: FXP ist weder Hexerei (kompliziert), noch braucht man eine separate Library dafür. Es reichen völlig die bei Python mitgelieferten Boardmittel und die FTP-Kommandos und Vorgehensweise aus (was ja hier zu finden war: http://www.proftpd.org/docs/howto/FXP.html).
Gruß,
>>Masasru<<
Code: Alles auswählen
import ftplib
import re
import StringIO
## Connect to target (ftp1) and source (ftp2) FTP server test instances.
ftp1 = ftplib.FTP()
ftp1.connect('localhost', 21)
ftp1.login('test', 'test')
ftp2 = ftplib.FTP()
ftp2.connect('localhost', 22)
ftp2.login('test', 'test')
try:
## Preparing a test file which will be transferred from source FTP (2) to
## the target FTP (1) in next step 'Site-to-site Transfer'.
test_file = StringIO.StringIO()
test_file.write("This is content for a simple test file.\n")
ftp2.storlines('STOR test.txt', test_file)
## Site-to-site Transfer.
# Set transfer modes to BINARY on both connections.
ftp1.sendcmd('TYPE I')
ftp2.sendcmd('TYPE I')
# Open passive transfer tunnel on first FTP and connect with second one.
tunnel_address = None
resp = ftp1.sendcmd('PASV')
match = re.match('.*(\()(?P<tunnel>[0-9,]*)(\)).*', resp)
if match:
tunnel_address = match.groupdict().get('tunnel', None)
assert tunnel_address
ftp2.sendcmd('PORT %s' % tunnel_address)
# Add an new empty file container on target FTP (1), which will be filled
# with data from file of the source FTP (2).
ftp1.sendcmd('STOR test.txt')
ftp2.sendcmd('RETR test.txt')
finally:
ftp1.close()
ftp2.close()Habe das ganze mit zwei lokalen (PyFTPdlib) FTP-Server Instanzen (einmal Port 21 und dann Port 22) getestet, welche beiden den "test"-User mitbekommen hatten.
Dabei bin ich zuerst auch in die Falle getappt und hatte vergessen, dem FTP-Server den FXP-Support freizuschalten ... "mit" klappte es auf jeden Fall deutlich besser
Gelernt habe ich dabei, dass ein Funktionieren von FXP nicht nur vom Client, sondern auch vom Server abhängt. Unterstützt nämlich dieser die Verbindung zu anderen FTP-Adressen nicht, so kann man das ganze knicken. Eine PyFTPdlib FTP-Server Instanz benötigt z.B. folgende FTPHandler-Einstellung:
Code: Alles auswählen
...
ftp_handler = ftpserver.FTPHandler
ftp_handler.permit_foreign_addresses = True # <- default is False
...Gruß,
>>Masasru<<
Könnte der Site - to - Site Transfer über die Function ftpcp() gelöst werden oder zielt diese nur auf einen Transfer von Files von einem localen Server auf einen entfernten ab?
ftpcp (source, sourcename, target, targetname, type)
MFG
ftpcp (source, sourcename, target, targetname, type)
MFG
-
BlackJack
@Bernd999: Der DocString sagt: zwischen FTP-Servern.
Und im Quelltext kann man das Vorgehen von Masaru's Beispiel wiedererkennen:
Einer der Vorteile von OpenSource — man kann nachschauen was genau passiert. 
Code: Alles auswählen
In [163]: ftplib.ftpcp?
Type: function
Base Class: <type 'function'>
String Form: <function ftpcp at 0x9678454>
Namespace: Interactive
File: /usr/lib/python2.6/ftplib.py
Definition: ftplib.ftpcp(source, sourcename, target, targetname='', type='I')
Docstring:
Copy file from one FTP-instance to another.Code: Alles auswählen
def ftpcp(source, sourcename, target, targetname = '', type = 'I'):
'''Copy file from one FTP-instance to another.'''
if not targetname: targetname = sourcename
type = 'TYPE ' + type
source.voidcmd(type)
target.voidcmd(type)
sourcehost, sourceport = parse227(source.sendcmd('PASV'))
target.sendport(sourcehost, sourceport)
# RFC 959: the user must "listen" [...] BEFORE sending the
# transfer request.
# So: STOR before RETR, because here the target is a "user".
treply = target.sendcmd('STOR ' + targetname)
if treply[:3] not in ('125', '150'): raise error_proto # RFC 959
sreply = source.sendcmd('RETR ' + sourcename)
if sreply[:3] not in ('125', '150'): raise error_proto # RFC 959
source.voidresp()
target.voidresp()