#!/usr/bin/env python
import time
import logging
import subprocess as sp

from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler


EXCLUDES = '*.pyc;*.git*;*.hg*;*ve/*;*build/*;'


class RsyncEventHandler(PatternMatchingEventHandler):
    """
    rsyncs on any event
    """

    def __init__(self, src, dest, exclude_from, callback, *args, **kwargs):
        self.src = src
        self.dest = dest
        self.exclude_from = exclude_from
        self.callback = callback
        super(RsyncEventHandler, self).__init__(*args, **kwargs)

    def on_any_event(self, event):
        if event.src_path.endswith('.py'):
            if event.event_type in ['modified', 'created']:
                logging.info(event)
                ex = ' --exclude-from="%s"' % self.exclude_from if self.exclude_from else ''
                cmd = """rsync -avP%s --delete %s %s""" % (ex, self.src, self.dest)
                logging.info(cmd)
                sp.check_call(cmd, shell=True)
                if self.callback:
                    logging.info('running callback:' + self.callback)
                    sp.check_call(self.callback, shell=True)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s  %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')

    import argparse

    p = argparse.ArgumentParser()
    p.add_argument('src')
    p.add_argument('dest')
    p.add_argument('-x', '--exclude_from', help='a file containing patterns to exclude from.  Passed to rsyncs `exclude-from` argument.', default=None)
    p.add_argument('-p', '--patterns', help='semi-colon separated list of patterns that trigger an rsync (default is `*.py`)', default='*.py')
    p.add_argument('-c', '--callback',
                   help="Executes this string after each rsync.  For example, if you're on a mac, you can play a sound with: "
                        "`-c 'afplay /System/Library/Sounds/Morse.aiff'`")
    args = p.parse_args()

    event_handler = RsyncEventHandler(args.src, args.dest, args.exclude_from, args.callback, patterns=args.patterns)
    observer = Observer()
    observer.schedule(event_handler, args.src, recursive=True)
    observer.start()
    logging.info('Sync started')
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()
