PYTHON 11
Gamin.py Guest on 3rd October 2020 02:56:19 PM
  1. #!/usr/bin/env python
  2.  
  3. import _gamin
  4. import os.path
  5.  
  6. has_debug_api = 0
  7. if _gamin.__dict__.has_key("MonitorDebug"):
  8.     has_debug_api = 1
  9.    
  10. #
  11. # the type of events provided in the callbacks.
  12. #
  13. GAMChanged=1
  14. GAMDeleted=2
  15. GAMStartExecuting=3
  16. GAMStopExecuting=4
  17. GAMCreated=5
  18. GAMMoved=6
  19. GAMAcknowledge=7
  20. GAMExists=8
  21. GAMEndExist=9
  22.  
  23. #
  24. # The Gamin Errno values
  25. GAM_OK =     0
  26. GAM_ARG=     1 # Bad arguments
  27. GAM_FILE=    2 # Bad filename
  28. GAM_CONNECT= 3 # Connection failure
  29. GAM_AUTH=    4 # Authentication failure
  30. GAM_MEM=     5 # Memory allocation
  31. GAM_UNIMPLEM=6 # Unimplemented
  32. GAM_INTR=    7 # Interrupted system call
  33.  
  34. def GaminErrno():
  35.     return _gamin.Errno()
  36.  
  37. def GaminErrmsg(err = None):
  38.     if err == None:
  39.         err = _gamin.Errno()
  40.     if err == GAM_ARG:
  41.         msg = "bad argument error"
  42.     elif err == GAM_FILE:
  43.         msg = "filename error"
  44.     elif err == GAM_CONNECT:
  45.         msg = "connection error"
  46.     elif err == GAM_AUTH:
  47.         msg = "authentication error"
  48.     elif err == GAM_MEM:
  49.         msg = "memory allocation error"
  50.     elif err == GAM_UNIMPLEM:
  51.         msg = "unimplemented part error"
  52.     elif err == GAM_INTR:
  53.         msg = "interrupted system call"
  54.     else:
  55.         msg = ""
  56.     return msg
  57.  
  58. class GaminException(Exception):
  59.     def __init__(self, value):
  60.         Exception.__init__(self)
  61.         self.value = value
  62.         self.errno = GaminErrno()
  63.  
  64.     def __str__(self):
  65.         str = GaminErrmsg(self.errno)
  66.         if str != "":
  67.             return repr(self.value) + ': ' + str
  68.         return repr(self.value)
  69.  
  70. class WatchMonitor:
  71.     """This is a wrapper for a FAM connection. It uses a single connection
  72.       to the gamin server, over a socket. Use get_fd() to get the file
  73.       descriptor which allows to plug it in an usual event loop. The
  74.       watch_directory(), watch_file() and stop_watch() are direct mapping
  75.       to the FAM API. The event raised are also a direct mapping of the
  76.       FAM API events."""
  77.  
  78.     class WatchObject:
  79.         def __init__ (self, monitor, mon_no, path, dir, callback, data=None):
  80.             self.monitor = monitor
  81.             self.callback = callback
  82.             self.data = data
  83.             self.path = path
  84.             self.__mon_no = mon_no
  85.             if dir == 1:
  86.                 ret = _gamin.MonitorDirectory(self.__mon_no, path, self);
  87.                 if ret < 0:
  88.                     raise(GaminException("Failed to monitor directory %s" %
  89.                                          (path)))
  90.             elif dir == 0:
  91.                 ret = _gamin.MonitorFile(self.__mon_no, path, self);
  92.                 if ret < 0:
  93.                     raise(GaminException("Failed to monitor file %s" %
  94.                                          (path)))
  95.             elif dir == -1:
  96.                 ret = _gamin.MonitorDebug(self.__mon_no, path, self);
  97.                 if ret < 0:
  98.                     raise(GaminException("Failed to debug %s" %
  99.                                          (path)))
  100.             self.__req_no = ret
  101.  
  102.         def _internal_callback(self, path, event):
  103.             # it is very important here to catch all exception which may
  104.             # arise in the client callback code.
  105.             try:
  106.                 if self.data != None:
  107.                     self.callback (path, event, self.data)
  108.                 else:
  109.                     self.callback (path, event)
  110.             except:
  111.                 import traceback
  112.                 traceback.print_exc()
  113.  
  114.             if event == GAMAcknowledge:
  115.                 try:
  116.                     self.monitor.cancelled.remove(self)
  117.                 except:
  118.                     print "gamin failed to remove from cancelled"
  119.                     pass
  120.  
  121.         def cancel(self):
  122.             ret = _gamin.MonitorCancel(self.__mon_no, self.__req_no);
  123.             if ret < 0:
  124.                 raise(GaminException("Failed to stop monitor on %s" %
  125.                                      (self.path)))
  126.             try:
  127.                 self.monitor.cancelled.append(self)
  128.             except:
  129.                 print "gamin cancel() failed to add to cancelled"
  130.  
  131.     def __init__ (self):
  132.         self.__no = _gamin.MonitorConnect()
  133.         if self.__no < 0:
  134.             raise(GaminException("Failed to connect to gam_server"))
  135.         self.objects = {}
  136.         self.__fd = _gamin.GetFd(self.__no)
  137.         if self.__fd < 0:
  138.             _gamin.MonitorClose(self.__no)
  139.             raise(GaminException("Failed to get file descriptor"))
  140.         self.cancelled = []
  141.  
  142.     def __del__ (self):
  143.         self.disconnect()
  144.    
  145.     def __raise_disconnected():
  146.         raise(GaminException("Already disconnected"))
  147.        
  148.     def _debug_object(self, value, callback, data = None):
  149.         if has_debug_api == 0:
  150.             return;
  151.  
  152.         if (self.__no < 0):
  153.             self.__raise_disconnected();
  154.         obj = self.WatchObject(self, self.__no, value, -1, callback, data)
  155.         # persistency need to be insured
  156.         self.objects["debug"] = obj
  157.         return obj
  158.  
  159.     def disconnect(self):
  160.         if (self.__no >= 0):
  161.             _gamin.MonitorClose(self.__no)
  162.         self.__no = -1;
  163.  
  164.     def watch_directory(self, directory, callback, data = None):
  165.         if (self.__no < 0):
  166.             self.__raise_disconnected();
  167.         directory = os.path.abspath(directory)
  168.  
  169.         obj = self.WatchObject(self, self.__no, directory, 1, callback, data)
  170.         if self.objects.has_key(directory):
  171.             self.objects[directory].append(obj)
  172.         else:
  173.             self.objects[directory] = [obj]
  174.         return obj
  175.  
  176.     def watch_file(self, file, callback, data = None):
  177.         if (self.__no < 0):
  178.             self.__raise_disconnected();
  179.         file = os.path.abspath(file)
  180.  
  181.         obj = self.WatchObject(self, self.__no, file, 0, callback, data)
  182.         if self.objects.has_key(file):
  183.             self.objects[file].append(obj)
  184.         else:
  185.             self.objects[file] = [obj]
  186.         return obj
  187.  
  188.     def no_exists(self):
  189.         if (self.__no < 0):
  190.             return
  191.         ret = _gamin.MonitorNoExists(self.__no)
  192.         return ret
  193.  
  194.     def stop_watch(self, path):
  195.         if (self.__no < 0):
  196.             return
  197.         path = os.path.abspath(path)
  198.         try:
  199.             list = self.objects[path]
  200.         except:
  201.             raise(GaminException("Resource %s is not monitored" % (path)))
  202.         for obj in list:
  203.             obj.cancel()
  204.         self.objects[path] = []
  205.        
  206.     def get_fd(self):
  207.         if (self.__no < 0):
  208.             self.__raise_disconnected();
  209.         return self.__fd
  210.  
  211.     def event_pending(self):
  212.         if (self.__no < 0):
  213.             self.__raise_disconnected();
  214.         ret = _gamin.EventPending(self.__no);
  215.         if ret < 0:
  216.             raise(GaminException("Failed to check pending events"))
  217.         return ret
  218.  
  219.     def handle_one_event(self):
  220.         if (self.__no < 0):
  221.             self.__raise_disconnected();
  222.         ret = _gamin.ProcessOneEvent(self.__no);
  223.         if ret < 0:
  224.             raise(GaminException("Failed to process one event"))
  225.         return ret
  226.  
  227.     def handle_events(self):
  228.         if (self.__no < 0):
  229.             self.__raise_disconnected();
  230.         ret = _gamin.ProcessEvents(self.__no);
  231.         if ret < 0:
  232.             raise(GaminException("Failed to process events"))
  233.         return ret
  234.  
  235. def run_unit_tests():
  236.     def callback(path, event):
  237.         print "Got callback: %s, %s" % (path, event)
  238.     mon = WatchMonitor()
  239.     print "watching current directory"
  240.     mon.watch_directory(".", callback)
  241.     import time
  242.     time.sleep(1)
  243.     print "fd: ", mon.get_fd()
  244.     ret = mon.event_pending()
  245.     print "pending: ", ret
  246.     if ret > 0:
  247.         ret = mon.handle_one_event()
  248.         print "processed %d event" % (ret)
  249.         ret = mon.handle_events()
  250.         print "processed %d remaining events" % (ret)
  251.     print "stop watching current directory"
  252.     mon.stop_watch(".")
  253.     print "disconnecting"
  254.     del mon
  255.  
  256. if __name__ == '__main__':
  257.     run_unit_tests()

Paste is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.