-
Notifications
You must be signed in to change notification settings - Fork 378
Handling Events
Niko Ehrenfeuchter edited this page Jun 30, 2015
·
6 revisions
We can subclass ProcessEvent
and provide our own event handler by defining appropriate methods. See the commented example below:
import pyinotify
class MyEventHandler(pyinotify.ProcessEvent):
def my_init(self, file_object=sys.stdout):
"""
This is your constructor it is automatically called from
ProcessEvent.__init__(), And extra arguments passed to __init__() would
be delegated automatically to my_init().
"""
self._file_object = file_object
def process_IN_DELETE(self, event):
"""
This method processes a specific type of event: IN_DELETE. event
is an instance of Event.
"""
self._file_object.write('deleting: %s\n' % event.pathname)
def process_IN_CLOSE(self, event):
"""
This method is called on these events: IN_CLOSE_WRITE and
IN_CLOSE_NOWRITE.
"""
self._file_object.write('closing: %s\n' % event.pathname)
def process_default(self, event):
"""
Eventually, this method is called for all others types of events.
This method can be useful when an action fits all events.
"""
self._file_object.write('default processing\n')
# A way to instantiate this class could be:
p = MyEventHandler(file('/tmp/output', 'w'))
Explanations and details:
-
IN_DELETE
has a specific method. An individual processing method is provided by a method whose the name is written with a specific syntax:process_EVENT_NAME
whereEVENT_NAME
is the name of the current event to process. - Related events most of the time need the same treatment. In those cases shared methods can be defined avoiding duplicating chunks of codes. Like for instance for those two following related events:
mask = pyinotify.IN_CLOSE_WRITE | pyinotify.IN_CLOSE_NOWRITE
It is enough to implement a method named process_IN_CLOSE
(according to pattern process_IN_FAMILYBASENAME
) to handle both types of events. Beware though, not to also implement process_IN_CLOSE_WRITE
or process_IN_CLOSE_NOWRITE
, because if defined these methods would have an higher precedence (see below) over process_IN_CLOSE
and the latter would not be called.
-
ALL_EVENTS
isn't an event by itself, it is the aggregation of all events codes, that means that you can't implement the methodprocess_ALL_EVENTS
. - If we need to apply a single treatment whatever the kind of event received or if we need to have a fall back method for unexpected events, we just need to implement process_default which is the default method.
- Processing methods lookup's order (by increasing order of priority): specialized methods (eg:
process_IN_CLOSE_WRITE
) first, then family methods (eg:process_IN_CLOSE
), finally default methodprocess_default
. - One more thing: say you redefine the method process_default which contains the instruction
os.ismount(my-mount-point)
, it would be for example a mistake having this method called for every eventIN_OPEN
occurring on/etc
. Because, one particularity ofos.ismount
is to check in/etc/mtab
if the partition is mounted, in this case it would lead to an endless situation:process_IN_OPEN
called,/etc/mtab
opened,process_IN_OPEN
called,/etc/mtab
opened... looping forever.
Whenever possible you should process your notifications this way:
notifier = pyinotify.Notifier(wm, MyEventHandler())
But, some watches may need a different kind of processing, you can attach them a specialized instance which will be called only on their associated watch:
wm.add_watch('/one/path', pyinotify.ALL_EVENTS, proc_fun=MyEventHandler())