/circuits/io/notify.py
https://bitbucket.org/prologic/circuits/ · Python · 106 lines · 80 code · 19 blank · 7 comment · 13 complexity · c47c8df4001ba5a785315768a5af65e6 MD5 · raw file
- # Module: notify
- # Date: 2nd March 2009
- # Author: James Mills, prologic at shortcircuit dot net dot au
- """File Notification Support
- A Component wrapping the inotify API using the pyinotify library.
- """
- try:
- from pyinotify import IN_UNMOUNT
- from pyinotify import WatchManager, Notifier, ALL_EVENTS
- from pyinotify import IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE
- from pyinotify import IN_CREATE, IN_DELETE, IN_DELETE_SELF, IN_MOVE_SELF
- from pyinotify import IN_CLOSE_NOWRITE, IN_OPEN, IN_MOVED_FROM, IN_MOVED_TO
- except ImportError:
- raise Exception("No pyinotify support available. Is pyinotify installed?")
- from circuits.core.utils import findcmp
- from circuits.core import handler, BaseComponent
- from circuits.core.pollers import BasePoller, Poller
- from .events import accessed, closed, created, deleted, modified, moved, opened, ready, unmounted
- MASK = ALL_EVENTS
- EVENT_MAP = {
- IN_MOVED_TO: moved,
- IN_MOVE_SELF: moved,
- IN_MOVED_FROM: moved,
- IN_CLOSE_WRITE: closed,
- IN_CLOSE_NOWRITE: closed,
- IN_OPEN: opened,
- IN_DELETE_SELF: deleted,
- IN_DELETE: deleted,
- IN_CREATE: created,
- IN_ACCESS: accessed,
- IN_MODIFY: modified,
- IN_ATTRIB: modified,
- IN_UNMOUNT: unmounted,
- }
- class Notify(BaseComponent):
- channel = "notify"
- def __init__(self, channel=channel):
- super(Notify, self).__init__(channel=channel)
- self._poller = None
- self._wm = WatchManager()
- self._notifier = Notifier(self._wm, self._on_process_events)
- def _on_process_events(self, event):
- dir = event.dir
- mask = event.mask
- path = event.path
- name = event.name
- pathname = event.pathname
- for k, v in EVENT_MAP.items():
- if mask & k:
- self.fire(v(name, path, pathname, dir))
- def add_path(self, path, mask=None, recursive=False):
- mask = mask or MASK
- self._wm.add_watch(path, mask, rec=recursive)
- def remove_path(self, path, recursive=False):
- wd = self._wm.get_wd(path)
- if wd:
- self._wm.rm_watch(wd, rec=recursive)
- @handler("ready")
- def _on_ready(self, component):
- self._poller.addReader(self, self._notifier._fd)
- @handler("registered", channel="*")
- def _on_registered(self, component, manager):
- if self._poller is None:
- if isinstance(component, BasePoller):
- self._poller = component
- self.fire(ready(self))
- else:
- if component is not self:
- return
- component = findcmp(self.root, BasePoller)
- if component is not None:
- self._poller = component
- self.fire(ready(self))
- else:
- self._poller = Poller().register(self)
- self.fire(ready(self))
- @handler("started", channel="*", priority=1)
- def _on_started(self, event, component):
- if self._poller is None:
- self._poller = Poller().register(self)
- self.fire(ready(self))
- event.stop()
- @handler("_read", priority=1)
- def __on_read(self, fd):
- self._notifier.read_events()
- self._notifier.process_events()