+class SFTPSync(Syncer):
+ def __init__(self, url):
+ import paramiko
+ # get host key, if we know one
+ hostkeytype = None
+ hostkey = None
+ try:
+ host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
+ except IOError:
+ try:
+ # try ~/ssh/ too, because windows can't have a folder named ~/.ssh/
+ host_keys = paramiko.util.load_host_keys(os.path.expanduser('~/ssh/known_hosts'))
+ except IOError:
+ print '*** Unable to open host keys file'
+ host_keys = {}
+
+ if host_keys.has_key(url.hostname):
+ hostkeytype = host_keys[url.hostname].keys()[0]
+ hostkey = host_keys[url.hostname][hostkeytype]
+ print 'Using host key of type %s' % hostkeytype
+
+
+ # now, connect and use paramiko Transport to negotiate SSH2 across the connection
+ port = 22
+ if url.port: port = url.port
+ self.t = paramiko.Transport((url.hostname, port))
+ password = url.password
+ if not password: password = options.password
+ self.t.connect(username=url.username, password=password, hostkey=hostkey)
+ self.sftp = paramiko.SFTPClient.from_transport(self.t)
+
+ def close(self):
+ self.sftp.close()
+ self.t.close()
+
+ def _mkd(self, path):
+ try:
+ self.sftp.mkdir(path)
+ except IOError, detail:
+ print "sftp warning:", detail
+
+ def _storbinary(self, file, path):
+ remote = self.sftp.open(path, 'w')
+ s = file.read(10000)
+ while s:
+ remote.write(s)
+ s = file.read(10000)
+ remote.close()
+
+
+ def _rmd(self, path):
+ """ Delete everything reachable from the directory named in 'self.dest_path',
+ assuming there are no symbolic links."""
+ self.sftp.rmdir(path)
+ # FIXME: this should be recursive deletion
+
+ def _delete(self, path):
+ self.sftp.remove(path)
+