Commits

Evaggelos Balaskas committed 7a6b8c1

Rewrite code for duplicate inode events, using python dictionary, Added option to run PIryncD in foreground, Added code for mirroring in first run, without looking inode events.

Comments (0)

Files changed (4)

+@Sat Jul 24 12:27:28 EEST 2010
+
+Rewrite code for duplicate inode events, using python dictionary
+
+Added option to run PIryncD in foreground
+
+Added code for mirroring in first run, without looking inode events.
+
+Scoring 7.35 with pylint (better code styling)
+
+Redifind global variables (errors may occured, plz notify me).
+
 @Fri Mar 26 00:29:25 EET 2010
 
 Added Counter variable for inode events (not from command line)
 #!/usr/bin/env python
+
 """
 PIrsyncD stands for: Python Inotify Rsync Daemon
 Copyright Evaggelos Balaskas, ebalaskas AT ebalaskas DOT gr (2009, 2010)
     sys.exit(1)
 
 # Version of PIrsyncD
-VERSION = "20100326"
+VERSION = "20100724"
 
 # Default Directories (Source & Destination Folder Paths)
 SOURCE_PATH = "/tmp/data/"
 RSYNC_V2     = False
 RSYNC_LOG    = "/tmp/.PIrsyncD.log"
 DEBUG_LOG    = "/tmp/.PIrsyncDebug"
+FOREGROUND	 = False
 MAX_SIZE     = ""
 MIN_SIZE     = ""
 
 FREQ = 0
 # You can configure PIrsyncD to run every N inode events, be carefull!
 INODES = COUNTER = 3
-PRE_EVENT = ""
+# Dictionary varialbe to store files & events
+EVENTS = {}
+
+FIRST_TIME = True
 
 # Usage message for help
 USAGE_MSG = "usage: pirsyncd [ -s <source> ] [ -d <destination> ] \
 [ --debug=debug_log ] [ --nodebug ] [ --rsync_append ] [ --rsync_v2 ] \n\t\t\
 [ --host=dest_server ] [ --rsync_daemon=rsync_daemon \
 --rsync_pass_file=rsync_pass_file ]\n\t\t[ --max_size ] [ --min_size ] \
-[ -h <help> ] [ -v <version>] [-k stop/status]"
+[ -h <help> ] [ -F <foreground> ] [ -v <version>] [-k stop/status]"
 
 # Example messages for help
 EXAMPLE_MSG = """
 
 ./PIrsyncD -k status
 
+./PIrsyncD -f
+
 ./PIrsyncD -p /tmp/.PIrsyncD.pid2
 
 ./PIrsyncD --nodebug --nolog -s /tmp/data3/ -d /tmp/data4/ -p /tmp/.PIrsyncD.pid2
 
 class PTmp(pyinotify.ProcessEvent):
     """ Handles the pyinotify events """
+
     def process_default(self, event):
         """ Default procudure is to debug and sychronize """
-        global PRE_EVENT
-        cur_event = event.maskname + event.pathname.replace("/", "_")
-        if cur_event.strip() != PRE_EVENT:
+        
+        # Dont rsync for duplicates events!
+        if (EVENTS.get(event.pathname.replace("/", "_")) != event.maskname):
+            EVENTS [ event.pathname.replace("/", "_") ] = event.maskname
+            cur_event = event.maskname + event.pathname.replace("/", "_")
             # Debugging
             logging.debug('PIrsyncD: ' + cur_event)
             # Synchronization
             mirror()
-        PRE_EVENT = cur_event.strip()
 
 def getarguments():
     """ Getting user arguments """
         const="/dev/null",
         dest="RSYNC_LOG",
         help="Disable rsync logging")
