Reputation: 263
I am using Pysftp to transfer files from a Windows server to a Buffalo Terastation. I would like to be able to tell it to transfer all files in a folder using the PUT_R command but when I run my code the files are transferred oddly.
My code:
srv.put_r('c:/temp1/photos', 'array1/test_sftp/photos', preserve_mtime=True)
When I run the code I get filenames on the Terastation that look like
photos\.\image1.jpg
photos\.\image2.jpg
I guess the code is not dealing with paths between platforms correctly. How can I correct the paths?
I have tried
dest = dest.replace('\\.\\','/')
But I get a "No Such File" error
Upvotes: 2
Views: 2314
Reputation: 138
I got it working by (temporarily) changing to the source directory on the local machine, iterating over the files and then using put() instead of put_r(). You'll need to make sure the remote directory already exists though.
Here is some example code:
import os
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
srv = pysftp.Connection(host=host, username=username, password=password, cnopts=cnopts)
local_folder = 'c:/temp1/photos'
remote_folder = 'array1/test_sftp/photos'
with pysftp.cd(local_folder):
srv.cwd(remote_folder)
for filename in os.listdir('.'):
srv.put(filename, preserve_mtime=True)
Upvotes: 0
Reputation: 87
I created a hacky workaround for this problem. It is not very clever and it might not be stable in all cases. Therefore, please use with care. Tested on Python 3.x with pysftp 0.2.9.
import os
import pysftp
# copy all folders (non-recursively) from from_dir (windows file system) to to_dir (linux file system)
def copy_files(host, user, pw, from_dir, to_dir):
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection(host=host, username=user, password=pw, cnopts=cnopts) as sftp:
from_dir = os.path.normpath(from_dir)
to_dir = "/" + os.path.normpath(to_dir).replace("\\", "/").strip("/")
top_folder = os.path.split(to_dir)[1]
files = [file for file in os.listdir(from_dir) if os.path.isfile(os.path.join(from_dir, file))]
for file in files:
sftp.cwd(to_dir)
sftp.put(os.path.join(from_dir, file), os.path.join("./{}".format(top_folder), file))
sftp.execute(r'mv "{2}/{0}\{1}" "{2}/{1}"'.format(top_folder, file, to_dir))
# usage: always use full paths for all directories
copy_files("hostname", "username", "password", "D:/Folder/from_folder", "/root/Documents/to_folder")
Upvotes: 1