Module inotifyx
[hide private]
[frames] | no frames]

Source Code for Module inotifyx

  1  # Copyright (c) 2005 Manuel Amador <rudd-o@rudd-o.com> 
  2  # Copyright (c) 2009 Forest Bond <forest@alittletooquiet.net> 
  3  # 
  4  # Permission is hereby granted, free of charge, to any person obtaining a 
  5  # copy of this software and associated documentation files (the "Software"), 
  6  # to deal in the Software without restriction, including without limitation 
  7  # the rights to use, copy, modify, merge, publish, distribute, sublicense, 
  8  # and/or sell copies of the Software, and to permit persons to whom the 
  9  # Software is furnished to do so, subject to the following conditions: 
 10  # 
 11  # The above copyright notice and this permission notice shall be included in 
 12  # all copies or substantial portions of the Software. 
 13  # 
 14  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 15  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 16  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 17  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 18  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 19  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 20  # DEALINGS IN THE SOFTWARE. 
 21   
 22  ''' 
 23  inotifyx is a simple Python binding to the Linux inotify file system event 
 24  monitoring API. 
 25   
 26  Generally, usage is as follows: 
 27   
 28  >>> fd = init() 
 29  >>> try: 
 30  ...     wd = add_watch(fd, '/path', IN_ALL_EVENTS) 
 31  ...     events = get_events(fd) 
 32  ...     rm_watch(fd, wd) 
 33  ... finally: 
 34  ...     os.close(fd) 
 35  ''' 
 36   
 37  import os, select 
 38   
 39  import _inotifyx 
 40   
 41   
 42  constants = {} 
 43   
 44  for name in dir(_inotifyx): 
 45      if name.startswith('IN_'): 
 46          globals()[name] = constants[name] = getattr(_inotifyx, name) 
 47   
 48   
 49  init = _inotifyx.init 
 50  rm_watch = _inotifyx.rm_watch 
 51  add_watch = _inotifyx.add_watch 
 52   
 53   
54 -class InotifyEvent(object):
55 ''' 56 InotifyEvent(wd, mask, cookie, name) 57 58 A representation of the inotify_event structure. See the inotify 59 documentation for a description of these fields. 60 ''' 61 62 wd = None 63 mask = None 64 cookie = None 65 name = None 66
67 - def __init__(self, wd, mask, cookie, name):
68 self.wd = wd 69 self.mask = mask 70 self.cookie = cookie 71 self.name = name
72
73 - def __str__(self):
74 return '%s: %s' % (self.wd, self.get_mask_description())
75
76 - def __repr__(self):
77 return '%s(%s, %s, %s, %s)' % ( 78 self.__class__.__name__, 79 repr(self.wd), 80 repr(self.mask), 81 repr(self.cookie), 82 repr(self.name), 83 )
84
85 - def get_mask_description(self):
86 ''' 87 Return an ASCII string describing the mask field in terms of 88 bitwise-or'd IN_* constants, or 0. The result is valid Python code 89 that could be eval'd to get the value of the mask field. In other 90 words, for a given event: 91 92 >>> from inotifyx import * 93 >>> assert (event.mask == eval(event.get_mask_description())) 94 ''' 95 96 parts = [] 97 for name, value in constants.items(): 98 if self.mask & value: 99 parts.append(name) 100 if parts: 101 return '|'.join(parts) 102 return '0'
103 104
105 -def get_events(fd, *args):
106 ''' 107 get_events(fd[, timeout]) 108 109 Return a list of InotifyEvent instances representing events read from 110 inotify. If timeout is None, this will block forever until at least one 111 event can be read. Otherwise, timeout should be an integer or float 112 specifying a timeout in seconds. If get_events times out waiting for 113 events, an empty list will be returned. If timeout is zero, get_events 114 will not block. 115 ''' 116 return [ 117 InotifyEvent(wd, mask, cookie, name) 118 for wd, mask, cookie, name in _inotifyx.get_events(fd, *args) 119 ]
120 121 122 if __name__ == '__main__': 123 import sys 124 125 if len(sys.argv) == 1: 126 print >>sys.stderr, 'usage: inotify path [path ...]' 127 sys.exit(1) 128 129 paths = sys.argv[1:] 130 131 fd = init() 132 133 wd_to_path = {} 134 135 try: 136 for path in paths: 137 wd = add_watch(fd, path) 138 wd_to_path[wd] = path 139 140 try: 141 while True: 142 events = get_events(fd) 143 for event in events: 144 path = wd_to_path[event.wd] 145 parts = [event.get_mask_description()] 146 if event.name: 147 parts.append(event.name) 148 print '%s: %s' % (path, ' '.join(parts)) 149 except KeyboardInterrupt: 150 pass 151 152 finally: 153 os.close(fd) 154