blob: dca0843b7ac5741ee512bed0146407fc47aa5770 [file] [log] [blame]
koder aka kdanilov80cb6192015-02-02 03:06:08 +02001import os.path
2
3
4def normalize_dirpath(dirpath):
5 while dirpath.endswith("/"):
6 dirpath = dirpath[:-1]
7 return dirpath
8
9
10def ssh_mkdir(sftp, remotepath, mode=0777, intermediate=False):
11 remotepath = normalize_dirpath(remotepath)
12 if intermediate:
13 try:
14 sftp.mkdir(remotepath, mode=mode)
15 except IOError:
16 ssh_mkdir(sftp, remotepath.rsplit("/", 1)[0], mode=mode,
17 intermediate=True)
18 return sftp.mkdir(remotepath, mode=mode)
19 else:
20 sftp.mkdir(remotepath, mode=mode)
21
22
23def ssh_copy_file(sftp, localfile, remfile, preserve_perm=True):
24 sftp.put(localfile, remfile)
25 if preserve_perm:
26 sftp.chmod(remfile, os.stat(localfile).st_mode & 0777)
27
28
29def put_dir_recursively(sftp, localpath, remotepath, preserve_perm=True):
30 "upload local directory to remote recursively"
31
32 assert remotepath.startswith("/"), "%s must be absolute path" % remotepath
33
34 # normalize
35 localpath = normalize_dirpath(localpath)
36 remotepath = normalize_dirpath(remotepath)
37
38 try:
39 sftp.chdir(remotepath)
40 localsuffix = localpath.rsplit("/", 1)[1]
41 remotesuffix = remotepath.rsplit("/", 1)[1]
42 if localsuffix != remotesuffix:
43 remotepath = os.path.join(remotepath, localsuffix)
44 except IOError:
45 pass
46
47 for root, dirs, fls in os.walk(localpath):
48 prefix = os.path.commonprefix([localpath, root])
49 suffix = root.split(prefix, 1)[1]
50 if suffix.startswith("/"):
51 suffix = suffix[1:]
52
53 remroot = os.path.join(remotepath, suffix)
54
55 try:
56 sftp.chdir(remroot)
57 except IOError:
58 if preserve_perm:
59 mode = os.stat(root).st_mode & 0777
60 else:
61 mode = 0777
62 ssh_mkdir(sftp, remroot, mode=mode, intermediate=True)
63 sftp.chdir(remroot)
64
65 for f in fls:
66 remfile = os.path.join(remroot, f)
67 localfile = os.path.join(root, f)
68 ssh_copy_file(sftp, localfile, remfile, preserve_perm)