#!/usr/bin/env python
# Copyright (c) 2007-2011 Arastra, Inc.  All rights reserved.
# Arastra, Inc. Confidential and Proprietary.

import pty, os, select, sys, time, optparse

op = optparse.OptionParser( usage="%prog [OPTIONS] DIRECTORY" )
op.add_option( "-c", "--command", action="store",
               help="run COMMAND when anything in DIRECTORY changes" )
op.add_option( "--ratelimit", action="store", type="float", metavar="PERIOD",
               help="run COMMAND at most once every PERIOD seconds " \
                  "(default=%default)" )
op.add_option( "-d", "--daemon", action="store_true",
               help="daemonize and return immediately" )
op.add_option( "--logfile", action="store",
               help="write output to LOGFILE (default=%default)" )
op.add_option( "--pidfile", action="store",
               help="write process ID to PIDFILE (default=%default)" )
op.add_option( "--debug", action="store_true",
               help="show inotifywait output" )
op.set_defaults( period=0 )
opts, args = op.parse_args()

if len( args ) != 1:
   op.error( "expected one argument" )

dir = args[0]

if opts.daemon:
   if os.fork() != 0:
      sys.exit()
   os.setsid()
   if os.fork() != 0:
      os._exit( 0 )
   os.umask( 0 )

os.close( 0 )
os.open( "/dev/null", os.O_RDONLY )
if opts.logfile:
   os.close( 1 )
   os.close( 2 )
   os.open( opts.logfile, os.O_RDWR | os.O_CREAT | os.O_APPEND )
   os.dup( 1 )

if opts.pidfile:
   file( opts.pidfile, "w" ).write( "%d\n" % os.getpid() )

os.chdir( dir )
pid, fd = pty.fork()
if pid == 0:
   x = [ "inotifywait", "-m", "-r", "-e", "modify", "-e", "create",
         "-e", "delete", "-e", "attrib", "-e", "move", "." ]
   os.execvp( x[0], x )
else:
   while True:
      if opts.command:
         os.spawnvp( os.P_WAIT, "sh", ["sh", "-c", opts.command] )
      select.select( [fd], [], [] )
      time.sleep( opts.period )
      try:
         while fd in select.select( [fd], [], [], 0 )[0]:
            x = os.read( fd, 1024 )
            if opts.debug:
               sys.stdout.write( x )
               sys.stdout.flush()
      except OSError: break

sys.exit( os.waitpid( pid, 0 )[1] )
