#!/usr/bin/env python
# #########################
# # $Id: sendfile.py,v 1.4 2008/03/19 11:59:52 dhylton Exp $
# # $Log: $
# #########################
import time
import os
import sys
#import paramiko
#import ftplib
#import pycurl
class SftpSClient (object):
def __init__(self, protocol, hostname, hostport, username, password, source_path, dest_path):
self.protocol = protocol
self.hostname = hostname
self.hostport = hostport
self.username = username
self.password = password
self.source_path = source_path
self.dest_path = dest_path
if self.protocol == "sftp":
import paramiko
self.client = paramiko.SSHClient()
self.client.load_system_host_keys()
elif self.protocol == "ftps":
import pycurl
self.client = pycurl.Curl()
else: #self.protocol == "ftp":
import ftplib
self.client = ftplib.FTP()
def xfer(self, source_file, dest_file=None):
if not dest_file: dest_file = source_file
source = os.path.join(self.source_path, source_file)
dest = os.path.join(self.dest_path, dest_file)
if self.protocol == "sftp":
if not self.hostport: self.hostport = 22
self.client.connect(self.hostname, self.hostport, self.username, self.password)
sftp_client = self.client.open_sftp()
sftp_client.put(source, dest)
sftp_client.close()
elif self.protocol == "ftps":
if not self.hostport: self.hostport = 990
userpwd = '%s:%s' % (self.username, self.password)
infile = open(source, 'rb')
self.client.setopt(pycurl.URL, 'ftp://%s:%d/%s' % (self.hostname, self.hostport, dest))
self.client.setopt(pycurl.FTP_SSL, 1)
self.client.setopt(pycurl.FTPSSLAUTH, 1)
self.client.setopt(pycurl.SSL_VERIFYHOST, 1)
self.client.setopt(pycurl.SSL_VERIFYPEER, 1)
self.client.setopt(pycurl.USERPWD, userpwd)
self.client.setopt(pycurl.READDATA, infile)
self.client.setopt(pycurl.UPLOAD, 1)
self.client.perform()
infile.close()
else: #self.protocol == "ftp":
if not self.hostport: self.hostport = 21
self.client.connect(self.hostname, self.hostport)
self.client.login(user=self.username, passwd=self.password)
self.client.set_pasv(False)
infile = open(source, 'rb')
self.client.storbinary('STOR ' + dest, infile)
infile.close()
def main():
hostname = 'localhost'
username = 'snark'
password = 'Bgt54rfv'
source_path = 'lo cal'
source_file = "test file'132"
dest_file = "remote test file'133"
print 'testing ftp'
protocol = 'ftp'
hostport = None
start = time.time()
dest_path = '%s/re mote' % (protocol)
p = SftpSClient(protocol, hostname, hostport, username, password, source_path, dest_path)
p.xfer(source_file, dest_file)
elapsedtime = time.time() - start
print 'elapsed time:', elapsedtime
print 'testing ftps'
protocol = 'ftps'
hostport = 990
start = time.time()
dest_path = '%s/re mote' % (protocol)
p = SftpSClient(protocol, hostname, hostport, username, password, source_path, dest_path)
p.xfer(source_file, dest_file)
elapsedtime = time.time() - start
print 'elapsed time:', elapsedtime
print 'testing sftp'
protocol = 'sftp'
hostport = 22
start = time.time()
dest_path = '%s/re mote' % (protocol)
p = SftpSClient(protocol, hostname, hostport, username, password, source_path, dest_path)
p.xfer(source_file, dest_file)
elapsedtime = time.time() - start
print 'elapsed time:', elapsedtime
if __name__ == '__main__': main()
Refactorings
No refactoring yet !
Simon Law
March 19, 2008, March 19, 2008 17:06, permalink
That's because pycurl is only defined in SftpSClient.__init__().
Here, it makes more sense for you to use a factory make SftpSClient.__init__() construct a good delegate object, that knows how to configure itself, instead of trying to keep state in SftpSClient.protocol.
dhylton.myopenid.com
March 19, 2008, March 19, 2008 17:13, permalink
why does this not apply to paramiko and ftplib?
could you (please) show an example of your recommendation?
Simon Law
March 20, 2008, March 20, 2008 00:02, permalink
You use pycurl outside of its imported scope.
Here is an example implementation that uses a delegate.
import time
import os
import sys
class SftpSClient(object):
def __init__(self, protocol, hostname, hostport, username, password,
source_path, dest_path):
if protocol == "sftp":
self.delegate = ParamikoClient(protocol, hostname, hostport,
username, password,
source_path, dest_path)
elif protocol == "ftps":
self.delegate = PycurlClient(protocol, hostname, hostport,
username, password,
source_path, dest_path)
else: #self.protocol == "ftp":
self.delegate = FtpClient(protocol, hostname, hostport,
username, password,
source_path, dest_path)
def _setup(self, protocol, hostname, hostport, username, password,
source_path, dest_path):
self.protocol = protocol
self.hostname = hostname
self.hostport = hostport
self.username = username
self.password = password
self.source_path = source_path
self.dest_path = dest_path
def _xfer(self, source_file, dest_file):
if not dest_file:
dest_file = source_file
source = os.path.join(self.source_path, source_file)
dest = os.path.join(self.dest_path, dest_file)
return (source, dest)
def xfer(self, source_file, dest_file):
self.delegate.xfer(*args, **kwargs)
class ParamikoClient(SftpSClient):
def __init__(self, *args, **kwargs):
self._setup(*args, **kwargs)
self.paramiko = __import__("paramiko")
self.client = self.paramiko.SSHClient()
self.client.load_system_host_keys()
def xfer(self, source_file, dest_file):
source, dest = self._xfer(source_file, dest_file)
if not self.hostport:
self.hostport = 22
self.client.connect(self.hostname, self.hostport,
self.username, self.password)
sftp_client = self.client.open_sftp()
sftp_client.put(source, dest)
sftp_client.close()
class PycurlClient(SftpSClient):
def __init__(self, *args, **kwargs):
self._setup(*args, **kwargs)
self.pycurl = __import__("pycurl")
self.client = self.pycurl.Curl()
def xfer(self, source_file, dest_file):
source, dest = self._xfer(source_file, dest_file)
if not self.hostport:
self.hostport = 990
userpwd = '%s:%s' % (self.username, self.password)
infile = open(source, 'rb')
self.client.setopt(self.pycurl.URL,
'ftp://%s:%d/%s' % (self.hostname, self.hostport,
dest))
self.client.setopt(self.pycurl.FTP_SSL, 1)
self.client.setopt(self.pycurl.FTPSSLAUTH, 1)
self.client.setopt(self.pycurl.SSL_VERIFYHOST, 1)
self.client.setopt(self.pycurl.SSL_VERIFYPEER, 1)
self.client.setopt(self.pycurl.USERPWD, userpwd)
self.client.setopt(self.pycurl.READDATA, infile)
self.client.setopt(self.pycurl.UPLOAD, 1)
self.client.perform()
infile.close()
class FtpClient(SftpSClient):
def __init__(self, *args, **kwargs):
self._setup(*args, **kwargs)
self.ftplib = __import__("ftplib")
self.client = self.ftplib.FTP()
def xfer(self, source_file, dest_file):
source, dest = self._xfer(source_file, dest_file)
if not self.hostport:
self.hostport = 21
self.client.connect(self.hostname, self.hostport)
self.client.login(user=self.username, passwd=self.password)
self.client.set_pasv(False)
infile = open(source, 'rb')
self.client.storbinary('STOR ' + dest, infile)
infile.close()
def main():
hostname = 'localhost'
username = 'snark'
password = 'Bgt54rfv'
source_path = 'lo cal'
source_file = "test file'132"
dest_file = "remote test file'133"
print 'testing ftp'
protocol = 'ftp'
hostport = None
start = time.time()
dest_path = '%s/re mote' % (protocol)
p = SftpSClient(protocol, hostname, hostport, username, password,
source_path, dest_path)
p.xfer(source_file, dest_file)
elapsedtime = time.time() - start
print 'elapsed time:', elapsedtime
print 'testing ftps'
protocol = 'ftps'
hostport = 990
start = time.time()
dest_path = '%s/re mote' % (protocol)
p = SftpSClient(protocol, hostname, hostport, username, password,
source_path, dest_path)
p.xfer(source_file, dest_file)
elapsedtime = time.time() - start
print 'elapsed time:', elapsedtime
print 'testing sftp'
protocol = 'sftp'
hostport = 22
start = time.time()
dest_path = '%s/re mote' % (protocol)
p = SftpSClient(protocol, hostname, hostport, username, password,
source_path, dest_path)
p.xfer(source_file, dest_file)
elapsedtime = time.time() - start
print 'elapsed time:', elapsedtime
if __name__ == '__main__':
main()
the goal is to be able to export the SftpSClient class ('from sendfile import SftpSClient') from another script that uses ConfigParser to define the actual variables (hostname, protocol, etc.) currently i get a name (scope) error with pycurl, but both ftplib and paramiko work just fine.