Package install :: Package MoSTBioDat :: Package Transfer :: Module SFTPtools
[hide private]
[frames] | no frames]

Source Code for Module install.MoSTBioDat.Transfer.SFTPtools

  1  #!/usr/bin/env python 
  2  ####################################### 
  3  # SFTPtools.py:                       # 
  4  # Secure File Transfer Protocol tools # 
  5  ####################################### 
  6   
  7  ###################################################### 
  8  # Copyright (c) 2007-2008 Andrzej Bak                # 
  9  # ARC Seibersdorf & University of Silesia            # 
 10  # Author: Andrzej Bak <Andrzej.Bak@us.edu.pl>        # 
 11  # License: GNU General Public License, version: 3    # 
 12  # URL: http://chemoinformatyka.us.edu.pl/mostbiodat/ # 
 13  # Version: 1, 06.01.2010                             # 
 14  ###################################################### 
 15   
 16  try: 
 17      import sys 
 18      import os 
 19      import socket 
 20      from getpass import getpass,getuser 
 21      import paramiko 
 22      from MoSTBioDat.Transfer.fileSFTPtools import fileSFtpTools,LocalHostKeys,fileInfo,fileFilter 
 23      from MoSTBioDat.Transfer.fileFTPtools import fileFtpTools 
 24      from MoSTBioDat.Log.MoSTBioDatLog import  MoSTBioDatLog,filterKeys,getCurrentUser 
 25  except ImportError,error: 
 26      print 'Missing modules ...',error 
 27      sys.exit(1) 
 28   
 29  ################## SFTPtools class ###################### 