+    parser.add_option("-f", "--foreground",
+        action="store_true",
+        default="False",
+        dest="FOREGROUND",
+        help="Dont put the PIrsyncD in background")
     parser.add_option("--debug",
         action="store",
         type="string",
 
 def mirror():
     """ This is the part that runs rsync """
+    
+    global COUNTER, FIRST_TIME
     # Rsync command debugging
-    global COUNTER
-    logging.debug('PIrsyncD: ' + RSYNC_COMMAND)
+    if FIRST_TIME:
+        COUNTER = 0
+        FIRST_TIME = False
     if ( COUNTER == 0 ) :
-        COUNTER = INODES + 1
         # Run rsync !
         try:
             retcode = subprocess.call(RSYNC_COMMAND, shell=True)
                 print "Child was terminated by signal", -retcode
         except OSError, ose:
             print "Execution failed: ", ose
+        logging.debug('PIrsyncD: ' + RSYNC_COMMAND)
+        COUNTER = INODES - 1 
+        logging.debug("COUNTER: " + str(COUNTER))
     else :
         COUNTER -= 1 
         logging.debug("COUNTER: " + str(COUNTER))
 def pirsyncd():
     """ Configuration of RSYNC_COMMAND upon user arguments & 
         watching for Kernel Inotify Events on source folder """
-    # Declare global variables
-    global RSYNC_COMMAND, RSYNC_ARGS, COUNTER
 
+    global COUNTER, RSYNC_ARGS, RSYNC_COMMAND
     # Configuration settings are in order
     if check_config():
         if ( RSYNC_APPEND != 'False' ):
         print "PIrsyncD is starting, waiting for daemonization..."
         # Try to mirror for the first time, 
         # perhaps inotify events never occurs to watched directory
-        COUNTER = COUNTER + 1
+        COUNTER += 1
         mirror()
         # monitor for events
         wmg = pyinotify.WatchManager()
             wmg.add_watch(SOURCE_PATH, mask, rec=True, auto_add=True)
         except pyinotify.WatchManagerError, err:
             print err, err.wmd
-        print "daemonizing\ntry ./PIrsyncD -k status to see the running PID."
+
         # Daemonize PIrsyncD
-        notifier.loop(daemonize=True, pid_file=PIDFILE)
+        if ( FOREGROUND != 'False' ):
+            print "Daemon is ready! PIrsyncD runs in foreground (ctrl + c) \
+to stop the daemon)\n\n"
+			# Daemonize in foreground
+            notifier.loop ( pid_file = PIDFILE )
+        else:
+            print "Daemon is ready! PIryncD runs in background\ntry \
+./PIrsyncD -k status to see the running PID.\n"
+            # Daemonize in background
+            notifier.loop(daemonize=True, pid_file=PIDFILE)
+
     # Configuration Settings arent in order, print this information message
     else:
         print "Please check your configuration settings. Try this: \
 
 def main( options = getarguments() ):
     """ Declaration variables with user arguments """
-    global SOURCE_PATH, DEST_PATH, RSYNC_PATH, DEST_SERVER, RSYNC_LOG, \
-MAX_SIZE, MIN_SIZE, DEBUG_LOG, RSYNC_APPEND, RSYNC_V2, RSYNC_DAEMON, \
-RSYNC_PASS_FILE, PIDFILE
+    
+    global FOREGROUND, RSYNC_APPEND, RSYNC_LOG, DEST_SERVER, DEBUG_LOG, \
+SOURCE_PATH, RSYNC_PASS_FILE, RSYNC_V2, RSYNC_PATH, MIN_SIZE, RSYNC_DAEMON, \
+PIDFILE, PIDFILE, MAX_SIZE, DEST_PATH
 
     # Re-Define variables
     SOURCE_PATH     = options.SOURCE_PATH
     RSYNC_PASS_FILE = options.RSYNC_PASS_FILE
     RSYNC_PATH      = options.RSYNC_PATH
     RSYNC_LOG       = options.RSYNC_LOG
+    FOREGROUND		= options.FOREGROUND
     MAX_SIZE        = options.MAX_SIZE
     MIN_SIZE        = options.MIN_SIZE
     DEBUG_LOG       = options.DEBUG_LOG
 #!/usr/bin/env python
+
 """
 PIrsyncD stands for: Python Inotify Rsync Daemon
 Copyright Evaggelos Balaskas, ebalaskas AT ebalaskas DOT gr (2009, 2010)
     sys.exit(1)
 
 # Version of PIrsyncD
-VERSION = "20100326"
+VERSION = "20100724"
 
 # Default Directories (Source & Destination Folder Paths)
 SOURCE_PATH = "/tmp/data/"
 RSYNC_V2     = False
 RSYNC_LOG    = "/tmp/.PIrsyncD.log"
 DEBUG_LOG    = "/tmp/.PIrsyncDebug"
+FOREGROUND	 = False
 MAX_SIZE     = ""
 MIN_SIZE     = ""
 
 # Read Events after n seconds. Value 0 (zero) is for immediately read
 FREQ = 0
 # You can configure PIrsyncD to run every N inode events, be carefull!
-INODES = COUNTER = 0
-PRE_EVENT = ""
+INODES = COUNTER = 3
+# Dictionary varialbe to store files & events
+EVENTS = {}
+
+FIRST_TIME = True
 
 # Usage message for help
 USAGE_MSG = "usage: pirsyncd [ -s <source> ] [ -d <destination> ] \
 [ --debug=debug_log ] [ --nodebug ] [ --rsync_append ] [ --rsync_v2 ] \n\t\t\
 [ --host=dest_server ] [ --rsync_daemon=rsync_daemon \
 --rsync_pass_file=rsync_pass_file ]\n\t\t[ --max_size ] [ --min_size ] \
-[ -h <help> ] [ -v <version>] [-k stop/status]"
+[ -h <help> ] [ -F <foreground> ] [ -v <version>] [-k stop/status]"
 
 # Example messages for help
 EXAMPLE_MSG = """
 
 ./PIrsyncD -k status
 
+./PIrsyncD -f
+
 ./PIrsyncD -p /tmp/.PIrsyncD.pid2
 
 ./PIrsyncD --nodebug --nolog -s /tmp/data3/ -d /tmp/data4/ -p /tmp/.PIrsyncD.pid2
 
 class PTmp(pyinotify.ProcessEvent):
     """ Handles the pyinotify events """
+
     def process_default(self, event):
         """ Default procudure is to debug and sychronize """
-        global PRE_EVENT
-        cur_event = event.maskname + event.pathname.replace("/", "_")
-        if cur_event.strip() != PRE_EVENT:
+        
+        # Dont rsync for duplicates events!
+        if (EVENTS.get(event.pathname.replace("/", "_")) != event.maskname):
+            EVENTS [ event.pathname.replace("/", "_") ] = event.maskname
+            cur_event = event.maskname + event.pathname.replace("/", "_")
             # Debugging
             logging.debug('PIrsyncD: ' + cur_event)
             # Synchronization
             mirror()
-        PRE_EVENT = cur_event.strip()
 
 def getarguments():
     """ Getting user arguments """
         const="/dev/null",
         dest="RSYNC_LOG",
         help="Disable rsync logging")
