#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "hiki"
# Email: 317606513@qq.com
'''
paramiko -- sftp : get/put
'''
import os
import stat
import logging
import paramiko
from OPS import settings
class SftpHandler(object):
def __init__(self, host, port, username):
self.host = host
self.port = port
self.username = username
self.key = settings.PKEY_FILE
self.backdir = settings.BACK_DIR
self.result = []
try:
paramiko.util.log_to_file(os.path.join(settings.PID_DIRS, "paramiko_sftp.log"))
key = paramiko.RSAKey.from_private_key_file(self.key)
self.t = paramiko.Transport((self.host, self.port))
self.t.connect(username=self.username, pkey=key)
self.sftp = paramiko.SFTPClient.from_transport(self.t)
except Exception,e:
print "out: ",e
log = logging.getLogger('sftp_error')
log.info('SFTP connection error from %s, %s.'%(self.host, e))
def __del__(self):
try:
self.t.close()
self.result = []
# print "del self.t"
except:
pass
def data_put(self, local_path, remote_path):
try:
if os.path.isfile(local_path):
filename = local_path.split("/")[-1]
remote_file = os.path.join(remote_path, filename)
result = self.sftp.put(local_path, remote_file)
# print result
if result:
log = logging.getLogger('sftp_access')
log.info('SFTP put [%s --> %s] success to %s.' % (local_path, remote_file, self.host))
self.result.append('SFTP put [%s --> %s] success to %s.' % (local_path, remote_file, self.host))
return self.result
else:
log = logging.getLogger('sftp_error')
log.info('SFTP put [%s --> %s] failed to %s, %s.' % (local_path, remote_file, self.host,result))
self.result.append('SFTP put [%s --> %s] failed to %s, %s.' % (local_path, remote_file, self.host,result))
return self.result
elif os.path.isdir(local_path):
# loop dir
result = self.data_put_loop_dir(local_path, remote_path)
return self.result
else:
log = logging.getLogger('sftp_error')
log.info('Local_path ==> [%s] is not exist.' % local_path)
self.result.append('Local_path ==> [%s] is not exist.' % local_path)
return self.result
except Exception,e:
log = logging.getLogger('sftp_error')
log.info('SFTP put error from %s, %s.'%(self.host, e))
self.result.append('SFTP put error from %s, %s.'%(self.host, e))
return self.result
def data_put_loop_dir(self, local_path, remote_path):
try:
file_list = os.listdir(local_path)
# Remote create dir if not exist
dirname = local_path.split("/")[-1]
mkdirname = os.path.join(remote_path, dirname)
try:
self.sftp.listdir_attr(mkdirname)
except:
result = self.sftp.mkdir(mkdirname)
if result == None:
log = logging.getLogger("sftp_access")
log.info('Remote create dir[%s] succeed.' % mkdirname)
else:
log = logging.getLogger("sftp_error")
log.info('Remote create dir[%s] failed, %s.' % (mkdirname, str(result)))
self.result.append('Remote create dir failed, %s.' % str(result))
return self.result
# if create dir succeed, then start put file_list
isfile_list = []
isdir_list = []
for filename in file_list:
if os.path.isfile(os.path.join(local_path, filename)):
isfile_list.append(filename)
elif os.path.isdir(os.path.join(local_path, filename)):
isdir_list.append(filename)
else:
pass
# first step: deal file
for file_name in isfile_list:
local_file = os.path.join(local_path, file_name)
remote_file = os.path.join(mkdirname, file_name)
result = self.sftp.put(local_file, remote_file)
if result:
log = logging.getLogger('sftp_access')
log.info('SFTP put [%s --> %s] success to %s.' % (local_path, remote_file, self.host))
self.result.append('SFTP put [%s --> %s] success to %s.' % (local_path, remote_file, self.host))
else:
log = logging.getLogger('sftp_error')
log.info('SFTP put [%s --> %s] failed to %s, %s.' % (local_path, remote_file, self.host, result))
self.result.append('SFTP put [%s --> %s] failed to %s, %s.' % (local_path, remote_file, self.host, result))
# second step: loop dir
n = 0
for dir_name in isdir_list:
if n > 0:
local_path = os.path.join(os.path.dirname(local_path), dir_name)
else:
local_path = os.path.join(local_path, dir_name)
remote_path = mkdirname
self.data_put_loop_dir(local_path, remote_path)
n += 1
return self.result
except Exception,e:
log = logging.getLogger('sftp_error')
log.info('SFTP put error, %s.' % e)
self.result.append('SFTP put error, %s.' % e)
return self.result
def data_get(self, local_path, remote_path):
try:
# check remote_path type
try:
result = self.sftp.stat(remote_path)
if result:
try:
self.sftp.listdir_attr(remote_path)
stdout, stderr = (['directory'],[])
except:
stdout, stderr = (['file'], [])
except Exception,e:
log = logging.getLogger('sftp_error')
log.info('SFTP get [%s] error, %s.' % (remote_path, e))
self.result.append('SFTP get [%s] error, %s.' % (remote_path,e))
return self.result
if len(stderr) == 0:
# stdout = stdout[0].split("\n")[0]
if 'file' in stdout:
filename = remote_path.split("/")[-1]
local_file = os.path.join(local_path, filename)
if os.path.isdir(local_path):
pass
else:
os.makedirs(local_path)
self.sftp.get(remote_path, local_file)
if os.path.isfile(local_file):
log = logging.getLogger('sftp_access')
log.info('SFTP get [%s --> %s] success to %s.' % (remote_path, local_file, self.host))
self.result.append('SFTP get [%s --> %s] success from %s.' % (remote_path, local_file, self.host))
return self.result
else:
log = logging.getLogger('sftp_error')
log.info('SFTP get [%s --> %s] failed to %s.' % (remote_path, local_file, self.host))
self.result.append('SFTP get [%s --> %s] failed from %s, %s not exit.' % (remote_path, local_file, self.host, local_file))
return self.result
elif 'directory' in stdout:
result = self.data_get_loop_dir(local_path, remote_path)
return self.result
else:
return self.result
except Exception,e:
log = logging.getLogger('sftp_error')
log.info('SFTP get error, %s.' % e)
self.result.append('SFTP get error, %s.' % e)
return self.result
def data_get_loop_dir(self, local_path, remote_path):
try:
if os.path.isdir(local_path):
pass
else:
os.makedirs(local_path)
# check file/dir
isfile_list = []
isdir_list = []
remote_allfiles = self.sftp.listdir_attr(remote_path)
for f in remote_allfiles:
remote_file = os.path.join(remote_path, f.filename)
dirname = remote_path.split("/")[-1]
local_file = os.path.join(os.path.join(local_path,dirname), f.filename)
if stat.S_ISDIR(f.st_mode):
isdir_list.append(remote_file)
else:
isfile_list.append(remote_file)
# first step: get file
for file_name in isfile_list:
remote_file = file_name
try:
os.makedirs(os.path.join(local_path,file_name.split("/")[-2]))
except:
pass
local_file = os.path.join(local_path,os.path.join(file_name.split("/")[-2], file_name.split("/")[-1]))
self.sftp.get(remote_file, local_file)
if os.path.isfile(local_file):
log = logging.getLogger('sftp_access')
log.info('SFTP get [%s --> %s] success to %s.' % (remote_file, local_file, self.host))
self.result.append('SFTP get [%s --> %s] success from %s.' % (remote_file, local_file, self.host))
else:
log = logging.getLogger('sftp_error')
log.info('SFTP get [%s --> %s] failed to %s.' % (remote_file, local_file, self.host))
self.result.append('SFTP get [%s --> %s] failed from %s, %s not exit.' % (remote_file, local_file, self.host, local_file))
# second step: loop dir
n = 0
for dir_name in isdir_list:
if n > 0:
local_path = local_path
else:
local_path = os.path.join(local_path, dir_name.split("/")[-2])
remote_path = dir_name
self.data_get_loop_dir(local_path, remote_path)
n += 1
return self.result
except Exception,e:
log = logging.getLogger('sftp_error')
log.info('SFTP get error, %s.' % e)
self.result.append('SFTP get error, %s.' % e)
return self.result