30 -class SFTPtools(object):
31 """ 32 methods to connect and transfer files 33 INPUT: 34 rserver - str, servername 35 ruser - str, remote user, default Anonymous 36 rpasswd - str, remote password, default empty 37 rdir - str, remote directory, default '.' 38 log - boolean 39 logfile - str, path to logfile 40 kwarg: 41 format - string format for log handler 42 filter - filter object from logger object 43 datefmt - data/time format 44 path - directory path to log file 45 filename - log file name, default log 46 filemode - mode to open log file, default='a' 47 level - set root logger level to specified level 48 logfilelevel- set level to log file 49 OUTPUT: 50 class object 51 """ 52
53 - def __init__(self,rserver=None,ruser='Anonymous',rpasswd='',rdir='.',log=True,logfile='/home/abak/ssh.log',port=22,*args,**kwargs):
54 if not rserver: 55 print 'Missing remote server!' 56 sys.exit(1) 57 self.servername=rserver 58 self.remoteuser=ruser 59 if ruser=='': 60 self.remoteuser=getCurrentUser() 61 self.remotepassword=rpasswd 62 self.logfile=logfile 63 self.log=log 64 self.port=port 65 self.remotedir=rdir 66 self.connection=None 67 self.sftp=None 68 if self.log: 69 try: 70 paramiko.util.log_to_file(logfile,level=1) 71 except IOError,e: 72 print "Error: %s, %s to %s" %(e[0],e[1],self.logfile) 73 self.kwargs={} 74 self.kwargs=kwargs 75 keys=("rserver","ruser","rpasswd","rdir","port", 76 "format","filter","datefmt","path", 77 "filename","filemode","level","logfilelevel") 78 filter(lambda key: filterKeys(kwargs,keys,key),kwargs.keys()) #check keys 79 try: 80 self.logobj=MoSTBioDatLog(**kwargs)#create logging object 81 self.log=self.logobj.getLogHandler()#create logging handler 82 except IOError,e: 83 print 'Error: %s, %s' %(e[0],e[1]) 84 sys.exit(1)
85
86 - def isSFtp(self):
87 """ 88 check whether ssh server is available 89 INPUT: 90 class object 91 OUTPUT: 92 boolean 93 """ 94 try: 95 sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # create new socket 96 sock.connect((self.servername,self.port)) # connect to server on given port 97 sock.settimeout(20) # set timeout on I/O operations 98 sock.close() 99 self.log.info('Check if SFTP server exists') 100 except socket.error,e: 101 print "Connection failed." 102 print "Error: %s, %s" %(e[0],e[1]) 103 self.log.exception('Socket error: %s',e) 104 return False 105 else: 106 return True
107
108 - def connectSFtp(self):
109 """ 110 connect to SSH server 111 INPUT: 112 class object 113 OUTPUT: 114 connection object 115 sftp client object 116 """ 117 try: 118 print "Trying to connect to %s on port %s, please wait ..." %(self.servername,self.port) 119 sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #create new socket 120 sock.connect((self.servername,self.port)) # connect to server on given port 121 sock.settimeout(20) # set timeout on I/O operations 122 self.log.info('Start SFTP connection to %s',self.servername) 123 except socket.error,e: 124 print 'Connection failed.' 125 print "Error: %s, %s" %(e[0],e[1]) 126 self.log.exception('Socket error: %s',e) 127 sock.close() 128 sys.exit(1) 129 130 lhostkeytype=None 131 lhostkey=None 132 lhostkeys=LocalHostKeys().getLocalHostKeys() #get local host keys dictionary 133 if lhostkeys.has_key(self.servername): 134 lhostkeytype=lhostkeys[self.servername].keys()[0] #get local host keys type 135 lhostkey=lhostkeys[self.servername][lhostkeytype] # get local host keys 136 print "Host key type: %s" %lhostkeytype 137 self.log.info('Host key type: %s',lhostkeytype) 138 else: 139 print 'Warning! Unknown host key for %s.' %self.servername 140 self.log.info('Warning! Unknown host key for %s',self.servername) 141 142 try: 143 print "Negotiating an encrypted session, please wait ..." 144 self.connection=paramiko.Transport((sock)) # create SSH session on existing socket 145 self.log.info('Negotiating an encrypted session') 146 except socket.error,e: 147 print "SSH negotiation failed." 148 print "Error: %s, %s" %(e[0],e[1]) 149 self.log.exception('Socket error: %s',e) 150 sys.exit(1) 151 152 try: 153 print "Connecting to %s ..." %self.servername 154 self.connection.connect(username=self.remoteuser,password=self.remotepassword,hostkey=lhostkey) 155 self.log.info('Logging as %s',self.remoteuser) 156 ### negotiate SSH session, optionally verify server host keys,authenticate using password 157 print 'Connection succeeded.' 158 except paramiko.SSHException, e: 159 print "Error: %s" %e 160 self.log.exception('SSH error: %s',e) 161 self.byeSFtp() 162 sys.exit(1) 163 164 try: 165 self.sftp=paramiko.SFTPClient.from_transport(self.connection) 166 ### create SFTP client channel from opened transport 167 self.sftp.chdir(self.remotedir) 168 self.log.info('CWD: %s',self.remotedir)# 169 except paramiko.SSHException, e: 170 print "Error %s:" %e 171 self.log.exception('SSH error: %s',e) 172 self.byeSFtp() 173 sys.exit(1) 174 except IOError,e: 175 print "Error: %s, %s or directory" %(e[0],e[1]) 176 self.log.exception('IO error: %s, %s or directory',e[0],e[1]) 177 self.byeSFtp() 178 sys.exit(1)
179
180 - def isEmpty(self,path='.'):
181 """ 182 check whether directory accessible for displaying 183 INPUT: 184 path - str, path on remote machine, default '.' 185 OUTPUT: boolean 186 """ 187 if self.sftp is None: 188 print 'Error: Connect to server!' 189 self.log.info('Connect to server') 190 sys.exit(1) 191 try: 192 return self.sftp.listdir(path)==[] 193 except IOError: 194 self.log.exception('IO error') 195 return True
196
197 - def lsSFtp(self,path='.',flag=True):
198 """ 199 list files on SSH server 200 INPUT: 201 class object 202 path - str, path on remote machine, default '.' 203 flag - boolean: default True - list files 204 OUTPUT: 205 list of class object 206 """ 207 listing=[] 208 if not self.isEmpty(path): 209 try: 210 listfile=self.sftp.listdir(path) # list of files in given path 211 listobj=self.sftp.listdir_attr(path) # list of objects with attributes of files 212 except IOError,e: 213 print "Error: %s, %s or directory" %(e[0],e[1]) 214 self.log.exception('IO error: %s, %s or directory',e[0],e[1]) 215 else: 216 return map(lambda fileobj,filename: fileInfo(path,fileobj,filename,flag),listobj,listfile) 217 ### list of fileInfo objects 218 else: 219 print 'Not accessible or empty! %s' %path 220 self.log.info('Not accessible or empty! %s',path) 221 return listing
222
223 - def pwdSFtp(self,flag=True):
224 """ 225 print working directory on FTP server 226 INPUT: 227 class object 228 flag - boolean: default True - print current working directory 229 """ 230 if self.sftp is None: 231 print 'Error: Connect to server!' 232 self.log.info('Connect to server') 233 sys.exit(1) 234 if flag: 235 print 'Current directory: %s' %self.sftp.getcwd() 236 return self.sftp.getcwd() # current working directory of sftp session
237
238 - def cdSFtp(self,path='.'):
239 """ 240 change directory on SSH server 241 INPUT: 242 class object 243 path - str, path to be changed on remote machine, default '.' 244 OUTPUT 245 boolean: True - enable to change directory 246 """ 247 if self.sftp is None: 248 print 'Error: Connect to server!' 249 self.log.info('Connect to server') 250 sys.exit(1) 251 try: 252 self.sftp.chdir(path) # change directory of sftp session 253 self.log.info('CWD: %s',path) 254 except IOError,e: 255 print "Error: %s, %s or directory" %(e[0],e[1]) 256 self.log.exception('IO error: %s, %s or directory',e[0],e[1]) 257 return False 258 else: 259 return True
260
261 - def getSFtp(self,filelist=[],localpath='',binary=True):
262 """ 263 get specified files from current working directory to local machine 264 INPUT: 265 class object 266 filelist - list of files to be downloaded [str] - default [] 267 localpath - str, path on the local machine, default default current working directory 268 binary - boolean, default True - binary transfer 269 """ 270 if localpath=='': 271 localpath=os.path.abspath(os.curdir) # get full path to current directory 272 if len(filelist)==0: 273 print 'Specify filenames ...' 274 else: 275 robjlist=self.lsSFtp(self.pwdSFtp(False),False) # list of file object on remote machine 276 robjlist=filter(lambda fileobj: fileFilter(fileobj),robjlist) # remove hidden objects from the list 277 listFtpfile=filter(lambda fileFtpInfo: fileSFtpTools(fileFtpInfo,filelist).files2download(),robjlist) 278 ### get only object files specified in filelist 279 if len(listFtpfile)==0: 280 print 'Sorry,no files to download ...' 281 else: 282 filter(lambda fileFtpInfo: fileSFtpTools(fileFtpInfo,filelist).transferFtpFile(self.sftp,localpath,self.log),listFtpfile)
283 ### transfer specified object files 284
285 - def mgetSFtp(self,localpath='',binary=True):
286 """ 287 get all files from current working directory to specified path on local machine 288 INPUT: 289 class object 290 localpath - str, path on the local machine, default current working directory 291 binary - boolean: default True - binary transfer 292 """ 293 if localpath=='': 294 localpath=os.path.abspath(os.curdir) # get full path to current directory 295 robjlist=self.lsSFtp(self.pwdSFtp(False),False) # list of file object on remote machine 296 if len(robjlist)==0: 297 print 'Sorry,no files to download ...' 298 else: 299 listFtpfile=filter(lambda fileobj: fileFilter(fileobj),robjlist) 300 ### remove hidden objects from list 301 filter(lambda fileFtpInfo: fileSFtpTools(fileFtpInfo).transferFtpFile(self.sftp,localpath,self.log),listFtpfile)
302 ### transfer specified object files 303
304 - def byeSFtp(self):
305 """ 306 close SSH connection 307 """ 308 if self.connection is None: 309 print 'Error: Connect to server!' 310 self.log.info('Connect to server') 311 sys.exit(1) 312 try: 313 self.connection.close() # close connection 314 print 'Connection closed.' 315 self.log.info('Connection closed') 316 except paramiko.SSHException, e: 317 print "Error: %s" %e 318 self.log.exception('SSH error: %s',e) 319 sys.exit(1)
320 321 ######################################################### 322 ############ Example of usage ########################## 323 ################### MAIN ################################ 324 if __name__=='__main__': 325 pass 326 #userpasswd=getpass('Password:') 327 # A=SFTPtools(rserver='',ruser='',rpasswd='',path='/tmp/Log',filename='sftp') 328 # A.connectSFtp() 329 # A.lsSFtp('/tmp/') 330 # A.pwdSFtp() 331 # A.cdSFtp('/tmp/') 332 # A.getSFtp(['test.png','test.spl'],'/tmp/test1') 333 # A.mgetSFtp('/tmp/test2') 334 # A.byeSFtp() 335 ######################################################## 336