Guest User

Untitled

a guest
Dec 11th, 2017
353
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.75 KB | None | 0 0
  1. #!/home/juvenal/.pythonenv/bin/python
  2. import pyinotify
  3. import asyncore
  4. import os, sys, time
  5. import paramiko
  6. import pathutils
  7. import yaml
  8.  
  9.  
  10. class EventHandler(pyinotify.ProcessEvent):
  11. def process_IN_CLOSE_WRITE(self, event):
  12. filename = event.name
  13. filepath = event.path
  14. fullpath = event.pathname
  15. print "Closed:", event.pathname
  16.  
  17. remote_path = Remote_Path_From_Local_Path(fullpath)
  18.  
  19. #open SSH
  20. ssh = SSH_Connect(ActiveConfig.host,ActiveConfig.user,port=ActiveConfig.port)
  21. if not ssh:
  22. print "Aborting, no SSH Connection!"
  23. return False
  24. #create remote directory for file transfer
  25. if not SSH_Create_Directory(ssh, os.path.dirname(remote_path), parent=True):
  26. print "Aboring, failed to create remote directory!"
  27. return False
  28. #send file
  29. if not SSH_Send_File(ssh, fullpath, remote_path):
  30. print "Aborting, file failed to transfer!"
  31. return False
  32. print "Done! %s transfered to %s sucessfully!" % (filename, ActiveConfig.host)
  33. ssh.close()
  34.  
  35. #remote_path = os.path.relpath(os.path.dirname(event.pathname), os.path.expanduser('~/Downloads'))
  36. #cmd = "rsync -vrzh --progress --chmod=Dugo+rx,u+wr,g+wr,o+r -e 'ssh -p 222' '%s' titansync@hs.juvsoft.com:'\"%s/\"'" % (event.pathname, remote_path)
  37. #args = shlex.split(cmd)
  38. #print args
  39. #subprocess.Popen(shlex.split("ssh -p 222 titansync@hs.juvsoft.com mkdir -p '\"%s\"'" % (remote_path,)), stdout=os.sys.stdout)
  40. #p = subprocess.Popen(args, stdout=os.sys.stdout, stderr=os.sys.stderr)
  41.  
  42.  
  43. def SSH_Connect(host, user, port=22, password=None):
  44. ssh = paramiko.SSHClient()
  45. ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
  46. ssh.set_missing_host_key_policy(paramiko.WarningPolicy())
  47. try:
  48. ssh.connect(host, username=user, port=port, password=password)
  49. except paramiko.AuthenticationException:
  50. print "Could not login to remote server, please check your keys!"
  51. return False
  52. except:
  53. print "Could not connect to remote server, unknown reason!"
  54. return False
  55. return ssh
  56.  
  57. def SSH_Create_Directory(SSHClient, directory, parent=False):
  58. pstr = ''
  59. if parent: pstr='--parents'
  60. command = "mkdir -v %s '%s'" % (pstr, directory)
  61. stdin, stdout, stderr = SSHClient.exec_command(command)
  62. s_out = stdout.readlines()
  63. s_err = stderr.readlines()
  64. if s_err:
  65. print "Error creating directory:"
  66. for l in s_err:
  67. print l
  68. return False
  69. if s_out:
  70. for l in s_out:
  71. print l
  72. return True
  73. if not s_out and not s_err:
  74. print "Nothing returned!"
  75. return False
  76.  
  77. def SSH_Send_File(SSHClient, localpath, remotepath, callback=None):
  78. _start_time = [time.time()]
  79. def _callback(done, total):
  80. t = time.time()
  81. t = (t-_start_time[0])
  82. prog = '%s of %s - %i%s - %s/s' % (pathutils.formatbytes(done),pathutils.formatbytes(total), (done * 100)/total, "%", pathutils.formatbytes(done/t))
  83. print prog, ' ', '\r',
  84. sys.stdout.flush()
  85.  
  86. if not callback:
  87. callback = _callback
  88. try:
  89. sftp = SSHClient.open_sftp()
  90. sftp.put(localpath, remotepath, callback)
  91. return True
  92. except:
  93. print "Unknown Error while sending file via sftp"
  94. return False
  95.  
  96. def Remote_Path_From_Local_Path(local_path):
  97. head = local_path
  98. tail = ' '
  99. while tail is not '':
  100. head,tail = os.path.split(head)
  101. #print head, tail
  102. for Dir in ActiveConfig.Dirs:
  103. if os.path.samefile(Dir.local_path, head):
  104. return os.path.join(Dir.remote_path, os.path.relpath(local_path, head))
  105.  
  106. class ScanDir(object):
  107. def __init__(self, name, conf_dict):
  108. self.name = name
  109. self.local_path = ''
  110. self.auto_add = False
  111. self.recursive = False
  112. self.remote_path = ''
  113.  
  114. for attr in ('local_path','remote_path'):
  115. if not attr in conf_dict:
  116. print "Config Error! %s ScanDir does not have required attribute %s" % (self.name, attr)
  117. return
  118. setattr(self, attr, conf_dict[attr])
  119. for attr in ('auto_add', 'recursive'):
  120. if attr in conf_dict:
  121. setattr(self, attr, conf_dict[attr])
  122. self.local_path = os.path.expanduser(self.local_path)
  123. def __repr__(self):
  124. return "<ScanDir %s Local:%s Remote:%s R:%s A:%s>" % (self.name, self.local_path, self.remote_path, self.recursive, self.auto_add)
  125.  
  126. class ActiveConfig(object):
  127. Dirs=[]
  128. WD={}
  129. mask = pyinotify.IN_CLOSE_WRITE | pyinotify.IN_CREATE
  130. wm = pyinotify.WatchManager()
  131. notifier = pyinotify.AsyncNotifier(wm, EventHandler())
  132.  
  133. def ParseConfig(filename):
  134. config = yaml.load(open(filename, 'r'))
  135. for attr in ('directories', 'remote_host'):
  136. if not attr in config:
  137. print "Config Error! %s is missing from root of config file %, it is required!" % (attr, filename)
  138. return False
  139. if not isinstance(config[attr], dict):
  140. print "Config Error! %s is not of the correct type! %s" % (attr, filename)
  141. return False
  142. dirlist = config['directories']
  143. remote_host = config['remote_host']
  144. for dirname, dirconf in dirlist.iteritems():
  145. d = ScanDir(dirname, dirconf)
  146. ActiveConfig.Dirs.append(d)
  147. for attr in ('host', 'user'):
  148. if not attr in remote_host:
  149. print "Config Error! %s is missing from remote_host section in %s" % (attr, filename)
  150. return False
  151. for key, val in remote_host.iteritems():
  152. setattr(ActiveConfig, key, val)
  153.  
  154. def AddWatches():
  155. for SDir in ActiveConfig.Dirs:
  156. if not os.path.isdir(SDir.local_path):
  157. print "Path specified in %s not found! %s" % (SDir.name, SDir.local_path)
  158. return False
  159. wdd = ActiveConfig.wm.add_watch(SDir.local_path, ActiveConfig.mask, rec=SDir.recursive, auto_add=SDir.auto_add)
  160. return True
  161.  
  162. if __name__ == "__main__":
  163. ParseConfig('config.yml')
  164. AddWatches()
  165. asyncore.loop()
Add Comment
Please, Sign In to add comment