
__all__ = ['SshExecutor']

import paramiko

class SshExecutor(object):
    """class docs"""
    
    def __init__(self, serverip, username, password):
        self._username = username
        self._password = password
        self._host = serverip
        self._port = 22
        
        self.connect()
    
    def logout(self):
        if not self.isClosed():
            self.client.close()
            self.client = None
    
    def connect(self):
        '''Try to connect, maybe again.'''
        self.client = paramiko.SSHClient()
        self.client.load_system_host_keys()
        self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.client.connect(self._host, self._port, self._username, self._password)
    
    def isClosed(self):
        '''Try to judge whether connect is closed or not.'''
        if self.client is None:
            return True
        
        transport = self.client.get_transport()
        if transport is None or not transport.is_active() or not transport.is_active():
            self.logout()
            return True
        
        return False
    
    def execute(self, cmd):
        print('Start to execute SSH command: %s' % cmd)
        ssh_stdin, ssh_stdout, ssh_stderr = self.client.exec_command(cmd)
        print('-' * 20 + '> STDOUT <' + '-' * 20)
        linestr = ssh_stdout.readline()
        while linestr:
            print linestr,
            linestr = ssh_stdout.readline()
        print('-' * 50)
        print('-' * 20 + '> STDERR <' + '-' * 20)
        linestr = ssh_stderr.read()
        while linestr:
            print linestr,
            linestr = ssh_stderr.read()
        print('-' * 50)
        return ssh_stdout.channel.recv_exit_status() 
    
    def executeSftpGet(self, remotepath, localpath):
        print('SFTP Get: {remotepath} {localpath} ...'.format(remotepath=remotepath, localpath=localpath))
        sftp = self.client.open_sftp()
        sftp.get(remotepath, localpath)
        sftp.close()
        print('SFTP Get: {remotepath} {localpath} done.'.format(remotepath=remotepath, localpath=localpath))
    
    def executeSftpPut(self, localpath, remotepath):
        print('SFTP Put: {localpath} {remotepath} ...'.format(localpath=localpath, remotepath=remotepath))
        sftp = self.client.open_sftp()
        sftp.put(localpath, remotepath)
        sftp.close()
        print('SFTP Put: {localpath} {remotepath} done'.format(localpath=localpath, remotepath=remotepath))

