import argparse
import sys
import time
import logging
import os
import shutil
import time
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
class EventHandler(LoggingEventHandler):
def __init__(self, dest, max_retries, retry_sleep):
self.dest = dest
self.max_retries = max_retries
self.retry_sleep = retry_sleep
#def on_moved(self, event):
# super(LoggingEventHandler, self).on_moved(event)
# logging.info("Moved %s: from %s to %s", what, event.src_path, event.dest_path)
def on_created(self, event):
super(LoggingEventHandler, self).on_created(event)
logging.info("Created %s: %s", self.what(event), event.src_path)
self.copy_file(event.src_path)
#def on_deleted(self, event):
# super(LoggingEventHandler, self).on_deleted(event)
# logging.info("Deleted %s: %s", self.what(event), event.src_path)
#def on_modified(self, event):
# super(LoggingEventHandler, self).on_modified(event)
# logging.info("Modified %s: %s", self.what(event), event.src_path)
def what(self, event):
return 'directory' if event.is_directory else 'file'
def copy_file(self, path, attempt=1):
try:
destination_filename=os.path.join(self.dest, os.path.basename(path))
logging.debug("Copying %s to %s" % (path, destination_filename))
shutil.copyfile(path, destination_filename)
except PermissionError:
if (attempt > self.max_retries):
raise
logging.warn("Attempt %d/%d: file locked - might still be getting written" % (attempt, self.max_retries))
time.sleep(self.retry_sleep)
self.copy_file(path, attempt+1)
except:
logging.error("Unexpected error:", sys.exc_info()[0])
def move_file(self, path, attempt=1):
try:
logging.debug("Moving %s to %s" % (path, self.dest))
shutil.move(path, self.dest)
except PermissionError:
if (attempt > self.max_retries):
raise
logging.warn("Attempt %d/%d: file locked - might still be getting written" % (attempt, self.max_retries))
time.sleep(self.retry_sleep)
self.move_file(path, attempt+1)
except:
logging.error("Unexpected error:", sys.exc_info()[0])
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='File System Watcher')
parser.add_argument('-s', '--source', type=str, help='Source path', required=True)
parser.add_argument('-d', '--dest', type=str, help='Destination path', required=True)
parser.add_argument('-r', '--retries', type=int, help='Maximum retry attempts', default=12)
parser.add_argument('-z', '--retry-sleep', dest='retry_sleep', type=int, help='Retry sleep time', default=5)
args = parser.parse_args()
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
event_handler = EventHandler(args.dest, args.retries, args.retry_sleep)
observer = Observer()
observer.schedule(event_handler, args.source, recursive=True)
observer.start()
try:
while True:
time.sleep(5)
except KeyboardInterrupt:
observer.stop()
observer.join()