+    parser.add_option("-f", "--foreground",
+        action="store_true",
+        default="False",
+        dest="FOREGROUND",
+        help="Dont put the PIrsyncD in background")
     parser.add_option("--debug",
         action="store",
         type="string",
 
 def mirror():
     """ This is the part that runs rsync """
+    
+    global COUNTER, FIRST_TIME
     # Rsync command debugging
-    global COUNTER
-    logging.debug('PIrsyncD: ' + RSYNC_COMMAND)
+    if FIRST_TIME:
+        COUNTER = 0
+        FIRST_TIME = False
     if ( COUNTER == 0 ) :
-        COUNTER = INODES + 1
         # Run rsync !
         try:
             retcode = subprocess.call(RSYNC_COMMAND, shell=True)
                 print("Child was terminated by signal", -retcode)
         except OSError as ose:
             print("Execution failed: ", ose)
+        logging.debug('PIrsyncD: ' + RSYNC_COMMAND)
+        COUNTER = INODES - 1 
+        logging.debug("COUNTER: " + str(COUNTER))
     else :
-        COUNTER = COUNTER - 1 
+        COUNTER -= 1 
         logging.debug("COUNTER: " + str(COUNTER))
 
 def pirsyncd():
     """ Configuration of RSYNC_COMMAND upon user arguments & 
         watching for Kernel Inotify Events on source folder """
-    # Declare global variables
-    global RSYNC_COMMAND, RSYNC_ARGS, RSYNC_APPEND, RSYNC_V2, COUNTER
 
+    global COUNTER, RSYNC_ARGS, RSYNC_COMMAND
+    
     # Configuration settings are in order
     if check_config():
         if ( RSYNC_APPEND != 'False' ):
         print("PIrsyncD is starting, waiting for daemonization...")
         # Try to mirror for the first time, 
         # perhaps inotify events never occurs to watched directory
-        COUNTER = COUNTER + 1
+        COUNTER += 1
         mirror()
         # monitor for events
         wmg = pyinotify.WatchManager()
             wmg.add_watch(SOURCE_PATH, mask, rec=True, auto_add=True)
         except pyinotify.WatchManagerError as err:
             print(err, err.wmd)
-        print("daemonizing\ntry ./PIrsyncD -k status to see the running PID.")
+
         # Daemonize PIrsyncD
-        notifier.loop(daemonize=True, pid_file=PIDFILE)
+        if ( FOREGROUND != 'False' ):
+            print("Daemon is ready! PIrsyncD runs in foreground (ctrl + c) \
+to stop the daemon)\n\n")
+			# Daemonize in foreground
+            notifier.loop ( pid_file = PIDFILE )
+        else:
+            print("Daemon is ready! PIryncD runs in background\ntry \
+./PIrsyncD -k status to see the running PID.\n")
+            # Daemonize in background
+            notifier.loop(daemonize=True, pid_file=PIDFILE)
+
     # Configuration Settings arent in order, print this information message
     else:
         print("Please check your configuration settings. Try this: \
 
 def main( options = getarguments() ):
     """ Declaration variables with user arguments """
-    global SOURCE_PATH, DEST_PATH, RSYNC_PATH, DEST_SERVER, RSYNC_LOG, \
-MAX_SIZE, MIN_SIZE, DEBUG_LOG, RSYNC_APPEND, RSYNC_V2, RSYNC_DAEMON, \
-RSYNC_PASS_FILE, PIDFILE
+    
+    global FOREGROUND, RSYNC_APPEND, RSYNC_LOG, DEST_SERVER, DEBUG_LOG, \
+SOURCE_PATH, RSYNC_PASS_FILE, RSYNC_V2, RSYNC_PATH, MIN_SIZE, RSYNC_DAEMON, \
+PIDFILE, DEST_PATH, MAX_SIZE
 
     # Re-Define variables
     SOURCE_PATH     = options.SOURCE_PATH
     RSYNC_PASS_FILE = options.RSYNC_PASS_FILE
     RSYNC_PATH      = options.RSYNC_PATH
     RSYNC_LOG       = options.RSYNC_LOG
+    FOREGROUND		= options.FOREGROUND
     MAX_SIZE        = options.MAX_SIZE
     MIN_SIZE        = options.MIN_SIZE
     DEBUG_LOG       = options.DEBUG_LOG
 01: exclude patterns
 
 02: Init Script
+
+03: Packaging