97 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import paramiko
 | 
						|
from paramiko.ssh_exception import SSHException, NoValidConnectionsError
 | 
						|
import time
 | 
						|
import hashlib
 | 
						|
import sys
 | 
						|
import os
 | 
						|
 | 
						|
class sftp_remote:
 | 
						|
    def __init__(self, config, settings):
 | 
						|
        self.config = config
 | 
						|
        self.path = config['path']
 | 
						|
        self.description = config['description']
 | 
						|
        self.hostname = config['hostname']
 | 
						|
        self.username = config['username']
 | 
						|
        self.port = config['port']
 | 
						|
        self.remote_type = config['remote_type']
 | 
						|
        self.remote_attempts = settings[self.remote_type]['remote_attempts']
 | 
						|
        self.remote_delay = settings[self.remote_type]['remote_delay']
 | 
						|
        self.remote_error = None
 | 
						|
        self.password = settings[self.remote_type][self.hostname][self.username]['password']
 | 
						|
        self.ssh = None
 | 
						|
 | 
						|
    def connect(self):
 | 
						|
        self.transport = paramiko.Transport((self.hostname, int(self.port)))
 | 
						|
        self.transport.connect(username = self.username, password = self.password)
 | 
						|
        self.sftp = paramiko.SFTPClient.from_transport(self.transport)
 | 
						|
 | 
						|
    def disconnect(self):
 | 
						|
        del (self.sftp)
 | 
						|
        self.transport.close()
 | 
						|
 | 
						|
    def __close__(self):
 | 
						|
        del (self.sftp)
 | 
						|
        self.transport.close()
 | 
						|
 | 
						|
    def ssh_connect(self):
 | 
						|
        self.ssh = paramiko.SSHClient()
 | 
						|
        #i trust my vm's
 | 
						|
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
 | 
						|
        self.ssh.connect(self.hostname, username=self.username, password=self.password)
 | 
						|
 | 
						|
    def ssh_disconnect(self):
 | 
						|
        self.ssh.close()
 | 
						|
 | 
						|
    def subtract_remote_attempts(self, total_attempts):
 | 
						|
        time.sleep(self.remote_delay)
 | 
						|
        return total_attempts -1
 | 
						|
 | 
						|
    def digest(self, file_path):
 | 
						|
        hashvalue = hashlib.sha256()
 | 
						|
        with open(file_path, 'rb') as file_:
 | 
						|
            while True:
 | 
						|
                chunk = file_.read(hashvalue.block_size)
 | 
						|
                if not chunk:
 | 
						|
                    break
 | 
						|
                hashvalue.update(chunk)
 | 
						|
        return hashvalue.hexdigest()
 | 
						|
 | 
						|
 | 
						|
    def put(self, local_path, remote_path, files_bytes = None):
 | 
						|
        sha256 = self.digest(local_path) #sha value at source
 | 
						|
        total_attempts = int(self.remote_attempts)
 | 
						|
        local_path_str = str(local_path)
 | 
						|
        local_path_get = ''.join([local_path_str[:local_path_str.rindex('/')]])
 | 
						|
        try:
 | 
						|
            self.connect()
 | 
						|
            #print('remote_path chdir: ', remote_path)
 | 
						|
            self.sftp.chdir(remote_path)  # Test if remote_path exists
 | 
						|
        except IOError:
 | 
						|
            self.sftp.mkdir(remote_path)
 | 
						|
        finally:
 | 
						|
            self.disconnect()
 | 
						|
            if not os.path.isdir(local_path_get):
 | 
						|
                original_umask = os.umask(0) #create local temp folder for redownloaded files
 | 
						|
                os.makedirs(local_path_get, 755)
 | 
						|
                os.umask(original_umask)
 | 
						|
 | 
						|
        filename = local_path_str.split("/")[-1]
 | 
						|
        remote_path = remote_path + filename
 | 
						|
        local_path_get = local_path_get + filename
 | 
						|
        while total_attempts > 0:
 | 
						|
            self.connect()
 | 
						|
            self.sftp.put(local_path, remote_path)
 | 
						|
            self.disconnect()
 | 
						|
            self.connect()
 | 
						|
            self.sftp.get(remote_path, local_path_get)
 | 
						|
            self.disconnect()
 | 
						|
            local_sha256 = self.digest(local_path_get)
 | 
						|
            os.remove(local_path_get)
 | 
						|
            if local_sha256 == sha256:
 | 
						|
                #print('sha confirmed')
 | 
						|
                return True
 | 
						|
            total_attempts = self.subtract_remote_attempts(total_attempts)
 | 
						|
            if total_attempts == 0:
 | 
						|
                return False
 | 
						|
 |