pyinotify/0000700000175000017500000000000011273645207012127 5ustar ookoiookoipyinotify/TODO0000644000175000017500000000012311247476555012636 0ustar ookoiookoi- Optionally store watchs in a DB to reduce memory footprint - Convert to Python 3 pyinotify/examples/0000755000175000017500000000000011273644725013763 5ustar ookoiookoipyinotify/examples/daemon.py0000644000175000017500000000044011270710713015562 0ustar ookoiookoi# Example: daemonize pyinotify's notifier. # import pyinotify wm = pyinotify.WatchManager() notifier = pyinotify.Notifier(wm) wm.add_watch('/tmp', pyinotify.ALL_EVENTS) notifier.loop(daemonize=True, pid_file='/tmp/pyinotify.pid', force_kill=True, stdout='/tmp/stdout.txt') pyinotify/examples/not_quiet.py0000644000175000017500000000150211270711601016323 0ustar ookoiookoi# Example: raise exceptions on errors. # # Overrides default behavior and raise exception on add_watch, update_watch # or rm_watch errors. import pyinotify wm = pyinotify.WatchManager() # default behavior, don't complain but keep trace of error in log and result r = wm.add_watch(['/tmp', '/tmp-do-not-exist'], pyinotify.ALL_EVENTS) print r # quiet=False raise exception try: wm.add_watch(['/tmp', '/tmp-do-not-exist'], pyinotify.ALL_EVENTS, quiet=False) except pyinotify.WatchManagerError, err: print err, err.wmd # quiet=False raise exception try: wm.update_watch(42, mask=0x42, quiet=False) except pyinotify.WatchManagerError, err: print err, err.wmd # quiet=False raise exception try: wm.rm_watch(42, quiet=False) except pyinotify.WatchManagerError, err: print err, err.wmd pyinotify/examples/loop.py0000644000175000017500000000027311270711065015275 0ustar ookoiookoi# Example: loops monitoring events forever. # import pyinotify wm = pyinotify.WatchManager() notifier = pyinotify.Notifier(wm) wm.add_watch('/tmp', pyinotify.ALL_EVENTS) notifier.loop() pyinotify/examples/transient_file.py0000644000175000017500000000171011270711424017326 0ustar ookoiookoi# Example: monitors transient files. # # Run this code, then run transient_file.sh in another shell. from pyinotify import * class ProcessTransientFile(ProcessEvent): def process_IN_MODIFY(self, event): # We have explicitely registered for this kind of event. print '\t', event.pathname, ' -> written' def process_default(self, event): # Implicitely IN_CREATE and IN_DELATE are watched too. You can # ignore them and provide an empty process_default or you can # process them, either with process_default or their dedicated # method (process_IN_CREATE, process_IN_DELETE) which would # override process_default. print 'default: ', event.maskname wm = WatchManager() notifier = Notifier(wm) # In this case you must give the class object (ProcessTransientFile) # as last parameter not a class instance. wm.watch_transient_file('/tmp/test1234', IN_MODIFY, ProcessTransientFile) notifier.loop() pyinotify/examples/stats.py0000644000175000017500000000134311270711276015465 0ustar ookoiookoi# Example: prints statistics. # from pyinotify import * class Identity(ProcessEvent): def process_default(self, event): # Does nothing, just to demonstrate how stuffs could trivially # be accomplished after having processed statistics. print 'Does nothing.' def on_loop(notifier): # notifier.proc_fun() is Identity's instance s_inst = notifier.proc_fun().nested_pevent() print repr(s_inst), '\n', s_inst, '\n' wm = WatchManager() # Stats is a subclass of ProcessEvent provided by pyinotify # for computing basics statistics. s = Stats() notifier = Notifier(wm, default_proc_fun=Identity(s), read_freq=5) wm.add_watch('/tmp/', ALL_EVENTS, rec=True, auto_add=True) notifier.loop(callback=on_loop) pyinotify/examples/chain.py0000644000175000017500000000220611270710647015411 0ustar ookoiookoi# Example: monitors events and logs them into a log file. # from pyinotify import * class Log(ProcessEvent): def my_init(self, fileobj): """ Method automatically called from ProcessEvent.__init__(). Additional keyworded arguments passed to ProcessEvent.__init__() are then delegated to my_init(). This is the case for fileobj. """ self._fileobj = fileobj def process_default(self, event): self._fileobj.write(str(event) + '\n') self._fileobj.flush() class TrackModifications(ProcessEvent): def process_IN_MODIFY(self, event): print 'IN_MODIFY' class Empty(ProcessEvent): def my_init(self, msg): self._msg = msg def process_default(self, event): print self._msg #log.setLevel(10) fo = file('/var/log/pyinotify_log', 'w') wm = WatchManager() # It is important to pass named extra arguments like 'fileobj'. notifier = Notifier(wm, default_proc_fun=Empty(TrackModifications(Log(fileobj=fo)), msg='outtee chained function')) wm.add_watch('/tmp', ALL_EVENTS) notifier.loop() fo.close() pyinotify/examples/exclude.py0000644000175000017500000000140211270711032015742 0ustar ookoiookoi# Example: excludes items from being monitored. # import pyinotify import os excl_file = os.path.join(os.getcwd(), 'exclude.patterns') wm = pyinotify.WatchManager() notifier = pyinotify.Notifier(wm) ### Method 1: # Exclude filter object excl = pyinotify.ExcludeFilter({excl_file: ('excl_lst1', 'excl_lst2')}) # Add watches wm.add_watch(['/etc/*', '/var'], pyinotify.ALL_EVENTS, rec=True, do_glob=True, exclude_filter=excl) ### Method 2 (Equivalent) wm.add_watch('/etc/*', pyinotify.ALL_EVENTS, rec=True, do_glob=True, exclude_filter=pyinotify.ExcludeFilter({excl_file:('excl_lst1',)})) wm.add_watch('/var', pyinotify.ALL_EVENTS, rec=True, exclude_filter=pyinotify.ExcludeFilter({excl_file:('excl_lst2',)})) notifier.loop() pyinotify/examples/tutorial_notifier.py0000644000175000017500000000110311070155230020051 0ustar ookoiookoi# Notifier example from tutorial # # See: http://trac.dbzteam.org/pyinotify/wiki/Tutorial # from pyinotify import WatchManager, Notifier, \ ThreadedNotifier, ProcessEvent, IN_DELETE, \ IN_CREATE wm = WatchManager() # Watch Manager mask = IN_DELETE | IN_CREATE # watched events class PTmp(ProcessEvent): def process_IN_CREATE(self, event): print "Creating:", event.pathname def process_IN_DELETE(self, event): print "Removing:", event.pathname p = PTmp() notifier = Notifier(wm, p) wdd = wm.add_watch('/tmp', mask, rec=True) notifier.loop() pyinotify/examples/tutorial_threadednotifier.py0000644000175000017500000000122111070155204021554 0ustar ookoiookoi# ThreadedNotifier example from tutorial # # See: http://trac.dbzteam.org/pyinotify/wiki/Tutorial # from pyinotify import WatchManager, Notifier, \ ThreadedNotifier, ProcessEvent, IN_DELETE, \ IN_CREATE, log wm = WatchManager() # Watch Manager mask = IN_DELETE | IN_CREATE # watched events class PTmp(ProcessEvent): def process_IN_CREATE(self, event): print "Creating:", event.pathname def process_IN_DELETE(self, event): print "Removing:", event.pathname #log.setLevel(10) notifier = ThreadedNotifier(wm, PTmp()) notifier.start() wdd = wm.add_watch('/tmp', mask, rec=True) wm.rm_watch(wdd.values()) notifier.stop() pyinotify/examples/stats_threaded.py0000644000175000017500000000237511270711340017323 0ustar ookoiookoi# Example: prints statistics (threaded version). # import time from pyinotify import * # Do the same thing than stats.py but with a ThreadedNotifier's # instance. # This example illustrates the use of this class but the recommanded # implementation is whom of stats.py class Identity(ProcessEvent): def process_default(self, event): # Does nothing, just to demonstrate how stuffs could be done # after having processed statistics. print 'Does nothing.' # Thread #1 wm1 = WatchManager() s1 = Stats() # Stats is a subclass of ProcessEvent notifier1 = ThreadedNotifier(wm1, default_proc_fun=Identity(s1)) notifier1.start() wm1.add_watch('/tmp/', ALL_EVENTS, rec=True, auto_add=True) # Thread #2 wm2 = WatchManager() s2 = Stats() # Stats is a subclass of ProcessEvent notifier2 = ThreadedNotifier(wm2, default_proc_fun=Identity(s2)) notifier2.start() wm2.add_watch('/var/log/', ALL_EVENTS, rec=False, auto_add=False) while True: try: print "Thread 1", repr(s1) print s1 print "Thread 2", repr(s2) print s2 print time.sleep(5) except KeyboardInterrupt: notifier1.stop() notifier2.stop() break except: notifier1.stop() notifier2.stop() raise pyinotify/examples/transient_file.sh0000755000175000017500000000020211042100442017273 0ustar ookoiookoi#!/bin/bash for a in 1 2 3 4 5 6 7 8 9 10 do touch /tmp/test1234; echo -ne "42" > /tmp/test1234; rm -f /tmp/test1234; done pyinotify/examples/unicode.py0000644000175000017500000000057711212363723015761 0ustar ookoiookoi# -*- coding: utf-8 -*- import os import sys from pyinotify import * # create path #path = u'/tmp/test\u0444' path = '/tmp/testф' path = unicode(path, sys.getfilesystemencoding()) if not os.path.isdir(path): os.mkdir(path) log.setLevel(10) wm = WatchManager() notifier = Notifier(wm) wdd = wm.add_watch(path, IN_OPEN) wm.update_watch(wdd[path], ALL_EVENTS) notifier.loop() pyinotify/examples/exclude.patterns0000644000175000017500000000070111245321544017162 0ustar ookoiookoi# -*- mode: python; -*- # Patterns can use unrestricted regexps (see re module) # regexps are matched against submitted paths through match() excl_lst1 = ['^/etc/apache[2]?/', '^/etc/rc.*', '^/etc/hostname', '^/etc/hosts', '^/etc/(fs|m)tab', '^/etc/cron\..*'] excl_lst2 = ['^/var/log/.*', '^/var/www/.*', '^/var/cache/.*', '^/var/spool/.*'] pyinotify/examples/tutorial_asyncnotifier.py0000644000175000017500000000114411236556235021132 0ustar ookoiookoi# AsyncNotifier example from tutorial # # See: http://trac.dbzteam.org/pyinotify/wiki/Tutorial # from pyinotify import WatchManager, AsyncNotifier, \ ThreadedNotifier, ProcessEvent, IN_DELETE, \ IN_CREATE import asyncore wm = WatchManager() # Watch Manager mask = IN_DELETE | IN_CREATE # watched events class PTmp(ProcessEvent): def process_IN_CREATE(self, event): print "Creating:", event.pathname def process_IN_DELETE(self, event): print "Removing:", event.pathname p = PTmp() notifier = AsyncNotifier(wm, p) wdd = wm.add_watch('/tmp', mask, rec=True) asyncore.loop() pyinotify/examples/autocompile.py0000755000175000017500000000320411270624552016651 0ustar ookoiookoi#!/usr/bin/env python # # Usage: # ./autocompile.py path ext1,ext2,extn cmd # # Blocks monitoring |path| and its subdirectories for modifications on # files ending with suffix |extk|. Run |cmd| each time a modification # is detected. |cmd| is optional and defaults to 'make'. # # Example: # ./autocompile.py /my-latex-document-dir .tex,.bib "make pdf" # # Dependancies: # Linux, Python 2.6, Pyinotify # import subprocess import sys import pyinotify class OnWriteHandler(pyinotify.ProcessEvent): def my_init(self, cwd, extension, cmd): self.cwd = cwd self.extensions = extension.split(',') self.cmd = cmd def _run_cmd(self): print '==> Modification detected' subprocess.call(self.cmd.split(' '), cwd=self.cwd) def process_IN_MODIFY(self, event): if all(not event.pathname.endswith(ext) for ext in self.extensions): return self._run_cmd() def auto_compile(path, extension, cmd): wm = pyinotify.WatchManager() handler = OnWriteHandler(cwd=path, extension=extension, cmd=cmd) notifier = pyinotify.Notifier(wm, default_proc_fun=handler) wm.add_watch(path, pyinotify.ALL_EVENTS, rec=True, auto_add=True) print '==> Start monitoring %s (type c^c to exit)' % path notifier.loop() if __name__ == '__main__': if len(sys.argv) < 3: print >> sys.stderr, "Command line error: missing argument(s)." sys.exit(1) # Required arguments path = sys.argv[1] extension = sys.argv[2] # Optional argument cmd = 'make' if len(sys.argv) == 4: cmd = sys.argv[3] # Blocks monitoring auto_compile(path, extension, cmd) pyinotify/setup.py0000755000175000017500000000234611273643535013665 0ustar ookoiookoi#!/usr/bin/env python # check Python's version import sys if sys.version < '2.4': sys.stderr.write('This module requires Python 2.4 or later.\n') sys.exit(1) # import statements from distutils.core import setup, Extension from distutils.util import get_platform # debug DISTUTILS_DEBUG = True # get platform platform = get_platform() # check linux platform if not platform.startswith('linux'): raise Exception, "inotify is not available under %s" % platform classif=[ 'Environment :: Console', 'Intended Audience :: Developers', 'License :: OSI Approved :: GNU General Public License (GPL)', 'Natural Language :: English', 'Operating System :: POSIX :: Linux', 'Programming Language :: Python', 'Topic :: Software Development :: Libraries', 'Topic :: System :: Monitoring' ] setup( name='pyinotify', version='0.8.8', description='Linux filesystem events monitoring', author='Sebastien Martini', author_email='sebastien.martini@gmail.com', license='GPLv2+', platforms='Linux', classifiers=classif, url='http://trac.dbzteam.org/pyinotify', download_url='http://seb.dbzteam.org/pub/pyinotify/releases/pyinotify-0.8.8.tar.gz', py_modules=['pyinotify'], ) pyinotify/Makefile0000644000175000017500000000037211247476770013613 0ustar ookoiookoiEPYDOC=epydoc DSTDOC=docstrings doc: clean-doc $(EPYDOC) --html --graph=all -v -o $(DSTDOC) pyinotify.py clean-doc: rm -rf $(DSTDOC) clean: clean-doc find . \( -name '*~' -or \ -name '*.pyc' -or \ -name '*.pyo' \) \ -print -exec rm {} \; pyinotify/pyinotify.py0000755000175000017500000022374011273643470014560 0ustar ookoiookoi#!/usr/bin/env python # -*- coding: iso-8859-1 -*- # # pyinotify.py - python interface to inotify # Copyright (C) Sebastien Martini # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. """ pyinotify @author: Sebastien Martini @license: GPLv2+ @contact: seb@dbzteam.org """ class PyinotifyError(Exception): """Indicates exceptions raised by a Pyinotify class.""" pass class UnsupportedPythonVersionError(PyinotifyError): """ Raised on unsupported Python versions. """ def __init__(self, version): """ @param version: Current Python version @type version: string """ PyinotifyError.__init__(self, ('Python %s is unsupported, requires ' 'at least Python 2.4') % version) class UnsupportedLibcVersionError(PyinotifyError): """ Raised on unsupported libc versions. """ def __init__(self, version): """ @param version: Current Libc version @type version: string """ PyinotifyError.__init__(self, ('Libc %s is not supported, requires ' 'at least Libc 2.4') % version) # Check Python version import sys if sys.version < '2.4': raise UnsupportedPythonVersionError(sys.version) # Import directives import threading import os import select import struct import fcntl import errno import termios import array import logging import atexit from collections import deque from datetime import datetime, timedelta import time import fnmatch import re import ctypes import ctypes.util import asyncore __author__ = "seb@dbzteam.org (Sebastien Martini)" __version__ = "0.8.8" __metaclass__ = type # Use new-style classes by default # Compatibity mode: set to True to improve compatibility with # Pyinotify 0.7.1. Do not set this variable yourself, call the # function compatibility_mode() instead. COMPATIBILITY_MODE = False # Load libc LIBC = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c')) # The libc version > 2.4 check. # XXX: Maybe it is better to check if the libc has the needed functions inside? # Because there are inotify patches for libc 2.3.6. LIBC.gnu_get_libc_version.restype = ctypes.c_char_p LIBC_VERSION = LIBC.gnu_get_libc_version() if (int(LIBC_VERSION.split('.')[0]) < 2 or (int(LIBC_VERSION.split('.')[0]) == 2 and int(LIBC_VERSION.split('.')[1]) < 4)): raise UnsupportedLibcVersionError(LIBC_VERSION) class PyinotifyLogger(logging.Logger): """ Pyinotify logger used for logging unicode strings. """ def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None): rv = UnicodeLogRecord(name, level, fn, lno, msg, args, exc_info, func) if extra is not None: for key in extra: if (key in ["message", "asctime"]) or (key in rv.__dict__): raise KeyError("Attempt to overwrite %r in LogRecord" % key) rv.__dict__[key] = extra[key] return rv class UnicodeLogRecord(logging.LogRecord): def __init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None): py_version = sys.version_info # func argument was added in Python 2.5, just ignore it otherwise. if py_version[0] >= 2 and py_version[1] >= 5: logging.LogRecord.__init__(self, name, level, pathname, lineno, msg, args, exc_info, func) else: logging.LogRecord.__init__(self, name, level, pathname, lineno, msg, args, exc_info) def getMessage(self): msg = self.msg if not isinstance(msg, (unicode, str)): try: msg = str(self.msg) except UnicodeError: pass if self.args: if isinstance(self.args, tuple): def str_to_unicode(s): """Return unicode string.""" if not isinstance(s, str): return s return unicode(s, sys.getfilesystemencoding()) args = tuple([str_to_unicode(m) for m in self.args]) else: args = self.args msg = msg % args if not isinstance(msg, unicode): msg = unicode(msg, sys.getfilesystemencoding()) return msg # Logging def logger_init(): """Initialize logger instance.""" logging.setLoggerClass(PyinotifyLogger) log = logging.getLogger("pyinotify") console_handler = logging.StreamHandler() console_handler.setFormatter( logging.Formatter("[Pyinotify %(levelname)s] %(message)s")) log.addHandler(console_handler) log.setLevel(20) return log log = logger_init() ### inotify's variables ### class SysCtlINotify: """ Access (read, write) inotify's variables through sysctl. Usually it requires administrator rights to update them. Examples: - Read max_queued_events attribute: myvar = max_queued_events.value - Update max_queued_events attribute: max_queued_events.value = 42 """ inotify_attrs = {'max_user_instances': 1, 'max_user_watches': 2, 'max_queued_events': 3} def __init__(self, attrname): sino = ctypes.c_int * 3 self._attrname = attrname self._attr = sino(5, 20, SysCtlINotify.inotify_attrs[attrname]) def get_val(self): """ Gets attribute's value. @return: stored value. @rtype: int """ oldv = ctypes.c_int(0) size = ctypes.c_int(ctypes.sizeof(oldv)) LIBC.sysctl(self._attr, 3, ctypes.c_voidp(ctypes.addressof(oldv)), ctypes.addressof(size), None, 0) return oldv.value def set_val(self, nval): """ Sets new attribute's value. @param nval: replaces current value by nval. @type nval: int """ oldv = ctypes.c_int(0) sizeo = ctypes.c_int(ctypes.sizeof(oldv)) newv = ctypes.c_int(nval) sizen = ctypes.c_int(ctypes.sizeof(newv)) LIBC.sysctl(self._attr, 3, ctypes.c_voidp(ctypes.addressof(oldv)), ctypes.addressof(sizeo), ctypes.c_voidp(ctypes.addressof(newv)), ctypes.addressof(sizen)) value = property(get_val, set_val) def __repr__(self): return '<%s=%d>' % (self._attrname, self.get_val()) # Singleton instances # # read: myvar = max_queued_events.value # update: max_queued_events.value = 42 # for attrname in ('max_queued_events', 'max_user_instances', 'max_user_watches'): globals()[attrname] = SysCtlINotify(attrname) ### iglob ### # Code taken from standart Python Lib, slightly modified in order to work # with pyinotify (don't exclude dotted files/dirs like .foo). # Original version: # @see: http://svn.python.org/projects/python/trunk/Lib/glob.py def iglob(pathname): if not has_magic(pathname): if hasattr(os.path, 'lexists'): if os.path.lexists(pathname): yield pathname else: if os.path.islink(pathname) or os.path.exists(pathname): yield pathname return dirname, basename = os.path.split(pathname) # relative pathname if not dirname: return # absolute pathname if has_magic(dirname): dirs = iglob(dirname) else: dirs = [dirname] if has_magic(basename): glob_in_dir = glob1 else: glob_in_dir = glob0 for dirname in dirs: for name in glob_in_dir(dirname, basename): yield os.path.join(dirname, name) def glob1(dirname, pattern): if not dirname: dirname = os.curdir try: names = os.listdir(dirname) except os.error: return [] return fnmatch.filter(names, pattern) def glob0(dirname, basename): if basename == '' and os.path.isdir(dirname): # `os.path.split()` returns an empty basename for paths ending with a # directory separator. 'q*x/' should match only directories. return [basename] if hasattr(os.path, 'lexists'): if os.path.lexists(os.path.join(dirname, basename)): return [basename] else: if (os.path.islink(os.path.join(dirname, basename)) or os.path.exists(os.path.join(dirname, basename))): return [basename] return [] MAGIC_CHECK = re.compile('[*?[]') def has_magic(s): return MAGIC_CHECK.search(s) is not None ### Core ### class EventsCodes: """ Set of codes corresponding to each kind of events. Some of these flags are used to communicate with inotify, whereas the others are sent to userspace by inotify notifying some events. @cvar IN_ACCESS: File was accessed. @type IN_ACCESS: int @cvar IN_MODIFY: File was modified. @type IN_MODIFY: int @cvar IN_ATTRIB: Metadata changed. @type IN_ATTRIB: int @cvar IN_CLOSE_WRITE: Writtable file was closed. @type IN_CLOSE_WRITE: int @cvar IN_CLOSE_NOWRITE: Unwrittable file closed. @type IN_CLOSE_NOWRITE: int @cvar IN_OPEN: File was opened. @type IN_OPEN: int @cvar IN_MOVED_FROM: File was moved from X. @type IN_MOVED_FROM: int @cvar IN_MOVED_TO: File was moved to Y. @type IN_MOVED_TO: int @cvar IN_CREATE: Subfile was created. @type IN_CREATE: int @cvar IN_DELETE: Subfile was deleted. @type IN_DELETE: int @cvar IN_DELETE_SELF: Self (watched item itself) was deleted. @type IN_DELETE_SELF: int @cvar IN_MOVE_SELF: Self (watched item itself) was moved. @type IN_MOVE_SELF: int @cvar IN_UNMOUNT: Backing fs was unmounted. @type IN_UNMOUNT: int @cvar IN_Q_OVERFLOW: Event queued overflowed. @type IN_Q_OVERFLOW: int @cvar IN_IGNORED: File was ignored. @type IN_IGNORED: int @cvar IN_ONLYDIR: only watch the path if it is a directory (new in kernel 2.6.15). @type IN_ONLYDIR: int @cvar IN_DONT_FOLLOW: don't follow a symlink (new in kernel 2.6.15). IN_ONLYDIR we can make sure that we don't watch the target of symlinks. @type IN_DONT_FOLLOW: int @cvar IN_MASK_ADD: add to the mask of an already existing watch (new in kernel 2.6.14). @type IN_MASK_ADD: int @cvar IN_ISDIR: Event occurred against dir. @type IN_ISDIR: int @cvar IN_ONESHOT: Only send event once. @type IN_ONESHOT: int @cvar ALL_EVENTS: Alias for considering all of the events. @type ALL_EVENTS: int """ # The idea here is 'configuration-as-code' - this way, we get our nice class # constants, but we also get nice human-friendly text mappings to do lookups # against as well, for free: FLAG_COLLECTIONS = {'OP_FLAGS': { 'IN_ACCESS' : 0x00000001, # File was accessed 'IN_MODIFY' : 0x00000002, # File was modified 'IN_ATTRIB' : 0x00000004, # Metadata changed 'IN_CLOSE_WRITE' : 0x00000008, # Writable file was closed 'IN_CLOSE_NOWRITE' : 0x00000010, # Unwritable file closed 'IN_OPEN' : 0x00000020, # File was opened 'IN_MOVED_FROM' : 0x00000040, # File was moved from X 'IN_MOVED_TO' : 0x00000080, # File was moved to Y 'IN_CREATE' : 0x00000100, # Subfile was created 'IN_DELETE' : 0x00000200, # Subfile was deleted 'IN_DELETE_SELF' : 0x00000400, # Self (watched item itself) # was deleted 'IN_MOVE_SELF' : 0x00000800, # Self (watched item itself) was moved }, 'EVENT_FLAGS': { 'IN_UNMOUNT' : 0x00002000, # Backing fs was unmounted 'IN_Q_OVERFLOW' : 0x00004000, # Event queued overflowed 'IN_IGNORED' : 0x00008000, # File was ignored }, 'SPECIAL_FLAGS': { 'IN_ONLYDIR' : 0x01000000, # only watch the path if it is a # directory 'IN_DONT_FOLLOW' : 0x02000000, # don't follow a symlink 'IN_MASK_ADD' : 0x20000000, # add to the mask of an already # existing watch 'IN_ISDIR' : 0x40000000, # event occurred against dir 'IN_ONESHOT' : 0x80000000, # only send event once }, } def maskname(mask): """ Returns the event name associated to mask. IN_ISDIR is appended to the result when appropriate. Note: only one event is returned, because only one event can be raised at a given time. @param mask: mask. @type mask: int @return: event name. @rtype: str """ ms = mask name = '%s' if mask & IN_ISDIR: ms = mask - IN_ISDIR name = '%s|IN_ISDIR' return name % EventsCodes.ALL_VALUES[ms] maskname = staticmethod(maskname) # So let's now turn the configuration into code EventsCodes.ALL_FLAGS = {} EventsCodes.ALL_VALUES = {} for flagc, valc in EventsCodes.FLAG_COLLECTIONS.iteritems(): # Make the collections' members directly accessible through the # class dictionary setattr(EventsCodes, flagc, valc) # Collect all the flags under a common umbrella EventsCodes.ALL_FLAGS.update(valc) # Make the individual masks accessible as 'constants' at globals() scope # and masknames accessible by values. for name, val in valc.iteritems(): globals()[name] = val EventsCodes.ALL_VALUES[val] = name # all 'normal' events ALL_EVENTS = reduce(lambda x, y: x | y, EventsCodes.OP_FLAGS.itervalues()) EventsCodes.ALL_FLAGS['ALL_EVENTS'] = ALL_EVENTS EventsCodes.ALL_VALUES[ALL_EVENTS] = 'ALL_EVENTS' class _Event: """ Event structure, represent events raised by the system. This is the base class and should be subclassed. """ def __init__(self, dict_): """ Attach attributes (contained in dict_) to self. @param dict_: Set of attributes. @type dict_: dictionary """ for tpl in dict_.iteritems(): setattr(self, *tpl) def __repr__(self): """ @return: Generic event string representation. @rtype: str """ s = '' for attr, value in sorted(self.__dict__.items(), key=lambda x: x[0]): if attr.startswith('_'): continue if attr == 'mask': value = hex(getattr(self, attr)) elif isinstance(value, basestring) and not value: value = "''" s += ' %s%s%s' % (Color.field_name(attr), Color.punctuation('='), Color.field_value(value)) s = '%s%s%s %s' % (Color.punctuation('<'), Color.class_name(self.__class__.__name__), s, Color.punctuation('>')) return s class _RawEvent(_Event): """ Raw event, it contains only the informations provided by the system. It doesn't infer anything. """ def __init__(self, wd, mask, cookie, name): """ @param wd: Watch Descriptor. @type wd: int @param mask: Bitmask of events. @type mask: int @param cookie: Cookie. @type cookie: int @param name: Basename of the file or directory against which the event was raised in case where the watched directory is the parent directory. None if the event was raised on the watched item itself. @type name: string or None """ # name: remove trailing '\0' super(_RawEvent, self).__init__({'wd': wd, 'mask': mask, 'cookie': cookie, 'name': name.rstrip('\0')}) log.debug(repr(self)) class Event(_Event): """ This class contains all the useful informations about the observed event. However, the presence of each field is not guaranteed and depends on the type of event. In effect, some fields are irrelevant for some kind of event (for example 'cookie' is meaningless for IN_CREATE whereas it is mandatory for IN_MOVE_TO). The possible fields are: - wd (int): Watch Descriptor. - mask (int): Mask. - maskname (str): Readable event name. - path (str): path of the file or directory being watched. - name (str): Basename of the file or directory against which the event was raised in case where the watched directory is the parent directory. None if the event was raised on the watched item itself. This field is always provided even if the string is ''. - pathname (str): Concatenation of 'path' and 'name'. - src_pathname (str): Only present for IN_MOVED_TO events and only in the case where IN_MOVED_FROM events are watched too. Holds the source pathname from where pathname was moved from. - cookie (int): Cookie. - dir (bool): True if the event was raised against a directory. """ def __init__(self, raw): """ Concretely, this is the raw event plus inferred infos. """ _Event.__init__(self, raw) self.maskname = EventsCodes.maskname(self.mask) if COMPATIBILITY_MODE: self.event_name = self.maskname try: if self.name: self.pathname = os.path.abspath(os.path.join(self.path, self.name)) else: self.pathname = os.path.abspath(self.path) except AttributeError, err: log.error(err) class ProcessEventError(PyinotifyError): """ ProcessEventError Exception. Raised on ProcessEvent error. """ def __init__(self, err): """ @param err: Exception error description. @type err: string """ PyinotifyError.__init__(self, err) class _ProcessEvent: """ Abstract processing event class. """ def __call__(self, event): """ To behave like a functor the object must be callable. This method is a dispatch method. Its lookup order is: 1. process_MASKNAME method 2. process_FAMILY_NAME method 3. otherwise calls process_default @param event: Event to be processed. @type event: Event object @return: By convention when used from the ProcessEvent class: - Returning False or None (default value) means keep on executing next chained functors (see chain.py example). - Returning True instead means do not execute next processing functions. @rtype: bool @raise ProcessEventError: Event object undispatchable, unknown event. """ stripped_mask = event.mask - (event.mask & IN_ISDIR) maskname = EventsCodes.ALL_VALUES.get(stripped_mask) if maskname is None: raise ProcessEventError("Unknown mask 0x%08x" % stripped_mask) # 1- look for process_MASKNAME meth = getattr(self, 'process_' + maskname, None) if meth is not None: return meth(event) # 2- look for process_FAMILY_NAME meth = getattr(self, 'process_IN_' + maskname.split('_')[1], None) if meth is not None: return meth(event) # 3- default call method process_default return self.process_default(event) def __repr__(self): return '<%s>' % self.__class__.__name__ class _SysProcessEvent(_ProcessEvent): """ There is three kind of processing according to each event: 1. special handling (deletion from internal container, bug, ...). 2. default treatment: which is applied to the majority of events. 3. IN_ISDIR is never sent alone, he is piggybacked with a standard event, he is not processed as the others events, instead, its value is captured and appropriately aggregated to dst event. """ def __init__(self, wm, notifier): """ @param wm: Watch Manager. @type wm: WatchManager instance @param notifier: Notifier. @type notifier: Notifier instance """ self._watch_manager = wm # watch manager self._notifier = notifier # notifier self._mv_cookie = {} # {cookie(int): (src_path(str), date), ...} self._mv = {} # {src_path(str): (dst_path(str), date), ...} def cleanup(self): """ Cleanup (delete) old (>1mn) records contained in self._mv_cookie and self._mv. """ date_cur_ = datetime.now() for seq in [self._mv_cookie, self._mv]: for k in seq.keys(): if (date_cur_ - seq[k][1]) > timedelta(minutes=1): log.debug('Cleanup: deleting entry %s', seq[k][0]) del seq[k] def process_IN_CREATE(self, raw_event): """ If the event affects a directory and the auto_add flag of the targetted watch is set to True, a new watch is added on this new directory, with the same attribute values than those of this watch. """ if raw_event.mask & IN_ISDIR: watch_ = self._watch_manager.get_watch(raw_event.wd) if watch_.auto_add: addw = self._watch_manager.add_watch newwd = addw(os.path.join(watch_.path, raw_event.name), watch_.mask, proc_fun=watch_.proc_fun, rec=False, auto_add=watch_.auto_add) # Trick to handle mkdir -p /t1/t2/t3 where t1 is watched and # t2 and t3 are created. # Since the directory is new, then everything inside it # must also be new. base = os.path.join(watch_.path, raw_event.name) if newwd[base] > 0: for name in os.listdir(base): inner = os.path.join(base, name) if (os.path.isdir(inner) and self._watch_manager.get_wd(inner) is None): # Generate (simulate) creation event for sub # directories. rawevent = _RawEvent(newwd[base], IN_CREATE | IN_ISDIR, 0, name) self._notifier.append_event(rawevent) return self.process_default(raw_event) def process_IN_MOVED_FROM(self, raw_event): """ Map the cookie with the source path (+ date for cleaning). """ watch_ = self._watch_manager.get_watch(raw_event.wd) path_ = watch_.path src_path = os.path.normpath(os.path.join(path_, raw_event.name)) self._mv_cookie[raw_event.cookie] = (src_path, datetime.now()) return self.process_default(raw_event, {'cookie': raw_event.cookie}) def process_IN_MOVED_TO(self, raw_event): """ Map the source path with the destination path (+ date for cleaning). """ watch_ = self._watch_manager.get_watch(raw_event.wd) path_ = watch_.path dst_path = os.path.normpath(os.path.join(path_, raw_event.name)) mv_ = self._mv_cookie.get(raw_event.cookie) to_append = {'cookie': raw_event.cookie} if mv_ is not None: self._mv[mv_[0]] = (dst_path, datetime.now()) # Let's assume that IN_MOVED_FROM event is always queued before # that its associated (they share a common cookie) IN_MOVED_TO # event is queued itself. It is then possible in that scenario # to provide as additional information to the IN_MOVED_TO event # the original pathname of the moved file/directory. to_append['src_pathname'] = mv_[0] elif raw_event.mask & IN_ISDIR and watch_.auto_add: # We got a diretory that's "moved in" from an unknown source and # auto_add is enabled. Manually add watches to the inner subtrees. self._watch_manager.add_watch(dst_path, watch_.mask, proc_fun=watch_.proc_fun, rec=True, auto_add=True) return self.process_default(raw_event, to_append) def process_IN_MOVE_SELF(self, raw_event): """ STATUS: the following bug has been fixed in recent kernels (FIXME: which version ?). Now it raises IN_DELETE_SELF instead. Old kernels were bugged, this event raised when the watched item were moved, so we had to update its path, but under some circumstances it was impossible: if its parent directory and its destination directory wasn't watched. The kernel (see include/linux/fsnotify.h) doesn't bring us enough informations like the destination path of moved items. """ watch_ = self._watch_manager.get_watch(raw_event.wd) src_path = watch_.path mv_ = self._mv.get(src_path) if mv_: dest_path = mv_[0] watch_.path = dest_path src_path_len = len(src_path) sep_len = len(os.path.sep) # The next loop renames all watches with src_path as base path. # It seems that IN_MOVE_SELF does not provide IN_ISDIR information # therefore the next loop is iterated even if raw_event is a file. for w in self._watch_manager.watches.itervalues(): if w.path.startswith(src_path): # Note that dest_path is a normalized path. w.path = os.path.join(dest_path, w.path[src_path_len + sep_len:]) else: log.error("The pathname '%s' of this watch %s has probably changed " "and couldn't be updated, so it cannot be trusted " "anymore. To fix this error move directories/files only " "between watched parents directories, in this case e.g. " "put a watch on '%s'.", watch_.path, watch_, os.path.normpath(os.path.join(watch_.path, os.path.pardir))) if not watch_.path.endswith('-unknown-path'): watch_.path += '-unknown-path' return self.process_default(raw_event) def process_IN_Q_OVERFLOW(self, raw_event): """ Only signal an overflow, most of the common flags are irrelevant for this event (path, wd, name). """ return Event({'mask': raw_event.mask}) def process_IN_IGNORED(self, raw_event): """ The watch descriptor raised by this event is now ignored (forever), it can be safely deleted from the watch manager dictionary. After this event we can be sure that neither the event queue nor the system will raise an event associated to this wd again. """ event_ = self.process_default(raw_event) self._watch_manager.del_watch(raw_event.wd) return event_ def process_default(self, raw_event, to_append=None): """ Commons handling for the followings events: IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_OPEN, IN_DELETE, IN_DELETE_SELF, IN_UNMOUNT. """ watch_ = self._watch_manager.get_watch(raw_event.wd) if raw_event.mask & (IN_DELETE_SELF | IN_MOVE_SELF): # Unfornulately this information is not provided by the kernel dir_ = watch_.dir else: dir_ = bool(raw_event.mask & IN_ISDIR) dict_ = {'wd': raw_event.wd, 'mask': raw_event.mask, 'path': watch_.path, 'name': raw_event.name, 'dir': dir_} if COMPATIBILITY_MODE: dict_['is_dir'] = dir_ if to_append is not None: dict_.update(to_append) return Event(dict_) class ProcessEvent(_ProcessEvent): """ Process events objects, can be specialized via subclassing, thus its behavior can be overriden: Note: you should not override __init__ in your subclass instead define a my_init() method, this method will be called from the constructor of this class with its optional parameters. 1. Provide specialized individual methods, e.g. process_IN_DELETE for processing a precise type of event (e.g. IN_DELETE in this case). 2. Or/and provide methods for processing events by 'family', e.g. process_IN_CLOSE method will process both IN_CLOSE_WRITE and IN_CLOSE_NOWRITE events (if process_IN_CLOSE_WRITE and process_IN_CLOSE_NOWRITE aren't defined though). 3. Or/and override process_default for catching and processing all the remaining types of events. """ pevent = None def __init__(self, pevent=None, **kargs): """ Enable chaining of ProcessEvent instances. @param pevent: Optional callable object, will be called on event processing (before self). @type pevent: callable @param kargs: This constructor is a implemented as a template method delegating its optionals keyworded arguments to the method my_init(). @type kargs: dict """ self.pevent = pevent self.my_init(**kargs) def my_init(self, **kargs): """ This method is called from base constructor ProcessEvent.__init__(). This method is useless here and is meant to be redifined in a subclass of ProcessEvent. In effect, when subclassing just override this method if you want to provide custom initialization to your subclass' instance. You MUST pass keyword arguments though. @param kargs: optional delegated arguments from __init__(). @type kargs: dict """ pass def __call__(self, event): stop_chaining = False if self.pevent is not None: # By default methods return None so we set as guideline # that methods asking for stop chaining must explicitely # return non None or non False values, otherwise the default # behavior will be to accept chain call to the corresponding # local method. stop_chaining = self.pevent(event) if not stop_chaining: return _ProcessEvent.__call__(self, event) def nested_pevent(self): return self.pevent def process_IN_Q_OVERFLOW(self, event): """ By default this method only reports warning messages, you can overredide it by subclassing ProcessEvent and implement your own process_IN_Q_OVERFLOW method. The actions you can take on receiving this event is either to update the variable max_queued_events in order to handle more simultaneous events or to modify your code in order to accomplish a better filtering diminishing the number of raised events. Because this method is defined, IN_Q_OVERFLOW will never get transmitted as arguments to process_default calls. @param event: IN_Q_OVERFLOW event. @type event: dict """ log.warning('Event queue overflowed.') def process_default(self, event): """ Default processing event method. By default does nothing. Subclass ProcessEvent and redefine this method in order to modify its behavior. @param event: Event to be processed. Can be of any type of events but IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW). @type event: Event instance """ pass class PrintAllEvents(ProcessEvent): """ Dummy class used to print events strings representations. For instance this class is used from command line to print all received events to stdout. """ def my_init(self, out=None): """ @param out: Where events will be written. @type out: Object providing a valid file object interface. """ if out is None: out = sys.stdout self._out = out def process_default(self, event): """ Writes event string representation to file object provided to my_init(). @param event: Event to be processed. Can be of any type of events but IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW). @type event: Event instance """ self._out.write(repr(event) + '\n') class ChainIfTrue(ProcessEvent): """ Makes conditional chaining depending on the result of the nested processing instance. """ def my_init(self, func): """ Method automatically called from base class constructor. """ self._func = func def process_default(self, event): return not self._func(event) class Stats(ProcessEvent): """ Compute and display trivial statistics about processed events. """ def my_init(self): """ Method automatically called from base class constructor. """ self._start_time = time.time() self._stats = {} self._stats_lock = threading.Lock() def process_default(self, event): """ Processes |event|. """ self._stats_lock.acquire() try: events = event.maskname.split('|') for event_name in events: count = self._stats.get(event_name, 0) self._stats[event_name] = count + 1 finally: self._stats_lock.release() def _stats_copy(self): self._stats_lock.acquire() try: return self._stats.copy() finally: self._stats_lock.release() def __repr__(self): stats = self._stats_copy() elapsed = int(time.time() - self._start_time) elapsed_str = '' if elapsed < 60: elapsed_str = str(elapsed) + 'sec' elif 60 <= elapsed < 3600: elapsed_str = '%dmn%dsec' % (elapsed / 60, elapsed % 60) elif 3600 <= elapsed < 86400: elapsed_str = '%dh%dmn' % (elapsed / 3600, (elapsed % 3600) / 60) elif elapsed >= 86400: elapsed_str = '%dd%dh' % (elapsed / 86400, (elapsed % 86400) / 3600) stats['ElapsedTime'] = elapsed_str l = [] for ev, value in sorted(stats.items(), key=lambda x: x[0]): l.append(' %s=%s' % (Color.field_name(ev), Color.field_value(value))) s = '<%s%s >' % (Color.class_name(self.__class__.__name__), ''.join(l)) return s def dump(self, filename): """ Dumps statistics to file |filename|. @param filename: pathname. @type filename: string """ file_obj = file(filename, 'wb') try: file_obj.write(str(self)) finally: file_obj.close() def __str__(self, scale=45): stats = self._stats_copy() if not stats: return '' m = max(stats.values()) unity = int(round(float(m) / scale)) or 1 fmt = '%%-26s%%-%ds%%s' % (len(Color.field_value('@' * scale)) + 1) def func(x): return fmt % (Color.field_name(x[0]), Color.field_value('@' * (x[1] / unity)), Color.simple('%d' % x[1], 'yellow')) s = '\n'.join(map(func, sorted(stats.items(), key=lambda x: x[0]))) return s class NotifierError(PyinotifyError): """ Notifier Exception. Raised on Notifier error. """ def __init__(self, err): """ @param err: Exception string's description. @type err: string """ PyinotifyError.__init__(self, err) class Notifier: """ Read notifications, process events. """ def __init__(self, watch_manager, default_proc_fun=ProcessEvent(), read_freq=0, threshold=0, timeout=None): """ Initialization. read_freq, threshold and timeout parameters are used when looping. @param watch_manager: Watch Manager. @type watch_manager: WatchManager instance @param default_proc_fun: Default processing method. @type default_proc_fun: instance of ProcessEvent @param read_freq: if read_freq == 0, events are read asap, if read_freq is > 0, this thread sleeps max(0, read_freq - timeout) seconds. But if timeout is None it can be different because poll is blocking waiting for something to read. @type read_freq: int @param threshold: File descriptor will be read only if the accumulated size to read becomes >= threshold. If != 0, you likely want to use it in combination with an appropriate value for read_freq because without that you would keep looping without really reading anything and that until the amount of events to read is >= threshold. At least with read_freq set you might sleep. @type threshold: int @param timeout: http://docs.python.org/lib/poll-objects.html#poll-objects @type timeout: int """ # Watch Manager instance self._watch_manager = watch_manager # File descriptor self._fd = self._watch_manager.get_fd() # Poll object and registration self._pollobj = select.poll() self._pollobj.register(self._fd, select.POLLIN) # This pipe is correctely initialized and used by ThreadedNotifier self._pipe = (-1, -1) # Event queue self._eventq = deque() # System processing functor, common to all events self._sys_proc_fun = _SysProcessEvent(self._watch_manager, self) # Default processing method self._default_proc_fun = default_proc_fun # Loop parameters self._read_freq = read_freq self._threshold = threshold self._timeout = timeout def append_event(self, event): """ Append a raw event to the event queue. @param event: An event. @type event: _RawEvent instance. """ self._eventq.append(event) def proc_fun(self): return self._default_proc_fun def check_events(self, timeout=None): """ Check for new events available to read, blocks up to timeout milliseconds. @param timeout: If specified it overrides the corresponding instance attribute _timeout. @type timeout: int @return: New events to read. @rtype: bool """ while True: try: # blocks up to 'timeout' milliseconds if timeout is None: timeout = self._timeout ret = self._pollobj.poll(timeout) except select.error, err: if err[0] == errno.EINTR: continue # interrupted, retry else: raise else: break if not ret or (self._pipe[0] == ret[0][0]): return False # only one fd is polled return ret[0][1] & select.POLLIN def read_events(self): """ Read events from device, build _RawEvents, and enqueue them. """ buf_ = array.array('i', [0]) # get event queue size if fcntl.ioctl(self._fd, termios.FIONREAD, buf_, 1) == -1: return queue_size = buf_[0] if queue_size < self._threshold: log.debug('(fd: %d) %d bytes available to read but threshold is ' 'fixed to %d bytes', self._fd, queue_size, self._threshold) return try: # Read content from file r = os.read(self._fd, queue_size) except Exception, msg: raise NotifierError(msg) log.debug('Event queue size: %d', queue_size) rsum = 0 # counter while rsum < queue_size: s_size = 16 # Retrieve wd, mask, cookie s_ = struct.unpack('iIII', r[rsum:rsum+s_size]) # Length of name fname_len = s_[3] # field 'length' useless s_ = s_[:-1] # Retrieve name s_ += struct.unpack('%ds' % fname_len, r[rsum + s_size:rsum + s_size + fname_len]) self._eventq.append(_RawEvent(*s_)) rsum += s_size + fname_len def process_events(self): """ Routine for processing events from queue by calling their associated proccessing method (an instance of ProcessEvent). It also does internal processings, to keep the system updated. """ while self._eventq: raw_event = self._eventq.popleft() # pop next event watch_ = self._watch_manager.get_watch(raw_event.wd) revent = self._sys_proc_fun(raw_event) # system processings if watch_ and watch_.proc_fun: watch_.proc_fun(revent) # user processings else: self._default_proc_fun(revent) self._sys_proc_fun.cleanup() # remove olds MOVED_* events records def __daemonize(self, pid_file=None, force_kill=False, stdin=os.devnull, stdout=os.devnull, stderr=os.devnull): """ pid_file: file to which the pid will be written. force_kill: if True kill the process associated to pid_file. stdin, stdout, stderr: files associated to common streams. """ if pid_file is None: dirname = '/var/run/' basename = sys.argv[0] or 'pyinotify' pid_file = os.path.join(dirname, basename + '.pid') if os.path.exists(pid_file): fo = file(pid_file, 'rb') try: try: pid = int(fo.read()) except ValueError: pid = None if pid is not None: try: os.kill(pid, 0) except OSError, err: log.error(err) else: if not force_kill: s = 'There is already a pid file %s with pid %d' raise NotifierError(s % (pid_file, pid)) else: os.kill(pid, 9) finally: fo.close() def fork_daemon(): # Adapted from Chad J. Schroeder's recipe # @see http://code.activestate.com/recipes/278731/ pid = os.fork() if (pid == 0): # parent 2 os.setsid() pid = os.fork() if (pid == 0): # child os.chdir('/') os.umask(0) else: # parent 2 os._exit(0) else: # parent 1 os._exit(0) fd_inp = os.open(stdin, os.O_RDONLY) os.dup2(fd_inp, 0) fd_out = os.open(stdout, os.O_WRONLY|os.O_CREAT) os.dup2(fd_out, 1) fd_err = os.open(stderr, os.O_WRONLY|os.O_CREAT) os.dup2(fd_err, 2) # Detach task fork_daemon() # Write pid file_obj = file(pid_file, 'wb') try: file_obj.write(str(os.getpid()) + '\n') finally: file_obj.close() atexit.register(lambda : os.unlink(pid_file)) def _sleep(self, ref_time): # Only consider sleeping if read_freq is > 0 if self._read_freq > 0: cur_time = time.time() sleep_amount = self._read_freq - (cur_time - ref_time) if sleep_amount > 0: log.debug('Now sleeping %d seconds', sleep_amount) time.sleep(sleep_amount) def loop(self, callback=None, daemonize=False, **args): """ Events are read only once time every min(read_freq, timeout) seconds at best and only if the size to read is >= threshold. @param callback: Functor called after each event processing. Expects to receive notifier object (self) as first parameter. @type callback: callable @param daemonize: This thread is daemonized if set to True. @type daemonize: boolean """ if daemonize: self.__daemonize(**args) # Read and process events forever while 1: try: self.process_events() if callback is not None: callback(self) ref_time = time.time() # check_events is blocking if self.check_events(): self._sleep(ref_time) self.read_events() except KeyboardInterrupt: # Unless sigint is caught (Control-C) log.debug('Pyinotify stops monitoring.') # Stop monitoring self.stop() break def stop(self): """ Close inotify's instance (close its file descriptor). It destroys all existing watches, pending events,... """ self._pollobj.unregister(self._fd) os.close(self._fd) class ThreadedNotifier(threading.Thread, Notifier): """ This notifier inherits from threading.Thread for instanciating a separate thread, and also inherits from Notifier, because it is a threaded notifier. Note that every functionality provided by this class is also provided through Notifier class. Moreover Notifier should be considered first because it is not threaded and could be easily daemonized. """ def __init__(self, watch_manager, default_proc_fun=ProcessEvent(), read_freq=0, threshold=0, timeout=None): """ Initialization, initialize base classes. read_freq, threshold and timeout parameters are used when looping. @param watch_manager: Watch Manager. @type watch_manager: WatchManager instance @param default_proc_fun: Default processing method. @type default_proc_fun: instance of ProcessEvent @param read_freq: if read_freq == 0, events are read asap, if read_freq is > 0, this thread sleeps max(0, read_freq - timeout) seconds. @type read_freq: int @param threshold: File descriptor will be read only if the accumulated size to read becomes >= threshold. If != 0, you likely want to use it in combination with an appropriate value set for read_freq because without that you would keep looping without really reading anything and that until the amount of events to read is >= threshold. At least with read_freq you might sleep. @type threshold: int @param timeout: see http://docs.python.org/lib/poll-objects.html#poll-objects @type timeout: int """ # Init threading base class threading.Thread.__init__(self) # Stop condition self._stop_event = threading.Event() # Init Notifier base class Notifier.__init__(self, watch_manager, default_proc_fun, read_freq, threshold, timeout) # Create a new pipe used for thread termination self._pipe = os.pipe() self._pollobj.register(self._pipe[0], select.POLLIN) def stop(self): """ Stop notifier's loop. Stop notification. Join the thread. """ self._stop_event.set() os.write(self._pipe[1], 'stop') threading.Thread.join(self) Notifier.stop(self) self._pollobj.unregister(self._pipe[0]) os.close(self._pipe[0]) os.close(self._pipe[1]) def loop(self): """ Thread's main loop. Don't meant to be called by user directly. Call inherited start() method instead. Events are read only once time every min(read_freq, timeout) seconds at best and only if the size of events to read is >= threshold. """ # When the loop must be terminated .stop() is called, 'stop' # is written to pipe fd so poll() returns and .check_events() # returns False which make evaluate the While's stop condition # ._stop_event.isSet() wich put an end to the thread's execution. while not self._stop_event.isSet(): self.process_events() ref_time = time.time() if self.check_events(): self._sleep(ref_time) self.read_events() def run(self): """ Start thread's loop: read and process events until the method stop() is called. Never call this method directly, instead call the start() method inherited from threading.Thread, which then will call run() in its turn. """ self.loop() class AsyncNotifier(asyncore.file_dispatcher, Notifier): """ This notifier inherits from asyncore.file_dispatcher in order to be able to use pyinotify along with the asyncore framework. """ def __init__(self, watch_manager, default_proc_fun=ProcessEvent(), read_freq=0, threshold=0, timeout=None, channel_map=None): """ Initializes the async notifier. The only additional parameter is 'channel_map' which is the optional asyncore private map. See Notifier class for the meaning of the others parameters. """ Notifier.__init__(self, watch_manager, default_proc_fun, read_freq, threshold, timeout) asyncore.file_dispatcher.__init__(self, self._fd, channel_map) def handle_read(self): """ When asyncore tells us we can read from the fd, we proceed processing events. This method can be overridden for handling a notification differently. """ self.read_events() self.process_events() class Watch: """ Represent a watch, i.e. a file or directory being watched. """ def __init__(self, **keys): """ Initializations. @param wd: Watch descriptor. @type wd: int @param path: Path of the file or directory being watched. @type path: str @param mask: Mask. @type mask: int @param proc_fun: Processing callable object. @type proc_fun: @param auto_add: Automatically add watches on new directories. @type auto_add: bool """ for k, v in keys.iteritems(): setattr(self, k, v) self.dir = os.path.isdir(self.path) def __repr__(self): """ @return: String representation. @rtype: str """ s = ' '.join(['%s%s%s' % (Color.field_name(attr), Color.punctuation('='), Color.field_value(getattr(self, attr))) \ for attr in self.__dict__ if not attr.startswith('_')]) s = '%s%s %s %s' % (Color.punctuation('<'), Color.class_name(self.__class__.__name__), s, Color.punctuation('>')) return s class ExcludeFilter: """ ExcludeFilter is an exclusion filter. """ def __init__(self, arg_lst): """ @param arg_lst: is either a list or dict of patterns: [pattern1, ..., patternn] {'filename1': (list1, listn), ...} where list1 is a list of patterns @type arg_lst: list or dict """ if isinstance(arg_lst, dict): lst = self._load_patterns(arg_lst) elif isinstance(arg_lst, list): lst = arg_lst else: raise TypeError self._lregex = [] for regex in lst: self._lregex.append(re.compile(regex, re.UNICODE)) def _load_patterns(self, dct): lst = [] for path, varnames in dct.iteritems(): loc = {} execfile(path, {}, loc) for varname in varnames: lst.extend(loc.get(varname, [])) return lst def _match(self, regex, path): return regex.match(path) is not None def __call__(self, path): """ @param path: Path to match against provided regexps. @type path: str @return: Return True if path has been matched and should be excluded, False otherwise. @rtype: bool """ for regex in self._lregex: if self._match(regex, path): return True return False class WatchManagerError(Exception): """ WatchManager Exception. Raised on error encountered on watches operations. """ def __init__(self, msg, wmd): """ @param msg: Exception string's description. @type msg: string @param wmd: This dictionary contains the wd assigned to paths of the same call for which watches were successfully added. @type wmd: dict """ self.wmd = wmd Exception.__init__(self, msg) class WatchManager: """ Provide operations for watching files and directories. Its internal dictionary is used to reference watched items. When used inside threaded code, one must instanciate as many WatchManager instances as there are ThreadedNotifier instances. """ def __init__(self, exclude_filter=lambda path: False): """ Initialization: init inotify, init watch manager dictionary. Raise OSError if initialization fails. @param exclude_filter: boolean function, returns True if current path must be excluded from being watched. Convenient for providing a common exclusion filter for every call to add_watch. @type exclude_filter: bool """ self._exclude_filter = exclude_filter self._wmd = {} # watch dict key: watch descriptor, value: watch self._fd = LIBC.inotify_init() # inotify's init, file descriptor if self._fd < 0: raise OSError() def get_fd(self): """ Return assigned inotify's file descriptor. @return: File descriptor. @rtype: int """ return self._fd def get_watch(self, wd): """ Get watch from provided watch descriptor wd. @param wd: Watch descriptor. @type wd: int """ return self._wmd.get(wd) def del_watch(self, wd): """ Remove watch entry associated to watch descriptor wd. @param wd: Watch descriptor. @type wd: int """ try: del self._wmd[wd] except KeyError, err: log.error(str(err)) @property def watches(self): """ Get a reference on the internal watch manager dictionary. @return: Internal watch manager dictionary. @rtype: dict """ return self._wmd def __add_watch(self, path, mask, proc_fun, auto_add): """ Add a watch on path, build a Watch object and insert it in the watch manager dictionary. Return the wd value. """ # Unicode strings are converted to byte strings, it seems to be # required because LIBC.inotify_add_watch does not work well when # it receives an ctypes.create_unicode_buffer instance as argument. # Therefore even wd are indexed with bytes string and not with # unicode paths. if isinstance(path, unicode): byte_path = path.encode(sys.getfilesystemencoding()) else: byte_path = path wd_ = LIBC.inotify_add_watch(self._fd, ctypes.create_string_buffer(byte_path), mask) if wd_ < 0: return wd_ watch_ = Watch(wd=wd_, path=os.path.normpath(byte_path), mask=mask, proc_fun=proc_fun, auto_add=auto_add) self._wmd[wd_] = watch_ log.debug('New %s', watch_) return wd_ def __glob(self, path, do_glob): if do_glob: return iglob(path) else: return [path] def add_watch(self, path, mask, proc_fun=None, rec=False, auto_add=False, do_glob=False, quiet=True, exclude_filter=None): """ Add watch(s) on the provided |path|(s) with associated |mask| flag value and optionally with a processing |proc_fun| function and recursive flag |rec| set to True. Ideally |path| components should not be unicode objects. Note that although unicode paths are accepted there are converted to byte strings before a watch is put on that path. The encoding used for converting the unicode object is given by sys.getfilesystemencoding(). @param path: Path to watch, the path can either be a file or a directory. Also accepts a sequence (list) of paths. @type path: string or list of strings @param mask: Bitmask of events. @type mask: int @param proc_fun: Processing object. @type proc_fun: function or ProcessEvent instance or instance of one of its subclasses or callable object. @param rec: Recursively add watches from path on all its subdirectories, set to False by default (doesn't follows symlinks in any case). @type rec: bool @param auto_add: Automatically add watches on newly created directories in watched parent |path| directory. @type auto_add: bool @param do_glob: Do globbing on pathname (see standard globbing module for more informations). @type do_glob: bool @param quiet: if False raises a WatchManagerError exception on error. See example not_quiet.py. @type quiet: bool @param exclude_filter: boolean function, returns True if current path must be excluded from being watched. Has precedence on exclude_filter defined into __init__. @type exclude_filter: bool @return: dict of paths associated to watch descriptors. A wd value is positive if the watch was added sucessfully, otherwise the value is negative. If the path was invalid it is not included into this returned dictionary. @rtype: dict of {str: int} """ ret_ = {} # return {path: wd, ...} if exclude_filter is None: exclude_filter = self._exclude_filter # normalize args as list elements for npath in self.__format_param(path): # unix pathname pattern expansion for apath in self.__glob(npath, do_glob): # recursively list subdirs according to rec param for rpath in self.__walk_rec(apath, rec): if not exclude_filter(rpath): wd = ret_[rpath] = self.__add_watch(rpath, mask, proc_fun, auto_add) if wd < 0: err = 'add_watch: cannot watch %s (WD=%d)' err = err % (rpath, wd) if quiet: log.error(err) else: raise WatchManagerError(err, ret_) else: # Let's say -2 means 'explicitely excluded # from watching'. ret_[rpath] = -2 return ret_ def __get_sub_rec(self, lpath): """ Get every wd from self._wmd if its path is under the path of one (at least) of those in lpath. Doesn't follow symlinks. @param lpath: list of watch descriptor @type lpath: list of int @return: list of watch descriptor @rtype: list of int """ for d in lpath: root = self.get_path(d) if root: # always keep root yield d else: # if invalid continue # nothing else to expect if not os.path.isdir(root): continue # normalization root = os.path.normpath(root) # recursion lend = len(root) for iwd in self._wmd.items(): cur = iwd[1].path pref = os.path.commonprefix([root, cur]) if root == os.sep or (len(pref) == lend and \ len(cur) > lend and \ cur[lend] == os.sep): yield iwd[1].wd def update_watch(self, wd, mask=None, proc_fun=None, rec=False, auto_add=False, quiet=True): """ Update existing watch descriptors |wd|. The |mask| value, the processing object |proc_fun|, the recursive param |rec| and the |auto_add| and |quiet| flags can all be updated. @param wd: Watch Descriptor to update. Also accepts a list of watch descriptors. @type wd: int or list of int @param mask: Optional new bitmask of events. @type mask: int @param proc_fun: Optional new processing function. @type proc_fun: function or ProcessEvent instance or instance of one of its subclasses or callable object. @param rec: Optionally adds watches recursively on all subdirectories contained into |wd| directory. @type rec: bool @param auto_add: Automatically adds watches on newly created directories in the watch's path corresponding to |wd|. @type auto_add: bool @param quiet: If False raises a WatchManagerError exception on error. See example not_quiet.py @type quiet: bool @return: dict of watch descriptors associated to booleans values. True if the corresponding wd has been successfully updated, False otherwise. @rtype: dict of {int: bool} """ lwd = self.__format_param(wd) if rec: lwd = self.__get_sub_rec(lwd) ret_ = {} # return {wd: bool, ...} for awd in lwd: apath = self.get_path(awd) if not apath or awd < 0: err = 'update_watch: invalid WD=%d' % awd if quiet: log.error(err) continue raise WatchManagerError(err, ret_) if mask: addw = LIBC.inotify_add_watch wd_ = addw(self._fd, ctypes.create_string_buffer(apath), mask) if wd_ < 0: ret_[awd] = False err = 'update_watch: cannot update WD=%d (%s)' % (wd_, apath) if quiet: log.error(err) continue raise WatchManagerError(err, ret_) assert(awd == wd_) if proc_fun or auto_add: watch_ = self._wmd[awd] if proc_fun: watch_.proc_fun = proc_fun if auto_add: watch_.proc_fun = auto_add ret_[awd] = True log.debug('Updated watch - %s', self._wmd[awd]) return ret_ def __format_param(self, param): """ @param param: Parameter. @type param: string or int @return: wrap param. @rtype: list of type(param) """ if isinstance(param, list): for p_ in param: yield p_ else: yield param def get_wd(self, path): """ Returns the watch descriptor associated to path. This method presents a prohibitive cost, always prefer to keep the WD returned by add_watch(). If the path is unknown it returns None. @param path: Path. @type path: str @return: WD or None. @rtype: int or None """ path = os.path.normpath(path) for iwd in self._wmd.iteritems(): if iwd[1].path == path: return iwd[0] log.debug('get_wd: unknown path %s', path) def get_path(self, wd): """ Returns the path associated to WD, if WD is unknown it returns None. @param wd: Watch descriptor. @type wd: int @return: Path or None. @rtype: string or None """ watch_ = self._wmd.get(wd) if watch_: return watch_.path log.debug('get_path: unknown WD %d', wd) def __walk_rec(self, top, rec): """ Yields each subdirectories of top, doesn't follow symlinks. If rec is false, only yield top. @param top: root directory. @type top: string @param rec: recursive flag. @type rec: bool @return: path of one subdirectory. @rtype: string """ if not rec or os.path.islink(top) or not os.path.isdir(top): yield top else: for root, dirs, files in os.walk(top): yield root def rm_watch(self, wd, rec=False, quiet=True): """ Removes watch(s). @param wd: Watch Descriptor of the file or directory to unwatch. Also accepts a list of WDs. @type wd: int or list of int. @param rec: Recursively removes watches on every already watched subdirectories and subfiles. @type rec: bool @param quiet: If False raises a WatchManagerError exception on error. See example not_quiet.py @type quiet: bool @return: dict of watch descriptors associated to booleans values. True if the corresponding wd has been successfully removed, False otherwise. @rtype: dict of {int: bool} """ lwd = self.__format_param(wd) if rec: lwd = self.__get_sub_rec(lwd) ret_ = {} # return {wd: bool, ...} for awd in lwd: # remove watch wd_ = LIBC.inotify_rm_watch(self._fd, awd) if wd_ < 0: ret_[awd] = False err = 'rm_watch: cannot remove WD=%d' % awd if quiet: log.error(err) continue raise WatchManagerError(err, ret_) ret_[awd] = True log.debug('Watch WD=%d (%s) removed', awd, self.get_path(awd)) return ret_ def watch_transient_file(self, filename, mask, proc_class): """ Watch a transient file, which will be created and deleted frequently over time (e.g. pid file). @attention: Currently under the call to this function it is not possible to correctly watch the events triggered into the same base directory than the directory where is located this watched transient file. For instance it would be wrong to make these two successive calls: wm.watch_transient_file('/var/run/foo.pid', ...) and wm.add_watch('/var/run/', ...) @param filename: Filename. @type filename: string @param mask: Bitmask of events, should contain IN_CREATE and IN_DELETE. @type mask: int @param proc_class: ProcessEvent (or of one of its subclass), beware of accepting a ProcessEvent's instance as argument into __init__, see transient_file.py example for more details. @type proc_class: ProcessEvent's instance or of one of its subclasses. @return: Same as add_watch(). @rtype: Same as add_watch(). """ dirname = os.path.dirname(filename) if dirname == '': return {} # Maintains coherence with add_watch() basename = os.path.basename(filename) # Assuming we are watching at least for IN_CREATE and IN_DELETE mask |= IN_CREATE | IN_DELETE def cmp_name(event): return basename == event.name return self.add_watch(dirname, mask, proc_fun=proc_class(ChainIfTrue(func=cmp_name)), rec=False, auto_add=False, do_glob=False) class Color: """ Internal class. Provide fancy colors used by string representations. """ normal = "\033[0m" black = "\033[30m" red = "\033[31m" green = "\033[32m" yellow = "\033[33m" blue = "\033[34m" purple = "\033[35m" cyan = "\033[36m" bold = "\033[1m" uline = "\033[4m" blink = "\033[5m" invert = "\033[7m" @staticmethod def punctuation(s): """Punctuation color.""" return Color.normal + s + Color.normal @staticmethod def field_value(s): """Field value color.""" if not isinstance(s, basestring): s = str(s) return Color.purple + s + Color.normal @staticmethod def field_name(s): """Field name color.""" return Color.blue + s + Color.normal @staticmethod def class_name(s): """Class name color.""" return Color.red + Color.bold + s + Color.normal @staticmethod def simple(s, color): if not isinstance(s, basestring): s = str(s) try: color_attr = getattr(Color, color) except AttributeError: return s return color_attr + s + Color.normal def compatibility_mode(): """ Use this function to turn on the compatibility mode. The compatibility mode is used to improve compatibility with Pyinotify 0.7.1 (or older) programs. The compatibility mode provides additional variables 'is_dir', 'event_name', 'EventsCodes.IN_*' and 'EventsCodes.ALL_EVENTS' as Pyinotify 0.7.1 provided. Do not call this function from new programs!! Especially if there are developped for Pyinotify >= 0.8.x. """ setattr(EventsCodes, 'ALL_EVENTS', ALL_EVENTS) for evname in globals(): if evname.startswith('IN_'): setattr(EventsCodes, evname, globals()[evname]) global COMPATIBILITY_MODE COMPATIBILITY_MODE = True def command_line(): """ By default the watched path is '/tmp' and all types of events are monitored. Events monitoring serves forever, type c^c to stop it. """ from optparse import OptionParser usage = "usage: %prog [options] [path1] [path2] [pathn]" parser = OptionParser(usage=usage) parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="Verbose mode") parser.add_option("-r", "--recursive", action="store_true", dest="recursive", help="Add watches recursively on paths") parser.add_option("-a", "--auto_add", action="store_true", dest="auto_add", help="Automatically add watches on new directories") parser.add_option("-e", "--events-list", metavar="EVENT[,...]", dest="events_list", help=("A comma-separated list of events to watch for - " "see the documentation for valid options (defaults" " to everything)")) parser.add_option("-s", "--stats", action="store_true", dest="stats", help="Display dummy statistics") (options, args) = parser.parse_args() if options.verbose: log.setLevel(10) if len(args) < 1: path = '/tmp' # default watched path else: path = args # watch manager instance wm = WatchManager() # notifier instance and init if options.stats: notifier = Notifier(wm, default_proc_fun=Stats(), read_freq=5) else: notifier = Notifier(wm, default_proc_fun=PrintAllEvents()) # What mask to apply mask = 0 if options.events_list: events_list = options.events_list.split(',') for ev in events_list: evcode = EventsCodes.ALL_FLAGS.get(ev, 0) if evcode: mask |= evcode else: parser.error("The event '%s' specified with option -e" " is not valid" % ev) else: mask = ALL_EVENTS # stats cb_fun = None if options.stats: def cb(s): print('%s\n%s\n' % (repr(s.proc_fun()), s.proc_fun())) cb_fun = cb log.debug('Start monitoring %s, (press c^c to halt pyinotify)' % path) wm.add_watch(path, mask, rec=options.recursive, auto_add=options.auto_add) # Loop forever (until sigint signal get caught) notifier.loop(callback=cb_fun) if __name__ == '__main__': command_line() pyinotify/COPYING0000644000175000017500000004310311042100440013150 0ustar ookoiookoi GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. pyinotify/NEWS0000644000175000017500000002323111042100440012614 0ustar ookoiookoiChanges in version 0.8.0: ------------------------ * Incompatible changes with version 0.7.x - Dropped support for python 2.3 (supports only CPython >= 2.4) - Changed attribute names of class Event: * 'is_dir' becomes 'dir' * 'event_name' becomes 'maskname' - Altered namespace: * Everything previously accessible under inotify.* is now accessible under pyinotify. - When meaningful, an event (instance of Event) brings a new attribute 'pathname' - Modified debugging messages: * The VERBOSE variable is removed, and is replaced by the logging module * Set the reporting level like this: log.setLevel(level) * print_err(msg) replaced by log.error(msg) - EventsCodes: * _get_event_name(mask) replaced by get_masks(mask) * EventsCodes.IN_* replaced by IN_* (avalaible at the pyinotify's scope) - Notifier: * Avoid use of ThreadedNotifier, everything can be done with Notifier and it provides more functionalities * Use Notifier.loop() method instead of using an infinite while loop Changes in version 0.6.2: ------------------------ * New features - Pathname pattern expansion: Something like python -m pyinotify /tmp/[0-9]*.gif now works. See http://www.python.org/doc/lib/module-glob.html for more details. Changes in version 0.6.0: ------------------------ * Incompatible changes List of incompatible changes in pyinotify.py: ------------------------------------------------------------------- | v0.5 | Now | |-------------------------------------------------------------------| | i1 = SimpleINotify() | wm = WatchManager() | | i2 = ThreadedINotify() | n1 = Notifier(wm) | | | n2 = ThreadedNotifier(wm) | |-------------------------------------------------------------------| | i2.start() | n2.start() | |-------------------------------------------------------------------| | i1.add_watch(...) | wm.add_watch(...) | | i2.rm_watch(...) | wm.rm_watch(...) | |-------------------------------------------------------------------| | i1.close() | n1.stop() | |-------------------------------------------------------------------| | DEBUG = True | VERBOSE = True | |-------------------------------------------------------------------| | event.isdir | event.is_dir | |-------------------------------------------------------------------| | i1.event_check() | n1.check_events() | |-------------------------------------------------------------------| | raise ProcessEventException(err) | raise ProcessEventError(err) | | raise INotifyException(err) | raise NotifierError(err) | |------------------------------------|------------------------------| | def process_default(s,a,b): | def process_default(s,event):| | pass | pass | ------------------------------------------------------------------- * New features - supported flags: IN_ONLYDIR, IN_DONT_FOLLOW, IN_MASK_ADD, IN_MOVE_SELF - auto_add: if a watch is added with this flag set to true, every new subdirectory will be automatically watched too. - possibility to pass one instance of your processing class to Notifier or ThreadedNotifier and this object will be called by default for each watch. Note, you always can give an instance to add_watch(), update_watch(). * Fixed - The pathname is appropriately updated in this case: wm.add_watch('/a/') wm.add_watch('/a/b/') echo "bar" > /a/foo.txt mv /a/foo.txt /a/b/foo.txt The necessary condition is to have watches both on the source dir and on the dst dir. - Ignored (deleted) watches are removed from watch manager. * Pending bug - Consider this case: wm.add_watch('/a/foo.txt') # where neither /a nor /a/b are watched mv /a/foo.txt /a/b/foo.txt In this case we have received IN_MOVE_SELF but we are unable to infer the new pathname. The event IN_MOVE_SELF doesn't provide this indication. Actually, the safest way to use pyinotify is to watch a top directory (say /tmp) one we don't expect be moved, and the watched items located in this directory should only be moved inside this directory or inside another watched top directory (in the same device). Example: wm.add_watch('/tmp', rec=True) mv /tmp/foo/ /tmp/bar/ [safe] mv /tmp/bar/ ~/tmp/ [unsafe] mv /tmp /tmp-new [unsafe] Changes in version 0.5.0: ------------------------ * Few namespace modifications (incompatible changes) - pyinotfiy.inotify.* becomes inotify.* this namespace is a simple wrap of inotify's features (3 systems calls, and 3 variables). - pyinotify.* unchanged. This namespace handle higher developments made on top of inotify. - python -m pyinotify now works (no need to wait python 2.4.5 :) ) * New features - You can read and update the followings variables (accessible through the namespace inotify): - max_queued_events - max_user_instances - max_user_watches Changes in version 0.4.0: ------------------------ Few things have been modified (again) to add more consistence and reliability. Reliability: it is now easy to immediately and precisely know if an operation failed or not, and on which path or wd. That, without interrupting (without raising exceptions) the monitoring. It is more consistent because once you have added a watch on a path you keep the returned wd and use it to further update or remove this watch, this is the natural way. Howewer, in case where you have lost the wd and only have the path you still might retrieve the wd with the method get_wd(path). * Incompatible changes - add_watch returns a dictionary {path: watch_descriptor, ...} where: - path is the path given as argument or a subdirectory (if rec is set to True) - watch_descriptor is the corresponding wd, which is a positive integer if the watch has been successfully added or is a negative integer if it failed. - update_watch only accepts a wd or a list of wd. Moreover, it now returns a dictionary {wd: success, ...} where: - wd is the watch directory being updated (given as argument or retrieved by rec=True). - success is boolean value. success is set to True is the update succeed, False otherwise. - rm_watch only accepts a wd or a list of wd. Moreover, it now returns a dictionary {wd: success, ...} see 'update_watch' just above. Changes in version 0.3.3: ------------------------ * bug fix and cosmetic changes. Changes in version 0.3.1: ------------------------ * Incompatible changes - Event.length removed. Changes in version 0.3.0: ------------------------ This is a development version, there are many changes from 0.2.x releases, this release must be considered as unstable. Most of the changes affects the SimpleINotify class. * Incompatible changes - No more raise an INotify Exception in case where an error occurred in the methods add_watch, update_watch, rm_watch. - Ignore update to an nonexistent watch. - Different behavior for the recursive treatment of the update_watch method. Recursively update only existing and valid watches, doesn't follow symlinks. - The method rm_watch returns a list of watch descriptor (those who were removed). * New features - two new methods: get_wd and get_path. The former takes a path and returns the associated watch descriptor, the latter takes a wd and returns a path. (returning None if the request couldn't be satisfied) - add_watch accepts a list of path as well as a single path. - update_watch and remove_watch accept both string path and int wd as argument. Note: that the preferred argument for update_watch is the path whereas the preferred one for rm_watch is the wd. - The methods rm_watch and update_watch can recursively be applied on theirs arguments. The symlinks aren't followed. Read also the next section. - rm_watch returns the list of watch descriptors of watches successfully removed. * Performances - Always prefer string path for update_watch, and int wd for rm_watch. - Always prefer to save the result of one operation e.g. add_watch for further update or remove watches with this list instead the use of the 'rec' option which is very expansive. * Exceptions vs errors vs nothing The previous versions raised exceptions on explicit errors, the drawback was to drop important informations. For example, given the list ['a-valid-path', 'non-valid-path', 'a-valid-path2'], the first item was successfully added whereas an exception was raised on the second, thus the first wd hadn't been returned to the caller, and the last item hadn't been processed. The new approach is to quietly ignore errors, process all items and to return all successfully executed operations. The benefit is to never hang up the execution of one operation, the called method will never unexpectedly fail, if all operations failed, the result is an empty list. The drawback is to not directly and explicitly report errors. This task is left to the caller, which is able to compare the input parameters to the received list. Obviously this is a subjective choice but i think this is the least worst. Anyway, feel free to send me a comment to say if in your use case this choice works or if it is really really annoying. pyinotify/docstrings/0000755000175000017500000000000011273644743014324 5ustar ookoiookoipyinotify/docstrings/uml_class_diagram_for_pyinotif_4.gif0000644000175000017500000000535411273644742023501 0ustar ookoiookoiGIF87a|LBDĊBD$"$Ԧd^\jd|<2, ܶbdT.,dJDĚvtܪ|b\\JDD:<Ԣt4&$$ĢzlԮ \FD̦&$j\TB<,$~t ̪24TBDZ\><䲤rdlVT rl侼̢tbdD64ԪNLnľL:<,"$vtTFD4*,̞, H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIfA8sɳϟ@ b&EA*]ʴӧPJ@Q ʵׯ` KkhZ55[ov-ֶt[v/_vcf֯U!0lrV{U0̀y B P 7dF5 :sgkkd y=#hJɒ3O=̻z52\}?GWG[.nG []PcS0KЍN[U[MARV!sg RjHX"vH"K [8Ԍ4hP <@)Di֋LJ-6)%gKNiWORfҖ\2%J`'ݨl#V;)tIdUi%&g|䧙yV+Bi⟂@P 5z2@ĉy:=dfEitèB^=wƚk)q J[h2 qXjVXBjypYb<]{$\mۘz&XeF\Qqd/oz V]]yp| eZ D_j)˕JW 8aV܃ڋ#g!}y1hQPuW33a:g猅 F@F .MJҠtϧ=# a.N4$7 Wn! wFn pM(P%Ǿ/WC&FGA0D'PCH@P@-aS!2 H?=c4B</>AKplL`T0@ Am '⮄& Sh&.|Lb(Cа.!Y H"HL.Pb=6Y'ŝPqzH2b FDpc!8q#נ>qu(2wdGFDcă m^׾թmňTJu]]Btic] نHlc#QUqF?!T%#>VSk"ia.-Pvlg.qqM XBQ= z`D@IK2%c>sjCI4D-Qր( jp= z$K2@/*QKLip<¸-\aal3_̷~N ;pyinotify/docstrings/pyinotify.UnsupportedPythonVersionError-class.html0000644000175000017500000002640511273644742026466 0ustar ookoiookoi pyinotify.UnsupportedPythonVersionError
Module pyinotify :: Class UnsupportedPythonVersionError
[hide private]
[frames] | no frames]

Class UnsupportedPythonVersionError

source code


Raised on unsupported Python versions.

Instance Methods [hide private]
 
__init__(self, version)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
source code

Inherited from exceptions.Exception: __new__

Inherited from exceptions.BaseException: __delattr__, __getattribute__, __getitem__, __getslice__, __reduce__, __repr__, __setattr__, __setstate__, __str__, __unicode__

Inherited from object: __format__, __hash__, __reduce_ex__, __sizeof__, __subclasshook__

Properties [hide private]

Inherited from exceptions.BaseException: args, message

Inherited from object: __class__

Method Details [hide private]

__init__(self, version)
(Constructor)

source code 

x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Parameters:
  • version (string) - Current Python version
Overrides: object.__init__

pyinotify/docstrings/pyinotify.EventsCodes-class.html0000644000175000017500000010751411273644742022577 0ustar ookoiookoi pyinotify.EventsCodes
Module pyinotify :: Class EventsCodes
[hide private]
[frames] | no frames]

Class EventsCodes

source code


Set of codes corresponding to each kind of events. Some of these flags are used to communicate with inotify, whereas the others are sent to userspace by inotify notifying some events.

Instance Methods [hide private]

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __init__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__

Static Methods [hide private]
str
maskname(mask)
Returns the event name associated to mask.
source code
Class Variables [hide private]
  FLAG_COLLECTIONS = {'EVENT_FLAGS': {'IN_IGNORED': 32768, 'IN_Q...
  ALL_FLAGS = {'ALL_EVENTS': 4095, 'IN_ACCESS': 1, 'IN_ATTRIB': ...
  ALL_VALUES = {1: 'IN_ACCESS', 2: 'IN_MODIFY', 4: 'IN_ATTRIB', ...
int ALL_EVENTS
Alias for considering all of the events.
  EVENT_FLAGS = {'IN_IGNORED': 32768, 'IN_Q_OVERFLOW': 16384, 'I...
int IN_ACCESS
File was accessed.
int IN_ATTRIB
Metadata changed.
int IN_CLOSE_NOWRITE
Unwrittable file closed.
int IN_CLOSE_WRITE
Writtable file was closed.
int IN_CREATE
Subfile was created.
int IN_DELETE
Subfile was deleted.
int IN_DELETE_SELF
Self (watched item itself) was deleted.
int IN_DONT_FOLLOW
don't follow a symlink (new in kernel 2.6.15).
int IN_IGNORED
File was ignored.
int IN_ISDIR
Event occurred against dir.
int IN_MASK_ADD
add to the mask of an already existing watch (new in kernel 2.6.14).
int IN_MODIFY
File was modified.
int IN_MOVED_FROM
File was moved from X.
int IN_MOVED_TO
File was moved to Y.
int IN_MOVE_SELF
Self (watched item itself) was moved.
int IN_ONESHOT
Only send event once.
int IN_ONLYDIR
only watch the path if it is a directory (new in kernel 2.6.15).
int IN_OPEN
File was opened.
int IN_Q_OVERFLOW
Event queued overflowed.
int IN_UNMOUNT
Backing fs was unmounted.
  OP_FLAGS = {'IN_ACCESS': 1, 'IN_ATTRIB': 4, 'IN_CLOSE_NOWRITE'...
  SPECIAL_FLAGS = {'IN_DONT_FOLLOW': 33554432, 'IN_ISDIR': 10737...
Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

maskname(mask)
Static Method

source code 

Returns the event name associated to mask. IN_ISDIR is appended to the result when appropriate. Note: only one event is returned, because only one event can be raised at a given time.

Parameters:
  • mask (int) - mask.
Returns: str
event name.

Class Variable Details [hide private]

FLAG_COLLECTIONS

Value:
{'EVENT_FLAGS': {'IN_IGNORED': 32768,
                 'IN_Q_OVERFLOW': 16384,
                 'IN_UNMOUNT': 8192},
 'OP_FLAGS': {'IN_ACCESS': 1,
              'IN_ATTRIB': 4,
              'IN_CLOSE_NOWRITE': 16,
              'IN_CLOSE_WRITE': 8,
              'IN_CREATE': 256,
...

ALL_FLAGS

Value:
{'ALL_EVENTS': 4095,
 'IN_ACCESS': 1,
 'IN_ATTRIB': 4,
 'IN_CLOSE_NOWRITE': 16,
 'IN_CLOSE_WRITE': 8,
 'IN_CREATE': 256,
 'IN_DELETE': 512,
 'IN_DELETE_SELF': 1024,
...

ALL_VALUES

Value:
{1: 'IN_ACCESS',
 2: 'IN_MODIFY',
 4: 'IN_ATTRIB',
 8: 'IN_CLOSE_WRITE',
 16: 'IN_CLOSE_NOWRITE',
 32: 'IN_OPEN',
 64: 'IN_MOVED_FROM',
 128: 'IN_MOVED_TO',
...

EVENT_FLAGS

Value:
{'IN_IGNORED': 32768, 'IN_Q_OVERFLOW': 16384, 'IN_UNMOUNT': 8192}

IN_DONT_FOLLOW

don't follow a symlink (new in kernel 2.6.15). IN_ONLYDIR we can make sure that we don't watch the target of symlinks.
Type:
int

OP_FLAGS

Value:
{'IN_ACCESS': 1,
 'IN_ATTRIB': 4,
 'IN_CLOSE_NOWRITE': 16,
 'IN_CLOSE_WRITE': 8,
 'IN_CREATE': 256,
 'IN_DELETE': 512,
 'IN_DELETE_SELF': 1024,
 'IN_MODIFY': 2,
...

SPECIAL_FLAGS

Value:
{'IN_DONT_FOLLOW': 33554432,
 'IN_ISDIR': 1073741824,
 'IN_MASK_ADD': 536870912,
 'IN_ONESHOT': 2147483648,
 'IN_ONLYDIR': 16777216}

pyinotify/docstrings/pyinotify.AsyncNotifier-class.html0000644000175000017500000004740411273644742023133 0ustar ookoiookoi pyinotify.AsyncNotifier
Module pyinotify :: Class AsyncNotifier
[hide private]
[frames] | no frames]

Class AsyncNotifier

source code


This notifier inherits from asyncore.file_dispatcher in order to be able to use pyinotify along with the asyncore framework.

Instance Methods [hide private]
 
__init__(self, watch_manager, default_proc_fun=<ProcessEvent>, read_freq=0, threshold=0, timeout=None, channel_map=None)
Initializes the async notifier.
source code
 
handle_read(self)
When asyncore tells us we can read from the fd, we proceed processing events.
source code

Inherited from asyncore.file_dispatcher: set_file

Inherited from asyncore.dispatcher: __getattr__, __repr__, accept, add_channel, bind, close, connect, create_socket, del_channel, handle_accept, handle_close, handle_connect, handle_connect_event, handle_error, handle_expt, handle_expt_event, handle_read_event, handle_write, handle_write_event, listen, log, log_info, readable, recv, send, set_reuse_addr, set_socket, writable

Inherited from Notifier: append_event, check_events, loop, proc_fun, process_events, read_events, stop

Inherited from Notifier (private): _sleep

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Class Variables [hide private]

Inherited from asyncore.dispatcher: accepting, addr, closing, connected, debug, ignore_log_types

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, watch_manager, default_proc_fun=<ProcessEvent>, read_freq=0, threshold=0, timeout=None, channel_map=None)
(Constructor)

source code 

Initializes the async notifier. The only additional parameter is 'channel_map' which is the optional asyncore private map. See Notifier class for the meaning of the others parameters.

Parameters:
  • watch_manager - Watch Manager.
  • default_proc_fun - Default processing method.
  • read_freq - if read_freq == 0, events are read asap, if read_freq is > 0, this thread sleeps max(0, read_freq - timeout) seconds. But if timeout is None it can be different because poll is blocking waiting for something to read.
  • threshold - File descriptor will be read only if the accumulated size to read becomes >= threshold. If != 0, you likely want to use it in combination with an appropriate value for read_freq because without that you would keep looping without really reading anything and that until the amount of events to read is >= threshold. At least with read_freq set you might sleep.
  • timeout - http://docs.python.org/lib/poll-objects.html#poll-objects
Overrides: object.__init__

handle_read(self)

source code 

When asyncore tells us we can read from the fd, we proceed processing events. This method can be overridden for handling a notification differently.

Overrides: asyncore.dispatcher.handle_read

pyinotify/docstrings/pyinotify.Notifier-class.html0000644000175000017500000006377611273644742022147 0ustar ookoiookoi pyinotify.Notifier
Module pyinotify :: Class Notifier
[hide private]
[frames] | no frames]

Class Notifier

source code


Read notifications, process events.

Instance Methods [hide private]
 
__init__(self, watch_manager, default_proc_fun=<ProcessEvent>, read_freq=0, threshold=0, timeout=None)
Initialization.
source code
 
append_event(self, event)
Append a raw event to the event queue.
source code
 
proc_fun(self) source code
bool
check_events(self, timeout=None)
Check for new events available to read, blocks up to timeout milliseconds.
source code
 
read_events(self)
Read events from device, build _RawEvents, and enqueue them.
source code
 
process_events(self)
Routine for processing events from queue by calling their associated proccessing method (an instance of ProcessEvent).
source code
 
__daemonize(self, pid_file=None, force_kill=False, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null')
pid_file: file to which the pid will be written.
source code
 
_sleep(self, ref_time) source code
 
loop(self, callback=None, daemonize=False, **args)
Events are read only once time every min(read_freq, timeout) seconds at best and only if the size to read is >= threshold.
source code
 
stop(self)
Close inotify's instance (close its file descriptor).
source code

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, watch_manager, default_proc_fun=<ProcessEvent>, read_freq=0, threshold=0, timeout=None)
(Constructor)

source code 

Initialization. read_freq, threshold and timeout parameters are used when looping.

Parameters:
  • watch_manager (WatchManager instance) - Watch Manager.
  • default_proc_fun (instance of ProcessEvent) - Default processing method.
  • read_freq (int) - if read_freq == 0, events are read asap, if read_freq is > 0, this thread sleeps max(0, read_freq - timeout) seconds. But if timeout is None it can be different because poll is blocking waiting for something to read.
  • threshold (int) - File descriptor will be read only if the accumulated size to read becomes >= threshold. If != 0, you likely want to use it in combination with an appropriate value for read_freq because without that you would keep looping without really reading anything and that until the amount of events to read is >= threshold. At least with read_freq set you might sleep.
  • timeout (int) - http://docs.python.org/lib/poll-objects.html#poll-objects
Overrides: object.__init__

append_event(self, event)

source code 

Append a raw event to the event queue.

Parameters:
  • event (_RawEvent instance.) - An event.

check_events(self, timeout=None)

source code 

Check for new events available to read, blocks up to timeout milliseconds.

Parameters:
  • timeout (int) - If specified it overrides the corresponding instance attribute _timeout.
Returns: bool
New events to read.

process_events(self)

source code 

Routine for processing events from queue by calling their associated proccessing method (an instance of ProcessEvent). It also does internal processings, to keep the system updated.

__daemonize(self, pid_file=None, force_kill=False, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null')

source code 

pid_file: file to which the pid will be written. force_kill: if True kill the process associated to pid_file. stdin, stdout, stderr: files associated to common streams.

loop(self, callback=None, daemonize=False, **args)

source code 

Events are read only once time every min(read_freq, timeout) seconds at best and only if the size to read is >= threshold.

Parameters:
  • callback (callable) - Functor called after each event processing. Expects to receive notifier object (self) as first parameter.
  • daemonize (boolean) - This thread is daemonized if set to True.

stop(self)

source code 

Close inotify's instance (close its file descriptor). It destroys all existing watches, pending events,...


pyinotify/docstrings/uml_class_diagram_for_pyinotif_19.gif0000644000175000017500000002211511273644742023561 0ustar ookoiookoiGIF87a|LBDĤBDĆ,"d^\Ԧjdbd|dJDT., <2,ܶĖvt|^TĞܪTJDlvllVL&$$D:4j\RTԢ,*$ԮĞ64 \F<̦rdnd쾼|fd~tL:4TB<~| ̤,"$Ԧ<24lVT$D:嚇.M~S壧|n/V.nS>s/o'i9џ.^gӄX3}/ELDŽzwֽYxLPף 64/x_FN'H%.zqAl["(HXrÕXe*V* [wEo]b!\"c\3 jhԝ,e)24DCrB,_/E`-)(`KǗ?h[BFp~H5[v2@>q%x GrK!SrDr(i#HapX2IEV{$"!yI24)O)Tu:[|q>1Kg=峜r2$ ,` 'Pa3LJ䑏":I}/GӪêW)ԏ6Ԉ =A-fII.xh`nرs-F I-|29tlߜ8Wdt)g\q3u(evޞ'繘.aԪ6ʫ[D9xzMmoLiK|J9!V1ى+>g=5 S6PEn\ U/P/hW2=y-lC.l! 3N6hCK~,SRA[{?U oD`S{/<,G߬w26 `(!vI쳒Wghv`إyaXK&[$P k;>A8%c E5/rh#'yb*GLʜ/4zl$!<.ϵیv|𹿽v#鼇f?a*AgЧ[_JOҪiV;y6ͨ_!H]up)ۑ%-mi_l&  a*no>(٩*6aLgBSdɶ!dHhD2{~.绫n6 1ŗ6h?/NW7g--~ S_`FRpC T `p`F`q~|A0G}gR"fr/s1$3 #CMqv郀 z@st?G7;Wt4ZvbIpuhsAucuW@rd'|$w\7Uutt-i(9WU{:jv1`Lngxp&dyr=t8SvxG|X:~TL5fUw!i9%yAi9878z1zSz zW0L,:T!5{V82vww(ŇlP,٤"$rmuJ!ȈNjFx^"vh([VVqwEn0o-"lQ 5%QBrr/ocR/Rq,r$ځR"51#r!s(Ȍ}"[.(vS687c7uSO587y󃠗A9vv1"9jP(hU8AX8ZE)4Bfw?H >ً(:{ѕ `IHWXEuAjFlXi4:Fbd {|5:(FZrGkKp{\Qԗaᅌօ]!r}*vU?n6~UO')A%BaMi* |p5pu13!h v׏aqsa.,7 0 1{cqt$cG*'7!?6aO7d mڃѓݩQĞt RjQeSy]FInIt9:J#*%' )+ڢe8yNS2*EQ9?9P?5xAGJpT6RBm^0DJrAn"ܸ~DEzW(tbzg )qэmZa7C(| y!)hJp_ٟ8闓ْC(S|fj: z j:*F Qj8Xv *Q*zxz5Z{i3*'|i!vѣ 7AChjkӁ\M\9R:9]ƥ!}HIF%kx:CvuZ9xq5pNǝ@r2[ut|'w$I=6c6t - ht{ʴhr;+:Rv*eLì`Kx.;8f hl+rJ:Ap{X-; @{;qv7qѮHz?#K* +$N״lݕD9ٞ<xrYT(Ӱkzaٸe[F(vX$`TRzgyՀi((&a'w0K iRR2;$kV ?ޛ>K6_]CA;L;F+yR1v+D_x7۳[ֵd%HZl[Cil l"LYx{hu¤ KU.pKUJ5}6V5MC,;G}^Uò*:dkrGpȼTR Ƚ4c kb3}`n;7<78>reƐcpx\0ܾX[eŊ <™y̼dw;y[8쨁;wܽ,t Lw9h b6tc \Zvq{ZĪ'%: 1W]훳̿i2\r/^g~i+ zvokoQ/2ɀٻ<l4a RUatHg&7l8 ;׿),>LI-4 #|!! *NPR=T]V}W\^Rm>Pf}hjlnք`t]v}k=z]g`׀` ؈@`D0ؐ= 0 9=9`0=9  V@ڬ]@{P ]/{` +a }]M ۾M}mo`}am]1 ^A. ^}>Q ">$^&~(n-`)..N׽W4n$0P4~3x$ >:}|yjύV9M.Z-h KS#f(\^[ K8d fNXRN$)Qb"ZP@%:M#$X 21bq-h✻&h-A!i.fKb'l-(`6h5[H,gtzr*nR>ئr/hrr^R虨 36/9㮾9c=c+1oRNZ55Z#r.Eo()TR8aCR9U=_=9ӖsCG$?&*?ePX2?4X3:wO/IAC+-EGIKM1_XZ;7<`O>/ZT=tiYQ(s ʢWHpx+ *,5~؀Ҷt1#d Kn R /˳1]_{.``; p}~.c0٧Lܷ KmʲſO!,)m `[L  H4;8Y_/بo7`-sb_OKs8,J@ DPB 1QDXEE:cE{%xdF3EZd2)8PN=y>YQ!<.q$"-H c!R1?ʤL ؈8}E!DD1sHb d(v+DHApɡ%*K֬ZʕmYs:+9"d'[Fz!fѭV-鈬b3V[w+|5}GdrCLι[zj̭_.9tjg^<]qͿ_=s=3w_A0@ D@D0cB0B 'B />C?G$Q CWdETĈNLpFoT(NTAFNJhN2I%LZ)e&pJ/TK VD3ͅR1`!5SN OO459 A OCA C HRR 0RMo|Ja!AٴTTUoD5U_eUXg%QVZoV\wNW^W`LXbEXdIYfUYh-HZjiv@7\q%\ssew v^{7_}_`xUzᏕ ʘ s-F`"B66 ;1X%Eq:ZQLcͨɆP jdڈ(MP7֙g7J+V 9UȖ5^HF i$H #QU2m ,PoC➻nzfѲ^hɐ6$hQx j% ˡ s0<ղy^hH&I~Yr/#*Wn:_,0ᮏ)@&|I ^qw$ J6џ!? 'zEZط/x10 J4g/ d hvNp )}d8 U*tCЇ?b8D"(aCpXD&6щOȐp5@h`1",Q! b3SdceF,wcu(E:Ďzd >rtcGD2Idd#HFR -yIdrdN _ JV+`,ȷ5KZe..X E/_K-J0OT S$r'g> NFhTGj+CiD:`:v;"HPQO: T?$Ozĝ(`,`¡5 &W`ʢD-.MGA $G%5RR0-rKWSj5Mq 4W7iz ,GEjRT6թOjT: LIժWjV@$ȫ_WI0լgEoz9`o}[:Wծw+]!׹8@׸ծlʇUucZڕXk[vV_ᚈE -g `uj=Y-mkVpE/Y> n- ؚ۸[k  zU}+W Mzw]W[oߚ-Cj1Yb Mz "xG`\c\ ̷q}jv{{z@A,bS b$bo݄f87?~ y,h 6?,|ȅ~q#s(1!I^r\klE<&!;d&u͛+e:'|ScuoE 7jC"VqLozHDQ PxWQL7Ak9a}CQze`9zk#=JԢkKd;{ף.Q^(Bz\lw\c; @uK\{/] $3"#΁mnt5q_mo|Vۖq%(WQkh*21H䛮p&gZf? \n#|pxeb\`)] 40J > j.4]\an\J]lW?>U{ouxO G6ꔉh bL$` ob ~z!R@ wa ݲDR`ⲽ+ ߸: a}oEҏ{q|_^-g.dB G_u@?_ُ7*5$ۿTd@<@# Af܀Rdtʬ{HA;Ac!$$T3@%(&ԉ'+BԈ@/01$C 4AHT5d6D8C†9C%C<Å+"Ί`,.a]? DDB:LXDAL8Jm BDbJ謼J9ĄDk+1J8r/+=/z]+8 F  Zŷ2F3fRĸSDG1{-P6I26dCǻGI<~|܌ ,"$Ԧ<24$lVTD:lI:h3x |RЬE@-[XkX>w~mܫ}#W\UuGq $Zp|)'Kւ >sC-ԡ_d_&`xDKl0ʸ!UR_ Hd'j-jA tHdni_k][dil)`myBlG%ekY斃&gyi`hDU iHPm':f!,(^{B`'몭 _om):[h]Wn[u([WXt1@)JJmm,k06mz,J mY-']f@Pqx,k,nH 0*B'/++ @mܱ ,[|p 7!1>e&Q EJAD&-7I%(iFP+y\!d^-C|G'tA-5Vct[sF k'dQ#2ywh_礗n][KTǮG%L/o<``7ӈH4B+kpZ6ӵDqm5zϞ;SBƢ^^ԍcD@:iU \zƤU}_=dֶG׺xҳ6r4_ X> 5 [ÙH/Vebcfp\3cHڅfALSI~> --u?0@0 U3xPɰ)@}"G~q WKs6hCF5tc Elp S*6' h _*z٥Ůc0c3K Fcayضa fV+E6 mJӼEm27ֲ % f(// `4KЏ}tgnռͭQjVֹoA`e,&Ra> 4>7}iV-^M2̎ gh쒆EaX Aox;F}o𬻠iOz +S6riw- ,uײ)D}BRxVq,2SPMlQtznq%S#-rs1vyFdf2s5F}>g8G>:G{kmcotM5>C@$v~dSttQg_ 4u-8gGu.N9P3T8VhmgYo8wYքgW9y8{7JօZCxb~aixrKQC!M#jaysYkyL؆v1z$bMv$'zX${qQlDmNn(]'/{XVdB}BTCwnG-h~f\~%on!Q)oъ!hhsRP$0 /gg(ƀeWd7-VSˈJ4oqsxu9P4'%>'r,((0@35hS긎1}ItTu:BȁQ{Hx Duǒ0?8-yI6<2Vv!YUvE9e:tIN)?VKUoQK[L0kW\ǥ$hz{e]M9Ȧ])ƊHt}x~}~!.Dn5Ռg'~ &>lAqaW3R1v<7#S*rvc<7+F )GGFY)Ld$)OFF;ɓOU Nٝ1Y99~QBY:BNtVT9JLSI9QSRd[W9'ɱ_Y4Ɵ)f$V'{ Zvl .^T rHIJc/vИ' Y37SvQrgМt[|tdY/)醆FztH#Guՙ l;-rzkZF}p|* Dwj8f-* 9SʥVkwiv]KE~!ʎ!\6kkrIUi(ɦ㥙[ZBফHɘ}ιʘFQoiأՑpۈaHp-h!6b%gڑ8caqAӉd;wJxj [+wgJf&wY}ѨSjw^?ѩc5;*t!\D䖱zq걵 (]$J"}y^ӗkHv:E$mڀ_{ϊݲ.Bo$"o9Uȍ"u*ݪ##23ɯI8qqrX#K)sBtv$m<8\bj=#)ui@*k; ۝˓~gб]u$z(Uٲ/1[UY[~AytQ{OQNORoqѵ˽onעuV;Djۍߺp!.{k7vl!л =7gzy+Vl'<) +̒-|*+- K:3˷99;ܼp񼣋f6ux#4W[:j?{A Ď+R%5x1Rh\Lۯ[LB[Т/]{`Ş Z9_^חxpѶmt|~[{m{}&33S`+mx7ocQ5{z@ |Ĩ*tiָܸӺMV° М/9/IB<\l=A@ \|L<]>bP] 0]5QO 1Op T&TCp Pp0}(P 1# 0J@B)@0GX0L'@< M]1Qm\IQGdJPU` je 0t]5 x]Q0yׂ==؃]؆׈y، ׎eْՔ]V}٘ԚCٞӠ1=ڤlڪڬڮڰۯs-۶}۸}7pA !uP:k9CfݷŭpܤSv9HV9 ح8݂XU<@ aCg潕ѳe4m}ܝzJIRz! ,L=@dmn!aѤN/N%nݗ'S(-N`$jZ| -q!^܍}g+cfCe{b[ENkM~*;N܍-n4/8>80^cV>-ε3ݢi ɇ6y %3%Ս^N0D,q3s.<3nh.mOOqJZ5S )*˝Q778\CkynܓcԣٍF01 z뺾uV./Ai-nˎ.۸ގ;>^.N>p12a,7m.&KBP x {?=f_ANFK\św g04yk@@a iP Sp{ ]fP Hhp޷(E[BZI0 } E468F}n*-nR^pab8l^`wZA@rL) ,[%EpEpSAS:0ʇs&n~o",>+_ϒ.ޝ@tO/>sR^S@@ qJB >Q"C6-^ĘQF7*H%IޘRJ-]t(0męSN SDOEERx$UԈ~DU]T)Pt|EV-DC@)j\^ZX}UUB*8EPTfzX䔘4PeΝOe(0TM+Rj֟ 8o#W^mul}o%~\9˝Sm\zӭ~]{۽]C,^շwo~|ǟ_~kx?R !dA0B 'B< lG$OD _F4 4(!ŃR1E;20"=1@4[RK,HMp3:4VYMEs ZC4$8# -.`5 "W`bդ3vDEoU+lX$=>\-esVnO6E)"D(MvEݷhKZlޅEq LW]XAUPzϐbYܖ[O43UP d;LyeT 5J5&[w ($ZšEqH@zIzId:/~v2kFF{uRކ;n离n;oa;p'|nݴGf<r/OzǼs!)?rGGtD'=p_Yw;vo{vQW}tw/x/'~=㏏޼->1D>GA D+1 X%pM4+.Àr 3S<@0 \ S" T'%- N @XapN@) BR06&DOFh(UDX54xM8A#f>M)N/Uo`sF12ge 5:gt#+1 cG>я#$^HBҐ{,wHF6ґ HJVPd+bINvғ&AIN:b1tR~ e,c Lz'$%S MD&-3LPޡte4Ljβ۹%5 _TC&ч 4fhZpE9[ x38YOf*Ӗg `o C+QPy6Ԙ?r1bʀ,E3J΃&t5̀@0h(,x_6ԡ-0PbҥMsIƀ5? iƠy12T-S˥6uHZ4O]ԔƼ*U9֖YV@h+.QL&@h. \ kZ)ԑuԃ1vnR{kC'0!l 6[Y⒱Zul5UZ֪qMmke;[ӑkmu۷.,__¸Enr\6׹υnt >(ҒnvA6o9o+܆׼.yc{^6)o{׾/|{_2@q;`6.u]7n};akz>_ /,݊MEQS8հr82(j0ͺZKqITȪ 2 96aԥcNvl%IKx9whÒ%ld^ E/"=AcX&!*Q{hE/QBC j1 c^$ɘ~neg rtW8tc=VF/֬Llb8u57iU2ٴ%+2maMJ"Ŏ_`;EQ;j}E&XWAo`%:XLRۂ m [fҘr/6W ʢYg,[1EA̸lXTbܸ |0g6a0 JJj1@q\#'9{Moܼ+7΃e>s9duscЅ>tGGzҕt;pyinotify/docstrings/identifier-index.html0000644000175000017500000013560611273644742020453 0ustar ookoiookoi Identifier Index
 
[hide private]
[frames] | no frames]

Identifier Index

[ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ ]

A

B

C

D

E

F

G

H

I

L

M

N

O

P

R

S

T

U

V

W

Y

_



pyinotify/docstrings/uml_class_diagram_for_pyinotif_9.gif0000644000175000017500000001716111273644742023505 0ustar ookoiookoiGIF87a0LBDĤFDĢ$"$|lZ\f\nlvtĺ <2,dJDԦlfdfdĖTJDvl$D:4,t4&$Ć|bTnl T><ܲdRLԮ\F<Ğ|亼ĴtbdԦL:4TB4TFLh\`hޔk;ZO,Ъt7 !4$7MfCMv8E0SD_ F YzeN=-YxF]4ڈ#u~22!uazU]wHfOBE^1*Wf|-TndMB9](2".ڵD}v'}p&)kmyY]ه3AH}5C (][!2t) r)uޢ5 Wo@@HA [45*+XTtk,9G29j+.`v㦫n`嚻Xc+ܺ{oտ,Uz@T$ 7G,hKƨRs,2eT#W&0rl_,<7A ,DW4SL7=G'suOSSWu;jf $w0BfTj!E䦭65kW&Lw(!q1n& H݅t| H uO1X(\&x`~7*PH$3RzeXu@~SI7xbeV"JR^8~k]hv)uT0BG ĮT߫T~jFk&i*f%K<*֑0*L/^_w$xa\^@B-52`XzW B;!\EC}M]cJqEQ)buE,DE/)2H6n H:QM1cM> i LdrdB 1,@$#d$ ?  !A "A!EDc# Hȥ@bUH&Y1 Blhh8lj^z(:iZ1(d )x`=Oxʳ5'@yρFP5B2p}"*ѫQG(Ful6 HGJҒ(MJWҕҠ4hLgJӚt ӞTh?~ӢONKEE/= TBSH&ZWuե5_) X³Yݪ[ץ&7o3`);L(+2:_i+G YB=T}v+dgYr*]Uv\e_;GƃSVT&8/GP# `[i[jdF0|n>L. u ]87#-DS8Duj'/۝p@I^MmvRT(!3&::y:YjXVrx+`Ze&egZ' 8α|@~+e ȔE|&; J*[Xβ.S 'J2hNsS8q'QLgy"s{g^Tݳ9Ntd"slt` 6q{a,;c%MjI[h+Z (=Ug\Fޟ~[ )F3RiMP!n2M.K}'/+CVҦvC,2ZUЍXfAUP/,ouq + ./+D CKIx׺yA.W|lȔL8Lr.(?de]-:YSm~tzQUK渺Ě=:ZжΚ W_Ȃjis˶og; P E2(>ռwpWV/|54Pb9_8r4b;=z4VWuۀ$7Vq=v03pWa-d+,LIW} N.2Gm"F T ;wA%5~<<< kkv\\#t!$"$5AJj7%Fz)˳#s7G]Uz$f%^.vaT-Hm<N.6AN7 &ʖ]gyr&v8oAXmVpmFƆV7loj012_E@u= f=kX?6agVv$*Qa99vn vVx`2։G:[2Y=FbtC|w%AbroגAocFcaJy+2FbLb3}|q,,%DVU..w:֎"lg1U.=tF"v`=#~?X8EtDq@ DxkDP&xFYtgg}}$ o!ih# g.Yl0)296 Nu"CU]5y7I`GfǓv"z'+Yi-.g|Ӌ;(]uAy92WAȧ|gy%z#zXgnS} ZUy~W}c]Ȗv[}9i8X$f[ƙ%=5XvY== =El26`xK_tAt~mqr8(qu &b)Bhaha ؉nmay+,荲ID,f$)-foh/4.19V.(2虞HDŐ萕DP3ipס $q&z/)F1u(uvFY6^*.b6CvIi17Tɓ73Wxt8yXi9QjoiiqiOJzq&vI&JeE ut!@禉Y;Ҧ"@n@٤x\ &ȅ{ktk?k5`:@im]-Gl19&vș=]Rφ$ڇLL@tXsȫHXƩm`h*T7@T0DH3yѝwjʢFpGbHhA (h&8+by$ YUY(.JU z{aDHd.I* p% "h!{Ė*;k,ETRuh| 5{2@Л|ADJTU~8 *W˒ F>1@yuUD%n7W*V0S$ F;0{Jz(zpN`XO2imju[P `tظ#躵$p&k3Tbx`[S`|~t[s1]v*OvAbsX`LБJ2 rzԁ"{!aY3XSZ`W{,Wk[0A ujw7$XV@1Bzuoi t[q7r:o~Ej1-Gp[>Wva?YS@ L ~){ kl} ;|ʁ'[tAz,$o~1 o(L {-NAIGN`\LYjűY_uº> _|Y_j}\yBjA`*`IРUlţwOܠ3K20ɺmVil&@?`i靳LBC`p1bF$0CXPIº}-aqu1ZJ|!؉ջ &HbQˏN aP@6 0_\|$ºC<;F0qyt%Âoo֟t1ZZd +./ N- 17RJ(smdZ#z֊Ƶ|,tn 'FDpG؎ؐm$G]ٖ}٘F٠ڢ=ڤHTڨڪڃHI5dI}5ItG3JtJ 4J-#KdKdKtL144L4M.dMrQ(4NdN&NNM+Ur߰1~\  I~>EQ>AW">$^&~(*"nd,2>4^03{rjTCi8]0D^F~HG0K`PBW.JC\`-a~`~]\` hF^ V>Y\xg>ANjM h>+@ @ + vnndn2f^x>,vvMAo]BF%%]0~~XNꦎW~ qp0{e>jp vN ^Q ] M `מnc1_x ,`w>䈐DUn^: ] :d@ v$I C^ PQ Dež겾dq p@̮+^3,]P C^1_ _J^*vN]@ p`"@ On 0fh0M ^oB_0DYM O, MZ'0d-m9?? 솿//o/_@.??[#p ʿ?_؟r03EE&O_2o?/oE@ $` >QD-^B=~RH%M TQJ-]>L5męSN=}T(Or^E%M>UTU^ŚUVX)(V,C'͞EVځ)Ǿ,[u-6^X0]} v#Œ$r8:R³~t-|Xă!dq.59:sm6zhaK^吣=~R::DxwoG/ǃRJnԥ(peS  M.s38Գ=Pj@Q:/=Ѝ.Cs1rQN)SDc?hhb-Ҥ&@q R&,QE,h#HLq1!Toq 5 jc?(8# ӏRXd J`#;£6d DO.%҉Xdo P~ÆVāhzxݏ>{-@<7z"t ,BoEA( ~D$C8וU-F6&PW,JDHYa?G>@ZcVdC:Qꂜ45! s/V&F;ᩎ/:x3dS$E-N/!JYrŽUIT%SUIvpC)+Y%ST$V-e 'Ii[%|˗ #!JQAuhIY%VIxi qAqYB1˅=@d)+4g\%bw2|E3@T~@ @ůsJq+cIz0ɪ^eU IQ# e:r8dBd ׉8"3Y\3e9 : K .LP?SlJRHb TB)ҷ,uwr4j`vm3+:8oi[Yqկw^Y׿V1!lKkX*gCd%;YVֲlf5Yvֳf،tŴEmjUZ"mle;[ֶmnu[ַnp;\׸Enr+;pyinotify/docstrings/uml_class_diagram_for_pyinotif_17.gif0000644000175000017500000001253611273644742023565 0ustar ookoiookoiGIF87aLBDĤBDĢ$"$lZ\Ċjdܲ<2, bddJD䴒T.,Ԧ|fdvt|D:4TJDvl4&$$Ԫ̖t|bTܾ dRTL:4\FD&$nlTB4:<4*$$Ԫ|bd亼  |j\~t̢̤,&$t^\z|\NLĄĎndܶ<24fd\64Ԧ|D:c6z]9Gs a0 Uwi։=!t5`F+e* exaAjzMX@xxr,Cd-^I`x$G (!j&GSI >EDfMHJm:W@qDpq1 M:AQ;;- #,Ѕucĥ0KMR9 097rL A\f17OfMS#g9wNQ:ģ>~s@JP}eІ:D#`ͨF#ЎdGG6o J2 vXL@P"LpLw'0!@Ӣ@:u(/ @@`G<=!!1"aX kNI ZkւլkK VhrͫJ@PS|ᯀ- Jؓ MbZƖdudOL#,f7r,hG[ђ1-jWղq-lgK js򶷣-p2"Mr:ЍtKZ؝z xK"x KzK5^GP ALN;Xp pAJUFxHJL؄udR8,iTZf]\b8Wdj%flr8tzv!8XxAD脐8XhPb؇8W qcW`a f `jlf7`X`tZ}(a f."```_g&v`֋Hb/&è'BӘ a4Mfc׍`H #`ѨtPfgfh`j hy|}V&|dVup 5h Iajs  }a to`( |"O0dff%y)ck. 54 $y NhSْ/ɔɑtFhfQ aVivnI`2g` f|(_Yi=ag>7 s0|&Lypx`fjn Q'nƓy&&&p7a6lRvk))ٚӶg7&_y9t1p a)8Ĺn۩©zfliٙ_Ȧl@6 avlɶlڨZv pijFlVcj:{cמ_ a pnp +_Faro5*qY q6j l HdP&}n98֣ +8e'eX2_pඣYol_h:tjJ`'w]*|*j` zʥՐ Rz(vM@n ,j@=FJ7x 3w`Lr)@j&JtzsJt;Jab'sRsʩRs: ɜ:j}}8BjJ`Ўp qnnjLYp juh_|@pʤ2_x@x[c _*qgo@DZj`kt0 mwʭ jWgk['Ke'i^~;pyinotify/docstrings/uml_class_diagram_for_pyinotif_28.gif0000644000175000017500000002650711273644743023573 0ustar ookoiookoiGIF87aK5|LBDĤBDĆd^\$"$ԦjddJDfd|<2,ܪ vtnlĚ&$TJD|bTdVT|vlRT4&$ĺD:4ܶ$Ğ|jl,tԮ \F<̦Ԣnd~t̞TB<,&$z|jlĤFDĊ|vt䲤̖*,̒rtfdlRL<.,Ģ̪D64ԪtbdlZ\亼䬊|ܮVTNL~|>< |fd^\̤Ԧ<24TJL|b\D:<$ \FDnl~|̞TBD\JLtZ\L:<,"$vtjdTFDdNLzt4*,,K5K H*\ȰÇ#JHŋ3LǏ CIdF&S\ɲ˗ QœI͛7eɳϟ uJQB*]ʴ¤NJ*իXׯٳhӪ]˶۷pʝ{؋b6,߿ LÈ+~ް+b#˘3_FKH͠CּvhI;1/kS`U !s=: ʍ_1̴-cbq9pȏ'5ơ J^9L,ÈςkI@HP9Y$Ͽ] X0Bz\vf6u YavqJ.}5 5T&*h \l%Hz&h0B[~6K*1ȩۍ{FI[| HD`GQاD؊@ `bQ2z"L&E+jtģ(H+tq< 򍂹fA"J`e/04DRԦ$`76 *>Bz)V*Q L ADjRY)ގ{ 0cEB1h~Wx̪ju? <8Y΂ Q7H!%-jY 餹%.ry\A+ȥ52+×Xd e1_!5aC *VVTlZR5h:SͥM3e"vJ˞R80vaHAu^op?-(U jP!T8 C&R(EwfQ`4*'xqhd>ꔐz z$UXR&Ϟ tt8Mx4@ B ׉REOnj̊jX Rj>"j1aU)8.JN0+55|$^ȥ"v0RtOԐT }F1l`1+ZfLB22$ȵ2(~O4V#OiScX"#Ǜ]̗#O2LӺKW5MjL 1 ߔӺ?: +*v ͑gt.ť` ҎwqR{T5cQaR9-'0'lBrX7{ ;|$b(NE\R'+8:,A%P(7Bl PTBJ{JlÒy)dGD) aKX9'_' M|aI` Ai/ X P9äV6R/5a? @KN ~0 $J ȄG +4-eQZ&"PU/duu\:տ^bdddٟ6@ljl 6-m{ܐAFέ#~wu}x;B}NO;\N'N[7: GN(OW0gNxCp6@ЇNHOqP y0}Ι^T`X7Z)p`;qs\hOڇދYT+bXUG:c)}@7E,Ot|\׻.D!Amh.|>%:O`#ކ lx+ >}ې|^lhBw~Іc9;y/E($H wh.s>e~PW ` >wevp` pw[' w7ЀHu`|WEyF~&Ig @w mPsPx?p}A  <t uC 8I9=8tR` m` RKMHuwǂ,OydG9s  ssC | ·Cgy u Bthx8wcs: s݇$jXy*8Qh ns t:@ NsDFsrtPzH@7>Wg@mALJ$gGMwo>s#hst0@> R` ?>G>(H@w08HuCPX)sg&8 `/ks }t7s} | y|`*s ɐ(m ^X19m ȏ'v0YS5:yx4d8 @Y@)$guE L9ňTZhg@0dYfyhjlٖnpr9tYvyxiea9Yyٖ{ٗ \דÈy^4Fy(dCٚYY YH򗉹ٛٛ9~ yșʹ9ؙҹvɚyعw9Й{IiJguY'yX詇g tywu~Y?d?}ZtwIt%tאd*t|Jtb}"Yw7uz|g|a8D }w xtYy(G}|G|2j{!)x ((S @ȁȌ\*tg@ m@pPv@Zu!8Hhwd m0"JfW& WIA8Q؅_Yy PuPW 3Exh>Gg+XWzt\ڧYׇX#iZtFYPnP}WȒ} ج Uʙ:vΪG RȊ A o,Ɏ||ګv7yz#z%j8u8䨪EGYy oHwK kyZ -I' ))|ȪzK* ȱ' hnjj ] C[I+h_vsvYk~PP}D{TJm u:`+9lTr{LIix۷:ʷ~;$*jhxɞɇk k}/ࠕkn+Twyᘾ|8|{] | -} -ڢ|KʫRʺ:}w 7wm`KϷ;LX?' zP*Ps ھ:+:y #[Zzux ̫+|\ يA P*PWbXІm($<|ਇ[xXgm}: bs ҹXiϷ(Y `ĭHuj*Ah(<>|@kӉ(tG+vNKWW੻ʤjs;: \TgRY DM 'ksup8 נbˏ'J, ls8>W͋8 Ϩ˞ +P{{|+ͷ|}Tg zyZ& m yIkm:'tNz},E˛{rʀzRG y_0ȬS@甦9{c{(כwimJt-*yͽujUͿʊQH^Xsmzh 7X=x_p *t> LͅցحZwʩt|Y}jyl\IJŝ{|",tm0D {ި ui扫^HJ u:ȃ$;К{. Ö׮'¨Hn[myPpDG?W^kyw̶XZϢMt2sZ߫u?g(wjJtt'n\ϼky؍( $mYpW;tа@G|D֫ ˰E>玹L ؗi,?ٳm,!9t{PA9(ja ڊ RwŬۜo̲FL`,| )E>g(/=~bǴ:m߁τ+X[ ˏu>v0ʘЎʲ~~흜Ku\>w ^k  υ>׈Dh!gy.m@Ƽ<@̔yܞb(ͪރp@w Ptpu@?K|@a?w΋z>Π}.wz !䴎Z?0>Lߩs޸Я{ =|A[0ƚ Mm|gA-J x>ݗ?>/|==+ ӫ7Ӻ7;:tcM}ϣKԦNyG- KO-Q8t_wV},|/z| ډm,%ߋ՟GAguimo;=ثm@jʦ?{}=cIT7ͅ}ۥ]F6lcRA RFm"h@Sv^y cņ$!_nUx1F%RDEWu P'M3BMB(mC[ \Z ̊*eVZJ7nuҹEFF E2%KcVĊ()ۈ5$V k`NZ^M<0'1kxċ .v<TJG n*LPsB ٨Jk/n];M~WL.p՜F6AKPk[0JFj$:*A$ZP;HA@+E)H Q!UސꑨҲ:x%EVHX#25̃<$B/%0CŔS)^C@ : 1Fҥh*RĎz RH*#&baM z63=+sΊ^!\ebC>ZE3l7+HXbeLEZL(t w\$ejh7]M2Xe^F$g i vc]ֶx}k%}=d_9fgnUb>fRId۟F:i۰XzgGjڼ.;5[ )(1IQz<ӦnNjۮm` 5 Va#?,r 7d+ )H `*0d*gmLQ?Rlb(R  BdB77Cԟ~w feUa:vR6:hZΰ>`i,3i33:R"<A`v$y&yu)B,I|x{%,(z11LcíL{f:4m0 XL4KP:FJS1rh)ҡu#H;-< $C=} ~Jt(A H R04T;-(j_ d4F2QldBhV ;Qf16 pgA)uKm^j郖ENv“'QTPZ`GݲjjCxCy TLLU]k 2+w4g!RYr6-W~?a|K]i^Q ޗ@&0mF;abC6&YcH222$]c3g-|e4ik*ekv&[֖$lk2چνWr7V_3Id/gܘle4͐rf:׹nj3g>s )ܴ!HnwQ&" >!]Yٺϗ|p堷Q.΀3={!ng>h}i[ӋYT{Oψ Vā@D 6DhI`)ӹ.a;=PڧvgXq|!h~D҈id"DS<1)@fq] Q(/Șrc6챏, نB<,T#ikʻ<59iOJDD'3a)t W<-CP%*KXB?0i`,3e׭jZf, ΆӹN4w1ʊV{*=uR$jBrT,T*(Dq9" 0Wцh|Z#R-)7B)JR[|cLcy4VnT3mxjT.gaSjDaʆGJ́(B\AX.&/(D )*|,,ɼCӔBd:@0uESC[, @CwȰZ|+ >86D3 ADkt%1HtDDK,MRr̲mN|PXp-j9EIEYQUُeYEMŕP/E&٘Ŕm٣3Te7SɦZ{ګ++Z#Z-$G4/X|CzGyd 4Ș,9ȄܱU?HZ1X`!$a|I6ͩ,[hDI\8̝4.ʘʝDʕ7*K};~k#Tˀ㖷>2>ݥ"]LL:L39LЌ|=ӕ=KMcMPMM쌥=:`N4N1%k_;Pko;);٢;; _E| Er؊X1 " $ , +#ESK)1` NjO7T8u:CAC;MT04T9 T@Ѳ T@@4a4U((+QUUqUW6!,e\6!bePDQBf.lV1Vj'$/h=PUVMcL`B C"3l035ܼ#ZWf|yC} >mIf^XU;D[D+HeՍ^]Z Y1AYzF-U\Zٝu-g&f̙*pvag6i>镾f>?^ZN5ʛFP v6 AHiM蟘ܧT͜@} 7h6Hj!iHU!N jX!9zK77C]]ץ;P7;D]Ԉ^̒M9LF$Є](Lk̎) F^Ͼl֐xv ߜ[MCTdFx9m#`%?n-.ϴ[F'd`|VNmFގ &nΚߊ6D,$`V= Eeh*p,%h;)&PQ`So `{JQgoF6pOKڔ❚ܫQ= b-6 -=!E@K.?/rJƽ¨Q2nX+bo6I95ܙ_y lPB,DRELuMHT5^SDE^/BG7tP}6ySDkvMFUOƭUUAZegE34I@ZF[F6<Y WOdBV/'(dAVV\ߎYIYB XoP-g'PuS`y1e/-PN_1frqvs Eȅ8D8O˂;J u}rxtXigsDJlJ/,j~p/qxRwvOhvrHnOin3 yib\?k4[!hy)y1hhxa褁薖 ڙ6tFzDNy[z^'7GW?1'/|CHyQgwLJȗɧʷ|OVg7GW'wׇؗ}oٷ'7~WgO~O;pyinotify/docstrings/uml_class_diagram_for_pyinotif_27.gif0000644000175000017500000000703411273644743023564 0ustar ookoiookoiGIF87aLBDĢFD$"$Ćf\lVTܲ<2,nl vt䴒\NLԦ|\FDD:4, 4&$fd$zl*,nl亼ԮTJDt^\̞L:4TB<̪d~|Ԧ ̢VT,"jd䲤D2,vldND|dJDĞ <.,|b\TF<  4*$,~|nd쾼|L><̢,&$̒z|dRTĄRTj\lZ\ܶ<24~tԪ|D:< $~t:<侼ܮtbd̞L:nTƒƙvPHu%a7` !!V]](bn<$ѯ׉t:1]s#6՚q5ˆ^7FS'#8 ڇtbQpOz3}zF4ږVow8C.۸y$^e#/7ּ AZ:=1/?> ,}L. o_@pPya,H>$t:<c(P1\p{x@ްrE @Qyy(b0vGBR/ᇡ+b !"p=48 X dHŐb` cTũ`/(#X4plt͈9-vc3<1`~c)]:$"7E>$8X̤&7Nz (;Ɂq`L*WN#,gIOA-w^>E\ IbL2f:)liLPӼ6Mn.0Ir3 n4a g?Ir3,B9PX`D$@%fяf@ ]PC - #iSJk#⬩NJC` @Q B2 İlA $B kAXӲ&ɩYת̧a+-!҉v!~ Rd$C!HC` `i\RQc'KVCq=,;/G5@Ȁ250m,e ٌHvl;LF "x'W?ȴ0L3d,n N&tfbJ6" x'T#a=aJ`QBz;Ҵ}u:1J8C$ Ҩ s 0,HX[P^DGL[$NCl⊠x۴&g4αub4&L"HN&;PC RͶW=bQ7l0B+o)|ZuY0Xc!ަ<S0}.i*yV{y1dkA^q^rۜ.gU53R)ڤ0 ,'Mb̋ft%a fA`oJB-D,3wC.!ɑ 6*]fK_݈N %Nq pyinotify

Module pyinotify


Classes

AsyncNotifier
ChainIfTrue
Color
Event
EventsCodes
ExcludeFilter
Notifier
NotifierError
PrintAllEvents
ProcessEvent
ProcessEventError
PyinotifyError
PyinotifyLogger
Stats
SysCtlINotify
ThreadedNotifier
UnicodeLogRecord
UnsupportedLibcVersionError
UnsupportedPythonVersionError
Watch
WatchManager
WatchManagerError

Functions

command_line
compatibility_mode
glob0
glob1
has_magic
iglob
logger_init

Variables

ALL_EVENTS
COMPATIBILITY_MODE
IN_ACCESS
IN_ATTRIB
IN_CLOSE_NOWRITE
IN_CLOSE_WRITE
IN_CREATE
IN_DELETE
IN_DELETE_SELF
IN_DONT_FOLLOW
IN_IGNORED
IN_ISDIR
IN_MASK_ADD
IN_MODIFY
IN_MOVED_FROM
IN_MOVED_TO
IN_MOVE_SELF
IN_ONESHOT
IN_ONLYDIR
IN_OPEN
IN_Q_OVERFLOW
IN_UNMOUNT
LIBC
LIBC_VERSION
MAGIC_CHECK
__author__
__package__
attrname
flagc
log
max_queued_events
max_user_instances
max_user_watches
name
val
valc

[hide private] pyinotify/docstrings/uml_class_diagram_for_pyinotif_2.gif0000644000175000017500000001666111273644742023502 0ustar ookoiookoiGIF87a0LBDĤFDĢ$"$|lVLf\nlvtĺ <2,dJDlfdԦĖfdTJDvl$D:4,tĆnl T><4&$ܲԮ\F4TF< |lZ\j\dNDԪrd\JDzl$|̒  *,4*$|f\쾼̼lRLVT̢̞,&$z|rtĬRTlVT~t<24tbdԦĚ$D:<:<^\ܮ䶴Ğ̒ԪD64\NLܶ侼|fd rd̦ \FDt^\|b\dRTL:Kh\`htk;z ,*t5 !4$MeCMv8E0SD_ F YzeN=`-DYxF]4ڈ#u~32!uazU]wHfOBEa*Wf|-TndMB9](.".ڕD}v'}p&)kmyY]ه4AH~EC 1][2t)'r)uޢ5 Wo@@GA[45*+XTtk,9G29j+.`v㦫n`嚻Xc+ܺ{oտ,UzT$ 7G,hKƨRs,2eT#W&0rl_,<7A ,DW4SL7=G'suOSSWu<jf $w0BfTjE䦭65kJJLw I!q1n H݅t| H uO1X)\&x`~7*PH$3RzeXu|@~SI7xbeV"JR^8~k]hv)uT0BG ĮT߫ķT~jFk&i*f%K<*֑0 *L/^_w.a\a@B-52`XzW B;!\EC}M]cJqEQ)buE,DE/)3H6n H:qM1cM> i LdrdB0,@$#d$ pC  !A "!E@!c# Hȥ@`bUH&Y1 Blhh8lj^z(:iZ2( )x`=Oxʳ5'@yρFP5B2p}"*ѫQG(Ful: HGJҒ(MJWҕ֠5hLgJӚtӞTh?~ӢONMEE/= TBSH&ZWuե5_) X³Yݪ[ץ&7o3`);K(+.:_i+G YB=T}v+dgYr*]Uv\e_;GƃSVT&8/GP# `[i[jdF0|n>L. u ]87#-DS8Duj'/۝p@I^MmvRT(!3&::y:YjXVrx+`Ze&egZ' 8α|@~+e ȔE|&;y J*[Xβ.S H'J2hNsS:q'QLgy"s{g^Tݳ9Ntd"slt` 6q{a,;c%MjI[h+Z (=Ug\Fޟ~[ )F3RiMP!n2M.K}'+CVҦvC,2ZUЍXf9AUP/,ouq + ./+D CKIx׺yA.W|lȔL8Lr.(?de]-:Ycm~tzQUK渺Ě=:ZжΚ W_Ȃjis˶og; $PE2a(>ռwpWV/|54Pb9_8r4b;=z4VWuـ$7Vq=v0s/pWa%d+,LIW} N.2Gi"F T ;wA%5~<<< kkv\\#t1$"$5AHj7%F{)˳#s7G]Uz$f%^.vaT-Hl<N.6AN80&ʖ]gyr&v8oAXmVpmFƆV7lo 012_E uf e=kX?6agVv$*Qa99vn vVpx`2։G:[BY= FbtC|w%AbroגAocFcaHy+2FbKb3~|q,,%DVU..w:֎"lg1U.ftF"v`f#~?X8EtDqP DxkDP&xFYtgg}}$ o!ih# g.Yl0)296 Nu"CU]5y7I`GfǓv"z'+Yi-.g|Ӌ;(]uAy92WAȧ|gy%z#zXgnS} ZUy~W}c]Ȗv[}9i8X$f[ƙ%=5XvY== =El26`xI_tAt~mqr8(qu &b)Bhaha ؉nmay+,荲ID,f$)-foh/4.19V.(2虞HDŐ萕DP3ipס $q&z/)F1u(uvFY6^*.b6CvIi17Tɓ73Wxt8yXi9QjoJiiqiOJzq&vI&JeE ut(@禉Y;Ҧ"@n@٤x\ &ȅ{ktk?k5`:@im]-Gl19&vș=]Rφ$ڇLK@tXsȫHXĹƩm`h*T8@T0DH3yѝwjʢFpGbHhQ (h&8+by$ YUY(.JU z{aDHd.I* p% "h!{Ė*;k,ETRuh|05{3@Л|ADJTU~8 *W˒ F>1@yuUD%n7W*V@S" F<@{Hz({N`XOBim u[P tظ#躵$p&k3Tbx`[S`|~at[s1]v*OvAbsX`KБJ2 rzԁ"{!aY3XSZ`W{,Wk[0A ujw7$XV@1Bzuoi t[q7r:o~Ej1-G[>Wva?YS@ K ~){ kl} ;|ʁ'[tAz,$o~A oK{-NAIGN`\KYjűY_uº> _|Y_j}\yB AL`\РUlţwOܠ4+30ɺmVil&@?`i靳LBC`pAbF"0CXPIº}-a!u1ZJ|!؉ջ &HbQˏN _'@6 0_\|$ºC<;Fpyt%Âoo֟t1ZZd +./ N- 17RJ(smdZ#z֊Ƶ|,tn 'FDpG؎ؐm$G]ٖ}٘F٠ڢ=ڤHTڨڪڃHI5dI}5ItG3JtJ 4J-#KdKdKtL144L4M.dMrQ(4NdN&NNM+Ur߰1~\  I~>EQ>AW">$^&~(*"~t,2>4^03}rjTCi8]0D^F~HJ%P @BC>H>RA\^R-`^f@P UnF>p Mp~x &CyF. @0vSn]fA荾$Pu耐s>k pP `鋾M!E @ nrpr cn@WCN  , 쯮nS P纞_ pD^~>PcP ~1~^eN %@d>c ,; |K.DP. /SNe~($j~ ~ uNs0P-*_0,K m S ! Ym0c-lLOI/K_j(lrn.p?x`^rz|-qp?_33>_T?_/O+~_(O&$!ȟʿ?>د!޿/?P: _p IE>Ѩ@ S2la-^Ę#>g<~RH%MD2e]l]Zƌ&AGvڐJEEeAm["u!A6ڴ 61g93X邕+W9(m4MXbKa g)[jV*ɋK+ 4yeFMD ]ih<[ j6/2%bōw,wL&X)HmƭM;.LYD1b_iW.dDǏ4M1[D<Ȱοh<$ʮ@DKϠ0'Ò3<=*)ZD eq 9*k@̰G60 AP4!(KX$e7iM%% ǖTѡ L 8{$NH5#D.) Mк p6JJ /mR,33LsMK/#Izð<<֘R /E5L/"cIzdz3KTw-jU2cEJSp;ds=WgQuYiVg]jT]h%\ qe]MW]mݥރu]tuv_z=  >,8 .5t _y_:ƂFcKc *8݌v^h&iSm#PG/z Zki, : QZBX8* M $amtł츶 +ժfo/Lb{q)OiKQDvl*CE5պh<5<ĞD6,tZT\JDTB<̞$d&$Ģ^\z|~|ĺnlĔ24̬䶴Ԫf\vlrt~t<2, 4*$\24FDĆܶ&$fddVTܾԬVTndĞvtܮ>< ܬ^\~| NL.,nl侼64ԦĎ̄nl̦̖̬ԮTFDt^\~|D:bl褗n騧ꬓ -n-7Ct{ngx'ГGvw1X]~ว^c7>|4bٵ^xH2񘏀u(؋O b`oyj^4e.D{u PMaPfY; ,bq&2 =aC5Q>"y"х o!knGWnO/2,YE8zu iHhN8VF'(X30\G1/w:@Fdôvg9+#0ΨJ0A%: OtU,e'Yf\<vAFIv֭p+v:Wi`ud\^/Rm]NzKG(A)%ǚw av_F|o~_J,d{Ckv,L7Xu1JTky0gJȎT*s q7hgiEbVB`pj Qy2vf *y~T)AQ5Yu2 7U+&+:8:d3cJSjkbgC0v>pXpJJ1p*oy/e;:͐faA@FF:>)>NgӆՑ/-eK*,\ZO7V:3J9!ɔP T*E2pva >Բgm[iQtߪV]nPݘ%mkqS}x/9V4BvnG%J7q-ʨCnM f/U4r<+umTOG "mHHMC=d^Ǝ38AG#fqWw-CLP]0kr";+Fȓz ȟIvt0C6!-|Snn8 -#0IR+37Aԯbe%~W굳V-;ˍzĄ`AXȺOvAN+(S82vx_~73 J(zWm 4q}"'V u} ^b.v.s~G~z.؁~~u G}Y(h^ޱ, kO'V1XX7rh [p(z6}U}&#(CEx&3ݖNX"sR.cxa&!6lSlzc8` !00je>$GQ  u5rbwx% .00d> ` z\,r&WBdRGgF凪|TȈS7ih(nj5e(z,  ` Ҁb>Ȅݸ@%n('x8xܑ_p %؈{u/XQa a|!zqWrmA.="pY(*pB3 SACaQBB;4 BE~C+T]$Y7#NNKNt%)EIP5RUPQSׄÖ́I߅Pi5YJyOIܩ2#^Q[$\$YZ^a,Hu*Ve]{$YQ@ٝ8c2dcFe hkFihVi fj/hƟzi#ڡuXڢhR=Fnw+o&'v4ipcWrzl3lwjs.R=r. wgwmgzbyGy~ut{G'|P:#R=94 zmxyV@0N)X}1ĨW[tzbQBI茡2w{؇bsxa󢩦)h)!! #ɫ0 j3wDcѓZ~vaB H#Zi+:zQ躮*=˺7ڮʮ::zj* B'dK{Yyjiq,(`yavhơjյu!*c}Ųn_{Vqb)iaE̽q)E/Lm,KP7Q]VՈZՒ2Ab9`]aѾ=I;DG  ,xj+UQ)RE1˲(ر=5Ą]" `J+Y~j)W"4~nS b,eVhV ȷm{|' "Z͢."{WsapnpD &?:zl qh}iWwzx̰5-i*.~HN * Ϗ ߕޑ.YM,'ڹPy - ~ѱ(}n>x'.ͭB#ϫ_CT -~/463:<@-Rw˚׉&o&a!C$F|ZwO3EK(  n1[A| ZHb2F ٠Ofl~MN mNu ؞/' l1|$=MBU6\QATa&L4{r$8W/)JT T ȯ%MDR|x|zﳿ>\TlMYZxJ@ ًĂn4ti, ^XT f`1muh' >ă`Hd{!rC$98Ċ5iHT3*Lΰq1ETRM>UTU^V]+o}[Tg8hղ=Im+\yYB`I8zm5y6MUҲ6hښW_Ǟ]vݽ7*V,Xaɚmw93{\`nI/'/z7}߇?~D^sA`&3f8S816ՁqhFaTRQGEy&iL+R|0^T'S4]M}:TjQԍ2vd3UҩЃjUB,psҪjլgEkZպVխok\:W5j@]W`jB_;XְE[  ld%;YVֲlf5YvֳmhE;Z*B jpiUZ&jB*Z;[ֶmn;{jnзnp;\׸EnrR 5B Pnt۪2 8t]v׻n5;^׼m-Ԁ]0 Xo~튗pKZ0E ^2!d00"` W5a(Zt(q/t_/cnW=~kb,?~7 п~l/G?S w-ﻂ$4DTdd@< p d@ <@X@ $4dtA,/$$B7" $@į T' !4) $,\@&/'/dA)B1 ,,KKB+`:@.|//=lAAT:tC8C:; C324C4$nPnh;EL@.8@`WXlB4@A$LE4DMDS E |DH8[/JT!A5xO4FCSD\cFbg cH= + = ;;d iVjȁit PjNDƁ:LLi܆v4d+mF:;@H8(+jp GCJpi<,@4/,F 4ĹpK@@H8 @W:̷+PLd˰˲<˴ǵ@KF4.ICJM @MĄM\DL؜ƏCqf~䂆XCLD@,/T@M,@WMD:N@qNMNDN$͠D=pLGMy,+@4NCARBSHUK1=`xL@E@5N\Lќ2M+DEETQȄ+ݬ50: + K"]bK C $5 k:9%5-.UK!%DR }O6M.4\0 Ft=#x:pISDiHpS@$/\L?pTH@ƌ=p:hG+Q%UB5D EmPWS}ƟtSXy)BWh0WxamL@Mɖ\EE$KIJ/KEE)mm+HjmPVrVyw=+~GLVNV~x]5UU# CWԅ ρ9-@XiX lz؎Y؊-YXqpϑmuYՓ9>jؚٝڜ,Y٣B-ڂ%”eLZکBZAZuReү]XYA%QTى-ZYEưȱ۬۹" ZAY AKǍ+Kȥ\ܛ$-%P5E:eue-!٥0Ƶ]]^ 5ޭ=U0[u^*m^3,;pyinotify/docstrings/uml_class_diagram_for_pyinotif_16.gif0000644000175000017500000003732611273644742023570 0ustar ookoiookoiGIF87allRL4.,lfdjdĂLJLD̢rdܲ"L:4vlBD̒$f\dRTܢ|\F<,&$  ̪rtD:424lZ\~|ܺ,LBDRTj\\NLt|D2,|bTbdԦrd̞~t|^Tjd TF<$"$*,T>4JLܪ|\JL Ԫ亼Z\jl|bdԢvt̚TJLt^T lVLĢd̢rt"$zlԖ4\JDD><24̔b\Tj\|nl~ttbdz|Ğ䶴䮜ԪTB<Ğ nlĎNLܮ侼^\nl|fdԦ̞̦vt&$64ԮL:<\FDD:/]m_ {It}Yt_^[bYxF'V (怢,5 b`/zmX8Hao>hJ`Xxdooh, & boxi\4loRD7fgfqlAI2/H hRo9%vY>teֵeo@'5ЃsƩsd.sW*o=TcXhVJjoXx+,.iز5quۛb).AAKkŹiB ř뢽)r |K!tmm܆p 5'"Rpp:y,m'%/4p4kߑ j$;2 k/Tm4lAt>$[QJjE|s?oZ`gxB*i5Bى,ypwBJ!79Ѓ3* a⋛03oyR)(zu K|0/oiIҫK`gD:p>;H$5 z"̠Alu(HGؕZ'L PA/ U gÃ@ #XI&:#HŏXԝyW.ZY |r*#z1WCNL,c 9KwģCblbȇ 񑊑 II糃&7Nz ( F0BL*WIKbG1)K\/_& &Nz 4fBnfD N` gִ`!XX &8I F'EG:%\'~_V.sw;ڐ?G׬n3p}zD/gG^/=Gx/F_/W>F|??/їE__/>E}.D_ Zfav,4zn;1.wne:EW( Auat W_-7?MWXWcQy)4nWb[ BHQyI+bd6f-xC/1(Qy\ffX^<(%^Qyg-Ck~6ԃoL(iaz8C름.\Qyk39Wjb8gS!oq(ƥsu(rVXt.HGW8B}Ȅlш@ifUaquz؉wH$iA2XlĊh$FxXwsshO^YtSWuWw9*$ցHhȀ2vc7a'pvivb5B'lWqeGI8=3!c5xrc`e{g&c2,dY9YysCGfxeׅ )ty_&gLBv{:c'}${Yg'ip-,XxGx!c\404]H6V#{5%I 9 H9GLWilIT9|:{Ɓj#{ beJbE-($qDYsFFRzr_4V(!$˷ zwA1-A,Gw8HdGQ)c eF k:He5r9}藸7py2+H` |Y|+Ѕ {^לYt|{䑁JcMy}yԛ_ sZ PzC majCJ4 E$Z&z(z@,0 4Z$<<79HJm< !7\Q 1)\ڥ^'?MlQxPP }D #R!OR~VXjt &f^9! phYGK${G~}o*;Gi`B/(*/A))9V0栩m}3[E֏A629$,Rb'}*ʫ*:*!fYұ0 /ҚWʜ79Gbȑ2jـ-G[;DccS5tjā 6ȕ:kʧ~}` "br$pv}@ A9+0 ~t'Hڀ< r:9 jy=X3֞B P@h yj}/^U9ٶPA.Q?@0V,)} fUs_3܎i^f.֟N]cj^}`Zo?]oI_4}׺|!:=~Ώnn8៉7=uy9ձ_w:\i-: \~t_O["¡+09깃 #[Uol .m \y>fz}tO~n{W~Y/B|t'/ĝjQO_oQ@@ DPB >VlhÍ EּCF'PlĨ#E6p*IҤ*M4bQI+2xb@ȋG,ɓP09]3/( uR@IiЩTrZfrvdT`$ZEXbƍ?Y6ƜYfvZtiG`R6׏>Q^wqٵZy7m\WEV̍\S&GyjV,9[6q+&I-rDcPj_[Nq9Gg.2$@dA0BB-`@*>(Y8P1=s+NlÞ4ˊNf+QFӎ~ȋb=r (9I@OB(DL3D@dM>s3(NJ"f.*ݲbOѭ!N@JTQG ͪN NJIMڴ&>RR+ LNd\4X;*fMW__ZUańsXcǜ"/.| U/JTY=qŞi>pfks>Ǘ%[h+] UT\'Cr׆l<ְd;Gk rB04-8Њո._*NIve$(DdWG;9啭jXFYeM"f%CQUfҋI_X郺ǡV &s\zآ~)"R,@=0F:,V q *nSqĥXqĭ8Pdcg+H7}ٝar* h@Wvщ|ipZmI>V+vE%%&睊-op{}a>o8)к杻YyNs~!pX!({~:ωslLܷAn{UQO#UoG:8?qKE,rmC1 tB"VDt(Px%fPD*.fPaH5"0#(B](TZSUUG\"G5эwcVk\7a[Eږ i[O(&kHHG͑ c$5IqX;ki9S](BPzMl,'6Kf̒M&eK^*ƓJ_xBI/'Nu̹rS‚<)%.uKmF'/oi~_8}nL99O@ajWL)mSM}ЗΔA25*CDe,\0(1yAxqIjrd/@ [=+xzORlj[YԤuMfqM[@_ _#AĒgHĕf6t+h '^Hԑ\I7lы~($%G0o qf%Wh,KP2F IQRӐ[7B%,\(wSL>@qL*=@5H"[Eje$;1WBjY/{WVh K>,WṠQ3hC +a]6~L^7aIql s!E.| nxU,jbNsuyf'Ast<5d!X,%SRe6 $E< A;b*U"jKYǽ/|BI4ԧd -d#4QLa`_%j+:zz&Jrgf wۘe9-)2l٢(g}Z־4* tu]3fUc2^K{v]j?5p3*Kv(t!-څ+dnsV*&#>h|3#͕-fڦ'䯺4ı-q8OC of^rŜ2 wR<4CLg}zi>uݛ)[##G^g.pL1fhMNW"/E`BϚMl 5i^ lf#+-/?!ҭ-g{$h[?iJ{)6S06"A.rD@N!T7`7rxR$+>J>:I zY@0#} 8Þ!,cKB;?{00;S]0II؂Ia)x%kP1SCs8+踤YC+ԌrJVc5lnƼy";]^cE`fCǗ(<$Ɋ䒬8j6 zEGm@%?`@[pCsK pɔ./T԰ĥMI&Ď7r˷|B}$T HP0ӹ1x<˛áIZI#<'$ 39{2Pz1 J3f̲1[ŧʆhKڄtDŽȔɤʴt =`Ll]ZĄ;`tׄؔ٤ڴMq`F@%p| q<\DM{FXF0|KSlNa`d/eH`[@PNND.a8f1J# wh-XֵxVVRIU G@F`B$XPd% ؋ZxŚNHСA@d<|: Q)p[Y\AUab ]X%W4 Z]}\sZBϊbfk_M^fjkՒq15[ES{gxpFЅ fAu2,M]ܻTcv8|ϊߍ UOni"Y- !t i]i4[F@9k ߔGO@:j6]5QKmgxB5R0иnk ^Fk:k4a nRv]a.lV~ʶl"fՓ~a-R)7^c$^b3./ScF`$b=0~;=֦.0dFAB]C N%4;vTf "FcPMoFޫ.9nѸެnM,Ld_+`KL>U/tTp`pHno~vWV:9de IqXW[%p$m:QA c>dFAwafL7#wX)zڬ͗ޱrip>K(4E&pr#]h`=g[Ƹ8ۂn[G5t֏%sxiF>\1&Fh"iRtVtlyl__Hruk ru_ALj_Qj_`/92M6ŻcΣ~ovav> }Dž'f  gQg/nW`\}}t(Fp#(]~ҒwF {ۿfP" llnZya a+/g &4?f|nO*ǿ$`a,h „ 2l!Ĉ'Rh[A">,i$ʔ*WR,%̘2g FZ5=j B-j4ˣJ2m2F\Nxl*֬ZL+ذC-l$V؀βm׷rEacWblP/`q.5)ame1䦃#S<.F|e[Gf94l5$gӖx6_a+-@u/~8rPY:/#cɧ>N:d\dM𖭋/O7Fec>? 8 x * R% J21!j!za8D@0)"-"18#5x#9#="> !Cy$I*$M ( ]q%Yj%]z%a9&ey&iZ0\9BNq :(z( U(J:)hqfel JaXz*Q240:+Z(y%*[nz+{엌J騕:,bʌ9|! (Ҽq" "Wq̹mj({(|˭f-2{0 ;%\'|A$a`͕p "^\|3's&ɇ G9؄L9393o\ = /D+[|b*hƜ0YSm[w=39*̇: g,׼F4u[jBH7k7}++|w%ehIbo*(,8v7睟wBz{>: lꘚ%:4Lb̜k)|"偣:0#XWf'_Ma0W޿͇ o330ug;ݠ#$:s!B<"DVq B()RV"-rZ<@xf<#Ө5n|#(9ұv#=~# )Aؐ-|$$D1$&!9IaT2$(mNg]KEQH]TNw*qs!ʄHl"b 1E|j<`2tP/ M8 L_ iҨUIFu_R*'OeL@KHs [r9tAI&^r鴺TB":\6Nן!< aqkYMG'ayiWrl]zW_ELp:wrW E(J~@-=M'H |x'qKo G< ^Q S:ԑ,%qK\}v ̣oure"[ʗB{v&,հ5ds\UhZPV_6i|[>`o>+]ׂ%&CvKquj.wb_XvVŶڢ㻎NЕ.uQ{5O~U)iNqжT!/=1aŏL@0!,暥o`t1y d ΓJbt7LcCCgOwc)q Le@R˴gW-ԏF]夁K(Br2Io^~/ͥ}t,F3 ;ғ>k~vkY ٤**픕#+we0%MnozەاzW근ݖMw^…_)f3-^odj-xU: QF7p ,Mm`4!3h!hD,Gi֢)Yfs}Ik\Ե*t&K&yt+ɂxӅaGPzGv=n|̱w$Jk^5 OKO(&xairV_cH?o\Rcxd+ :K3lgVx &Wi'{luu4|\\cim@p=e//Wp烠W̩S }ra8ί_ %q: SPq: _% }_5]ah-mUޕBq_-Nf۬ƅ-_cIm4đKUi`aI6 \6F9ܕ뜏:BGi߱ ea|Kag]Nah!aNl0 ߺ0 ۋa Raa! aj_7|4\ 埉!ra§NØј n$rr$VV&} b(K  ^ !Ϙ ԏ1xAA6Ё`3A f߱]O!7)%|ϕ1OQ|㜐%lx [T5*R*ٗגE|OymcJҤr* Ƚɮ.( OU;j]ׁ ^M *6*`@vAx'M(Aa O.-z+*#dR='0B$E$HO+>և9&jɥt eFW>'Yۤ{,ȕrThƎ,n,tGf ˚ hll,----.m*->m:-N-Jf R-׾Iԟjז)},jM͉~ږemtn Fھ@B۝u[ު6#-ݛ +"Mg9.)&  v.Jnj˹+!*뻶櫽cZD16lWzV.J' u/jʢI˒/Tͮ(l|nگz-/00?'0'Ir60?)-Gmw>3??3@@4AA4Bt|4C?4DWD4EWE_d`Fo4GwNLGH4ISjI4JtHJK4n4L4MtaȴMNW4O4PP Q5R'R/5S7S?5TGTO5UWU_5VgVo5WwW5XX5YY;pyinotify/docstrings/uml_class_diagram_for_pyinotif_13.gif0000644000175000017500000004024511273644742023557 0ustar ookoiookoiGIF87a #|LBDČjdTĂ$"$d^\Ģ|nd<2,4dJDܲ |^TnlT>4TF<~|Ĭrt,dND|bTvtԴԪD><4*$  亼|vlĞ:<̦<24TJLԦD:z鷚K~eלeQLv̰]ͻϥ[U&Ϳ/س\^}f$BPZW%;ʯޙ=[i!u-:K_םfiqW]i4B4hJ)NRڅ7d!th! Cj .H`w 2 9\p!L$yHI@H0Vbt78d9Ωv%!j.fjkR"qJwxNwbnx9)h2Bj&Ay磑Eq唛ij韀9JRha-N!b'*RG ~+y(gp׀HIKNaw ~'.Z'j^,!1d&/vlhhv06lھFLֿ*qxhf1Ʈm|H"2q$V%4lͦW@-DmH'L7,V(lգ M9ٍ4|']9O=;-Wn9P?9f9o.I~nkHUۚZjlr4[i"n ZZrħԺtXokG\p{j;l Zw./G_+i򱿶!m{)v,z€| 4E~}t@3"&ׂ:@x@pkpР,Z Q=o73jы%!PVbX#`4i O(EuO]Җ4s 5T CS◚pwNnjo%DN9BC=Њ֞vDu $5b&NIO] L}ҌAS(w xfnKN2IWPHBD &8yE\W-XZ!Y+K\䣊q"谖` w3O+O.d 8Cuf3$aL6b>JQ3d3p0VT=HG澏2#MiL=T+ei\RTiM=wSN;[O}9Ϗ*kj%nwPk癡qFm`49%t`%* 13+_άj=o`  p:BF0Py{CQxa9ˇ3CntN'MNWRKtiPLԣZM2T:m9f\jZuvk\;KjnVkzvW=h[-4g]vM64qJsWUo\[}B[tjf8} ~6P Wz7d ݚ0pkp="å\NN^v w)8j`(FS "jHlڨm|=Aw2S'>5)cer3-&e',cs& zIH+T\UǚY1%|L 1W$ĥ.hXomWs=|t.a<<=x,5twx4|SA?W+G6.9Z zҝ(]zR{{KNA%]#? LdOƘϾ 3{qKb0.~^-1b0 %:A ($q@x8@q1P 1P a0 X8|(@x) G~@ :X@FPD`n E6PRM(X PXUHO_a8UXfXhNln:rtX!xxz؇~x7xxr~؈qP8( ۷؉xJjvb|Cxj/ShsVыX!行LraNoFHad!%2D$$ Bwhg!e!\&AX vs$SLYD%)c'h.^xݘG `}v2MH{ԑKǍIi(K@)(,6*(/ c9Qw8D*Ғ2BV)Pfw8X%֒-Tgߑu'-^"ySQ)x/ᖯ!XUƗj l | 0}I9 1 Øs1Yqiy:xI9Y5vp9ٚ3ٙ7yIiJ%Yqa9 [E,iYZWaYCHqtSC)ٜ) ّYAyz q?ӡ+ZTaifʟT9(z;zؙ.Zy.:٢402>z8$j9D;ʢ=/jNKzM:#ZGzXZ\ڥ 5X%gS?XNkj?̸Ye b7_Z[U[tB"F>c[#$\w 6y߉]]ѱGiaOs)9_)רwju'tdGCutGGVWzmd  d1ItK`Dfu+9\BePKbuge 7*MֺM-e9g)3:)Aʛaz yPԺQzZ(# |*8+ٰ k9{49) k& 7)5x&plQ57#VJQ 2 @PKm=q+FmOHg./@>KPn*CNv%o Doژ2vm gJXNUXXo+tڅ>[B7p%q?twKK`ʧeU[5qCtO$rc*-骞^rruGJ %[5^ߵu[O9#Ketdtm&BAt"F`TpUaCuҊ^b TequK0b%fs`vxJk 6'rdtwe*MM[Dx <)d1{+SK-oxqN'Ɋ'.rOdff꠯`8@ wKaz΁z)_zB, p.^@@>8 !?>E>^yBDs2` \ fQGMG`,W ; `]]t bCeΪWDI"Mf+٫7}bMu.iXTB`q@>P`+y26v*TKw_;Z;@ǔqd2(-)'~ <ȡAVQPK0y2NxCLM-,LW"HxJ}wrdM­)TPb<0>Xns9/ 2^m~/)ֽAA!2#f /gC#"i}"l>?HEOO͊vlX3ٲmڋ2@VT/W%0h*0_oa?ٶ=yRcvm;4ם-M1+/`M߶M:>)dѬ,~ qjᑛȇ .$n!t(q,X^Ҡ^:^<'>nAbEGKM~Pes^r-͔ a<%H q BK $QD$)\\Q`Ç "T8QHW\ 8*(N$S"ƅ:1!$} @DEETRM>UTU^ŚUkRJ$fYsI%d|)  4*Fja+@ŠXzmw$CF"phɡ:,7޾kTzЭMFZj֭v+0%4JRBtB >t6m!G 5L ]:EOH7*Q,IQiAi/;[GH~?f6$ѣ$v`+B ),ȖP(Ч5\B"'/h[HbES\ I|0B *@'2J)pɈ8ʈxR$$bˈK1$3r<ӧ&3N9*OK Dc'%=@} uS:'RKSpJ%.H4Q;mTQIaTRYguL_5W]w57k6XaWcE6Y~YgMXeZc6[m}JZk7\+\sV\ueצXυ7`m^{%W^}qF_ niO1~*_~'J=ǁcd0yy$8f],ۘ^_Еgy=dߝiO[d @X" XjC C01<H` Pz HP/$y!CbB928Pm ij޺N[E{$!%^j֚kC % y`g}*y(JRxKߜ` /6'P耐5~ !a5H>{ 3B%kٽ%@z,dW;60*Uځ HHO` jH $FH@$-b ˂2B4 +\Ihn:,!AlB-gK'X%\0B"D E.VI%,q Ldr HF࢓0<܈\rrı'F1$2 JŖ1#Ms'p%I;AF2 `sFh3Y x b h23dgr?B41LeRrch&9-ީp3MtOHY7 B%<*RgtHc?" Li *҇*t eh%r@$H$ Ґ"P(fF㧎x#T#5@ӥ3٫҄%1Mi:MDR "YSK_:ԉTQ:dDO"HSԟHXT=IT˨ժ)pTg2k:VEL]kz/UQk^5WկLz^[+հ`۬"ֱb%K>ֲud5;^ֳfE$`H00윐zXB;Z$jұddo6Em1*rWWIl]DmjgljlkkZխ&xs-nPR:ǡr z}_ҦsnxI׸ uwr]A?Cn wIπwʠo|Kv~W@_Ɲxan~@ _)hA Fć a(6DJ/tbdBJ7,(e&:Plg+bL}rŕRlKiG5#z8Yty:"ǂ٭U= /$frossMP['Ɨf #,!ȫ1KY !%0QjjcL;kLӜ$qr9܎hy;yrHe=i7=TW\iuHIRAAґD!R (JKDE =uBG"gI3ZQMwjHѴK=NandɪDr)Rdթ>5D VIt^)}"ϥZ+Zzue}"mn'؟\=YiWv qW;&?T`*EVlkx>9mC\w5R;yʫ\խƃ3MD{_ݰwjo8:7T aMP|7H386N}rŐ/櫯>>Ü<ɰ$*S13a#p/ȅ5[1', (ېą Mѵ?K@5; M%&L;QA0;3%'\Ѐ(54-23˳) !N:BG#\Az(BrRc4ٴ()$5>)0Ŵb̂=Xl5TМ?NY tMߌM @ 4@ BZ1 2"˱kZpٚl,+ d!Zﬡ,ij"9%;+[׭-VƆ5KS5C$Z5P % N#CB=21[~9CL  hC8݈xhCds5@%A|%Y ܪl5QO z6(Rx'&D{&R7T67V^) ^$0%4 e<=(, ;F<9SM|Fi_e_S=_ot,qDT`^QGWcGn`RVz{$ᥣL}h[QR.ȭcWHn^Vkaa b!".b:b$%^b\'(jb*V[|Vn NW"ḅ/F[zw=xEzm5UrSjW1=\JB~MmG>*/sBE?mXXu̒Y >{>DY ZYILScFو%? ZMMU eZbޱ嬍eY*f8!uN^ }3l[ O4q[&SANciNVj )PE:B\nF#1$P̅9\$54P{\حYeA 5ևK NAMڽK]D&,zE{G\mbWDxR_RdxS'亮nEKRvidt_.8_fB'-(Ae%`83 VԴV*TT6J~].ixaaTb+⿺ll\lmmҦ>Lmf nf.׮hgc֍jYiT1cV4ΏF 9w-x}ʇ=m6#@nH*~ nۡg\ (J6LKOxo囯dce 0#%MecYue ~gH? ̞yф$faVZ4fDfeqޜqf pƢg [-gD[~ @qfHf|[wFe9g%2uAr!34s}ip4''Z5%h}n\X~\M3hN$Oz:1 _Pݍ.Gu]]]L]>]t CGpvKQ$X7i$tiits|SDuv7TO \lӮkӆ56X8k_ߨ.FS '>j4w^`fon"Tp̕9s}`ykkky.arx:/k춋xe1^x+G >yvIy7 oyuyy' pyjzy-` nm8yJ9B7nH'ȅ#pM1PĮz: o8EN,Z{02>WQ I KNv{{hM0 v?`lɧ/AJ(ݱ}]A|3O,֟2ORn~&X\ vrc`2J7Ah]/y/7HBx(P'HKXm _8R#,i\ AK$:B"ƌ7r#Ȑ"G "ʔ*Wl%̘2gҬi&Μ:w%%%(QCKJ$.Yp׸RDH"E.\ͺrҭkɟz/ek3w$91Ol2̚3Y`݊G.1ԪWn3p1#6܇Q7(a.n8򏼅3oOɧSNz9ڷkn;#s/oj׳_O=oo>8Svaő GPBPrW~I8|GG\pD;XtRx" eԅnm!$ hD,@br&#Dh,z@D\"[EVHр=  pčKHI%XgeSVXqQ# d$DAN0FD_*`V@<@u@?d)5& TIjƙKP !JKD:)E ;,g+F昄,A V|f8PAE6Y6DFQTIF6QZ{oOD .,!Q*ۖgEagBcPFQ y(D0,u8%? D'>1QX^;E/a B3QiT# FWG;RyaS!J@JG9(|$'I&R9H8 /![.Ii.aRm\,UbQ_Z'$&HH-@|iMN;̉J: 0Ѥ0,i~%@Tt˞tu "9G-Q 0,Uڕ&2V"NQ-iCdC/*kvOu-|=U}ֶxfadc@4 \Z%]K@-\BOg%A=u]vtB#_[IMauF*Յ5l^-%# ']ƖTLf7sQ)If2ENlm.b4th)A3RN%x`%<I(SŨI 9Ֆ@ N؁$6ݍkHUA1$6ϖm>݈j6Ci!mY;,gI@z]%"r`bo&e)єS>ǔ-[ 8) /R^%n׺.2s{G.Lp_/;[O9`>肅W`G݄'1S.^ Ӹ6:a>1,!g)B a%3N^rfw,X"02,h!2Ġlk㶷];pO#1tb#x˻'|᷿^ 3sx23P@83"ezC.򑓼&?9S򕳼.9c.Ӽ69s@[!F?:ғ3N:ԣ.S;,tDDTU U?;Ӯn'ޗ9v;wyCqt= e;3qz#/b)no蝧'I((b])*` (`-",>`B"v"0F^&&1*z IU 22#9@#)%8>#A 1c #O#;q=^<0?dޙ $BJ]l""6C""AV$޹NEnٝ(,y$HB].Еd$GaNhK$M$MdN<$OO$PP%QB_ĂR.%S6S>%TFTN%UVU^%VfVn%WvW~%XX%YY M[<$N$\֥]M%^_eM%`a fM&b6c>e%dVe^f)&MdQvg~&hh&i&Q&Yj&kk&lƦl&mFeZBfn>fc&pMJRf)ٝm*` !'!ؑY'^avBw|B%N^sVxgՑ&]H' z*( V]|{&z:e}Aqc1(,+2މ.LܡB(\B؂\ &4u#"nIB%Ё'aBd(]Ei _ҩ( ia(2)B)䩔!i)&hh)!'^Ng.Ji &ȂQ)!Y*VB ZV Ѕ߫^ڪA߮&a{@.x&_5,">r.\9 J B'`Bݹk+@ҟ) P@.-Ѕj"+u뷆+"jþXkgRkrĎ_b,(,0&ҕ빦+,,&] |"lǦĂ6c⫾#*}Jm,҉&Ҋ!nm:y-`*nN (%aYTB+(_n^""*#F,XAbٵ`-޺j.,$ *g6>>-X.>"Ӂ fҵ,($/z  32.*` !҉Fh~.r /o٭y%VԧYp,6r,T6(a *p?#()\)Cb!"\`W0V *ޯ?p!&C*CҠ p5/7#n]/01+!0 ƄJ؂A '^(av*"+.Jr؝H"B 0V/W!, 1 jR/ Үǖ:"r_$%%2љo*.+ A`@!qґr)k0q2 Ӳ-`+*/!zVooA֞"/bZ3b3-l,,.<|BN,7"( >s4036{>Wb720C2),W;>B."=0C"%&]?њ880WA(!B*|s8ϲA>t^E_~F*CK,E2e3"@(ZA#s#:a#B:u:.*,H07jߩ)]%,@R*v^uR4u"\7T5\W/ʊq^V0=4Y5~c85ѱRav\Uc *u$EA1\uVϲ\Gc잶KD8gwo8uxK,888Ǹ8׸8縎88_($/97?9GO9W_9go9w99999ǹ9׹9繞 9::'/:7?:GO:W_:gcz@;pyinotify/docstrings/pyinotify._SysProcessEvent-class.html0000644000175000017500000005301511273644743023630 0ustar ookoiookoi pyinotify._SysProcessEvent
Module pyinotify :: Class _SysProcessEvent
[hide private]
[frames] | no frames]

Class _SysProcessEvent

source code


There is three kind of processing according to each event:

  1. special handling (deletion from internal container, bug, ...).
  2. default treatment: which is applied to the majority of events.
  3. IN_ISDIR is never sent alone, he is piggybacked with a standard event, he is not processed as the others events, instead, its value is captured and appropriately aggregated to dst event.
Instance Methods [hide private]
 
__init__(self, wm, notifier)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
source code
 
cleanup(self)
Cleanup (delete) old (>1mn) records contained in self._mv_cookie and self._mv.
source code
 
process_IN_CREATE(self, raw_event)
If the event affects a directory and the auto_add flag of the targetted watch is set to True, a new watch is added on this new directory, with the same attribute values than those of this watch.
source code
 
process_IN_MOVED_FROM(self, raw_event)
Map the cookie with the source path (+ date for cleaning).
source code
 
process_IN_MOVED_TO(self, raw_event)
Map the source path with the destination path (+ date for cleaning).
source code
 
process_IN_MOVE_SELF(self, raw_event)
STATUS: the following bug has been fixed in recent kernels (FIXME: which version ?).
source code
 
process_IN_Q_OVERFLOW(self, raw_event)
Only signal an overflow, most of the common flags are irrelevant for this event (path, wd, name).
source code
 
process_IN_IGNORED(self, raw_event)
The watch descriptor raised by this event is now ignored (forever), it can be safely deleted from the watch manager dictionary.
source code
 
process_default(self, raw_event, to_append=None)
Commons handling for the followings events:
source code

Inherited from _ProcessEvent: __call__, __repr__

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, wm, notifier)
(Constructor)

source code 

x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Parameters:
  • wm (WatchManager instance) - Watch Manager.
  • notifier (Notifier instance) - Notifier.
Overrides: object.__init__

process_IN_MOVE_SELF(self, raw_event)

source code 

STATUS: the following bug has been fixed in recent kernels (FIXME: which version ?). Now it raises IN_DELETE_SELF instead.

Old kernels were bugged, this event raised when the watched item were moved, so we had to update its path, but under some circumstances it was impossible: if its parent directory and its destination directory wasn't watched. The kernel (see include/linux/fsnotify.h) doesn't bring us enough informations like the destination path of moved items.

process_IN_IGNORED(self, raw_event)

source code 

The watch descriptor raised by this event is now ignored (forever), it can be safely deleted from the watch manager dictionary. After this event we can be sure that neither the event queue nor the system will raise an event associated to this wd again.

process_default(self, raw_event, to_append=None)

source code 

Commons handling for the followings events:

IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, IN_OPEN, IN_DELETE, IN_DELETE_SELF, IN_UNMOUNT.


pyinotify/docstrings/class-tree.html0000644000175000017500000002566611273644742017272 0ustar ookoiookoi Class Hierarchy
 
[hide private]
[frames] | no frames]
[ Module Hierarchy | Class Hierarchy ]

Class Hierarchy

pyinotify/docstrings/pyinotify.ChainIfTrue-class.html0000644000175000017500000003371511273644742022517 0ustar ookoiookoi pyinotify.ChainIfTrue
Module pyinotify :: Class ChainIfTrue
[hide private]
[frames] | no frames]

Class ChainIfTrue

source code


Makes conditional chaining depending on the result of the nested processing instance.

Instance Methods [hide private]
 
my_init(self, func)
Method automatically called from base class constructor.
source code
 
process_default(self, event)
Default processing event method.
source code

Inherited from ProcessEvent: __call__, __init__, nested_pevent, process_IN_Q_OVERFLOW

Inherited from _ProcessEvent: __repr__

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Class Variables [hide private]

Inherited from ProcessEvent: pevent

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

my_init(self, func)

source code 

Method automatically called from base class constructor.

Parameters:
  • kargs - optional delegated arguments from __init__().
Overrides: ProcessEvent.my_init

process_default(self, event)

source code 

Default processing event method. By default does nothing. Subclass ProcessEvent and redefine this method in order to modify its behavior.

Parameters:
  • event - Event to be processed. Can be of any type of events but IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW).
Overrides: ProcessEvent.process_default
(inherited documentation)

pyinotify/docstrings/epydoc.js0000644000175000017500000002452511273644741016153 0ustar ookoiookoifunction toggle_private() { // Search for any private/public links on this page. Store // their old text in "cmd," so we will know what action to // take; and change their text to the opposite action. var cmd = "?"; var elts = document.getElementsByTagName("a"); for(var i=0; i...
"; elt.innerHTML = s; } } function toggle(id) { elt = document.getElementById(id+"-toggle"); if (elt.innerHTML == "-") collapse(id); else expand(id); return false; } function highlight(id) { var elt = document.getElementById(id+"-def"); if (elt) elt.className = "py-highlight-hdr"; var elt = document.getElementById(id+"-expanded"); if (elt) elt.className = "py-highlight"; var elt = document.getElementById(id+"-collapsed"); if (elt) elt.className = "py-highlight"; } function num_lines(s) { var n = 1; var pos = s.indexOf("\n"); while ( pos > 0) { n += 1; pos = s.indexOf("\n", pos+1); } return n; } // Collapse all blocks that mave more than `min_lines` lines. function collapse_all(min_lines) { var elts = document.getElementsByTagName("div"); for (var i=0; i 0) if (elt.id.substring(split, elt.id.length) == "-expanded") if (num_lines(elt.innerHTML) > min_lines) collapse(elt.id.substring(0, split)); } } function expandto(href) { var start = href.indexOf("#")+1; if (start != 0 && start != href.length) { if (href.substring(start, href.length) != "-") { collapse_all(4); pos = href.indexOf(".", start); while (pos != -1) { var id = href.substring(start, pos); expand(id); pos = href.indexOf(".", pos+1); } var id = href.substring(start, href.length); expand(id); highlight(id); } } } function kill_doclink(id) { var parent = document.getElementById(id); parent.removeChild(parent.childNodes.item(0)); } function auto_kill_doclink(ev) { if (!ev) var ev = window.event; if (!this.contains(ev.toElement)) { var parent = document.getElementById(this.parentID); parent.removeChild(parent.childNodes.item(0)); } } function doclink(id, name, targets_id) { var elt = document.getElementById(id); // If we already opened the box, then destroy it. // (This case should never occur, but leave it in just in case.) if (elt.childNodes.length > 1) { elt.removeChild(elt.childNodes.item(0)); } else { // The outer box: relative + inline positioning. var box1 = document.createElement("div"); box1.style.position = "relative"; box1.style.display = "inline"; box1.style.top = 0; box1.style.left = 0; // A shadow for fun var shadow = document.createElement("div"); shadow.style.position = "absolute"; shadow.style.left = "-1.3em"; shadow.style.top = "-1.3em"; shadow.style.background = "#404040"; // The inner box: absolute positioning. var box2 = document.createElement("div"); box2.style.position = "relative"; box2.style.border = "1px solid #a0a0a0"; box2.style.left = "-.2em"; box2.style.top = "-.2em"; box2.style.background = "white"; box2.style.padding = ".3em .4em .3em .4em"; box2.style.fontStyle = "normal"; box2.onmouseout=auto_kill_doclink; box2.parentID = id; // Get the targets var targets_elt = document.getElementById(targets_id); var targets = targets_elt.getAttribute("targets"); var links = ""; target_list = targets.split(","); for (var i=0; i" + target[0] + ""; } // Put it all together. elt.insertBefore(box1, elt.childNodes.item(0)); //box1.appendChild(box2); box1.appendChild(shadow); shadow.appendChild(box2); box2.innerHTML = "Which "+name+" do you want to see documentation for?" + ""; } return false; } function get_anchor() { var href = location.href; var start = href.indexOf("#")+1; if ((start != 0) && (start != href.length)) return href.substring(start, href.length); } function redirect_url(dottedName) { // Scan through each element of the "pages" list, and check // if "name" matches with any of them. for (var i=0; i-m" or "-c"; // extract the portion & compare it to dottedName. var pagename = pages[i].substring(0, pages[i].length-2); if (pagename == dottedName.substring(0,pagename.length)) { // We've found a page that matches `dottedName`; // construct its URL, using leftover `dottedName` // content to form an anchor. var pagetype = pages[i].charAt(pages[i].length-1); var url = pagename + ((pagetype=="m")?"-module.html": "-class.html"); if (dottedName.length > pagename.length) url += "#" + dottedName.substring(pagename.length+1, dottedName.length); return url; } } } pyinotify/docstrings/pyinotify.ProcessEventError-class.html0000644000175000017500000002622111273644742024002 0ustar ookoiookoi pyinotify.ProcessEventError
Module pyinotify :: Class ProcessEventError
[hide private]
[frames] | no frames]

Class ProcessEventError

source code


ProcessEventError Exception. Raised on ProcessEvent error.

Instance Methods [hide private]
 
__init__(self, err)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
source code

Inherited from exceptions.Exception: __new__

Inherited from exceptions.BaseException: __delattr__, __getattribute__, __getitem__, __getslice__, __reduce__, __repr__, __setattr__, __setstate__, __str__, __unicode__

Inherited from object: __format__, __hash__, __reduce_ex__, __sizeof__, __subclasshook__

Properties [hide private]

Inherited from exceptions.BaseException: args, message

Inherited from object: __class__

Method Details [hide private]

__init__(self, err)
(Constructor)

source code 

x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Parameters:
  • err (string) - Exception error description.
Overrides: object.__init__

pyinotify/docstrings/uml_class_diagram_for_pyinotif_10.gif0000644000175000017500000002250411273644742023552 0ustar ookoiookoiGIF87a`0LBDČNDTĢ$"$b\ĂlZ\bd"$ܲ,<2,dJD rd|fdtԦvl|RTTJDD:4|^T4&$24ܺԪrt̒dRT̞ \F< |bT4*$Ԫ̒  ~t|vl̜fdrt^\:<̢䶴Ğ\4|<.,L><̦<24ԦD:<̞ \FDztL:v[DIJ S!U4.5@AXp};ڀde y wTr/7bhm԰_QLmC\?#K3}OlXg VU`-&QK2g? oGM*&֍f ~8ʀC,84"[T4b7nԹ'u1J2y(9irvѡTabk>,yߝq$g#hϠI~;<7yO6wi(ÃL@ XSGo_&w^Rnxdis1^)uoQ:h4Ac<ūV} G]?*VZ8Bq4`S.$CMt-l\Ԓhn)ܗfÁ<+g_6JhB&JOd$Bg+A[bD4ʫvkM/8Q5s TF;2XɁ IB<$F:9%JZ̤&7I-h (-9I<(*SŠ)L%I KXb.? -Z.\B 1iPb)BjFDZ@0=X )biE,nA[Ģ@ܙ`g9 "|Ѓ@:l{Bh,ψjaE1QJ(H=zёS&&JSZ͕t.}0c*S]Ҵ)NUӝdXPJԢHMRԦ25 SJժZL@&zWSh$ ;p\J׺xu`aկ]\i!wZ5",ڋBH#,fZzoU,[AKj֭HFizZ̶vhږpgF_یTPbn1*qʠ^C[]Ε(6W0`A%d`u V F5ܺ9cQn0/w`+vP a.^ыZ׽ zW+XA/b;cŽ^av0+z GX<1;W^4ŌqcW5mGKQpyq (u+n51* xe2\m @иZѲ|^*ctmY˸k1p,Wao54n~iOx4i|IWpk5x p# z.u% W`VjMwʴ=!]-3* 3[ wվ6lM@9NWwmzؤvݐU zq7~{>M8;'N[ϸ7{@eô(OWN0w/3揝nj<]ommK؟A'c+;: 7[QW den_]*W/y{7 l^80-a~uNx2[?zxFF>օϼ^3\cnOO}9g,t\hG܃Wzl}p j ze( ;_ ,np/lYiϋW^6u{?o~g1uX%fQr+8X-. r؁ 'r.ǀ&xXhx,Z(p hWUYE'X Yud VtWX|WEzu JVZ)X+(XMW$9x`2p{s5-gu @ p `(6$ZMHOX YHe iE +|` ҕn/Hog^6YlWzg% xvXQW\u`c]vkeנ \ \imXW`Pxu^Vp [\w :]V‡% aWtu >p` 6 wƈ28wu'`~a&|w(xg_xHߘYv j2`[U_v e`+Y ƍn5 Hs1ȉNaWwb=coEyfxVidKx 2V̀|b'cpy'YyĀve,&+C[{ָ&fdff瑠`5zo)qg@Ɔsق@FD Wm8XxRJLNP1T~VXi>xpuuneu)XJ[]zXQ8p8^:ie8wzlڣRuZrHW:i*XXm[P 2`m[Y^h]l7xuyWʋn(h ɸյwZy vh0a0 _`؍xkWi٬ ALue-.٩3YuA"dY9:ٕbA)dU@ Ku|iv)gKfN)Ydi9°oyfMZZwnE ˮouh +iV9yיgk`YVjvn t8jȩeɜΙݚ5 9 [n疝۩mjVٟ:݉D*J`Š^ZWWpyZ Y"Z$j&+W*ڧCZW^ׅXX0fr;Y ;ktozΗH{{7FQ zv%IUtkJ[벅%I%c|J<{X{W*uZKhu\:hy%HhGdWHv8vJ;_PYv hr戫 Lx766dqIWj(6&$yd&9DkpeKհmBgTYz+p5ɴwuղoE{+Gp5jvjv0,ik6VKk|6ƪ) >loelj˟iv%vPd}ee}wnr+,ez Y [£k롷[dA1z湒 {?;nW@qʨ|uO>˲|t,^a ]KȺ_ bqJ+ð[;uV{+:KΕ+Ee0]uUvf{m:aH̾ f{e pQhw wv@zw`WPqϰԻxhzQVnV jVXМobPW^o%tEZ!V :ř&.WJW f ]l ZڻB vv5\k\f&:]쥪XUGp x;WWs $n O^l֙YeWN 5 ΃f8*Xu+񼾍Hlkj__f7`jXp{0p Xx2Рn ֝JM 7XFWGaV ,owZשNu=b~&\ d.YuWpnsP~n 5 ONY 0 `Ґ߈pYН/$fK^zԓm9f{[)qo5tũv0% M;)8rũ o `P2;|D=Vi2/b=[yZ0chp%_ghz~ZYu`0 `wsuW@PnDWvz/jP{"& ^yamRՏ3{֛Fjv{֡jk. s @ ]t ՠzp5~_~FVz_o`gne21}W&Uؖ֝ViW` pp=W`M  -6 ^ @T1ЈJ| aF)Z E;+hJ)8$[5męSN=}$hSDTRM&TTU f5&7UB:SXe͞ZtcWmݾ$mUZRhlQTF|TibL.*/G:—f`Ν=lYhҥMGY겡O[vԬmzn޽}3[8nݿGN{p涋']ͭs~>]v2_8{teTj&#Mx>hv޵zxdC/!Qob:"ApЃ? /5ZP%0GKID&j WM-H#0;,H T(c*9fG;@$%28`"U̐k*y%9ʨ`I%$0!S4D (J5a`",9&REAAsQlaw `ffI$2*O5VtSÔKTP1ՔS0b1ӎ`]Ui^q*A Cz1^|ņ^!mL܁IWf#rK:W1`~u;E u| X[^k1Rs^h)i]ZiC.ר$"d,)䑗c>؈5c|SJdIfl>@ݓMG7b+xjgbszk^9kh|-dZk^KcnS%8bQa&^ခ&iY;8<㤸Y8\S5UՙgA<2V8)W].ϼVhwv 7QEDE.vы_b:F2ьZ, θ'VBKl$T8G:2FlG>яܣHBҐy Cp#XAX< L ZdIR'[ 2!$ HA ('hЂ,|a Pւ_8b :`D Y\4@ 8E:]r)@A 6B,NpB <81Mࠖ5zY$-B-9х+Pa5EY R&C yPpB 'pPޤ(|!hI) -'HLm\$Z@7o 0N -xd<ʊL$ f La"Tj0S -ŪR$ &LxB k)A0AfBBFЊt29)᯼&^ -@(E(L;W̼>g@Q1Ӿ(F @ ' OwcpIah_=zui@ @EhCڞgr7A~pBx_x륍 ﰸٳ~x%NT@Ȁ<|l-75u16sUBxU75sh@gy$:OhHޛi,,*XJh??'ks格hH;;۾b< <7s;T@C : #P>>xd=AUp :eTx.x?|3kÆW (?J?PC6tCTST8$t?46TBA9E 8&#T$D x;Gei˃eDC$X:HIl7#8 &R: KBG`ūFS##(Ad=&ȃJpl(76.xwiDCxGz|7c< 3hgpG*$XXRFl|Ơ6not:p,,ȽeX(G ?@];pyinotify/docstrings/pyinotify-module.html0000644000175000017500000010410211273644742020524 0ustar ookoiookoi pyinotify
Module pyinotify
[hide private]
[frames] | no frames]

Module pyinotify

source code

pyinotify


Author: Sebastien Martini

License: GPLv2+

Contact: seb@dbzteam.org

Version: 0.8.8

Classes [hide private]
  PyinotifyError
Indicates exceptions raised by a Pyinotify class.
  UnsupportedPythonVersionError
Raised on unsupported Python versions.
  UnsupportedLibcVersionError
Raised on unsupported libc versions.
  PyinotifyLogger
Pyinotify logger used for logging unicode strings.
  UnicodeLogRecord
  SysCtlINotify
Access (read, write) inotify's variables through sysctl.
  EventsCodes
Set of codes corresponding to each kind of events.
  _Event
Event structure, represent events raised by the system.
  _RawEvent
Raw event, it contains only the informations provided by the system.
  Event
This class contains all the useful informations about the observed event.
  ProcessEventError
ProcessEventError Exception.
  _ProcessEvent
Abstract processing event class.
  _SysProcessEvent
There is three kind of processing according to each event:
  ProcessEvent
Process events objects, can be specialized via subclassing, thus its behavior can be overriden:
  PrintAllEvents
Dummy class used to print events strings representations.
  ChainIfTrue
Makes conditional chaining depending on the result of the nested processing instance.
  Stats
Compute and display trivial statistics about processed events.
  NotifierError
Notifier Exception.
  Notifier
Read notifications, process events.
  ThreadedNotifier
This notifier inherits from threading.Thread for instanciating a separate thread, and also inherits from Notifier, because it is a threaded notifier.
  AsyncNotifier
This notifier inherits from asyncore.file_dispatcher in order to be able to use pyinotify along with the asyncore framework.
  Watch
Represent a watch, i.e.
  ExcludeFilter
ExcludeFilter is an exclusion filter.
  WatchManagerError
WatchManager Exception.
  WatchManager
Provide operations for watching files and directories.
  Color
Internal class.
Functions [hide private]
 
logger_init()
Initialize logger instance.
source code
 
iglob(pathname) source code
 
glob1(dirname, pattern) source code
 
glob0(dirname, basename) source code
 
has_magic(s) source code
 
compatibility_mode()
Use this function to turn on the compatibility mode.
source code
 
command_line()
By default the watched path is '/tmp' and all types of events are monitored.
source code
Variables [hide private]
  __author__ = 'seb@dbzteam.org (Sebastien Martini)'
  COMPATIBILITY_MODE = False
  LIBC = <CDLL 'libc.so.6', handle 4004f7f8 at 97f4e6c>
  LIBC_VERSION = '2.10.1'
  log = logger_init()
  MAGIC_CHECK = re.compile(r'[\*\?\[]')
  ALL_EVENTS = 4095
  IN_ACCESS = 1
  IN_ATTRIB = 4
  IN_CLOSE_NOWRITE = 16
  IN_CLOSE_WRITE = 8
  IN_CREATE = 256
  IN_DELETE = 512
  IN_DELETE_SELF = 1024
  IN_DONT_FOLLOW = 33554432
  IN_IGNORED = 32768
  IN_ISDIR = 1073741824
  IN_MASK_ADD = 536870912
  IN_MODIFY = 2
  IN_MOVED_FROM = 64
  IN_MOVED_TO = 128
  IN_MOVE_SELF = 2048
  IN_ONESHOT = 2147483648
  IN_ONLYDIR = 16777216
  IN_OPEN = 32
  IN_Q_OVERFLOW = 16384
  IN_UNMOUNT = 8192
  __package__ = None
  attrname = 'max_user_watches'
  flagc = 'EVENT_FLAGS'
  max_queued_events = <max_queued_events=16384>
  max_user_instances = <max_user_instances=128>
  max_user_watches = <max_user_watches=8192>
  name = 'IN_UNMOUNT'
  val = 8192
  valc = {'IN_IGNORED': 32768, 'IN_Q_OVERFLOW': 16384, 'IN_UNMOU...
Function Details [hide private]

compatibility_mode()

source code 

Use this function to turn on the compatibility mode. The compatibility mode is used to improve compatibility with Pyinotify 0.7.1 (or older) programs. The compatibility mode provides additional variables 'is_dir', 'event_name', 'EventsCodes.IN_*' and 'EventsCodes.ALL_EVENTS' as Pyinotify 0.7.1 provided. Do not call this function from new programs!! Especially if there are developped for Pyinotify >= 0.8.x.

command_line()

source code 

By default the watched path is '/tmp' and all types of events are monitored. Events monitoring serves forever, type c^c to stop it.


Variables Details [hide private]

valc

Value:
{'IN_IGNORED': 32768, 'IN_Q_OVERFLOW': 16384, 'IN_UNMOUNT': 8192}

pyinotify/docstrings/uml_class_diagram_for_pyinotif_5.gif0000644000175000017500000001514611273644742023502 0ustar ookoiookoiGIF87aULBDĢ$"$tbd<24dRTܲrt4&$jl \JL̪D:<侼Ԝ~|<.,ĞL>2Q@Wu3 I&mn>{:]cismq]£պu<7<Ũ04JzsI(A`yH+@!RЮ71)Y`zd@*P*T%%LVSFj<'d nRP5o##HVUc!a@75.bI1r$ChΔo|3%9v#iQKUml0?2\FѶ;[6@Ҷu6$k5s:k;{@ntIJ})azh7|nW1wVv~x;JA4GjnO;^-xٯ_c%IV 1AyZ~;l}MR{AlX#nwtˆYאw`nM=u"kc5՚'ûbc|UۡJDk{x/iU/ vz|wryR/Sq~q,gc;C(AprBAE3TGzremt 'ADd\Uet8uvgjVoWrvuTWw:f5}"FxHxM(S~Lxh.^H"7YRW~@iGeyyEC0t80Y&['L|FgnX16kz@#4E{ሸ6zs3a0|C5VA`Y&mϖK!my5}T}w8gUطO}1BrREoS7H~[~fs)W>t=C=-B%8=pCap"1LY X9Xn(48]TfIBB2B!D8)ہsU'sKvZDC\:K7VtumXV!HWq5x$(2, .24YTYxux0 G6xiF93K@jKgLu; aU ?![VQ olGAwdL զ]a5B$A°"覗 Q) !Brp=׌iY5@ ##H?2rɋ8(-=prYIH(N'av_1`ӅHGI&U%XeF7t+q)}(9F幞9099y6;a(p--6z.-l=)J8P@)1.NrlXVj 030 {HLݨ1L#!1F@KPO:;01\ٕfS4VQ0![J 0bIwj{j?96lXa6:3BV CYVTٗf;P9x.~*ÎˢC0ڑY0TeÜf ;sݖ)9>p,F970IHCIֈ:J1 ap:3+C)6Wu*@ 3-j@ T9e]?C N "zڋʩ0ABf#C$dBZF "C3b,r5™XZ+BRjٜLD&[dESdMtFIF#i42'A9@Ggsӝx_BwNbe:K<;DkF9KM{🵓x%:c@kZy z1# L7j=@6:ɕxK@?J3D47MQS:;c 8Ƥ\zK^3f7dl:n #f'{rx>mTyKY:OU{Z?zY݇gqHл֛ xey .Ҹa>דԿ+ eͪd8jҫ=::^`ம' ,~LNT[>^C Uړ"L¤N+| H&M8Ʋ'k#*%>3g%$ !)VHRhNIFC:5(vGsgpkhp֭ ~>uEuGIgMgOogQ?gE]IbN^n~  e;O_o h<@Q:Dpᯂ+ZQ in5"GFj\dQ#T#=!'UKbFl9Ć7J&th:,jBC<0醧QV tiSCXa *eTWC4\ I㡣(vXcE%b \@ ;DO$ӠlsƏ#OF"(1dӨ/g管GQЍ/p$ F ].CN]x:yt;wvX@G7G2@<Ȁ (V)pG&XRw6`PL}&DX!DK+^W QCHcyH@ߐYc#7 r-d:G%kdpum٥>!E,^)&teIsTCP9xD@ Q 6аsPxHYyFT  ,[0'j$5!LvM.; (l8{ ^ mz%Kn枋>8 oKoދoojLpp /p? qOLq_qoq r"Lrɾ;pyinotify/docstrings/uml_class_diagram_for_pyinotif_25.gif0000644000175000017500000001500311273644743023555 0ustar ookoiookoiGIF87allRL<.,ĢBDĂ<lfd"$LBDĺjdlbdT.,$ĔFDvtԦ\NL̒  |24,&$t^TD:4d\F<Ԝvl|ܲ~tԪRT,ܺ*,Ě̞|^T|  D6,TTJD$"$ndT><L:4~trtlZ\̪JLĊf\TB<$ĖT6,^\~|ܢ:<\&$dJD체ܪz| tD2,̢"$ljlvlԢdND |4&$\JLzl䲤Z\쾼*,̚|bdrl̄jlTF< Ԯ̴̦Ԧt^\D:<\FDvt̞ D64L:<~|TBD$T64vtdNLztTFDlVT<24d"$,"$|b\jd, H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXj S`ÊKٳhӪ]pj ݻx˷߿ DX Z̸Ǎòw˘!͌ygk #=U?dkΩ_c'{qhҸ8bpx _{8o^tOЅvUq/un{ Z@PZ|>zAB!,DV _զsp=R 'P=#=q 8P$sbl}8"qc &l p!q,,υ7 r쯴&d ,)ɪLfkg;؁b /a- Fn@f-uk'0 ̨G,m7l1IߙwQl2hF 0,sZlsG9`<@-DmH@*77'Gm2NWRg=1VwZ0^=b-fp'rtݘM-߀U{.PI'7>҆n7ޔ;w6O^c9Y8y_z iܞ; :fv$Xê+)uų_Vi{>|[vAw-,;"{^~g"zxU6_}/.h/6& m!RV ,5HD ŨC:e8F2l0ߌcv( |ACt%<)J:d^X&/IL4a\jo`X.|'=m  #< wG_P EX^,-f'V`Ns]8;, t3CH- +6+OV1ɩGdSZg=sO|JMM?y24%h zP$a˝ |;zn'Qxac(F$oyrz^H/:R~F8O|h2ZQ%&Z/}E[ :$' 稧IOIC%X!?,p1^`UH8:X+%q&Ҷ&楊qur2glUF9q~u+`]eIYB=^5|eidVpْ8`Ur^ Ѳ}16]¦)lSJ7:(2W1oRZW%PI f)ؐݫȂxCb]W66@pMK.AF6 'L O*aa  #Q "E"PE . `ELͨ6E0CIoF2 2F1BLmD p(Adx ϐ@p]ըA6,[^3D@J.\ s/6 7 dh7-2Dc3a\c!C5&Mi5 ހBE8PjN-!楰uZ[Lpp1fXc MF~!B8 p6amC7RІQk0|@ ( aRhs!n)H۰_M͸r>k$#xxJPpy`fFoppG3g" ( p4`~j d` fe\+-o3 tA >U0rZȥ.};uc~`dOAG׮;ܑ6}[t`Awb&(vrB2&w_zS O|՗;Џ_ LJL{OgwOIo8~xW Ȁ]x~UӁ X(,A&,((4*؂2/188X5h371_0dq;= @ N ?28X4W?0Bh`Zȁ\8C _@ _ce~^~΀u{gI~аw} ؈׈+ n@ @ i~~l33n؊>l_~Gx~Q~ Pn~؉HȊxhhȋh8x5= $?ЊMpM~PPԈ  ɋ>(e@Cxpn >x+وi(p Bpl LL@9'؏>nY i 9yKcɑ J9%) +i_! $>hЊ+p' QB~}] ns~Y*n0Dlىo9'h~ΰ !` n p)t`)@fj~閕yy}9Y.7΀z܃~Z Z^yÉ(}]Yip _ț;Yxiمى )yYǩbٜؕy9eg~hg ǟ9 n]~Yt ~p| jiiH~Gʎ z1 (~M``O ? in @ȣ> ˙TM P n A:홠6*58L_z{hHJiꤴ 2:牫H_p-0 FDŘYjO/ i_Ѩ|~ ꉕ*Z~jꢰJڬj5#|Һ0ֺ!xHV0 ڭ Ꚁ 3:⪌ϙ#دS:+yh -Y{++:{+2T {T)"˭02ȧ\@ 8 >{`%ۗ_T[Ve.\PR1]j[mp lr[VU0 ?ao˵1r;[{k8pbװ@v[P j u z2g DV`w2P P  0fuk;B`p m`  ˠnWsPo(FxbQ , >7ymF/0p6;"bEpְ  e0ouK` Pnm hp xvms [e0r s@2 ѐQ+d0j X Dpd@5 [9 ` 80mAo!pj&N`,9l#g yFPn׻ltڐ  ,b`0rmP|Q 7r`п! @x1;GGoZn# ur|܀v#7f@Ɖ%VȰt-! `tƼp'Auʬ @{kc;@QuuFpymۻ, 0wlʻ 8! ϼ5QFF@ {; S\ P0 {  q# a|mǓ/tPmnG'^=X pZ`-ʈXуk؆o: 1ʓtUzp) NуgpמJW.]yxE :o~ Z 4Pnz~f=~I~hPi?PX^XX~^~X؀y~݈^ʹqHb~^]uHWZP$ޅ@ITnג/+*پiY _ȏ؊X p I^OI) ކ貭)YȜx *٘?vI.߹aO,~0 7 y~ mɚ-%/= Zpډ0/+Jy8ѹ_M?ة~.O?; ji9R AhIP6/{_o]:z%:J>9NBP O( Jу3@e|~OlgMУjJ~Uz_v XInj|ްo|`s@` p ^zeh/~꫸]驠*_{ZOF@74(0a‚rA -T@F3LP.X誇65męSN=} PEEM TT7K^}V]ƜUX6~EvղmkUK۶pŋT&]} x\X &JpV޻X2Ï- T< Ԧ<24TJL$jdD:< \FD~|TBD\JLL:<,"$vt̞TFDdNL|b\zt4*,t^\lVT,W H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳC JѣH*]ʴӧPzڤիXjʵׯ`ÊK$SZ˶۷p c ݻCs-AvZ~W0!/h;bPkq+%*#Nlrdi97,.i J".kMOk!c#B4r:haB}i|"TҬM-WXY4wNmܫ}#W\UuG (ZnA|)(Mւ >xs-x_e_`xDMh@C0ʸ!UR_ Hd'j-jA tJe5ni_k]d&il%mBlG%ekY斃&Ii`hD iHPm':f+$^~ D`'몭 _om):[h]Wn[u([WXt1*JJmi,kQ1/mz,J mY-']fQ!t-k,jH 0*B#(/+@mܱ ,[|p 7!1>e&Q FA׈DVL.7I%qFP+IH\Qd^-C|G'tA-5Vct[sF k'dQ#2ywh_礗n][KTǮG#\/o|{`7ӈH4B+kpZ6ӵDqm5zϞ;SBƢ^^ԍcD@:iU \zƤU}_]dֶG׺xҳ6r4_ X> 5 [ÙD/Vebcf`X3cHڅfL#SI~4 --E?@1x@0 U3Pɰ)@}"G~ `Ks6hCF5t %lp S*6' h _*z٥Ůc0c3K &cayضa(fV+ۗD6 mPӼEm27ֲ %f(// X`4KЏ}tgnռͭQjVֹoҍ`E,&Rb> 4>7}iV-^M2̎ ׄhEBX Aox;F}o 񬻤iOz +S6riw- ,uײ54}BRxVq,23PMlQtznq%S#-rs1vyFd2s5F}>g8G>:G{kmcotM5>CEzv~dSttQgap 4u-8gGu.N9P3T8VhmgYo8wYքgW9y8{7JօZCxb~aixrKQC!M#jaysYkyL؆v1z$bMv$'zX${qQlDmNn(]'/{XVdB}BTCwnG-h~f\~%on!Q)oъ!hhsRP$0 /gg(ƀeWd7-VSJ4oqsHu9P4'%>'B,((0@35hS긎1}ItTu:Bȁ!~Hx Duǒ0?8-yI6<2Vv!YUvE9e:tIN)?VKUoQK[L0kW\ǥ$hz{e]M9Ȧ])ƊHt}x~}~!.Dn5Ռg'~ &>lAqaW3R1v<7#S*rvc<7+F )GGFY)Ld$)OFF;ɓOU Nٝ1Y99~QBY:BNtVT9JLSI9QSRd[W9'ɱ_Y4Ɵ)f$V'{ Zvl .^T rHIJc/vИ' Y37SvQrМt[|tdY/)醆FztH#Guՙ l;-rzkZF}p|* Dwj8f-* 9SʥVkwiv]KE~!ʎ!\6kkrIUi(ɦ㥙[ZBফHɘ}ιʘFQoiأՑpۈaHp-h!6b%ڑ8caqAӉd;wJxj [+wgJf&wY}ѨSjw^?ѩc5;*t!\D䖱zq걵 (]$J"}y^ӗkHv:E$mڀ_{ϊݲ.Bo$"o9Uȍ"u*ݚ##23ɯI8qqrX#K)sBtv$m<8\bj=#)ui@*k; ۝˓~б]u$J(Uٲ/1[UY[~AytQ{OQNORoqѵ˽onעuV;Djۍߺp!.{k7vl!л =7gzy+Vl'<) +̒-|*+- K:3˷99;ܼp񼣋f6ux#4W[:j?{A Ď+R%5x1Rh\Lۯ[LB[Т/]{`Ş Z9_^חxpѶmtL~[{m{}&33S`+mx7ocQ5{z@ |Ĩ*tiָܸӺMV° М/9.ID<\l>A@ \|,<]>cP_ 0]5T 1T U&UF Pp0}&P 01# 0L`B(`0I X0L$ @=` M]1Qm\IQGdLPV` je 0t]5 x]S0yׂ==؃]؆׈y، ׎eْՔ]V}٘ԚCٞӠ1=ڤڪڬڮڰۯ s-۶}۸}BpA%^P:k9CfݷŭpܤSv9HV9 ح8݂XU<@ aCg潕ѳe4m}ܝzJIRz! ,L=@dmn!aѤN/N%nݗ'S(-N`$jZ| -q!^܍}+cfCe{b[ENkM~*;N܍-n4/8>80^cV>-ε3ݢi ɇ6y %3%Ս^N0D,q3s.<3nh.mOOqJZ5S )*˝Q778\CkynܓcԣٍF01нz뺾uV./Ai-nˎ.۸ގ;>^.N>p12a,7m.&KD  }@ {?=faAOFK\śG 06yja Ap 3p{ ]f Jip޷(E[DEZK` } r468F}n*-nR^pb8l^`wZrL) ,[%rpr@3AS<0ʇs&n~o",>+_ϒ.ޝ@tO/>uR^S@@ (JB >Q"A-^ĘQF7* H%I RJ-]t0męSN Qh2DOEEЊSz$UԈ@¢) U]TҪQv|EV-BF)j\^ߨZ(}U@*:ERUnX䔘4PeΝWe(0a+VM+R j֡ 8"[^ml}o%~\9˝Sm\zӭ~]{۽]C,^շwo~|jǟ_~G^ @D0?`0B 'B /0C 7B%G$`D4@cD 0QDFbADDG @$RD'Q= dhGK@Fd+/$sD#L_FT 5FE14)1,L>̩1I.Ԑ$ lAKr.r?P!D0hADDb0J/TS>v1UW1t+\eKM)FS1X@&ca@HA"4LCZE%4$ QG< .PU.$sCb\s5MFx\EE<.5-jas .!&$Z0S%aZTaD9D.DIsS9!0VeeYDTd+%TD:: YJMA 5t.\΁ [$Q#F kmc%\y>huҕE%nT[SjjN_pїa.hY+'\)zKEeR\ss`F$R'$e*UhʜR +q֥-3 + 7+ūp %$K$JR0Wgv+T0 0N$d&c?b٬jeM%x0N_Kf &f1h!VYo9#&er; Wre.w_st=hB};pyinotify/docstrings/help.html0000644000175000017500000002473511273644742016154 0ustar ookoiookoi Help
 
[hide private]
[frames] | no frames]

API Documentation

This document contains the API (Application Programming Interface) documentation for this project. Documentation for the Python objects defined by the project is divided into separate pages for each package, module, and class. The API documentation also includes two pages containing information about the project as a whole: a trees page, and an index page.

Object Documentation

Each Package Documentation page contains:

  • A description of the package.
  • A list of the modules and sub-packages contained by the package.
  • A summary of the classes defined by the package.
  • A summary of the functions defined by the package.
  • A summary of the variables defined by the package.
  • A detailed description of each function defined by the package.
  • A detailed description of each variable defined by the package.

Each Module Documentation page contains:

  • A description of the module.
  • A summary of the classes defined by the module.
  • A summary of the functions defined by the module.
  • A summary of the variables defined by the module.
  • A detailed description of each function defined by the module.
  • A detailed description of each variable defined by the module.

Each Class Documentation page contains:

  • A class inheritance diagram.
  • A list of known subclasses.
  • A description of the class.
  • A summary of the methods defined by the class.
  • A summary of the instance variables defined by the class.
  • A summary of the class (static) variables defined by the class.
  • A detailed description of each method defined by the class.
  • A detailed description of each instance variable defined by the class.
  • A detailed description of each class (static) variable defined by the class.

Project Documentation

The Trees page contains the module and class hierarchies:

  • The module hierarchy lists every package and module, with modules grouped into packages. At the top level, and within each package, modules and sub-packages are listed alphabetically.
  • The class hierarchy lists every class, grouped by base class. If a class has more than one base class, then it will be listed under each base class. At the top level, and under each base class, classes are listed alphabetically.

The Index page contains indices of terms and identifiers:

  • The term index lists every term indexed by any object's documentation. For each term, the index provides links to each place where the term is indexed.
  • The identifier index lists the (short) name of every package, module, class, method, function, variable, and parameter. For each identifier, the index provides a short description, and a link to its documentation.

The Table of Contents

The table of contents occupies the two frames on the left side of the window. The upper-left frame displays the project contents, and the lower-left frame displays the module contents:

Project
Contents
...
API
Documentation
Frame


Module
Contents
 
...
 

The project contents frame contains a list of all packages and modules that are defined by the project. Clicking on an entry will display its contents in the module contents frame. Clicking on a special entry, labeled "Everything," will display the contents of the entire project.

The module contents frame contains a list of every submodule, class, type, exception, function, and variable defined by a module or package. Clicking on an entry will display its documentation in the API documentation frame. Clicking on the name of the module, at the top of the frame, will display the documentation for the module itself.

The "frames" and "no frames" buttons below the top navigation bar can be used to control whether the table of contents is displayed or not.

The Navigation Bar

A navigation bar is located at the top and bottom of every page. It indicates what type of page you are currently viewing, and allows you to go to related pages. The following table describes the labels on the navigation bar. Note that not some labels (such as [Parent]) are not displayed on all pages.

Label Highlighted when... Links to...
[Parent] (never highlighted) the parent of the current package
[Package] viewing a package the package containing the current object
[Module] viewing a module the module containing the current object
[Class] viewing a class the class containing the current object
[Trees] viewing the trees page the trees page
[Index] viewing the index page the index page
[Help] viewing the help page the help page

The "show private" and "hide private" buttons below the top navigation bar can be used to control whether documentation for private objects is displayed. Private objects are usually defined as objects whose (short) names begin with a single underscore, but do not end with an underscore. For example, "_x", "__pprint", and "epydoc.epytext._tokenize" are private objects; but "re.sub", "__init__", and "type_" are not. However, if a module defines the "__all__" variable, then its contents are used to decide which objects are private.

A timestamp below the bottom navigation bar indicates when each page was last updated.

pyinotify/docstrings/redirect.html0000644000175000017500000000333011273644743017012 0ustar ookoiookoiEpydoc Redirect Page

Epydoc Auto-redirect page

When javascript is enabled, this page will redirect URLs of the form redirect.html#dotted.name to the documentation for the object with the given fully-qualified dotted name.

 

pyinotify/docstrings/pyinotify.Stats-class.html0000644000175000017500000004522211273644742021450 0ustar ookoiookoi pyinotify.Stats
Module pyinotify :: Class Stats
[hide private]
[frames] | no frames]

Class Stats

source code


Compute and display trivial statistics about processed events.

Instance Methods [hide private]
 
my_init(self)
Method automatically called from base class constructor.
source code
 
process_default(self, event)
Processes |event|.
source code
 
_stats_copy(self) source code
 
__repr__(self)
repr(x)
source code
 
dump(self, filename)
Dumps statistics to file |filename|.
source code
 
__str__(self, scale=45)
str(x)
source code

Inherited from ProcessEvent: __call__, __init__, nested_pevent, process_IN_Q_OVERFLOW

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __subclasshook__

Class Variables [hide private]

Inherited from ProcessEvent: pevent

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

my_init(self)

source code 

Method automatically called from base class constructor.

Parameters:
  • kargs - optional delegated arguments from __init__().
Overrides: ProcessEvent.my_init

process_default(self, event)

source code 

Processes |event|.

Parameters:
  • event - Event to be processed. Can be of any type of events but IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW).
Overrides: ProcessEvent.process_default

__repr__(self)
(Representation operator)

source code 

repr(x)

Overrides: object.__repr__
(inherited documentation)

dump(self, filename)

source code 

Dumps statistics to file |filename|.

Parameters:
  • filename (string) - pathname.

__str__(self, scale=45)
(Informal representation operator)

source code 

str(x)

Overrides: object.__str__
(inherited documentation)

pyinotify/docstrings/pyinotify.ThreadedNotifier-class.html0000644000175000017500000005104411273644742023571 0ustar ookoiookoi pyinotify.ThreadedNotifier
Module pyinotify :: Class ThreadedNotifier
[hide private]
[frames] | no frames]

Class ThreadedNotifier

source code


This notifier inherits from threading.Thread for instanciating a separate thread, and also inherits from Notifier, because it is a threaded notifier.

Note that every functionality provided by this class is also provided through Notifier class. Moreover Notifier should be considered first because it is not threaded and could be easily daemonized.

Instance Methods [hide private]
 
__init__(self, watch_manager, default_proc_fun=<ProcessEvent>, read_freq=0, threshold=0, timeout=None)
Initialization, initialize base classes.
source code
 
stop(self)
Stop notifier's loop.
source code
 
loop(self)
Thread's main loop.
source code
 
run(self)
Start thread's loop: read and process events until the method stop() is called.
source code

Inherited from threading.Thread: __repr__, getName, isAlive, isDaemon, is_alive, join, setDaemon, setName, start

Inherited from threading.Thread (private): _set_daemon, _set_ident

Inherited from threading._Verbose (private): _note

Inherited from Notifier: append_event, check_events, proc_fun, process_events, read_events

Inherited from Notifier (private): _sleep

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]

Inherited from threading.Thread: daemon, ident, name

Inherited from object: __class__

Method Details [hide private]

__init__(self, watch_manager, default_proc_fun=<ProcessEvent>, read_freq=0, threshold=0, timeout=None)
(Constructor)

source code 

Initialization, initialize base classes. read_freq, threshold and timeout parameters are used when looping.

Parameters:
  • watch_manager (WatchManager instance) - Watch Manager.
  • default_proc_fun (instance of ProcessEvent) - Default processing method.
  • read_freq (int) - if read_freq == 0, events are read asap, if read_freq is > 0, this thread sleeps max(0, read_freq - timeout) seconds.
  • threshold (int) - File descriptor will be read only if the accumulated size to read becomes >= threshold. If != 0, you likely want to use it in combination with an appropriate value set for read_freq because without that you would keep looping without really reading anything and that until the amount of events to read is >= threshold. At least with read_freq you might sleep.
  • timeout (int) - see http://docs.python.org/lib/poll-objects.html#poll-objects
Overrides: object.__init__

stop(self)

source code 

Stop notifier's loop. Stop notification. Join the thread.

Overrides: Notifier.stop

loop(self)

source code 

Thread's main loop. Don't meant to be called by user directly. Call inherited start() method instead.

Events are read only once time every min(read_freq, timeout) seconds at best and only if the size of events to read is >= threshold.

Parameters:
  • callback - Functor called after each event processing. Expects to receive notifier object (self) as first parameter.
  • daemonize - This thread is daemonized if set to True.
Overrides: Notifier.loop

run(self)

source code 

Start thread's loop: read and process events until the method stop() is called. Never call this method directly, instead call the start() method inherited from threading.Thread, which then will call run() in its turn.

Overrides: threading.Thread.run

pyinotify/docstrings/pyinotify.PyinotifyLogger-class.html0000644000175000017500000003215611273644742023506 0ustar ookoiookoi pyinotify.PyinotifyLogger
Module pyinotify :: Class PyinotifyLogger
[hide private]
[frames] | no frames]

Class PyinotifyLogger

source code


Pyinotify logger used for logging unicode strings.

Instance Methods [hide private]
 
makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None)
A factory method which can be overridden in subclasses to create specialized LogRecords.
source code

Inherited from logging.Logger: __init__, addHandler, callHandlers, critical, debug, error, exception, fatal, findCaller, getEffectiveLevel, handle, info, isEnabledFor, log, removeHandler, setLevel, warn, warning

Inherited from logging.Logger (private): _log

Inherited from logging.Filterer: addFilter, filter, removeFilter

Class Variables [hide private]

Inherited from logging.Logger: manager, root

Method Details [hide private]

makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None)

source code 

A factory method which can be overridden in subclasses to create specialized LogRecords.

Overrides: logging.Logger.makeRecord
(inherited documentation)

pyinotify/docstrings/pyinotify.SysCtlINotify-class.html0000644000175000017500000004573211273644742023103 0ustar ookoiookoi pyinotify.SysCtlINotify
Module pyinotify :: Class SysCtlINotify
[hide private]
[frames] | no frames]

Class SysCtlINotify

source code


Access (read, write) inotify's variables through sysctl. Usually it requires administrator rights to update them.

Examples:

  • Read max_queued_events attribute: myvar = max_queued_events.value
  • Update max_queued_events attribute: max_queued_events.value = 42
Instance Methods [hide private]
 
__init__(self, attrname)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
source code
int
get_val(self)
Gets attribute's value.
source code
 
set_val(self, nval)
Sets new attribute's value.
source code
 
__repr__(self)
repr(x)
source code

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Class Variables [hide private]
  inotify_attrs = {'max_queued_events': 3, 'max_user_instances':...
Properties [hide private]
int value
Gets attribute's value.

Inherited from object: __class__

Method Details [hide private]

__init__(self, attrname)
(Constructor)

source code 

x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Overrides: object.__init__
(inherited documentation)

get_val(self)

source code 

Gets attribute's value.

Returns: int
stored value.

set_val(self, nval)

source code 

Sets new attribute's value.

Parameters:
  • nval (int) - replaces current value by nval.

__repr__(self)
(Representation operator)

source code 

repr(x)

Overrides: object.__repr__
(inherited documentation)

Class Variable Details [hide private]

inotify_attrs

Value:
{'max_queued_events': 3,
 'max_user_instances': 1,
 'max_user_watches': 2}

Property Details [hide private]

value

Gets attribute's value.

Get Method:
get_val(self) - Gets attribute's value.
Set Method:
set_val(self, nval) - Sets new attribute's value.
Type:
int

pyinotify/docstrings/pyinotify.UnicodeLogRecord-class.html0000644000175000017500000002415011273644742023536 0ustar ookoiookoi pyinotify.UnicodeLogRecord
Module pyinotify :: Class UnicodeLogRecord
[hide private]
[frames] | no frames]

Class UnicodeLogRecord

source code


Instance Methods [hide private]
 
__init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None)
Initialize a logging record with interesting information.
source code
 
getMessage(self)
Return the message for this LogRecord.
source code

Inherited from logging.LogRecord: __str__

Method Details [hide private]

__init__(self, name, level, pathname, lineno, msg, args, exc_info, func=None)
(Constructor)

source code 

Initialize a logging record with interesting information.

Overrides: logging.LogRecord.__init__
(inherited documentation)

getMessage(self)

source code 

Return the message for this LogRecord.

Return the message for this LogRecord after merging any user-supplied arguments with the message.

Overrides: logging.LogRecord.getMessage
(inherited documentation)

pyinotify/docstrings/uml_class_diagram_for_pyinotif_21.gif0000644000175000017500000002527511273644742023564 0ustar ookoiookoiGIF87aLBD$"$Ģtbd<24dRTܲrt4&$ \JL̪|jlD:<侼~|<.,L> "ew砇.褗n:.n/o'7s@]hRngOV?V? Gh:7tijp~ h} QBQ Me BC|8̡5=g.b6)iJ$(*e+ 4`% ؀vm` F< s hЃ!E*ȵ(xMR=J0ǫaڕ5BU)##5 bd+VS "GIJ*r:H5n] ׸dU/ x#y+Y^ &O-!kmA&V1ZEe\ZYD#'^-d5M'L:GDOj= Z|4dmk_AD*p@bdu-M댨D'NDpͨFRC\t iD;j(E$I aҔ9\)!Z Ӛt~2MoӞf/OJÁRԦ:PTJժZXͪVծz` XJֲhMZֶRH[J׺xͫ^׾+\CT=P;ud'/.V+Rmq%5B`2˭6VKh>҆ŵ<`_Rk!<`EmTf, tH e .X_rRPzv%5_`­d\ w2]Jy{ `@Up ` J\$$hwQ7ର}`t^^iv?I,?ow_ 񺡹~7pU7L"b#D96&ΈB&X }dPc5@ Y.UP.4 CO65@Mpq1#"hqǚJh(Jk4T6xW e0g= ꁟh(` A|,?R гd#UKeҜ̏X]6ī{R.L TTĥ(:GP#`4smiK3 $o̠GK} PY⼧ |2Wl]dgJ<:}yS[sc/[}Xz!/ Qe%qGV8R~6%6w̭$$i?@* w|pAv <t{Z/0DJ'iwE0yGs}TsB(#+ 0"z-|3r fzUG]KMS4ؤ2w)M˶1cN!Nt2)M~tM=~&+6VNM'nD#g+!cIyQ0ΔvUxNT$0!R1Jc244OJRRq|}"@0EP%5^+?PVYf4eÕP+w[Z2]Vk5hghORy8P E5^U34f@pC@eV&=q p)4SGyZևQFQ%r# xq3xaF$`$2 Fc Qbi&2{}Yix 8y`%Dž,ErE\Ց*RY1^R]&G`+y Ւ?[4`B+rB9Q#erfaiBfI6\+BRf8X)L#W%WbmFpҎSTEvm‡Y4rs7t`)H)+7G.G)7~ǖYH#gyxs'GI\y|ab~w #K7Kb9;$Ӆ-HąQ$2M(8:Y4/5ZӊO8K蔆8Pe'~h@ 6eAY݃&w7{8h?#g828fXec석SY)!ٟşZD=azW!8\ zE^!F20a$z zdS&G%"&F)!NffVAAAAAFg\FBv'H#J;aàD{~$H۴IKN5cR[BVi␙V $vu^yZ\˓d7:!}#jtY]U,^KH0jZT>*6[6BqJF\LfBbv(M*?:_VWI:rԶEDCdd$RnjDm*E6lh~;xE)ń&?'JJuèPBWwuw[NhRVzg/ǘ%(|ꖚy~`* ~rIQ κJ*K%۩#g=`ZMjzjND1gZԅ|:rY;Oen {k(d]+lW8H}jĒc๧L\kQL;+8+:;<[V `n9.NHV4=m]۴ٍz=ۻy>ݍ؅pjTX\o}C]Y*+ ,IIc}p1XKԈ +?MN=ݩ2rVA¼QG˗:+4$TG0xu6%p0w)MW2&; Vf~?~sr9"s ċZ1v++Ϋ*>ʛf.shn*X񖁄NZ̤u7A\s~5ws2>5*nRʙGg廢38l3&zYzUᾦ|5ϢA,Ezxx*tx%}EԩqGn^>~{xyynJњ7 ^ݎҪGD^}C7yVy:.^\쫪9rJ~Ԛ/bzsp&}3}kno}zDA6~<|ItJ{c.D{H/!L l Bđ3gs=Q}} !{ 88dKBQ2n/=#rpU !Q]ʨbӐRSzشͮT;ݔn7i > E"e8iYvXS72a7 ؿ{dӳ/>nSa@O7)mh`WCa=8 m`n!^!oA2ЀA#%PJ vc:c>dBiZ6n#J.dN> eRf䑢%9eZne^~ fUZ afjfI&wIgvމg+f hJh|ʟ=uT  ]"l!=:Q EVA 2y( (JX P8 j#i bM#51^תjn,8p뒹"ʫN0.а(MfjHڋoخoi!,< .K}b"TyG40_!Or֗mm/ ,@Kv;)"G$ pIr*%H`B=D(=[ `! :׃ 0w5ջުL0-aA'PX,PPDX!@ P|΁ &'IXCP o~qe*`Ŏd%Kh=Q/zA{h+"^x@w-"%D̎H>+?I%@ p ,ꐀp, !aH! `Bp"b@HNҀd.M*t")F”%@,@0X;f,$[eUŘ'MCGC,s]ô5MP4S8'yMl⥓/yvmWJ9Z2s<AWA61ЃU" -LCG$0hA@G3R!HvwtT"i;< gOd$HjRRl]U0#R2GQ;E:H]4x3OILLujOu%&[DPBԙB8+XyT9!-s݌ |`sKcҌt) `1HXJ " "#:XPc$&IRemp0Lukc XfaWmsFb4|Hf2@HԆnhӥ/dnm<ՠ@K=.] |EYxjy-pZNƽEzq%Ppսƈ0&yxĻuGOFa{9Mt(]ɐF e.#]z3NqFQf)ugi~XABCAD@oVtZ}_~(^7~4 FKJ0JO 8JtJ)D P!rrQTScS'RuRCUTkT0WW1W-u%;ȃBv OE/u_ZE*[ul`=Y'?Xt` iB+bcdcPd6 *Y<{iZ{&\hq×[p 7 &kVٰ n kbw1LJ[⇊qrrH$8Hq27AgHAP"'"ttUWH0rňɘxǨ范Gq6{H(qh٨K0xW.y(aOzazzzȏlq{s{Ԉg|a}}}")<Wy#;s )4w:} iȈ~gBE;?SAԒ0~ >'byxAY؈PΡDG˴S=PLr8 HZOQB'8X3(Ue,Uf/iES` +S[)|HB`%\U.ք^YuE_KhstT~`(iA.h0f1ӆmPX)vDlɃ 1x֖FkphæCa X{Qrc1ɜד19KC0gl$<@dsjG~D{4|?TT:p$GPF:yTe|p*+K EIT4NKJKObN8F-t)ũȚZPYIٕpUe-WV020;lUWЭ0W J*ȗVpZڗ)aH8%]5 NX`EH&VO(^D^u^_`ʦwySWȯjb{fh`1pfci4Ȳyhf2K{fFig&dhiibVJt]: 9klmZte6ZFmJnfkMarp{Enm w pyinotify.WatchManagerError
Module pyinotify :: Class WatchManagerError
[hide private]
[frames] | no frames]

Class WatchManagerError

source code


WatchManager Exception. Raised on error encountered on watches operations.

Instance Methods [hide private]
 
__init__(self, msg, wmd)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
source code

Inherited from exceptions.Exception: __new__

Inherited from exceptions.BaseException: __delattr__, __getattribute__, __getitem__, __getslice__, __reduce__, __repr__, __setattr__, __setstate__, __str__, __unicode__

Inherited from object: __format__, __hash__, __reduce_ex__, __sizeof__, __subclasshook__

Properties [hide private]

Inherited from exceptions.BaseException: args, message

Inherited from object: __class__

Method Details [hide private]

__init__(self, msg, wmd)
(Constructor)

source code 

x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Parameters:
  • msg (string) - Exception string's description.
  • wmd (dict) - This dictionary contains the wd assigned to paths of the same call for which watches were successfully added.
Overrides: object.__init__

pyinotify/docstrings/uml_class_diagram_for_pyinotif_24.gif0000644000175000017500000000520111273644743023553 0ustar ookoiookoiGIF87aLBDĤBDĢ$"$jdĺĆlZ\fd<2, dJD&$ԦvtļԬRTD:<̢\NLĤFDndĊt^\<24*,ļԬVTD><ܶ$~t4*,j\侼 Ď~|lVT><^\L:<ܮNLrt䶴rl<.,D64z| ,&$ԦԮ̦|bd\JLTBDdNL̞, H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜIM\ɳϟ@ JѢxӧPJJիXRt`ÊKY(?Ϫ۰_vݻEظ] &w†[7`apA `!^btK? e!(@i!=˨㥳귧727PzE$(Vu7q5nW(21z蹗͞q޿jу+a {g0W\6E!gɅZcpWVE#WUhh,ȝޅ2F#Nj;N$QDiH"ՑPF)TViXfEH(\?9X(yhFf xΩCC&)蠄GLn袌6(jfwiiCzlF}[rjgVda\8ib|B~g} VdIBݨWu^eHک,Zyvf4emv-ieQ`Sz%FIyfmzoJ(|!`l ↞-p C,;V$t;aq+q[wZAWA'g) wYja1^Yq'[Z$z+3Y~7u`0YqeqBҒ. VH"â89rDFggIa\Wɲ]4L*Glw̲ <0X#ɒzQ\N}&TʁPIJfR"4IjZ̦6D` 8y\5@9b`;K!=y0\CIЈR`Dj0:!X@D=< q0  !diH!KP)HӐlC-P0 yЩCWP6m(@ZPA]PQi>JjHTb^jVzձ`=+Zͪ}ne+\ֹUvI]W&{Gx M:VeZͬf7CEV!ЂFKҚM-j ̿VlςVͭnkk[V-o{k.q bj[Eִ.x]~׹A$0Z@v\պ P!B W AxkZE- !Al7(a 6b_7oy͋ZV@ph bǣpw[Z=B0w, hmPDAWme 7J^,8wt{). The page title may be followed by a link to the * corresponding source code (using 'span.codelink'). * - The footer consists of a navigation bar, a timestamp, and a * pointer to epydoc's homepage. */ h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; } h2.epydoc { font-size: +130%; font-weight: bold; } h3.epydoc { font-size: +115%; font-weight: bold; margin-top: 0.2em; } td h3.epydoc { font-size: +115%; font-weight: bold; margin-bottom: 0; } table.navbar { background: #a0c0ff; color: #000000; border: 2px groove #c0d0d0; } table.navbar table { color: #000000; } th.navbar-select { background: #70b0ff; color: #000000; } table.navbar a { text-decoration: none; } table.navbar a:link { color: #0000ff; } table.navbar a:visited { color: #204080; } span.breadcrumbs { font-size: 85%; font-weight: bold; } span.options { font-size: 70%; } span.codelink { font-size: 85%; } td.footer { font-size: 85%; } /* Table Headers * - Each summary table and details section begins with a 'header' * row. This row contains a section title (marked by * 'span.table-header') as well as a show/hide private link * (marked by 'span.options', defined above). * - Summary tables that contain user-defined groups mark those * groups using 'group header' rows. */ td.table-header { background: #70b0ff; color: #000000; border: 1px solid #608090; } td.table-header table { color: #000000; } td.table-header table a:link { color: #0000ff; } td.table-header table a:visited { color: #204080; } span.table-header { font-size: 120%; font-weight: bold; } th.group-header { background: #c0e0f8; color: #000000; text-align: left; font-style: italic; font-size: 115%; border: 1px solid #608090; } /* Summary Tables (functions, variables, etc) * - Each object is described by a single row of the table with * two cells. The left cell gives the object's type, and is * marked with 'code.summary-type'. The right cell gives the * object's name and a summary description. * - CSS styles for the table's header and group headers are * defined above, under 'Table Headers' */ table.summary { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin-bottom: 0.5em; } td.summary { border: 1px solid #608090; } code.summary-type { font-size: 85%; } table.summary a:link { color: #0000ff; } table.summary a:visited { color: #204080; } /* Details Tables (functions, variables, etc) * - Each object is described in its own div. * - A single-row summary table w/ table-header is used as * a header for each details section (CSS style for table-header * is defined above, under 'Table Headers'). */ table.details { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } table.details table { color: #000000; } table.details a:link { color: #0000ff; } table.details a:visited { color: #204080; } /* Fields */ dl.fields { margin-left: 2em; margin-top: 1em; margin-bottom: 1em; } dl.fields dd ul { margin-left: 0em; padding-left: 0em; } dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; } div.fields { margin-left: 2em; } div.fields p { margin-bottom: 0.5em; } /* Index tables (identifier index, term index, etc) * - link-index is used for indices containing lists of links * (namely, the identifier index & term index). * - index-where is used in link indices for the text indicating * the container/source for each link. * - metadata-index is used for indices containing metadata * extracted from fields (namely, the bug index & todo index). */ table.link-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; } td.link-index { border-width: 0px; } table.link-index a:link { color: #0000ff; } table.link-index a:visited { color: #204080; } span.index-where { font-size: 70%; } table.metadata-index { border-collapse: collapse; background: #e8f0f8; color: #000000; border: 1px solid #608090; margin: .2em 0 0 0; } td.metadata-index { border-width: 1px; border-style: solid; } table.metadata-index a:link { color: #0000ff; } table.metadata-index a:visited { color: #204080; } /* Function signatures * - sig* is used for the signature in the details section. * - .summary-sig* is used for the signature in the summary * table, and when listing property accessor functions. * */ .sig-name { color: #006080; } .sig-arg { color: #008060; } .sig-default { color: #602000; } .summary-sig { font-family: monospace; } .summary-sig-name { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:link { color: #006080; font-weight: bold; } table.summary a.summary-sig-name:visited { color: #006080; font-weight: bold; } .summary-sig-arg { color: #006040; } .summary-sig-default { color: #501800; } /* Subclass list */ ul.subclass-list { display: inline; } ul.subclass-list li { display: inline; } /* To render variables, classes etc. like functions */ table.summary .summary-name { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:link { color: #006080; font-weight: bold; font-family: monospace; } table.summary a.summary-name:visited { color: #006080; font-weight: bold; font-family: monospace; } /* Variable values * - In the 'variable details' sections, each varaible's value is * listed in a 'pre.variable' box. The width of this box is * restricted to 80 chars; if the value's repr is longer than * this it will be wrapped, using a backslash marked with * class 'variable-linewrap'. If the value's repr is longer * than 3 lines, the rest will be ellided; and an ellipsis * marker ('...' marked with 'variable-ellipsis') will be used. * - If the value is a string, its quote marks will be marked * with 'variable-quote'. * - If the variable is a regexp, it is syntax-highlighted using * the re* CSS classes. */ pre.variable { padding: .5em; margin: 0; background: #dce4ec; color: #000000; border: 1px solid #708890; } .variable-linewrap { color: #604000; font-weight: bold; } .variable-ellipsis { color: #604000; font-weight: bold; } .variable-quote { color: #604000; font-weight: bold; } .variable-group { color: #008000; font-weight: bold; } .variable-op { color: #604000; font-weight: bold; } .variable-string { color: #006030; } .variable-unknown { color: #a00000; font-weight: bold; } .re { color: #000000; } .re-char { color: #006030; } .re-op { color: #600000; } .re-group { color: #003060; } .re-ref { color: #404040; } /* Base tree * - Used by class pages to display the base class hierarchy. */ pre.base-tree { font-size: 80%; margin: 0; } /* Frames-based table of contents headers * - Consists of two frames: one for selecting modules; and * the other listing the contents of the selected module. * - h1.toc is used for each frame's heading * - h2.toc is used for subheadings within each frame. */ h1.toc { text-align: center; font-size: 105%; margin: 0; font-weight: bold; padding: 0; } h2.toc { font-size: 100%; font-weight: bold; margin: 0.5em 0 0 -0.3em; } /* Syntax Highlighting for Source Code * - doctest examples are displayed in a 'pre.py-doctest' block. * If the example is in a details table entry, then it will use * the colors specified by the 'table pre.py-doctest' line. * - Source code listings are displayed in a 'pre.py-src' block. * Each line is marked with 'span.py-line' (used to draw a line * down the left margin, separating the code from the line * numbers). Line numbers are displayed with 'span.py-lineno'. * The expand/collapse block toggle button is displayed with * 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not * modify the font size of the text.) * - If a source code page is opened with an anchor, then the * corresponding code block will be highlighted. The code * block's header is highlighted with 'py-highlight-hdr'; and * the code block's body is highlighted with 'py-highlight'. * - The remaining py-* classes are used to perform syntax * highlighting (py-string for string literals, py-name for names, * etc.) */ pre.py-doctest { padding: .5em; margin: 1em; background: #e8f0f8; color: #000000; border: 1px solid #708890; } table pre.py-doctest { background: #dce4ec; color: #000000; } pre.py-src { border: 2px solid #000000; background: #f0f0f0; color: #000000; } .py-line { border-left: 2px solid #000000; margin-left: .2em; padding-left: .4em; } .py-lineno { font-style: italic; font-size: 90%; padding-left: .5em; } a.py-toggle { text-decoration: none; } div.py-highlight-hdr { border-top: 2px solid #000000; border-bottom: 2px solid #000000; background: #d8e8e8; } div.py-highlight { border-bottom: 2px solid #000000; background: #d0e0e0; } .py-prompt { color: #005050; font-weight: bold;} .py-more { color: #005050; font-weight: bold;} .py-string { color: #006030; } .py-comment { color: #003060; } .py-keyword { color: #600000; } .py-output { color: #404040; } .py-name { color: #000050; } .py-name:link { color: #000050 !important; } .py-name:visited { color: #000050 !important; } .py-number { color: #005000; } .py-defname { color: #000060; font-weight: bold; } .py-def-name { color: #000060; font-weight: bold; } .py-base-class { color: #000060; } .py-param { color: #000060; } .py-docstring { color: #006030; } .py-decorator { color: #804020; } /* Use this if you don't want links to names underlined: */ /*a.py-name { text-decoration: none; }*/ /* Graphs & Diagrams * - These CSS styles are used for graphs & diagrams generated using * Graphviz dot. 'img.graph-without-title' is used for bare * diagrams (to remove the border created by making the image * clickable). */ img.graph-without-title { border: none; } img.graph-with-title { border: 1px solid #000000; } span.graph-title { font-weight: bold; } span.graph-caption { } /* General-purpose classes * - 'p.indent-wrapped-lines' defines a paragraph whose first line * is not indented, but whose subsequent lines are. * - The 'nomargin-top' class is used to remove the top margin (e.g. * from lists). The 'nomargin' class is used to remove both the * top and bottom margin (but not the left or right margin -- * for lists, that would cause the bullets to disappear.) */ p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em; margin: 0; } .nomargin-top { margin-top: 0; } .nomargin { margin-top: 0; margin-bottom: 0; } /* HTML Log */ div.log-block { padding: 0; margin: .5em 0 .5em 0; background: #e8f0f8; color: #000000; border: 1px solid #000000; } div.log-error { padding: .1em .3em .1em .3em; margin: 4px; background: #ffb0b0; color: #000000; border: 1px solid #000000; } div.log-warning { padding: .1em .3em .1em .3em; margin: 4px; background: #ffffb0; color: #000000; border: 1px solid #000000; } div.log-info { padding: .1em .3em .1em .3em; margin: 4px; background: #b0ffb0; color: #000000; border: 1px solid #000000; } h2.log-hdr { background: #70b0ff; color: #000000; margin: 0; padding: 0em 0.5em 0em 0.5em; border-bottom: 1px solid #000000; font-size: 110%; } p.log { font-weight: bold; margin: .5em 0 .5em 0; } tr.opt-changed { color: #000000; font-weight: bold; } tr.opt-default { color: #606060; } pre.log { margin: 0; padding: 0; padding-left: 1em; } pyinotify/docstrings/index.html0000644000175000017500000000111711273644743016321 0ustar ookoiookoi API Documentation pyinotify/docstrings/pyinotify.PrintAllEvents-class.html0000644000175000017500000003463511273644742023272 0ustar ookoiookoi pyinotify.PrintAllEvents
Module pyinotify :: Class PrintAllEvents
[hide private]
[frames] | no frames]

Class PrintAllEvents

source code


Dummy class used to print events strings representations. For instance this class is used from command line to print all received events to stdout.

Instance Methods [hide private]
 
my_init(self, out=None)
This method is called from base constructor ProcessEvent.__init__().
source code
 
process_default(self, event)
Writes event string representation to file object provided to my_init().
source code

Inherited from ProcessEvent: __call__, __init__, nested_pevent, process_IN_Q_OVERFLOW

Inherited from _ProcessEvent: __repr__

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Class Variables [hide private]

Inherited from ProcessEvent: pevent

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

my_init(self, out=None)

source code 

This method is called from base constructor ProcessEvent.__init__(). This method is useless here and is meant to be redifined in a subclass of ProcessEvent. In effect, when subclassing just override this method if you want to provide custom initialization to your subclass' instance. You MUST pass keyword arguments though.

Parameters:
  • out (Object providing a valid file object interface.) - Where events will be written.
Overrides: ProcessEvent.my_init

process_default(self, event)

source code 

Writes event string representation to file object provided to my_init().

Parameters:
  • event (Event instance) - Event to be processed. Can be of any type of events but IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW).
Overrides: ProcessEvent.process_default

pyinotify/docstrings/uml_class_diagram_for_pyinotif_20.gif0000644000175000017500000000350611273644742023554 0ustar ookoiookoiGIF87aULBD$"$Ģtbd<24ܲdRTrt \JL4&$̪D:<亼̄jllZ\z|L:< TBD,"$̢|bd䶴lVTvt dNL<.,Ԫ쾼Ğ$D64ܶdVTvt  \NL4*,D><侼Ԅnlt^\~|L> 2 2<>q`Ȃ( gbYܘHsI$1ס:'9\Qƕ-$9C I(81Â:^W9<$1R /\r˩3 B >(Bȉ(S†"M +Ǫڵ؃"ZAC9 QΠy{+դ7rA E,,aʼn$7ʱ@$Ibs(Q|Q`ޫ0 tXtСL;Lg =0DbR԰ Ğʍ ;Bg ؠ(^`y!Wq$g % 6(ZVa%) (2Ix@,0(4hcQ<*!%($U&8HZ.G&?KJTX$MV9QF`)ɉ7lic;n)'qi'@WZeJ|SQ C]95%$S$QEPEQ$$zZq*yVJB $ڪS`:iATjbP@:0 

:>*MY۾ Qc> 3$i>nmCPN+ּ.Y$) 0]SltiB 8hM?q;q:GK'sB1fj /mcqL 9 UCJZG#Ͽ1IC C8i2)g؍3"=ֿg"߄ AD zY4, UʁQ1©$ؾ*V+KZYW8 j -s(<`Cp ()>,, 0C's 1T2-~27'+~[J}fGu?bv轤n0(| CQpQ \Ea 8٧A~]SR:à2w2 #Kɪo%#y,~H#Q Qdc__6>a [Zf!i& 1IA.vtJ@z̧>~ >MBІ:D'JъZE ;pyinotify/docstrings/uml_class_diagram_for_pyinotif_11.gif0000644000175000017500000002043611273644742023555 0ustar ookoiookoiGIF87a|LBDĤBDĆ$"$jdԦd^\bd|T., dJD<2,ĖvtܶĞܪ|^TlvlTJD&$$RT4&$lVLD:4ԢԮĞj\64 \F<̦rdԜČndԼ~tTB<,&$z|̢ĤFD,lfd\64䲤̒fdtlRLrt侼ĊĢ:<̪D64̢̚Ԫ\NL*,fd|ĚܮVTrdNL^\><~|܌ Ԧ<24$lVTD:sC-p_e_*`xDJ`00ʸ!UR_ Hd'j-jA tGFe ni_k]d&il%m}BlG%ekY斃&Yi`hDe iHPm':f,,^|A`'몭 _om):[h]Wn[u([WXt1)JJma,k07mz,J mY-']f0 Qt|,k,bD 0*B'/++ @mܱ ,[|p 7!1>e&Q JA'D&-GI%(mFP+Y\!d^-C|G'tA-5Vct[sF k'dQ#2ywh_礗n][KTǮG%\/o|x`7ӈH4B+kpZ6ӵDqm5zϞ;SBƢ^^ԍcD@:iU \zƤU}_EdֶG׺xҳ6r4_ X> 5 [ÙH/Vebcfh3cHڅfRSI~3 --U?0@0 U3|Pɰ)@}"G~ ^Ks6hCF5tc %lp S*6' h _*z٥Ůc0c3K &cayضa (fV+ۗE6 mLӼEm27ֲ % f(// h`4KЏ}tgnռͭQjVֹoR`,&Rb>K 4>7}iV-^M2̎ ׅh X Aox;F}o 񬻠iOz +S6riw- ,uײ6D}BRxVq,2SPMlQtznq%S#-rs1vyFdV2s5F}>g8G>:G{kmcotM5>C@$v~dSttQgaP 4u-8gGu.N9P3T8VhmgYo8wYքgW9y8{7JօZCxb~aixrKQC!M#jaysYkyL؆v1z$bMv$'zX${qQlDmNn(]'/{XVdB}BTCwnG-h~f\~%on!Q)oъ!hhsRP$0 /gg(ƀeWd7-VS˨J4oqsXu9P4'%>'R,((0@35hS긎1}ItTu:BȁA|Hx Duǒ0?8-yI6<2Vv!YUvE9e:tIN)?VKUoQK[L0kW\ǥ$hz{e]M9Ȧ])ƊHt}x~}~!.Dn5Ռg'~ &>lAqaW3R1v<7#S*rvc<7+F )GGFY)Ld$)OFF;ɓOU Nٝ1Y99~QBY:BNtVT9JLSI9QSRd[W9'ɱ_Y4Ɵ)f$V'{ Zvl .^T rHIJc/vИ' Y37SvQrМt[|tdY/)醆FztH#Guՙ l;-rzkZF}p|* Dwj8f-* 9SʥVkwiv]KE~!ʎ!\6kkrIUi(ɦ㥙[ZBফHɘ}ιʘFQoiأՑpۈaHp-h!6b%ڑ8caqAӉd;wJxj [+wgJf&wY}ѨSjw^?ѩc5;*t!\D䖱zq걵 (]$J"}y^ӗkHv:E$mڀ_{ϊݲ.Bo$"o9Uȍ"u*ݺ##23ɯI8qqrX#K)sBtv$m<8\bj=#)ui@*k; ۝˓~б]u$Z(Uٲ/1[UY[~AytQ{OQNORoqѵ˽onעuV;Djۍߺp!.{k7vl!л =7gzy+Vl'<) +̒-|*+- K:3˷99;ܼp񼣋f6ux#4W[:j?{A Ď+R%5x1Rh\Lۯ[LB[Т/]{`Ş Z9_^חxpѶmt\~[{m{}&33S`+mx7ocQ5{z@ |Ĩ*tiָܸӺMV° М/9/IA<\l<A? \|L<]>cP_ 0]5aO 1O T&TB Pp0}'P 1# 0I`B(`0FX0L&@;@ M]1Qm\IQGdIPUp je 0t]5 x]Q0yׂ==؃]؆׈y، ׎eْՔ]V}٘ԚCٞӠ1=ڤlڪڬڮڰۯs-۶}۸}6pA !\P:k9CfݷŭpܤSv9HV9 ح8݂XU<@ aCg潕ѳe4m}ܝzJIRz! ,L=@dmn!aѤN/N%nݗ'S(-N`$jZ| -q!^܍}+cfCe{b[ENkM~*;N܍-n4/8>80^cV>-ε3ݢi ɇ6y %3%Ս^N0D,q3s.<3nh.mOOqJZ5S )*˝Q778\CkynܓcԣٍF01Ѝz뺾uV ./Ai-nˎ.۸ގ;>^.N>p12a,7m.&KA@ z {?=faALFK\śW 05yk@0a iP Sp{ ]f` Ghp޷(E[AZH0 } D468F}n*-nR^pQb8l^`wZR@rL) ,[%DpDPSAS:0ʇs&n~o",>+_ϒ.ޝ@tO/>uR^S@@ JB >Q"C6-^ĘQF7"*H%IژRJ-]t(0męSN QDOEE Rv$UԈDU]TPv|EV-CB)j\^ZX}]UB*8EQTjzX䔙4PeΝQY(0!+UM+Rj֠ 8o#Y^ml}o%~\9˝Sm\zӭ~]{۽]C,^շwo~|ǟ_~ox?R  dA0B 'B,l BG$OD_F44(!ŃR1;20"=1@4>QH%O1G[lOXXr(Y*lɇvR [:B&XC(0)DHM*3QFaBSD-K/3Z0 ";=,C;ԡO>[RK,HpB:4VYMEs ZC4$( -.`U "W`bդBvDEoUE+lX$?>\-esVnQ66"D(MvEݷhKZlޅEq TW]XAUPz bYܖ[O,3UP ;LyeT 5J5&[w ($ZšEH@zIzId:0v2kFF{}Sކ;n离n;oa;p'|nݴGf<r/OzǼs!)?rGGtD'=p_Yw;vo{vQW}tw/x/'~=㏏޼-B>1D>GA D1 `%pM43.<r #T8@0 \ T" T($-  PXapL) R06&DOFh$UDX54xM8A#f>M)N/Uo`sF12ge 5:gt#+α cG>яd$^HBҐ4sHF6ґ HJVҒ "]|~d(E9JRҔ<)UIG2<%&5IR{,uKZp/W)K`l!Lfe/L @K ~%@M]a .hZ|Rws$&l'- >Р&*Ʌ7c&Tr-c`b '}@-"r1 N!%' \ SZn  +e/d΄$R;ѐ&UNE*X@* `qU(M,Ve"t]$d5+-Mlbs*`9Ut&E MWu |E%A8X,ke/PQNqT WrV}m, [Fu&a 8d%$rqPꖷ~fA6D-lUz=T\Lxd08 .L< oQi.ik2v1 7w^`v 1 8 ^ nE;NV .+1\w£MnٹWWW8RfUbfB5dqe-aƒL..MO>u+,1}Mث%V-SAE=hRxL%|YZS➪ij]NTµ0/qj{$v)92ԛ;3]lSwRe.! 1JYc2@uj]Pt{z|%1yukY[_ͪ6 Nia2%n)kYЖ,iCaorK[d-_).Wlm_җ#,z ^Wdz.o\-&:';K76|cW9'}ӠsАXX4=M' pyinotify
Module pyinotify
[hide private]
[frames] | no frames]

Source Code for Module pyinotify

   1  #!/usr/bin/env python 
   2  # -*- coding: iso-8859-1 -*- 
   3  # 
   4  # pyinotify.py - python interface to inotify 
   5  # Copyright (C) Sebastien Martini <sebastien.martini@gmail.com> 
   6  # 
   7  # This program is free software; you can redistribute it and/or 
   8  # modify it under the terms of the GNU General Public License 
   9  # as published by the Free Software Foundation; either version 2 
  10  # of the License, or (at your option) any later version. 
  11  # 
  12  # This program is distributed in the hope that it will be useful, 
  13  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15  # GNU General Public License for more details. 
  16  # 
  17  # You should have received a copy of the GNU General Public License 
  18  # along with this program; if not, write to the Free Software 
  19  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
  20  # 02110-1301, USA. 
  21   
  22  """ 
  23  pyinotify 
  24   
  25  @author: Sebastien Martini 
  26  @license: GPLv2+ 
  27  @contact: seb@dbzteam.org 
  28  """ 
29 30 -class PyinotifyError(Exception):
31 """Indicates exceptions raised by a Pyinotify class.""" 32 pass
33
34 35 -class UnsupportedPythonVersionError(PyinotifyError):
36 """ 37 Raised on unsupported Python versions. 38 """
39 - def __init__(self, version):
40 """ 41 @param version: Current Python version 42 @type version: string 43 """ 44 PyinotifyError.__init__(self, 45 ('Python %s is unsupported, requires ' 46 'at least Python 2.4') % version)
47
48 49 -class UnsupportedLibcVersionError(PyinotifyError):
50 """ 51 Raised on unsupported libc versions. 52 """
53 - def __init__(self, version):
54 """ 55 @param version: Current Libc version 56 @type version: string 57 """ 58 PyinotifyError.__init__(self, 59 ('Libc %s is not supported, requires ' 60 'at least Libc 2.4') % version)
61 62 63 # Check Python version 64 import sys 65 if sys.version < '2.4': 66 raise UnsupportedPythonVersionError(sys.version) 67 68 69 # Import directives 70 import threading 71 import os 72 import select 73 import struct 74 import fcntl 75 import errno 76 import termios 77 import array 78 import logging 79 import atexit 80 from collections import deque 81 from datetime import datetime, timedelta 82 import time 83 import fnmatch 84 import re 85 import ctypes 86 import ctypes.util 87 import asyncore 88 89 __author__ = "seb@dbzteam.org (Sebastien Martini)" 90 91 __version__ = "0.8.8" 92 93 __metaclass__ = type # Use new-style classes by default 94 95 96 # Compatibity mode: set to True to improve compatibility with 97 # Pyinotify 0.7.1. Do not set this variable yourself, call the 98 # function compatibility_mode() instead. 99 COMPATIBILITY_MODE = False 100 101 102 # Load libc 103 LIBC = ctypes.cdll.LoadLibrary(ctypes.util.find_library('c')) 104 105 # The libc version > 2.4 check. 106 # XXX: Maybe it is better to check if the libc has the needed functions inside? 107 # Because there are inotify patches for libc 2.3.6. 108 LIBC.gnu_get_libc_version.restype = ctypes.c_char_p 109 LIBC_VERSION = LIBC.gnu_get_libc_version() 110 if (int(LIBC_VERSION.split('.')[0]) < 2 or 111 (int(LIBC_VERSION.split('.')[0]) == 2 and 112 int(LIBC_VERSION.split('.')[1]) < 4)): 113 raise UnsupportedLibcVersionError(LIBC_VERSION)
114 115 116 -class PyinotifyLogger(logging.Logger):
117 """ 118 Pyinotify logger used for logging unicode strings. 119 """
120 - def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, 121 extra=None):
122 rv = UnicodeLogRecord(name, level, fn, lno, msg, args, exc_info, func) 123 if extra is not None: 124 for key in extra: 125 if (key in ["message", "asctime"]) or (key in rv.__dict__): 126 raise KeyError("Attempt to overwrite %r in LogRecord" % key) 127 rv.__dict__[key] = extra[key] 128 return rv
129
130 131 -class UnicodeLogRecord(logging.LogRecord):
132 - def __init__(self, name, level, pathname, lineno, 133 msg, args, exc_info, func=None):
134 py_version = sys.version_info 135 # func argument was added in Python 2.5, just ignore it otherwise. 136 if py_version[0] >= 2 and py_version[1] >= 5: 137 logging.LogRecord.__init__(self, name, level, pathname, lineno, 138 msg, args, exc_info, func) 139 else: 140 logging.LogRecord.__init__(self, name, level, pathname, lineno, 141 msg, args, exc_info)
142
143 - def getMessage(self):
144 msg = self.msg 145 if not isinstance(msg, (unicode, str)): 146 try: 147 msg = str(self.msg) 148 except UnicodeError: 149 pass 150 if self.args: 151 if isinstance(self.args, tuple): 152 def str_to_unicode(s): 153 """Return unicode string.""" 154 if not isinstance(s, str): 155 return s 156 return unicode(s, sys.getfilesystemencoding())
157 args = tuple([str_to_unicode(m) for m in self.args]) 158 else: 159 args = self.args 160 msg = msg % args 161 if not isinstance(msg, unicode): 162 msg = unicode(msg, sys.getfilesystemencoding()) 163 return msg
164
165 166 # Logging 167 -def logger_init():
168 """Initialize logger instance.""" 169 logging.setLoggerClass(PyinotifyLogger) 170 log = logging.getLogger("pyinotify") 171 console_handler = logging.StreamHandler() 172 console_handler.setFormatter( 173 logging.Formatter("[Pyinotify %(levelname)s] %(message)s")) 174 log.addHandler(console_handler) 175 log.setLevel(20) 176 return log
177 178 log = logger_init()
179 180 181 182 ### inotify's variables ### 183 184 185 -class SysCtlINotify:
186 """ 187 Access (read, write) inotify's variables through sysctl. Usually it 188 requires administrator rights to update them. 189 190 Examples: 191 - Read max_queued_events attribute: myvar = max_queued_events.value 192 - Update max_queued_events attribute: max_queued_events.value = 42 193 """ 194 195 inotify_attrs = {'max_user_instances': 1, 196 'max_user_watches': 2, 197 'max_queued_events': 3} 198
199 - def __init__(self, attrname):
200 sino = ctypes.c_int * 3 201 self._attrname = attrname 202 self._attr = sino(5, 20, SysCtlINotify.inotify_attrs[attrname])
203
204 - def get_val(self):
205 """ 206 Gets attribute's value. 207 208 @return: stored value. 209 @rtype: int 210 """ 211 oldv = ctypes.c_int(0) 212 size = ctypes.c_int(ctypes.sizeof(oldv)) 213 LIBC.sysctl(self._attr, 3, 214 ctypes.c_voidp(ctypes.addressof(oldv)), 215 ctypes.addressof(size), 216 None, 0) 217 return oldv.value
218
219 - def set_val(self, nval):
220 """ 221 Sets new attribute's value. 222 223 @param nval: replaces current value by nval. 224 @type nval: int 225 """ 226 oldv = ctypes.c_int(0) 227 sizeo = ctypes.c_int(ctypes.sizeof(oldv)) 228 newv = ctypes.c_int(nval) 229 sizen = ctypes.c_int(ctypes.sizeof(newv)) 230 LIBC.sysctl(self._attr, 3, 231 ctypes.c_voidp(ctypes.addressof(oldv)), 232 ctypes.addressof(sizeo), 233 ctypes.c_voidp(ctypes.addressof(newv)), 234 ctypes.addressof(sizen))
235 236 value = property(get_val, set_val) 237
238 - def __repr__(self):
239 return '<%s=%d>' % (self._attrname, self.get_val())
240 241 242 # Singleton instances 243 # 244 # read: myvar = max_queued_events.value 245 # update: max_queued_events.value = 42 246 # 247 for attrname in ('max_queued_events', 'max_user_instances', 'max_user_watches'): 248 globals()[attrname] = SysCtlINotify(attrname)
249 250 251 252 ### iglob ### 253 254 255 # Code taken from standart Python Lib, slightly modified in order to work 256 # with pyinotify (don't exclude dotted files/dirs like .foo). 257 # Original version: 258 # @see: http://svn.python.org/projects/python/trunk/Lib/glob.py 259 260 -def iglob(pathname):
261 if not has_magic(pathname): 262 if hasattr(os.path, 'lexists'): 263 if os.path.lexists(pathname): 264 yield pathname 265 else: 266 if os.path.islink(pathname) or os.path.exists(pathname): 267 yield pathname 268 return 269 dirname, basename = os.path.split(pathname) 270 # relative pathname 271 if not dirname: 272 return 273 # absolute pathname 274 if has_magic(dirname): 275 dirs = iglob(dirname) 276 else: 277 dirs = [dirname] 278 if has_magic(basename): 279 glob_in_dir = glob1 280 else: 281 glob_in_dir = glob0 282 for dirname in dirs: 283 for name in glob_in_dir(dirname, basename): 284 yield os.path.join(dirname, name)
285
286 -def glob1(dirname, pattern):
287 if not dirname: 288 dirname = os.curdir 289 try: 290 names = os.listdir(dirname) 291 except os.error: 292 return [] 293 return fnmatch.filter(names, pattern)
294
295 -def glob0(dirname, basename):
296 if basename == '' and os.path.isdir(dirname): 297 # `os.path.split()` returns an empty basename for paths ending with a 298 # directory separator. 'q*x/' should match only directories. 299 return [basename] 300 if hasattr(os.path, 'lexists'): 301 if os.path.lexists(os.path.join(dirname, basename)): 302 return [basename] 303 else: 304 if (os.path.islink(os.path.join(dirname, basename)) or 305 os.path.exists(os.path.join(dirname, basename))): 306 return [basename] 307 return []
308 309 MAGIC_CHECK = re.compile('[*?[]')
310 311 -def has_magic(s):
312 return MAGIC_CHECK.search(s) is not None
313
314 315 316 ### Core ### 317 318 319 -class EventsCodes:
320 """ 321 Set of codes corresponding to each kind of events. 322 Some of these flags are used to communicate with inotify, whereas 323 the others are sent to userspace by inotify notifying some events. 324 325 @cvar IN_ACCESS: File was accessed. 326 @type IN_ACCESS: int 327 @cvar IN_MODIFY: File was modified. 328 @type IN_MODIFY: int 329 @cvar IN_ATTRIB: Metadata changed. 330 @type IN_ATTRIB: int 331 @cvar IN_CLOSE_WRITE: Writtable file was closed. 332 @type IN_CLOSE_WRITE: int 333 @cvar IN_CLOSE_NOWRITE: Unwrittable file closed. 334 @type IN_CLOSE_NOWRITE: int 335 @cvar IN_OPEN: File was opened. 336 @type IN_OPEN: int 337 @cvar IN_MOVED_FROM: File was moved from X. 338 @type IN_MOVED_FROM: int 339 @cvar IN_MOVED_TO: File was moved to Y. 340 @type IN_MOVED_TO: int 341 @cvar IN_CREATE: Subfile was created. 342 @type IN_CREATE: int 343 @cvar IN_DELETE: Subfile was deleted. 344 @type IN_DELETE: int 345 @cvar IN_DELETE_SELF: Self (watched item itself) was deleted. 346 @type IN_DELETE_SELF: int 347 @cvar IN_MOVE_SELF: Self (watched item itself) was moved. 348 @type IN_MOVE_SELF: int 349 @cvar IN_UNMOUNT: Backing fs was unmounted. 350 @type IN_UNMOUNT: int 351 @cvar IN_Q_OVERFLOW: Event queued overflowed. 352 @type IN_Q_OVERFLOW: int 353 @cvar IN_IGNORED: File was ignored. 354 @type IN_IGNORED: int 355 @cvar IN_ONLYDIR: only watch the path if it is a directory (new 356 in kernel 2.6.15). 357 @type IN_ONLYDIR: int 358 @cvar IN_DONT_FOLLOW: don't follow a symlink (new in kernel 2.6.15). 359 IN_ONLYDIR we can make sure that we don't watch 360 the target of symlinks. 361 @type IN_DONT_FOLLOW: int 362 @cvar IN_MASK_ADD: add to the mask of an already existing watch (new 363 in kernel 2.6.14). 364 @type IN_MASK_ADD: int 365 @cvar IN_ISDIR: Event occurred against dir. 366 @type IN_ISDIR: int 367 @cvar IN_ONESHOT: Only send event once. 368 @type IN_ONESHOT: int 369 @cvar ALL_EVENTS: Alias for considering all of the events. 370 @type ALL_EVENTS: int 371 """ 372 373 # The idea here is 'configuration-as-code' - this way, we get our nice class 374 # constants, but we also get nice human-friendly text mappings to do lookups 375 # against as well, for free: 376 FLAG_COLLECTIONS = {'OP_FLAGS': { 377 'IN_ACCESS' : 0x00000001, # File was accessed 378 'IN_MODIFY' : 0x00000002, # File was modified 379 'IN_ATTRIB' : 0x00000004, # Metadata changed 380 'IN_CLOSE_WRITE' : 0x00000008, # Writable file was closed 381 'IN_CLOSE_NOWRITE' : 0x00000010, # Unwritable file closed 382 'IN_OPEN' : 0x00000020, # File was opened 383 'IN_MOVED_FROM' : 0x00000040, # File was moved from X 384 'IN_MOVED_TO' : 0x00000080, # File was moved to Y 385 'IN_CREATE' : 0x00000100, # Subfile was created 386 'IN_DELETE' : 0x00000200, # Subfile was deleted 387 'IN_DELETE_SELF' : 0x00000400, # Self (watched item itself) 388 # was deleted 389 'IN_MOVE_SELF' : 0x00000800, # Self (watched item itself) was moved 390 }, 391 'EVENT_FLAGS': { 392 'IN_UNMOUNT' : 0x00002000, # Backing fs was unmounted 393 'IN_Q_OVERFLOW' : 0x00004000, # Event queued overflowed 394 'IN_IGNORED' : 0x00008000, # File was ignored 395 }, 396 'SPECIAL_FLAGS': { 397 'IN_ONLYDIR' : 0x01000000, # only watch the path if it is a 398 # directory 399 'IN_DONT_FOLLOW' : 0x02000000, # don't follow a symlink 400 'IN_MASK_ADD' : 0x20000000, # add to the mask of an already 401 # existing watch 402 'IN_ISDIR' : 0x40000000, # event occurred against dir 403 'IN_ONESHOT' : 0x80000000, # only send event once 404 }, 405 } 406
407 - def maskname(mask):
408 """ 409 Returns the event name associated to mask. IN_ISDIR is appended to 410 the result when appropriate. Note: only one event is returned, because 411 only one event can be raised at a given time. 412 413 @param mask: mask. 414 @type mask: int 415 @return: event name. 416 @rtype: str 417 """ 418 ms = mask 419 name = '%s' 420 if mask & IN_ISDIR: 421 ms = mask - IN_ISDIR 422 name = '%s|IN_ISDIR' 423 return name % EventsCodes.ALL_VALUES[ms]
424 425 maskname = staticmethod(maskname)
426 427 428 # So let's now turn the configuration into code 429 EventsCodes.ALL_FLAGS = {} 430 EventsCodes.ALL_VALUES = {} 431 for flagc, valc in EventsCodes.FLAG_COLLECTIONS.iteritems(): 432 # Make the collections' members directly accessible through the 433 # class dictionary 434 setattr(EventsCodes, flagc, valc) 435 436 # Collect all the flags under a common umbrella 437 EventsCodes.ALL_FLAGS.update(valc) 438 439 # Make the individual masks accessible as 'constants' at globals() scope 440 # and masknames accessible by values. 441 for name, val in valc.iteritems(): 442 globals()[name] = val 443 EventsCodes.ALL_VALUES[val] = name 444 445 446 # all 'normal' events 447 ALL_EVENTS = reduce(lambda x, y: x | y, EventsCodes.OP_FLAGS.itervalues()) 448 EventsCodes.ALL_FLAGS['ALL_EVENTS'] = ALL_EVENTS 449 EventsCodes.ALL_VALUES[ALL_EVENTS] = 'ALL_EVENTS'
450 451 452 -class _Event:
453 """ 454 Event structure, represent events raised by the system. This 455 is the base class and should be subclassed. 456 457 """
458 - def __init__(self, dict_):
459 """ 460 Attach attributes (contained in dict_) to self. 461 462 @param dict_: Set of attributes. 463 @type dict_: dictionary 464 """ 465 for tpl in dict_.iteritems(): 466 setattr(self, *tpl)
467
468 - def __repr__(self):
469 """ 470 @return: Generic event string representation. 471 @rtype: str 472 """ 473 s = '' 474 for attr, value in sorted(self.__dict__.items(), key=lambda x: x[0]): 475 if attr.startswith('_'): 476 continue 477 if attr == 'mask': 478 value = hex(getattr(self, attr)) 479 elif isinstance(value, basestring) and not value: 480 value = "''" 481 s += ' %s%s%s' % (Color.field_name(attr), 482 Color.punctuation('='), 483 Color.field_value(value)) 484 485 s = '%s%s%s %s' % (Color.punctuation('<'), 486 Color.class_name(self.__class__.__name__), 487 s, 488 Color.punctuation('>')) 489 return s
490
491 492 -class _RawEvent(_Event):
493 """ 494 Raw event, it contains only the informations provided by the system. 495 It doesn't infer anything. 496 """
497 - def __init__(self, wd, mask, cookie, name):
498 """ 499 @param wd: Watch Descriptor. 500 @type wd: int 501 @param mask: Bitmask of events. 502 @type mask: int 503 @param cookie: Cookie. 504 @type cookie: int 505 @param name: Basename of the file or directory against which the 506 event was raised in case where the watched directory 507 is the parent directory. None if the event was raised 508 on the watched item itself. 509 @type name: string or None 510 """ 511 # name: remove trailing '\0' 512 super(_RawEvent, self).__init__({'wd': wd, 513 'mask': mask, 514 'cookie': cookie, 515 'name': name.rstrip('\0')}) 516 log.debug(repr(self))
517
518 519 -class Event(_Event):
520 """ 521 This class contains all the useful informations about the observed 522 event. However, the presence of each field is not guaranteed and 523 depends on the type of event. In effect, some fields are irrelevant 524 for some kind of event (for example 'cookie' is meaningless for 525 IN_CREATE whereas it is mandatory for IN_MOVE_TO). 526 527 The possible fields are: 528 - wd (int): Watch Descriptor. 529 - mask (int): Mask. 530 - maskname (str): Readable event name. 531 - path (str): path of the file or directory being watched. 532 - name (str): Basename of the file or directory against which the 533 event was raised in case where the watched directory 534 is the parent directory. None if the event was raised 535 on the watched item itself. This field is always provided 536 even if the string is ''. 537 - pathname (str): Concatenation of 'path' and 'name'. 538 - src_pathname (str): Only present for IN_MOVED_TO events and only in 539 the case where IN_MOVED_FROM events are watched too. Holds the 540 source pathname from where pathname was moved from. 541 - cookie (int): Cookie. 542 - dir (bool): True if the event was raised against a directory. 543 544 """
545 - def __init__(self, raw):
546 """ 547 Concretely, this is the raw event plus inferred infos. 548 """ 549 _Event.__init__(self, raw) 550 self.maskname = EventsCodes.maskname(self.mask) 551 if COMPATIBILITY_MODE: 552 self.event_name = self.maskname 553 try: 554 if self.name: 555 self.pathname = os.path.abspath(os.path.join(self.path, 556 self.name)) 557 else: 558 self.pathname = os.path.abspath(self.path) 559 except AttributeError, err: 560 log.error(err)
561
562 563 -class ProcessEventError(PyinotifyError):
564 """ 565 ProcessEventError Exception. Raised on ProcessEvent error. 566 """
567 - def __init__(self, err):
568 """ 569 @param err: Exception error description. 570 @type err: string 571 """ 572 PyinotifyError.__init__(self, err)
573
574 575 -class _ProcessEvent:
576 """ 577 Abstract processing event class. 578 """
579 - def __call__(self, event):
580 """ 581 To behave like a functor the object must be callable. 582 This method is a dispatch method. Its lookup order is: 583 1. process_MASKNAME method 584 2. process_FAMILY_NAME method 585 3. otherwise calls process_default 586 587 @param event: Event to be processed. 588 @type event: Event object 589 @return: By convention when used from the ProcessEvent class: 590 - Returning False or None (default value) means keep on 591 executing next chained functors (see chain.py example). 592 - Returning True instead means do not execute next 593 processing functions. 594 @rtype: bool 595 @raise ProcessEventError: Event object undispatchable, 596 unknown event. 597 """ 598 stripped_mask = event.mask - (event.mask & IN_ISDIR) 599 maskname = EventsCodes.ALL_VALUES.get(stripped_mask) 600 if maskname is None: 601 raise ProcessEventError("Unknown mask 0x%08x" % stripped_mask) 602 603 # 1- look for process_MASKNAME 604 meth = getattr(self, 'process_' + maskname, None) 605 if meth is not None: 606 return meth(event) 607 # 2- look for process_FAMILY_NAME 608 meth = getattr(self, 'process_IN_' + maskname.split('_')[1], None) 609 if meth is not None: 610 return meth(event) 611 # 3- default call method process_default 612 return self.process_default(event)
613
614 - def __repr__(self):
615 return '<%s>' % self.__class__.__name__
616
617 618 -class _SysProcessEvent(_ProcessEvent):
619 """ 620 There is three kind of processing according to each event: 621 622 1. special handling (deletion from internal container, bug, ...). 623 2. default treatment: which is applied to the majority of events. 624 3. IN_ISDIR is never sent alone, he is piggybacked with a standard 625 event, he is not processed as the others events, instead, its 626 value is captured and appropriately aggregated to dst event. 627 """
628 - def __init__(self, wm, notifier):
629 """ 630 631 @param wm: Watch Manager. 632 @type wm: WatchManager instance 633 @param notifier: Notifier. 634 @type notifier: Notifier instance 635 """ 636 self._watch_manager = wm # watch manager 637 self._notifier = notifier # notifier 638 self._mv_cookie = {} # {cookie(int): (src_path(str), date), ...} 639 self._mv = {} # {src_path(str): (dst_path(str), date), ...}
640
641 - def cleanup(self):
642 """ 643 Cleanup (delete) old (>1mn) records contained in self._mv_cookie 644 and self._mv. 645 """ 646 date_cur_ = datetime.now() 647 for seq in [self._mv_cookie, self._mv]: 648 for k in seq.keys(): 649 if (date_cur_ - seq[k][1]) > timedelta(minutes=1): 650 log.debug('Cleanup: deleting entry %s', seq[k][0]) 651 del seq[k]
652
653 - def process_IN_CREATE(self, raw_event):
654 """ 655 If the event affects a directory and the auto_add flag of the 656 targetted watch is set to True, a new watch is added on this 657 new directory, with the same attribute values than those of 658 this watch. 659 """ 660 if raw_event.mask & IN_ISDIR: 661 watch_ = self._watch_manager.get_watch(raw_event.wd) 662 if watch_.auto_add: 663 addw = self._watch_manager.add_watch 664 newwd = addw(os.path.join(watch_.path, raw_event.name), 665 watch_.mask, proc_fun=watch_.proc_fun, 666 rec=False, auto_add=watch_.auto_add) 667 668 # Trick to handle mkdir -p /t1/t2/t3 where t1 is watched and 669 # t2 and t3 are created. 670 # Since the directory is new, then everything inside it 671 # must also be new. 672 base = os.path.join(watch_.path, raw_event.name) 673 if newwd[base] > 0: 674 for name in os.listdir(base): 675 inner = os.path.join(base, name) 676 if (os.path.isdir(inner) and 677 self._watch_manager.get_wd(inner) is None): 678 # Generate (simulate) creation event for sub 679 # directories. 680 rawevent = _RawEvent(newwd[base], 681 IN_CREATE | IN_ISDIR, 682 0, name) 683 self._notifier.append_event(rawevent) 684 return self.process_default(raw_event)
685
686 - def process_IN_MOVED_FROM(self, raw_event):
687 """ 688 Map the cookie with the source path (+ date for cleaning). 689 """ 690 watch_ = self._watch_manager.get_watch(raw_event.wd) 691 path_ = watch_.path 692 src_path = os.path.normpath(os.path.join(path_, raw_event.name)) 693 self._mv_cookie[raw_event.cookie] = (src_path, datetime.now()) 694 return self.process_default(raw_event, {'cookie': raw_event.cookie})
695
696 - def process_IN_MOVED_TO(self, raw_event):
697 """ 698 Map the source path with the destination path (+ date for 699 cleaning). 700 """ 701 watch_ = self._watch_manager.get_watch(raw_event.wd) 702 path_ = watch_.path 703 dst_path = os.path.normpath(os.path.join(path_, raw_event.name)) 704 mv_ = self._mv_cookie.get(raw_event.cookie) 705 to_append = {'cookie': raw_event.cookie} 706 if mv_ is not None: 707 self._mv[mv_[0]] = (dst_path, datetime.now()) 708 # Let's assume that IN_MOVED_FROM event is always queued before 709 # that its associated (they share a common cookie) IN_MOVED_TO 710 # event is queued itself. It is then possible in that scenario 711 # to provide as additional information to the IN_MOVED_TO event 712 # the original pathname of the moved file/directory. 713 to_append['src_pathname'] = mv_[0] 714 elif raw_event.mask & IN_ISDIR and watch_.auto_add: 715 # We got a diretory that's "moved in" from an unknown source and 716 # auto_add is enabled. Manually add watches to the inner subtrees. 717 self._watch_manager.add_watch(dst_path, watch_.mask, 718 proc_fun=watch_.proc_fun, 719 rec=True, auto_add=True) 720 return self.process_default(raw_event, to_append)
721
722 - def process_IN_MOVE_SELF(self, raw_event):
723 """ 724 STATUS: the following bug has been fixed in recent kernels (FIXME: 725 which version ?). Now it raises IN_DELETE_SELF instead. 726 727 Old kernels were bugged, this event raised when the watched item 728 were moved, so we had to update its path, but under some circumstances 729 it was impossible: if its parent directory and its destination 730 directory wasn't watched. The kernel (see include/linux/fsnotify.h) 731 doesn't bring us enough informations like the destination path of 732 moved items. 733 """ 734 watch_ = self._watch_manager.get_watch(raw_event.wd) 735 src_path = watch_.path 736 mv_ = self._mv.get(src_path) 737 if mv_: 738 dest_path = mv_[0] 739 watch_.path = dest_path 740 src_path_len = len(src_path) 741 sep_len = len(os.path.sep) 742 # The next loop renames all watches with src_path as base path. 743 # It seems that IN_MOVE_SELF does not provide IN_ISDIR information 744 # therefore the next loop is iterated even if raw_event is a file. 745 for w in self._watch_manager.watches.itervalues(): 746 if w.path.startswith(src_path): 747 # Note that dest_path is a normalized path. 748 w.path = os.path.join(dest_path, 749 w.path[src_path_len + sep_len:]) 750 else: 751 log.error("The pathname '%s' of this watch %s has probably changed " 752 "and couldn't be updated, so it cannot be trusted " 753 "anymore. To fix this error move directories/files only " 754 "between watched parents directories, in this case e.g. " 755 "put a watch on '%s'.", 756 watch_.path, watch_, 757 os.path.normpath(os.path.join(watch_.path, 758 os.path.pardir))) 759 if not watch_.path.endswith('-unknown-path'): 760 watch_.path += '-unknown-path' 761 return self.process_default(raw_event)
762
763 - def process_IN_Q_OVERFLOW(self, raw_event):
764 """ 765 Only signal an overflow, most of the common flags are irrelevant 766 for this event (path, wd, name). 767 """ 768 return Event({'mask': raw_event.mask})
769
770 - def process_IN_IGNORED(self, raw_event):
771 """ 772 The watch descriptor raised by this event is now ignored (forever), 773 it can be safely deleted from the watch manager dictionary. 774 After this event we can be sure that neither the event queue nor 775 the system will raise an event associated to this wd again. 776 """ 777 event_ = self.process_default(raw_event) 778 self._watch_manager.del_watch(raw_event.wd) 779 return event_
780
781 - def process_default(self, raw_event, to_append=None):
782 """ 783 Commons handling for the followings events: 784 785 IN_ACCESS, IN_MODIFY, IN_ATTRIB, IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, 786 IN_OPEN, IN_DELETE, IN_DELETE_SELF, IN_UNMOUNT. 787 """ 788 watch_ = self._watch_manager.get_watch(raw_event.wd) 789 if raw_event.mask & (IN_DELETE_SELF | IN_MOVE_SELF): 790 # Unfornulately this information is not provided by the kernel 791 dir_ = watch_.dir 792 else: 793 dir_ = bool(raw_event.mask & IN_ISDIR) 794 dict_ = {'wd': raw_event.wd, 795 'mask': raw_event.mask, 796 'path': watch_.path, 797 'name': raw_event.name, 798 'dir': dir_} 799 if COMPATIBILITY_MODE: 800 dict_['is_dir'] = dir_ 801 if to_append is not None: 802 dict_.update(to_append) 803 return Event(dict_)
804
805 806 -class ProcessEvent(_ProcessEvent):
807 """ 808 Process events objects, can be specialized via subclassing, thus its 809 behavior can be overriden: 810 811 Note: you should not override __init__ in your subclass instead define 812 a my_init() method, this method will be called from the constructor of 813 this class with its optional parameters. 814 815 1. Provide specialized individual methods, e.g. process_IN_DELETE for 816 processing a precise type of event (e.g. IN_DELETE in this case). 817 2. Or/and provide methods for processing events by 'family', e.g. 818 process_IN_CLOSE method will process both IN_CLOSE_WRITE and 819 IN_CLOSE_NOWRITE events (if process_IN_CLOSE_WRITE and 820 process_IN_CLOSE_NOWRITE aren't defined though). 821 3. Or/and override process_default for catching and processing all 822 the remaining types of events. 823 """ 824 pevent = None 825
826 - def __init__(self, pevent=None, **kargs):
827 """ 828 Enable chaining of ProcessEvent instances. 829 830 @param pevent: Optional callable object, will be called on event 831 processing (before self). 832 @type pevent: callable 833 @param kargs: This constructor is a implemented as a template method 834 delegating its optionals keyworded arguments to the method 835 my_init(). 836 @type kargs: dict 837 """ 838 self.pevent = pevent 839 self.my_init(**kargs)
840
841 - def my_init(self, **kargs):
842 """ 843 This method is called from base constructor ProcessEvent.__init__(). 844 This method is useless here and is meant to be redifined in a 845 subclass of ProcessEvent. In effect, when subclassing just override 846 this method if you want to provide custom initialization to your 847 subclass' instance. You MUST pass keyword arguments though. 848 849 @param kargs: optional delegated arguments from __init__(). 850 @type kargs: dict 851 """ 852 pass
853
854 - def __call__(self, event):
855 stop_chaining = False 856 if self.pevent is not None: 857 # By default methods return None so we set as guideline 858 # that methods asking for stop chaining must explicitely 859 # return non None or non False values, otherwise the default 860 # behavior will be to accept chain call to the corresponding 861 # local method. 862 stop_chaining = self.pevent(event) 863 if not stop_chaining: 864 return _ProcessEvent.__call__(self, event)
865
866 - def nested_pevent(self):
867 return self.pevent
868
869 - def process_IN_Q_OVERFLOW(self, event):
870 """ 871 By default this method only reports warning messages, you can overredide 872 it by subclassing ProcessEvent and implement your own 873 process_IN_Q_OVERFLOW method. The actions you can take on receiving this 874 event is either to update the variable max_queued_events in order to 875 handle more simultaneous events or to modify your code in order to 876 accomplish a better filtering diminishing the number of raised events. 877 Because this method is defined, IN_Q_OVERFLOW will never get 878 transmitted as arguments to process_default calls. 879 880 @param event: IN_Q_OVERFLOW event. 881 @type event: dict 882 """ 883 log.warning('Event queue overflowed.')
884
885 - def process_default(self, event):
886 """ 887 Default processing event method. By default does nothing. Subclass 888 ProcessEvent and redefine this method in order to modify its behavior. 889 890 @param event: Event to be processed. Can be of any type of events but 891 IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW). 892 @type event: Event instance 893 """ 894 pass
895
896 897 -class PrintAllEvents(ProcessEvent):
898 """ 899 Dummy class used to print events strings representations. For instance this 900 class is used from command line to print all received events to stdout. 901 """
902 - def my_init(self, out=None):
903 """ 904 @param out: Where events will be written. 905 @type out: Object providing a valid file object interface. 906 """ 907 if out is None: 908 out = sys.stdout 909 self._out = out
910
911 - def process_default(self, event):
912 """ 913 Writes event string representation to file object provided to 914 my_init(). 915 916 @param event: Event to be processed. Can be of any type of events but 917 IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW). 918 @type event: Event instance 919 """ 920 self._out.write(repr(event) + '\n')
921
922 923 -class ChainIfTrue(ProcessEvent):
924 """ 925 Makes conditional chaining depending on the result of the nested 926 processing instance. 927 """
928 - def my_init(self, func):
929 """ 930 Method automatically called from base class constructor. 931 """ 932 self._func = func
933
934 - def process_default(self, event):
935 return not self._func(event)
936
937 938 -class Stats(ProcessEvent):
939 """ 940 Compute and display trivial statistics about processed events. 941 """
942 - def my_init(self):
943 """ 944 Method automatically called from base class constructor. 945 """ 946 self._start_time = time.time() 947 self._stats = {} 948 self._stats_lock = threading.Lock()
949
950 - def process_default(self, event):
951 """ 952 Processes |event|. 953 """ 954 self._stats_lock.acquire() 955 try: 956 events = event.maskname.split('|') 957 for event_name in events: 958 count = self._stats.get(event_name, 0) 959 self._stats[event_name] = count + 1 960 finally: 961 self._stats_lock.release()
962
963 - def _stats_copy(self):
964 self._stats_lock.acquire() 965 try: 966 return self._stats.copy() 967 finally: 968 self._stats_lock.release()
969
970 - def __repr__(self):
971 stats = self._stats_copy() 972 973 elapsed = int(time.time() - self._start_time) 974 elapsed_str = '' 975 if elapsed < 60: 976 elapsed_str = str(elapsed) + 'sec' 977 elif 60 <= elapsed < 3600: 978 elapsed_str = '%dmn%dsec' % (elapsed / 60, elapsed % 60) 979 elif 3600 <= elapsed < 86400: 980 elapsed_str = '%dh%dmn' % (elapsed / 3600, (elapsed % 3600) / 60) 981 elif elapsed >= 86400: 982 elapsed_str = '%dd%dh' % (elapsed / 86400, (elapsed % 86400) / 3600) 983 stats['ElapsedTime'] = elapsed_str 984 985 l = [] 986 for ev, value in sorted(stats.items(), key=lambda x: x[0]): 987 l.append(' %s=%s' % (Color.field_name(ev), 988 Color.field_value(value))) 989 s = '<%s%s >' % (Color.class_name(self.__class__.__name__), 990 ''.join(l)) 991 return s
992
993 - def dump(self, filename):
994 """ 995 Dumps statistics to file |filename|. 996 997 @param filename: pathname. 998 @type filename: string 999 """ 1000 file_obj = file(filename, 'wb') 1001 try: 1002 file_obj.write(str(self)) 1003 finally: 1004 file_obj.close()
1005
1006 - def __str__(self, scale=45):
1007 stats = self._stats_copy() 1008 if not stats: 1009 return '' 1010 1011 m = max(stats.values()) 1012 unity = int(round(float(m) / scale)) or 1 1013 fmt = '%%-26s%%-%ds%%s' % (len(Color.field_value('@' * scale)) 1014 + 1) 1015 def func(x): 1016 return fmt % (Color.field_name(x[0]), 1017 Color.field_value('@' * (x[1] / unity)), 1018 Color.simple('%d' % x[1], 'yellow'))
1019 s = '\n'.join(map(func, sorted(stats.items(), key=lambda x: x[0]))) 1020 return s
1021
1022 1023 -class NotifierError(PyinotifyError):
1024 """ 1025 Notifier Exception. Raised on Notifier error. 1026 1027 """
1028 - def __init__(self, err):
1029 """ 1030 @param err: Exception string's description. 1031 @type err: string 1032 """ 1033 PyinotifyError.__init__(self, err)
1034
1035 1036 -class Notifier:
1037 """ 1038 Read notifications, process events. 1039 1040 """
1041 - def __init__(self, watch_manager, default_proc_fun=ProcessEvent(), 1042 read_freq=0, threshold=0, timeout=None):
1043 """ 1044 Initialization. read_freq, threshold and timeout parameters are used 1045 when looping. 1046 1047 @param watch_manager: Watch Manager. 1048 @type watch_manager: WatchManager instance 1049 @param default_proc_fun: Default processing method. 1050 @type default_proc_fun: instance of ProcessEvent 1051 @param read_freq: if read_freq == 0, events are read asap, 1052 if read_freq is > 0, this thread sleeps 1053 max(0, read_freq - timeout) seconds. But if 1054 timeout is None it can be different because 1055 poll is blocking waiting for something to read. 1056 @type read_freq: int 1057 @param threshold: File descriptor will be read only if the accumulated 1058 size to read becomes >= threshold. If != 0, you likely 1059 want to use it in combination with an appropriate 1060 value for read_freq because without that you would 1061 keep looping without really reading anything and that 1062 until the amount of events to read is >= threshold. 1063 At least with read_freq set you might sleep. 1064 @type threshold: int 1065 @param timeout: 1066 http://docs.python.org/lib/poll-objects.html#poll-objects 1067 @type timeout: int 1068 """ 1069 # Watch Manager instance 1070 self._watch_manager = watch_manager 1071 # File descriptor 1072 self._fd = self._watch_manager.get_fd() 1073 # Poll object and registration 1074 self._pollobj = select.poll() 1075 self._pollobj.register(self._fd, select.POLLIN) 1076 # This pipe is correctely initialized and used by ThreadedNotifier 1077 self._pipe = (-1, -1) 1078 # Event queue 1079 self._eventq = deque() 1080 # System processing functor, common to all events 1081 self._sys_proc_fun = _SysProcessEvent(self._watch_manager, self) 1082 # Default processing method 1083 self._default_proc_fun = default_proc_fun 1084 # Loop parameters 1085 self._read_freq = read_freq 1086 self._threshold = threshold 1087 self._timeout = timeout
1088
1089 - def append_event(self, event):
1090 """ 1091 Append a raw event to the event queue. 1092 1093 @param event: An event. 1094 @type event: _RawEvent instance. 1095 """ 1096 self._eventq.append(event)
1097
1098 - def proc_fun(self):
1099 return self._default_proc_fun
1100
1101 - def check_events(self, timeout=None):
1102 """ 1103 Check for new events available to read, blocks up to timeout 1104 milliseconds. 1105 1106 @param timeout: If specified it overrides the corresponding instance 1107 attribute _timeout. 1108 @type timeout: int 1109 1110 @return: New events to read. 1111 @rtype: bool 1112 """ 1113 while True: 1114 try: 1115 # blocks up to 'timeout' milliseconds 1116 if timeout is None: 1117 timeout = self._timeout 1118 ret = self._pollobj.poll(timeout) 1119 except select.error, err: 1120 if err[0] == errno.EINTR: 1121 continue # interrupted, retry 1122 else: 1123 raise 1124 else: 1125 break 1126 1127 if not ret or (self._pipe[0] == ret[0][0]): 1128 return False 1129 # only one fd is polled 1130 return ret[0][1] & select.POLLIN
1131
1132 - def read_events(self):
1133 """ 1134 Read events from device, build _RawEvents, and enqueue them. 1135 """ 1136 buf_ = array.array('i', [0]) 1137 # get event queue size 1138 if fcntl.ioctl(self._fd, termios.FIONREAD, buf_, 1) == -1: 1139 return 1140 queue_size = buf_[0] 1141 if queue_size < self._threshold: 1142 log.debug('(fd: %d) %d bytes available to read but threshold is ' 1143 'fixed to %d bytes', self._fd, queue_size, 1144 self._threshold) 1145 return 1146 1147 try: 1148 # Read content from file 1149 r = os.read(self._fd, queue_size) 1150 except Exception, msg: 1151 raise NotifierError(msg) 1152 log.debug('Event queue size: %d', queue_size) 1153 rsum = 0 # counter 1154 while rsum < queue_size: 1155 s_size = 16 1156 # Retrieve wd, mask, cookie 1157 s_ = struct.unpack('iIII', r[rsum:rsum+s_size]) 1158 # Length of name 1159 fname_len = s_[3] 1160 # field 'length' useless 1161 s_ = s_[:-1] 1162 # Retrieve name 1163 s_ += struct.unpack('%ds' % fname_len, 1164 r[rsum + s_size:rsum + s_size + fname_len]) 1165 self._eventq.append(_RawEvent(*s_)) 1166 rsum += s_size + fname_len
1167
1168 - def process_events(self):
1169 """ 1170 Routine for processing events from queue by calling their 1171 associated proccessing method (an instance of ProcessEvent). 1172 It also does internal processings, to keep the system updated. 1173 """ 1174 while self._eventq: 1175 raw_event = self._eventq.popleft() # pop next event 1176 watch_ = self._watch_manager.get_watch(raw_event.wd) 1177 revent = self._sys_proc_fun(raw_event) # system processings 1178 if watch_ and watch_.proc_fun: 1179 watch_.proc_fun(revent) # user processings 1180 else: 1181 self._default_proc_fun(revent) 1182 self._sys_proc_fun.cleanup() # remove olds MOVED_* events records
1183 1184
1185 - def __daemonize(self, pid_file=None, force_kill=False, stdin=os.devnull, 1186 stdout=os.devnull, stderr=os.devnull):
1187 """ 1188 pid_file: file to which the pid will be written. 1189 force_kill: if True kill the process associated to pid_file. 1190 stdin, stdout, stderr: files associated to common streams. 1191 """ 1192 if pid_file is None: 1193 dirname = '/var/run/' 1194 basename = sys.argv[0] or 'pyinotify' 1195 pid_file = os.path.join(dirname, basename + '.pid') 1196 1197 if os.path.exists(pid_file): 1198 fo = file(pid_file, 'rb') 1199 try: 1200 try: 1201 pid = int(fo.read()) 1202 except ValueError: 1203 pid = None 1204 if pid is not None: 1205 try: 1206 os.kill(pid, 0) 1207 except OSError, err: 1208 log.error(err) 1209 else: 1210 if not force_kill: 1211 s = 'There is already a pid file %s with pid %d' 1212 raise NotifierError(s % (pid_file, pid)) 1213 else: 1214 os.kill(pid, 9) 1215 finally: 1216 fo.close() 1217 1218 1219 def fork_daemon(): 1220 # Adapted from Chad J. Schroeder's recipe 1221 # @see http://code.activestate.com/recipes/278731/ 1222 pid = os.fork() 1223 if (pid == 0): 1224 # parent 2 1225 os.setsid() 1226 pid = os.fork() 1227 if (pid == 0): 1228 # child 1229 os.chdir('/') 1230 os.umask(0) 1231 else: 1232 # parent 2 1233 os._exit(0) 1234 else: 1235 # parent 1 1236 os._exit(0) 1237 1238 fd_inp = os.open(stdin, os.O_RDONLY) 1239 os.dup2(fd_inp, 0) 1240 fd_out = os.open(stdout, os.O_WRONLY|os.O_CREAT) 1241 os.dup2(fd_out, 1) 1242 fd_err = os.open(stderr, os.O_WRONLY|os.O_CREAT) 1243 os.dup2(fd_err, 2)
1244 1245 # Detach task 1246 fork_daemon() 1247 1248 # Write pid 1249 file_obj = file(pid_file, 'wb') 1250 try: 1251 file_obj.write(str(os.getpid()) + '\n') 1252 finally: 1253 file_obj.close() 1254 1255 atexit.register(lambda : os.unlink(pid_file))
1256 1257
1258 - def _sleep(self, ref_time):
1259 # Only consider sleeping if read_freq is > 0 1260 if self._read_freq > 0: 1261 cur_time = time.time() 1262 sleep_amount = self._read_freq - (cur_time - ref_time) 1263 if sleep_amount > 0: 1264 log.debug('Now sleeping %d seconds', sleep_amount) 1265 time.sleep(sleep_amount)
1266 1267
1268 - def loop(self, callback=None, daemonize=False, **args):
1269 """ 1270 Events are read only once time every min(read_freq, timeout) 1271 seconds at best and only if the size to read is >= threshold. 1272 1273 @param callback: Functor called after each event processing. Expects 1274 to receive notifier object (self) as first parameter. 1275 @type callback: callable 1276 @param daemonize: This thread is daemonized if set to True. 1277 @type daemonize: boolean 1278 """ 1279 if daemonize: 1280 self.__daemonize(**args) 1281 1282 # Read and process events forever 1283 while 1: 1284 try: 1285 self.process_events() 1286 if callback is not None: 1287 callback(self) 1288 ref_time = time.time() 1289 # check_events is blocking 1290 if self.check_events(): 1291 self._sleep(ref_time) 1292 self.read_events() 1293 except KeyboardInterrupt: 1294 # Unless sigint is caught (Control-C) 1295 log.debug('Pyinotify stops monitoring.') 1296 # Stop monitoring 1297 self.stop() 1298 break
1299
1300 - def stop(self):
1301 """ 1302 Close inotify's instance (close its file descriptor). 1303 It destroys all existing watches, pending events,... 1304 """ 1305 self._pollobj.unregister(self._fd) 1306 os.close(self._fd)
1307
1308 1309 -class ThreadedNotifier(threading.Thread, Notifier):
1310 """ 1311 This notifier inherits from threading.Thread for instanciating a separate 1312 thread, and also inherits from Notifier, because it is a threaded notifier. 1313 1314 Note that every functionality provided by this class is also provided 1315 through Notifier class. Moreover Notifier should be considered first because 1316 it is not threaded and could be easily daemonized. 1317 """
1318 - def __init__(self, watch_manager, default_proc_fun=ProcessEvent(), 1319 read_freq=0, threshold=0, timeout=None):
1320 """ 1321 Initialization, initialize base classes. read_freq, threshold and 1322 timeout parameters are used when looping. 1323 1324 @param watch_manager: Watch Manager. 1325 @type watch_manager: WatchManager instance 1326 @param default_proc_fun: Default processing method. 1327 @type default_proc_fun: instance of ProcessEvent 1328 @param read_freq: if read_freq == 0, events are read asap, 1329 if read_freq is > 0, this thread sleeps 1330 max(0, read_freq - timeout) seconds. 1331 @type read_freq: int 1332 @param threshold: File descriptor will be read only if the accumulated 1333 size to read becomes >= threshold. If != 0, you likely 1334 want to use it in combination with an appropriate 1335 value set for read_freq because without that you would 1336 keep looping without really reading anything and that 1337 until the amount of events to read is >= threshold. At 1338 least with read_freq you might sleep. 1339 @type threshold: int 1340 @param timeout: 1341 see http://docs.python.org/lib/poll-objects.html#poll-objects 1342 @type timeout: int 1343 """ 1344 # Init threading base class 1345 threading.Thread.__init__(self) 1346 # Stop condition 1347 self._stop_event = threading.Event() 1348 # Init Notifier base class 1349 Notifier.__init__(self, watch_manager, default_proc_fun, read_freq, 1350 threshold, timeout) 1351 # Create a new pipe used for thread termination 1352 self._pipe = os.pipe() 1353 self._pollobj.register(self._pipe[0], select.POLLIN)
1354
1355 - def stop(self):
1356 """ 1357 Stop notifier's loop. Stop notification. Join the thread. 1358 """ 1359 self._stop_event.set() 1360 os.write(self._pipe[1], 'stop') 1361 threading.Thread.join(self) 1362 Notifier.stop(self) 1363 self._pollobj.unregister(self._pipe[0]) 1364 os.close(self._pipe[0]) 1365 os.close(self._pipe[1])
1366
1367 - def loop(self):
1368 """ 1369 Thread's main loop. Don't meant to be called by user directly. 1370 Call inherited start() method instead. 1371 1372 Events are read only once time every min(read_freq, timeout) 1373 seconds at best and only if the size of events to read is >= threshold. 1374 """ 1375 # When the loop must be terminated .stop() is called, 'stop' 1376 # is written to pipe fd so poll() returns and .check_events() 1377 # returns False which make evaluate the While's stop condition 1378 # ._stop_event.isSet() wich put an end to the thread's execution. 1379 while not self._stop_event.isSet(): 1380 self.process_events() 1381 ref_time = time.time() 1382 if self.check_events(): 1383 self._sleep(ref_time) 1384 self.read_events()
1385
1386 - def run(self):
1387 """ 1388 Start thread's loop: read and process events until the method 1389 stop() is called. 1390 Never call this method directly, instead call the start() method 1391 inherited from threading.Thread, which then will call run() in 1392 its turn. 1393 """ 1394 self.loop()
1395
1396 1397 -class AsyncNotifier(asyncore.file_dispatcher, Notifier):
1398 """ 1399 This notifier inherits from asyncore.file_dispatcher in order to be able to 1400 use pyinotify along with the asyncore framework. 1401 1402 """
1403 - def __init__(self, watch_manager, default_proc_fun=ProcessEvent(), 1404 read_freq=0, threshold=0, timeout=None, channel_map=None):
1405 """ 1406 Initializes the async notifier. The only additional parameter is 1407 'channel_map' which is the optional asyncore private map. See 1408 Notifier class for the meaning of the others parameters. 1409 1410 """ 1411 Notifier.__init__(self, watch_manager, default_proc_fun, read_freq, 1412 threshold, timeout) 1413 asyncore.file_dispatcher.__init__(self, self._fd, channel_map)
1414
1415 - def handle_read(self):
1416 """ 1417 When asyncore tells us we can read from the fd, we proceed processing 1418 events. This method can be overridden for handling a notification 1419 differently. 1420 1421 """ 1422 self.read_events() 1423 self.process_events()
1424
1425 1426 -class Watch:
1427 """ 1428 Represent a watch, i.e. a file or directory being watched. 1429 1430 """
1431 - def __init__(self, **keys):
1432 """ 1433 Initializations. 1434 1435 @param wd: Watch descriptor. 1436 @type wd: int 1437 @param path: Path of the file or directory being watched. 1438 @type path: str 1439 @param mask: Mask. 1440 @type mask: int 1441 @param proc_fun: Processing callable object. 1442 @type proc_fun: 1443 @param auto_add: Automatically add watches on new directories. 1444 @type auto_add: bool 1445 """ 1446 for k, v in keys.iteritems(): 1447 setattr(self, k, v) 1448 self.dir = os.path.isdir(self.path)
1449
1450 - def __repr__(self):
1451 """ 1452 @return: String representation. 1453 @rtype: str 1454 """ 1455 s = ' '.join(['%s%s%s' % (Color.field_name(attr), 1456 Color.punctuation('='), 1457 Color.field_value(getattr(self, attr))) \ 1458 for attr in self.__dict__ if not attr.startswith('_')]) 1459 1460 s = '%s%s %s %s' % (Color.punctuation('<'), 1461 Color.class_name(self.__class__.__name__), 1462 s, 1463 Color.punctuation('>')) 1464 return s
1465
1466 1467 -class ExcludeFilter:
1468 """ 1469 ExcludeFilter is an exclusion filter. 1470 """
1471 - def __init__(self, arg_lst):
1472 """ 1473 @param arg_lst: is either a list or dict of patterns: 1474 [pattern1, ..., patternn] 1475 {'filename1': (list1, listn), ...} where list1 is 1476 a list of patterns 1477 @type arg_lst: list or dict 1478 """ 1479 if isinstance(arg_lst, dict): 1480 lst = self._load_patterns(arg_lst) 1481 elif isinstance(arg_lst, list): 1482 lst = arg_lst 1483 else: 1484 raise TypeError 1485 1486 self._lregex = [] 1487 for regex in lst: 1488 self._lregex.append(re.compile(regex, re.UNICODE))
1489
1490 - def _load_patterns(self, dct):
1491 lst = [] 1492 for path, varnames in dct.iteritems(): 1493 loc = {} 1494 execfile(path, {}, loc) 1495 for varname in varnames: 1496 lst.extend(loc.get(varname, [])) 1497 return lst
1498
1499 - def _match(self, regex, path):
1500 return regex.match(path) is not None
1501
1502 - def __call__(self, path):
1503 """ 1504 @param path: Path to match against provided regexps. 1505 @type path: str 1506 @return: Return True if path has been matched and should 1507 be excluded, False otherwise. 1508 @rtype: bool 1509 """ 1510 for regex in self._lregex: 1511 if self._match(regex, path): 1512 return True 1513 return False
1514
1515 1516 -class WatchManagerError(Exception):
1517 """ 1518 WatchManager Exception. Raised on error encountered on watches 1519 operations. 1520 1521 """
1522 - def __init__(self, msg, wmd):
1523 """ 1524 @param msg: Exception string's description. 1525 @type msg: string 1526 @param wmd: This dictionary contains the wd assigned to paths of the 1527 same call for which watches were successfully added. 1528 @type wmd: dict 1529 """ 1530 self.wmd = wmd 1531 Exception.__init__(self, msg)
1532
1533 1534 -class WatchManager:
1535 """ 1536 Provide operations for watching files and directories. Its internal 1537 dictionary is used to reference watched items. When used inside 1538 threaded code, one must instanciate as many WatchManager instances as 1539 there are ThreadedNotifier instances. 1540 1541 """
1542 - def __init__(self, exclude_filter=lambda path: False):
1543 """ 1544 Initialization: init inotify, init watch manager dictionary. 1545 Raise OSError if initialization fails. 1546 1547 @param exclude_filter: boolean function, returns True if current 1548 path must be excluded from being watched. 1549 Convenient for providing a common exclusion 1550 filter for every call to add_watch. 1551 @type exclude_filter: bool 1552 """ 1553 self._exclude_filter = exclude_filter 1554 self._wmd = {} # watch dict key: watch descriptor, value: watch 1555 self._fd = LIBC.inotify_init() # inotify's init, file descriptor 1556 if self._fd < 0: 1557 raise OSError()
1558
1559 - def get_fd(self):
1560 """ 1561 Return assigned inotify's file descriptor. 1562 1563 @return: File descriptor. 1564 @rtype: int 1565 """ 1566 return self._fd
1567
1568 - def get_watch(self, wd):
1569 """ 1570 Get watch from provided watch descriptor wd. 1571 1572 @param wd: Watch descriptor. 1573 @type wd: int 1574 """ 1575 return self._wmd.get(wd)
1576
1577 - def del_watch(self, wd):
1578 """ 1579 Remove watch entry associated to watch descriptor wd. 1580 1581 @param wd: Watch descriptor. 1582 @type wd: int 1583 """ 1584 try: 1585 del self._wmd[wd] 1586 except KeyError, err: 1587 log.error(str(err))
1588 1589 @property
1590 - def watches(self):
1591 """ 1592 Get a reference on the internal watch manager dictionary. 1593 1594 @return: Internal watch manager dictionary. 1595 @rtype: dict 1596 """ 1597 return self._wmd
1598
1599 - def __add_watch(self, path, mask, proc_fun, auto_add):
1600 """ 1601 Add a watch on path, build a Watch object and insert it in the 1602 watch manager dictionary. Return the wd value. 1603 """ 1604 # Unicode strings are converted to byte strings, it seems to be 1605 # required because LIBC.inotify_add_watch does not work well when 1606 # it receives an ctypes.create_unicode_buffer instance as argument. 1607 # Therefore even wd are indexed with bytes string and not with 1608 # unicode paths. 1609 if isinstance(path, unicode): 1610 byte_path = path.encode(sys.getfilesystemencoding()) 1611 else: 1612 byte_path = path 1613 1614 wd_ = LIBC.inotify_add_watch(self._fd, 1615 ctypes.create_string_buffer(byte_path), 1616 mask) 1617 if wd_ < 0: 1618 return wd_ 1619 watch_ = Watch(wd=wd_, path=os.path.normpath(byte_path), mask=mask, 1620 proc_fun=proc_fun, auto_add=auto_add) 1621 self._wmd[wd_] = watch_ 1622 log.debug('New %s', watch_) 1623 return wd_
1624
1625 - def __glob(self, path, do_glob):
1626 if do_glob: 1627 return iglob(path) 1628 else: 1629 return [path]
1630
1631 - def add_watch(self, path, mask, proc_fun=None, rec=False, 1632 auto_add=False, do_glob=False, quiet=True, 1633 exclude_filter=None):
1634 """ 1635 Add watch(s) on the provided |path|(s) with associated |mask| flag 1636 value and optionally with a processing |proc_fun| function and 1637 recursive flag |rec| set to True. 1638 Ideally |path| components should not be unicode objects. Note that 1639 although unicode paths are accepted there are converted to byte 1640 strings before a watch is put on that path. The encoding used for 1641 converting the unicode object is given by sys.getfilesystemencoding(). 1642 1643 @param path: Path to watch, the path can either be a file or a 1644 directory. Also accepts a sequence (list) of paths. 1645 @type path: string or list of strings 1646 @param mask: Bitmask of events. 1647 @type mask: int 1648 @param proc_fun: Processing object. 1649 @type proc_fun: function or ProcessEvent instance or instance of 1650 one of its subclasses or callable object. 1651 @param rec: Recursively add watches from path on all its 1652 subdirectories, set to False by default (doesn't 1653 follows symlinks in any case). 1654 @type rec: bool 1655 @param auto_add: Automatically add watches on newly created 1656 directories in watched parent |path| directory. 1657 @type auto_add: bool 1658 @param do_glob: Do globbing on pathname (see standard globbing 1659 module for more informations). 1660 @type do_glob: bool 1661 @param quiet: if False raises a WatchManagerError exception on 1662 error. See example not_quiet.py. 1663 @type quiet: bool 1664 @param exclude_filter: boolean function, returns True if current 1665 path must be excluded from being watched. 1666 Has precedence on exclude_filter defined 1667 into __init__. 1668 @type exclude_filter: bool 1669 @return: dict of paths associated to watch descriptors. A wd value 1670 is positive if the watch was added sucessfully, 1671 otherwise the value is negative. If the path was invalid 1672 it is not included into this returned dictionary. 1673 @rtype: dict of {str: int} 1674 """ 1675 ret_ = {} # return {path: wd, ...} 1676 1677 if exclude_filter is None: 1678 exclude_filter = self._exclude_filter 1679 1680 # normalize args as list elements 1681 for npath in self.__format_param(path): 1682 # unix pathname pattern expansion 1683 for apath in self.__glob(npath, do_glob): 1684 # recursively list subdirs according to rec param 1685 for rpath in self.__walk_rec(apath, rec): 1686 if not exclude_filter(rpath): 1687 wd = ret_[rpath] = self.__add_watch(rpath, mask, 1688 proc_fun, 1689 auto_add) 1690 if wd < 0: 1691 err = 'add_watch: cannot watch %s (WD=%d)' 1692 err = err % (rpath, wd) 1693 if quiet: 1694 log.error(err) 1695 else: 1696 raise WatchManagerError(err, ret_) 1697 else: 1698 # Let's say -2 means 'explicitely excluded 1699 # from watching'. 1700 ret_[rpath] = -2 1701 return ret_
1702
1703 - def __get_sub_rec(self, lpath):
1704 """ 1705 Get every wd from self._wmd if its path is under the path of 1706 one (at least) of those in lpath. Doesn't follow symlinks. 1707 1708 @param lpath: list of watch descriptor 1709 @type lpath: list of int 1710 @return: list of watch descriptor 1711 @rtype: list of int 1712 """ 1713 for d in lpath: 1714 root = self.get_path(d) 1715 if root: 1716 # always keep root 1717 yield d 1718 else: 1719 # if invalid 1720 continue 1721 1722 # nothing else to expect 1723 if not os.path.isdir(root): 1724 continue 1725 1726 # normalization 1727 root = os.path.normpath(root) 1728 # recursion 1729 lend = len(root) 1730 for iwd in self._wmd.items(): 1731 cur = iwd[1].path 1732 pref = os.path.commonprefix([root, cur]) 1733 if root == os.sep or (len(pref) == lend and \ 1734 len(cur) > lend and \ 1735 cur[lend] == os.sep): 1736 yield iwd[1].wd
1737
1738 - def update_watch(self, wd, mask=None, proc_fun=None, rec=False, 1739 auto_add=False, quiet=True):
1740 """ 1741 Update existing watch descriptors |wd|. The |mask| value, the 1742 processing object |proc_fun|, the recursive param |rec| and the 1743 |auto_add| and |quiet| flags can all be updated. 1744 1745 @param wd: Watch Descriptor to update. Also accepts a list of 1746 watch descriptors. 1747 @type wd: int or list of int 1748 @param mask: Optional new bitmask of events. 1749 @type mask: int 1750 @param proc_fun: Optional new processing function. 1751 @type proc_fun: function or ProcessEvent instance or instance of 1752 one of its subclasses or callable object. 1753 @param rec: Optionally adds watches recursively on all 1754 subdirectories contained into |wd| directory. 1755 @type rec: bool 1756 @param auto_add: Automatically adds watches on newly created 1757 directories in the watch's path corresponding to 1758 |wd|. 1759 @type auto_add: bool 1760 @param quiet: If False raises a WatchManagerError exception on 1761 error. See example not_quiet.py 1762 @type quiet: bool 1763 @return: dict of watch descriptors associated to booleans values. 1764 True if the corresponding wd has been successfully 1765 updated, False otherwise. 1766 @rtype: dict of {int: bool} 1767 """ 1768 lwd = self.__format_param(wd) 1769 if rec: 1770 lwd = self.__get_sub_rec(lwd) 1771 1772 ret_ = {} # return {wd: bool, ...} 1773 for awd in lwd: 1774 apath = self.get_path(awd) 1775 if not apath or awd < 0: 1776 err = 'update_watch: invalid WD=%d' % awd 1777 if quiet: 1778 log.error(err) 1779 continue 1780 raise WatchManagerError(err, ret_) 1781 1782 if mask: 1783 addw = LIBC.inotify_add_watch 1784 wd_ = addw(self._fd, ctypes.create_string_buffer(apath), mask) 1785 if wd_ < 0: 1786 ret_[awd] = False 1787 err = 'update_watch: cannot update WD=%d (%s)' % (wd_, 1788 apath) 1789 if quiet: 1790 log.error(err) 1791 continue 1792 raise WatchManagerError(err, ret_) 1793 1794 assert(awd == wd_) 1795 1796 if proc_fun or auto_add: 1797 watch_ = self._wmd[awd] 1798 1799 if proc_fun: 1800 watch_.proc_fun = proc_fun 1801 1802 if auto_add: 1803 watch_.proc_fun = auto_add 1804 1805 ret_[awd] = True 1806 log.debug('Updated watch - %s', self._wmd[awd]) 1807 return ret_
1808
1809 - def __format_param(self, param):
1810 """ 1811 @param param: Parameter. 1812 @type param: string or int 1813 @return: wrap param. 1814 @rtype: list of type(param) 1815 """ 1816 if isinstance(param, list): 1817 for p_ in param: 1818 yield p_ 1819 else: 1820 yield param
1821
1822 - def get_wd(self, path):
1823 """ 1824 Returns the watch descriptor associated to path. This method 1825 presents a prohibitive cost, always prefer to keep the WD 1826 returned by add_watch(). If the path is unknown it returns None. 1827 1828 @param path: Path. 1829 @type path: str 1830 @return: WD or None. 1831 @rtype: int or None 1832 """ 1833 path = os.path.normpath(path) 1834 for iwd in self._wmd.iteritems(): 1835 if iwd[1].path == path: 1836 return iwd[0] 1837 log.debug('get_wd: unknown path %s', path)
1838
1839 - def get_path(self, wd):
1840 """ 1841 Returns the path associated to WD, if WD is unknown it returns None. 1842 1843 @param wd: Watch descriptor. 1844 @type wd: int 1845 @return: Path or None. 1846 @rtype: string or None 1847 """ 1848 watch_ = self._wmd.get(wd) 1849 if watch_: 1850 return watch_.path 1851 log.debug('get_path: unknown WD %d', wd)
1852
1853 - def __walk_rec(self, top, rec):
1854 """ 1855 Yields each subdirectories of top, doesn't follow symlinks. 1856 If rec is false, only yield top. 1857 1858 @param top: root directory. 1859 @type top: string 1860 @param rec: recursive flag. 1861 @type rec: bool 1862 @return: path of one subdirectory. 1863 @rtype: string 1864 """ 1865 if not rec or os.path.islink(top) or not os.path.isdir(top): 1866 yield top 1867 else: 1868 for root, dirs, files in os.walk(top): 1869 yield root
1870
1871 - def rm_watch(self, wd, rec=False, quiet=True):
1872 """ 1873 Removes watch(s). 1874 1875 @param wd: Watch Descriptor of the file or directory to unwatch. 1876 Also accepts a list of WDs. 1877 @type wd: int or list of int. 1878 @param rec: Recursively removes watches on every already watched 1879 subdirectories and subfiles. 1880 @type rec: bool 1881 @param quiet: If False raises a WatchManagerError exception on 1882 error. See example not_quiet.py 1883 @type quiet: bool 1884 @return: dict of watch descriptors associated to booleans values. 1885 True if the corresponding wd has been successfully 1886 removed, False otherwise. 1887 @rtype: dict of {int: bool} 1888 """ 1889 lwd = self.__format_param(wd) 1890 if rec: 1891 lwd = self.__get_sub_rec(lwd) 1892 1893 ret_ = {} # return {wd: bool, ...} 1894 for awd in lwd: 1895 # remove watch 1896 wd_ = LIBC.inotify_rm_watch(self._fd, awd) 1897 if wd_ < 0: 1898 ret_[awd] = False 1899 err = 'rm_watch: cannot remove WD=%d' % awd 1900 if quiet: 1901 log.error(err) 1902 continue 1903 raise WatchManagerError(err, ret_) 1904 1905 ret_[awd] = True 1906 log.debug('Watch WD=%d (%s) removed', awd, self.get_path(awd)) 1907 return ret_
1908 1909
1910 - def watch_transient_file(self, filename, mask, proc_class):
1911 """ 1912 Watch a transient file, which will be created and deleted frequently 1913 over time (e.g. pid file). 1914 1915 @attention: Currently under the call to this function it is not 1916 possible to correctly watch the events triggered into the same 1917 base directory than the directory where is located this watched 1918 transient file. For instance it would be wrong to make these 1919 two successive calls: wm.watch_transient_file('/var/run/foo.pid', ...) 1920 and wm.add_watch('/var/run/', ...) 1921 1922 @param filename: Filename. 1923 @type filename: string 1924 @param mask: Bitmask of events, should contain IN_CREATE and IN_DELETE. 1925 @type mask: int 1926 @param proc_class: ProcessEvent (or of one of its subclass), beware of 1927 accepting a ProcessEvent's instance as argument into 1928 __init__, see transient_file.py example for more 1929 details. 1930 @type proc_class: ProcessEvent's instance or of one of its subclasses. 1931 @return: Same as add_watch(). 1932 @rtype: Same as add_watch(). 1933 """ 1934 dirname = os.path.dirname(filename) 1935 if dirname == '': 1936 return {} # Maintains coherence with add_watch() 1937 basename = os.path.basename(filename) 1938 # Assuming we are watching at least for IN_CREATE and IN_DELETE 1939 mask |= IN_CREATE | IN_DELETE 1940 1941 def cmp_name(event): 1942 return basename == event.name
1943 return self.add_watch(dirname, mask, 1944 proc_fun=proc_class(ChainIfTrue(func=cmp_name)), 1945 rec=False, 1946 auto_add=False, do_glob=False)
1947
1948 1949 -class Color:
1950 """ 1951 Internal class. Provide fancy colors used by string representations. 1952 """ 1953 normal = "\033[0m" 1954 black = "\033[30m" 1955 red = "\033[31m" 1956 green = "\033[32m" 1957 yellow = "\033[33m" 1958 blue = "\033[34m" 1959 purple = "\033[35m" 1960 cyan = "\033[36m" 1961 bold = "\033[1m" 1962 uline = "\033[4m" 1963 blink = "\033[5m" 1964 invert = "\033[7m" 1965 1966 @staticmethod
1967 - def punctuation(s):
1968 """Punctuation color.""" 1969 return Color.normal + s + Color.normal
1970 1971 @staticmethod
1972 - def field_value(s):
1973 """Field value color.""" 1974 if not isinstance(s, basestring): 1975 s = str(s) 1976 return Color.purple + s + Color.normal
1977 1978 @staticmethod
1979 - def field_name(s):
1980 """Field name color.""" 1981 return Color.blue + s + Color.normal
1982 1983 @staticmethod
1984 - def class_name(s):
1985 """Class name color.""" 1986 return Color.red + Color.bold + s + Color.normal
1987 1988 @staticmethod
1989 - def simple(s, color):
1990 if not isinstance(s, basestring): 1991 s = str(s) 1992 try: 1993 color_attr = getattr(Color, color) 1994 except AttributeError: 1995 return s 1996 return color_attr + s + Color.normal
1997
1998 1999 -def compatibility_mode():
2000 """ 2001 Use this function to turn on the compatibility mode. The compatibility 2002 mode is used to improve compatibility with Pyinotify 0.7.1 (or older) 2003 programs. The compatibility mode provides additional variables 'is_dir', 2004 'event_name', 'EventsCodes.IN_*' and 'EventsCodes.ALL_EVENTS' as 2005 Pyinotify 0.7.1 provided. Do not call this function from new programs!! 2006 Especially if there are developped for Pyinotify >= 0.8.x. 2007 """ 2008 setattr(EventsCodes, 'ALL_EVENTS', ALL_EVENTS) 2009 for evname in globals(): 2010 if evname.startswith('IN_'): 2011 setattr(EventsCodes, evname, globals()[evname]) 2012 global COMPATIBILITY_MODE 2013 COMPATIBILITY_MODE = True
2014
2015 2016 -def command_line():
2017 """ 2018 By default the watched path is '/tmp' and all types of events are 2019 monitored. Events monitoring serves forever, type c^c to stop it. 2020 """ 2021 from optparse import OptionParser 2022 2023 usage = "usage: %prog [options] [path1] [path2] [pathn]" 2024 2025 parser = OptionParser(usage=usage) 2026 parser.add_option("-v", "--verbose", action="store_true", 2027 dest="verbose", help="Verbose mode") 2028 parser.add_option("-r", "--recursive", action="store_true", 2029 dest="recursive", 2030 help="Add watches recursively on paths") 2031 parser.add_option("-a", "--auto_add", action="store_true", 2032 dest="auto_add", 2033 help="Automatically add watches on new directories") 2034 parser.add_option("-e", "--events-list", metavar="EVENT[,...]", 2035 dest="events_list", 2036 help=("A comma-separated list of events to watch for - " 2037 "see the documentation for valid options (defaults" 2038 " to everything)")) 2039 parser.add_option("-s", "--stats", action="store_true", 2040 dest="stats", 2041 help="Display dummy statistics") 2042 2043 (options, args) = parser.parse_args() 2044 2045 if options.verbose: 2046 log.setLevel(10) 2047 2048 if len(args) < 1: 2049 path = '/tmp' # default watched path 2050 else: 2051 path = args 2052 2053 # watch manager instance 2054 wm = WatchManager() 2055 # notifier instance and init 2056 if options.stats: 2057 notifier = Notifier(wm, default_proc_fun=Stats(), read_freq=5) 2058 else: 2059 notifier = Notifier(wm, default_proc_fun=PrintAllEvents()) 2060 2061 # What mask to apply 2062 mask = 0 2063 if options.events_list: 2064 events_list = options.events_list.split(',') 2065 for ev in events_list: 2066 evcode = EventsCodes.ALL_FLAGS.get(ev, 0) 2067 if evcode: 2068 mask |= evcode 2069 else: 2070 parser.error("The event '%s' specified with option -e" 2071 " is not valid" % ev) 2072 else: 2073 mask = ALL_EVENTS 2074 2075 # stats 2076 cb_fun = None 2077 if options.stats: 2078 def cb(s): 2079 print('%s\n%s\n' % (repr(s.proc_fun()), 2080 s.proc_fun()))
2081 cb_fun = cb 2082 2083 log.debug('Start monitoring %s, (press c^c to halt pyinotify)' % path) 2084 2085 wm.add_watch(path, mask, rec=options.recursive, auto_add=options.auto_add) 2086 # Loop forever (until sigint signal get caught) 2087 notifier.loop(callback=cb_fun) 2088 2089 2090 if __name__ == '__main__': 2091 command_line() 2092

pyinotify/docstrings/pyinotify.WatchManager-class.html0000644000175000017500000012600411273644743022712 0ustar ookoiookoi pyinotify.WatchManager
Module pyinotify :: Class WatchManager
[hide private]
[frames] | no frames]

Class WatchManager

source code


Provide operations for watching files and directories. Its internal dictionary is used to reference watched items. When used inside threaded code, one must instanciate as many WatchManager instances as there are ThreadedNotifier instances.

Instance Methods [hide private]
 
__init__(self, exclude_filter=<function <lambda> at 0x97f7f44>)
Initialization: init inotify, init watch manager dictionary.
source code
int
get_fd(self)
Return assigned inotify's file descriptor.
source code
 
get_watch(self, wd)
Get watch from provided watch descriptor wd.
source code
 
del_watch(self, wd)
Remove watch entry associated to watch descriptor wd.
source code
 
__add_watch(self, path, mask, proc_fun, auto_add)
Add a watch on path, build a Watch object and insert it in the watch manager dictionary.
source code
 
__glob(self, path, do_glob) source code
dict of {str: int}
add_watch(self, path, mask, proc_fun=None, rec=False, auto_add=False, do_glob=False, quiet=True, exclude_filter=None)
Add watch(s) on the provided |path|(s) with associated |mask| flag value and optionally with a processing |proc_fun| function and recursive flag |rec| set to True.
source code
list of int
__get_sub_rec(self, lpath)
Get every wd from self._wmd if its path is under the path of one (at least) of those in lpath.
source code
dict of {int: bool}
update_watch(self, wd, mask=None, proc_fun=None, rec=False, auto_add=False, quiet=True)
Update existing watch descriptors |wd|.
source code
list of type(param)
__format_param(self, param)
Returns: wrap param.
source code
int or None
get_wd(self, path)
Returns the watch descriptor associated to path.
source code
string or None
get_path(self, wd)
Returns the path associated to WD, if WD is unknown it returns None.
source code
string
__walk_rec(self, top, rec)
Yields each subdirectories of top, doesn't follow symlinks.
source code
dict of {int: bool}
rm_watch(self, wd, rec=False, quiet=True)
Removes watch(s).
source code
Same as add_watch().
watch_transient_file(self, filename, mask, proc_class)
Watch a transient file, which will be created and deleted frequently over time (e.g.
source code

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]
dict watches
Get a reference on the internal watch manager dictionary.

Inherited from object: __class__

Method Details [hide private]

__init__(self, exclude_filter=<function <lambda> at 0x97f7f44>)
(Constructor)

source code 

Initialization: init inotify, init watch manager dictionary. Raise OSError if initialization fails.

Parameters:
  • exclude_filter (bool) - boolean function, returns True if current path must be excluded from being watched. Convenient for providing a common exclusion filter for every call to add_watch.
Overrides: object.__init__

get_fd(self)

source code 

Return assigned inotify's file descriptor.

Returns: int
File descriptor.

get_watch(self, wd)

source code 

Get watch from provided watch descriptor wd.

Parameters:
  • wd (int) - Watch descriptor.

del_watch(self, wd)

source code 

Remove watch entry associated to watch descriptor wd.

Parameters:
  • wd (int) - Watch descriptor.

__add_watch(self, path, mask, proc_fun, auto_add)

source code 

Add a watch on path, build a Watch object and insert it in the watch manager dictionary. Return the wd value.

add_watch(self, path, mask, proc_fun=None, rec=False, auto_add=False, do_glob=False, quiet=True, exclude_filter=None)

source code 

Add watch(s) on the provided |path|(s) with associated |mask| flag value and optionally with a processing |proc_fun| function and recursive flag |rec| set to True. Ideally |path| components should not be unicode objects. Note that although unicode paths are accepted there are converted to byte strings before a watch is put on that path. The encoding used for converting the unicode object is given by sys.getfilesystemencoding().

Parameters:
  • path (string or list of strings) - Path to watch, the path can either be a file or a directory. Also accepts a sequence (list) of paths.
  • mask (int) - Bitmask of events.
  • proc_fun (function or ProcessEvent instance or instance of one of its subclasses or callable object.) - Processing object.
  • rec (bool) - Recursively add watches from path on all its subdirectories, set to False by default (doesn't follows symlinks in any case).
  • auto_add (bool) - Automatically add watches on newly created directories in watched parent |path| directory.
  • do_glob (bool) - Do globbing on pathname (see standard globbing module for more informations).
  • quiet (bool) - if False raises a WatchManagerError exception on error. See example not_quiet.py.
  • exclude_filter (bool) - boolean function, returns True if current path must be excluded from being watched. Has precedence on exclude_filter defined into __init__.
Returns: dict of {str: int}
dict of paths associated to watch descriptors. A wd value is positive if the watch was added sucessfully, otherwise the value is negative. If the path was invalid it is not included into this returned dictionary.

__get_sub_rec(self, lpath)

source code 

Get every wd from self._wmd if its path is under the path of one (at least) of those in lpath. Doesn't follow symlinks.

Parameters:
  • lpath (list of int) - list of watch descriptor
Returns: list of int
list of watch descriptor

update_watch(self, wd, mask=None, proc_fun=None, rec=False, auto_add=False, quiet=True)

source code 

Update existing watch descriptors |wd|. The |mask| value, the processing object |proc_fun|, the recursive param |rec| and the |auto_add| and |quiet| flags can all be updated.

Parameters:
  • wd (int or list of int) - Watch Descriptor to update. Also accepts a list of watch descriptors.
  • mask (int) - Optional new bitmask of events.
  • proc_fun (function or ProcessEvent instance or instance of one of its subclasses or callable object.) - Optional new processing function.
  • rec (bool) - Optionally adds watches recursively on all subdirectories contained into |wd| directory.
  • auto_add (bool) - Automatically adds watches on newly created directories in the watch's path corresponding to |wd|.
  • quiet (bool) - If False raises a WatchManagerError exception on error. See example not_quiet.py
Returns: dict of {int: bool}
dict of watch descriptors associated to booleans values. True if the corresponding wd has been successfully updated, False otherwise.

__format_param(self, param)

source code 
Parameters:
  • param (string or int) - Parameter.
Returns: list of type(param)
wrap param.

get_wd(self, path)

source code 

Returns the watch descriptor associated to path. This method presents a prohibitive cost, always prefer to keep the WD returned by add_watch(). If the path is unknown it returns None.

Parameters:
  • path (str) - Path.
Returns: int or None
WD or None.

get_path(self, wd)

source code 

Returns the path associated to WD, if WD is unknown it returns None.

Parameters:
  • wd (int) - Watch descriptor.
Returns: string or None
Path or None.

__walk_rec(self, top, rec)

source code 

Yields each subdirectories of top, doesn't follow symlinks. If rec is false, only yield top.

Parameters:
  • top (string) - root directory.
  • rec (bool) - recursive flag.
Returns: string
path of one subdirectory.

rm_watch(self, wd, rec=False, quiet=True)

source code 

Removes watch(s).

Parameters:
  • wd (int or list of int.) - Watch Descriptor of the file or directory to unwatch. Also accepts a list of WDs.
  • rec (bool) - Recursively removes watches on every already watched subdirectories and subfiles.
  • quiet (bool) - If False raises a WatchManagerError exception on error. See example not_quiet.py
Returns: dict of {int: bool}
dict of watch descriptors associated to booleans values. True if the corresponding wd has been successfully removed, False otherwise.

watch_transient_file(self, filename, mask, proc_class)

source code 

Watch a transient file, which will be created and deleted frequently over time (e.g. pid file).

Parameters:
  • filename (string) - Filename.
  • mask (int) - Bitmask of events, should contain IN_CREATE and IN_DELETE.
  • proc_class (ProcessEvent's instance or of one of its subclasses.) - ProcessEvent (or of one of its subclass), beware of accepting a ProcessEvent's instance as argument into __init__, see transient_file.py example for more details.
Returns: Same as add_watch().
Same as add_watch().

Attention: Currently under the call to this function it is not possible to correctly watch the events triggered into the same base directory than the directory where is located this watched transient file. For instance it would be wrong to make these two successive calls: wm.watch_transient_file('/var/run/foo.pid', ...) and wm.add_watch('/var/run/', ...)


Property Details [hide private]

watches

Get a reference on the internal watch manager dictionary.

Get Method:
unreachable.watches(self) - Get a reference on the internal watch manager dictionary.
Type:
dict

pyinotify/docstrings/uml_class_diagram_for_pyinotif_18.gif0000644000175000017500000002155611273644742023570 0ustar ookoiookoiGIF87a|LBDĤBDĆ$"$Ԧd^\jdbddJDT.,| <2,ܶĖvtĴĞܪ|^TTJDlvllVL&$$D:4RT4&$Ԣj\ԮĞ64 \F<̦rdnd쾼~tL:4TB<4*$jl  rt~tL><~| Ԧ<24lVT$D:H|FȀ.R5#&Ԩ <5I, @m l&9V X*X#!震.u-Ѝ0%.|24IHf2(!PF)g"?$ci.B#ˋ@2 c\` 4>f#9:縑:rFBE!!H(r{ "*JKK!%=Jj#?PZd|)+Re! ,"e{̃čA|R URP0UCCjMihG=PȤh1ƜH+ PݢNZ2`ebrR|;D%]pU,ˤh-{\=4DϕuPqVB%PIHe[b>ĶHT"HYQS"d6-ͦmbhu,BMj-K#ʍ1*D86H=uTcT9UuTC V!d-ڐzleHhG׺׾ lѷ0 qaQXM4!$H0# x!#7c ccXظ6tCȑQ\'S/+Oi S1  %BD'&Ue". #f e(\zL.,6P_`._A& u١@VCs/aH0P( E qb-0&!cTtoSN+xy1<ڙc(Jś#@8< cśb$S0TM9SbE v"D\0{n)-您y͍k3A m5dϕ_2=9Αɋh2ђm2cz𝋟a ֶ3^`W]qe\nz(:KRT*B®[{7U.ȀJ\1%xJi:Z.T!ٲʔN}cAW͋}-jM9!A3 _}zt+CBP19lFՙ!΀_NFƒ0#&+1wzl ]8,>fɃAW+b1p@5čglcݸ7H-3Xk0~y<Ȟ9"\#q+IRUpʆ2`\juֵ[ul wG}g(w6|{Ft,{Bo׫@A4%MӬ ̻ڷ|N iz2anm&/4X.^w57lS٭I21D/C^ Cm-l6wvVNNGx.[ܷ|Z\ ʴ~9bop 6)g26gqp$qGqaq*aWrpr/01Wg>.b4UsqcA`Bc4V6bHmatu,Xyt' oad}kFS>U6S3eWGvba DvKWvLy׆nwp7thgj8o'hZV[HTB(SgZy׳iz#zhPL+7$4g{P+{l!|$bM'LJ'|.}ifڗ@8޷^(omnzn+-o_a-hP8Kuw8p PoB/ p'/Hq!QR"20q!xB)uOƂ=s|sc8Տ~4N71GCwp7utCs"'iJRWp1xAm1w YBP\#9xd܁,YwvNvMI%cUT)US\yxYfqyyed!A^dh%ej[7{5Dnޅ|U]}!B]&fuՖvV'܆^$)(~X_C=*eP7`pE&pQ숀1Vauiara$" 0i!x4%n1-S&+9DYvaT6ee\9xؒzJu *:e@䕟#pUޣod6#pA šy4YO*$χW!J ~n?Gzouoƍ<-蛉/w~`!)*i4#73c*"XR 87qi7Vv8nF}  1vz:g]i:pS g4f*TkJ {8Yvj*&hY_oaxxK%5qJĶ]](mFܚ"X*AR̺[d_Do!zx1Q`*SׯO:ah :hhRP2B ^3o38skSj7vs)۰Nx +q4p0 :B9vd<ٳת>D[ǠGʱQsqӴh\ AZXq9[wzK*?&l;$犪]Fr皵} ȮNmxqQkBoz(vp&;{BWQ w1s1|k8R+9+/(sZ L2㉰(*kH,;.?24 z>=9{e;VUٽkOZ cTVXU۫n[5:jTGՊ\1q{ַ \_I݅q1GR+ ǩ*XqŦspar8yh ̽Z\o26q3 [vkkںǫˀr%7 1Ti];'^%J|\o/^7~¬ ؏EIJ;9C~K+ɛp- q ;ț83aR3kAz#8ױ95KQ\mG+ iI|ra =zXO M8 ! &}(=.02=4]6}8ӄP>@5 P঳̟qi ..eC pZH~\@Q3%ءc㶘#$&( \D$@]>*)=S%7L?@6_BʏMF>"?PI"L (ۦk¤B[omKڤ ].52}[1.{ǥrQ f:-Lpb/tހ;~I-g^)f?n#3٦31JPoqݜpځ(K377{z50⃣/yEicU ?zJGn9>9N랠>| X~WtΠNn/  ? P$_Q!~=1\Yx/lqCC@Ĉ@U=~RH%M%J-]%id ΆOTǔ<]iFF"%ҍC^źD]~ !Xa Q"VmF%vWȭkśw,ܹ}X`U ^FYbw4d&~ZFZ5X],[lڵmƝ6tō&Q@O͝?2Ŧ"LDǞ]+Pڱ]x%5XeӑkTҪQzǟ!X:NaE?< U<dAN)`/P$J#N0 3)$A ED ABrgoD1GQ (Fs]:1QI'c'.J*J,lNK.tK0DLL2ϔL4״JM6M8IN:N0iYyУϬ{O R!|G?}g}E}?_q>׿/w$j d?F0Y-( ~aEH>#a UȾ^AEˢa r]P|CTC hDJYjTOE*zT.Ƞ"E.b!5),B pEHSANqJ $l!;&BEX"$HZ+@Y@6JLI$D)3IN~ĒT兖P+\–,@by!Vȗ<.3(a 1e.JMr&LU5dMmf)47Lq4340g<9OzӞ<%|ӟ=%Ԡq6ԡ0LԢhF5Qvԣ}G3Qt%hf!_)GQӲԣ@DOљԧ?,|JRtFsXթ;}jGqS4W-P*Ә0`U5S$ZUR &:@**Is Z{D-:JXW{ @°plxATRt_!0pE `W|ual, {ҷuvj=.\'ɾvݦf Ǯvm;V~wQUPbG|x7|%?yS>FywO U>zҗMzֻCQ}e?{^(}uS~'{^ǧ=27χ~/KF~}҈Ob|7 Ϳ$o+WR?(]}voH>̛Z;K8ջ@;RJX[=Jxs?-*)6胹Z:(7p8p:-T-s-- 7;3JKj./z2A8z&q+:.9{d !$.#.ʂ%0 ;2 ۨW?_@*(&sC(cDȂ1.#@D#(`CK3 )(ZsrDóX3?#Ð0NLC 3_5;[@C88CMK1BC,+TC0t/u+Ŏ c8j3B8`0$D )RĨ*6b{9Kƞ9t,p:2 nEl4H4գKds=>P«z֛1"@p*WӨ @ȋ$P 3Ȏ*ȑ)$ɔ(⾗ɘ4ܺlVLjlTB<̒Ԝ~tԪ\JDvt쾼$|bd^\̞<2,̢\*$z| dRT4*$:<|ܞ䶴\.,ĞtZT~t,"$D64|b\d"$FDĆ&$fdԬVTD>u?6Cv߷WBɥZSZ|'[ `z`p9qZ0_yA[FXЄ#JZ Zn,/g̥V&@c䑺 ٣ՅsJT&epD\vTDd ihlpfIДUY[v gj(}ءu6E*F嗜vD%JИrjꩨ:vZziOƪaRZegWr W !*:aY+)8Wl= YjG! F^~"(,[s ~AE"Whq.Ô-KWrG2:GQp\{0F-@wno]AZ%CG}kyx#˵4K_esr̄6׹E\nG/ 0~Woa;6ԭJdiAtL&4Qw\6jkc~" E׊\1aq CF-9 !2kD ~8/k'#!~"]/-m?i11wdOr1drCK(T!.,xokcƟo?Bz(MմdOB`{5-آ[#2`P$Hr ? !E=M@J c$C(˽}4*d@q@V3 {A! cRDnt=T&f#g@wX4ЇZĖ#IkZkRe]@P:vvy[[~ 7cY6DCȉȖŭq%'w.,>hb4@X8յuc%F7jQӊ"=_:2:ߵO13$ ( 7pRf>)[І< #%``\ROp@JЂTH :=BmZԠ>h%X#KdT'R& Z@%XBI7() X,!0QZ ',&iLRRdS(0bdBPKdA Rx @BL^0 FDRTa p@j֘<1B&PWSX R0%WA1 2UKA>7'&a -PUELa)|OEM&хV\b }ilM.uj%xb oBo:\u B?K.,VXhP]bH@ Module Hierarchy
 
[hide private]
[frames] | no frames]
[ Module Hierarchy | Class Hierarchy ]

Module Hierarchy

pyinotify/docstrings/pyinotify._RawEvent-class.html0000644000175000017500000002371211273644743022245 0ustar ookoiookoi pyinotify._RawEvent
Module pyinotify :: Class _RawEvent
[hide private]
[frames] | no frames]

Class _RawEvent

source code


Raw event, it contains only the informations provided by the system. It doesn't infer anything.

Instance Methods [hide private]
 
__init__(self, wd, mask, cookie, name)
Attach attributes (contained in dict_) to self.
source code

Inherited from _Event: __repr__

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, wd, mask, cookie, name)
(Constructor)

source code 

Attach attributes (contained in dict_) to self.

Parameters:
  • wd (int) - Watch Descriptor.
  • mask (int) - Bitmask of events.
  • cookie (int) - Cookie.
  • name (string or None) - Basename of the file or directory against which the event was raised in case where the watched directory is the parent directory. None if the event was raised on the watched item itself.
Overrides: object.__init__

pyinotify/docstrings/crarr.png0000644000175000017500000000052411273644741016142 0ustar ookoiookoiPNG  IHDR eE,tEXtCreation TimeTue 22 Aug 2006 00:43:10 -0500` XtIME)} pHYsnu>gAMA aEPLTEðf4sW ЊrD`@bCܖX{`,lNo@xdE螊dƴ~TwvtRNS@fMIDATxc`@0&+(;; /EXؑ? n  b;'+Y#(r<"IENDB`pyinotify/docstrings/uml_class_diagram_for_pyinotif.gif0000644000175000017500000005371411273644742023261 0ustar ookoiookoiGIF87a|llRLĂ<2,tbdĢbdTJD<.,rdl&$ĺ|\64BDĖܪt,&$f\z|L>4̪~tĚdVT"$RLܲT><2,  lZ\L:4dJD,ܺԦvlԞ|D:4rdnlrd̞RTTF<|jl$"$Լ:<|^T| z| D2,|bTjl\JD$4.,jdzltZT쾼Ċ̢T.,|JLԖ4&$jlԪ*,䲤24 dRT亼Ԣtvt̚Z\\F<|bd~|t^T lVLrt\:<̒䮜,j\LBDĞZTd*,lzld^\|̄ ndd24rt̢Ԫ䶴nd$TB<64dND,"vlD6,\NL$~t4*$ ^\Ćfd|FDܮĞ&$ܾܶVT><~|̴nlĎNL.,64侼Ԧ̞^\|fdvt̖d., vțԮ<24TJLL>j Ѩ41Zs`1 J:́B6 G?Zr:&E%{_RI|]&W)*l /+U caYhN)ZKT҆ fѨt5od;) Amkj:Gf{:Չw4k;ivڌ'vdx>CO IPjpM?]rЊjf(&)jю 8ђ"MHjҖ*i\JST*gMwT:PS@?U_Pԯ;rRRԦZU+ON%+9&U` 7Թ(t:r:q1HVrf]eaXZ*M\ӜT)BRq_#2f+2$P-zYk RބV[kS,1c yBQ7d%1pdX~{Ve^9`̎{ d"9#)g0 [H.a~2GVbcc(DymUlh;9ϐEZi5a̒YIRsEj(KQ?u3<+,S2d_OY!T1ݾ1{oUx琑C%c}l,SIvo~%_xKھ$'<xؼg@o`7y>>F8· Zx';oXg 򐟱#'qMN+Yp1]~s\5yρ;ָRD`,'D9{@G@/kUNg4v3z~l>uc˛VNORb/p![.sjWG|aR}vm tnpg9Ͼ`6y ;'x0wG_юXݚg;֕ʛYoU \o< r/=wZ_ϱ_'gFK?9Χ>Mw_Wx ~P_,zee*Ȝk2r"Wsb{%}6 X'(w8b6+BYws;V."#jhaf16I.sj#|W.l4͑^76z~2(O8`$Ed/xM1'~IxrL`>4IXVJXZԅ#`(Hb؃KXtHjFl8nU7tDu0d,y(Dܧyr84t/Tw/2rv!cVIn($~#s{'8Vyأ=jR931|q1oJq>]`)=vp3WvFN-w{C BYyA";U@99@ח~Y%z~陮hRs9 < 2q3S IhB pM Lo ޲P`o)9:-0t-@2m *ι)GThvfXwu)PpR✼Hb9+ (Z.)[Ibh,Hlɠ✚% k&1υx0 J26qS z7ٛɢ-/:/5 M C9j5{ ?Oz@ A Q A=aށ<ڣ[ORe ޡ eMx9~:Qwx:O]z֧\|Hzz}|zҷzQ‰~Ut6?a)IHeq!rvH09:xi<)Fg et!FEVW!hjrY#کܹeP1@l6j!҉VJ&%YjE(р '%)5|(6&0)(Y)>M Th Khxk]ѰXiZFi=J2Aǒ*%b*T2ҍk(ğځ0Xsgwh,I|s0![J6cƂf-8]{{h>1sx*cj2wCWcPd\'\"#)x+;la9hL!^%_k5'0`:8j:wj+IaHb깟;nM`"7KGNrI:#穬ʑnAi2Y__N*BUG˃蛾NJK˸e+Ӧ^ %|wt,|\pq{p[[Z թ]9-#LjD7)<Z?1468i½BSЪ:\AĞ چ3MCU S,|]8E:WىIŝr9Wiйfi!rZz #!-nVݜٿUgINru‘<Bg; 0X&,c`ʾädZ f0K@{ l˿x*KK51ӈ:W߬;ٌN-3d ̉^() /}:ѓ)Lԇꡒ!ſ!0ߢԱ.e0gBl_QNl oP JOTOw Ou BP}o1٭Yv[0كcph4}8zgzۨ= E=SIM;F-Af ҍK=^tfAs#uf y>I Mм[c{eH.r,=|_W.0 Kn똡%:!.wGto.ϯ t2 c.H)E̫8lc SFᅈ^98!ch nHIY%d:~J^䘛 ֱ1EETRM>UTU^ŚUV]~Vا5Ք6šKi׶=j&@+O;`av+N;/` 9ygI$`4aEtqyhȉǠ$n޽}\pōOj*QL!eC;sc2@7\c ׳i[]uAݿE8aCUZO~bSoDx P-9L+BU1ZZ&c'waL5O !^BGhId vz&>:饛- 0Ix56X4FzΏ tٹ΃oT%R ;p$ 7q]{$w\EsYP &/ 7$Λ˞=vٓ7:RN)͡6ߗ#w) *X؅%2wh>w+{ [ٷ{*H!W|0| %JYn1D!U=(Ԟ8@EMdZ"%2B:Qj1IiNS&P̑A*UЁyЅ/c; !~̧ؒ9ΆB؆h;9LA:BЊWx#A H[Q8F2K`pB4ecuFgM婍;9HVV HFFʐHJVOd&55IKvғ&E+N~Ҕ<&Gx%TJZe.{3KFw"ֺdvZJҕDf2}/|R׋bf6L~us?L2jDg:24 dYNĔ$&s:D c0iwM:+&N64M#le': I&J9kqiP:ԥ/}g\osc\MY $HWE%c Srh$ hMZ(iP֪>oC6ŭoY⑹niK+>ȏEh;nuuɻ^,r,/{ ;o~V__Z7׀ J#dIL$&lw{$W~)t 'z׆aˎO[iSŶToul1 cX*P c= }$h1 m͍]w[Oj99Pa QD)rԣ tTҫMkT3J=.{X0_JO"dhhz UE?w^OF .C;*Vyq'YhTn:}t JR_ ÿ*Ʈxed?(},5ɡ rP-pM*kJ&wI`S m@z< ߣZȖPxCQ1)GQrFWUtiD݉0ޣCrY8e+1yWs3:FMIwɆat~[&g:KO ޺y>_T, B\@9^`dǾ߁oX `ZW}݁=]M=/W|%٫A>I' ,냿ܥk ͢ts۬rk^J| 23@?ݺ*8i!{١6 #@AB+Ѹɒ9 A,A$B[(;%D:B+?,ZB.t:/Y C1<:2,CkB4=5\CsjC7<;f"k`[<,[3ÜCCJ;9,D;D #@,{9BD&'<'@<*#(!|'S432O yʏ۬(r[=Bd FЩC\ƊVC#FT*G`sw\1xF?@(6xH|,7!l Ȉ`,!|(H4{| 8|"ďl~c$ JyNƘ:9vPsA>ʹqG0G ->M$îҪ ?D{|lO︪~tш*G ?/5PmLH%cs\H+R'S̐<@+ I|ІHjIXɝ ܢRR(\ń$8ѷ-ֳI|BI ҭMҜ;͆XiJZyCJŮKL8SJU%H I]UJKܙOUjU[ UUU^\U VaM8_-;VdeZCL<Vb֦C̳C1g eCHMk1Vr-WR| ڼzNRp Iř|MNDVm}W:edΤN$?,F;#O=g5؃m(R)!EG]I+U>s6v$̎Xu/qWYKYtRQ%Y ] "}f@uסu.59S/匾Z,1,uZ95A?MSrqA8-ԘZUi51TZM&[MtT%\]2\JUm\[q%ܳjV̕&\n\5C ]\=]]=mSJ]Mju >:ŌH]] LDF =^L^s^=|}m:x&o*xg#f[} 1S'1"+s[ y{Q-5nsjQ3^zͽy}) X}!̡ܣg: G(aGxyrяyȆZ{/{>{.0No{z2EVoܺo Eᦋ5|p|%nɧ|0|o|ͧϧ!}n1 ؗ٧ڷ'7}x7wgwkX~O}K^}diEϛ?!c1E/lbrb,h „ 2l $H'Rh"ƌ7r#Ȑhd$ʔ*Wl%̘2gҬi&Μ:w\ ȠB?B8(ҤJ2m"RRj*֬Zr+ذbǒ-klVkO"--ܸr`ۘz/.l0Ċ3nk R2̚7s2ТG.m4j;&v5زg6ܺw潚v/n\Rs;ʀcD|Qs78\Ǔ//79o!z^S^f?f;nx 8 zIz-ZHzH:I|xCJ)0p0.e`^2h!1X9N1TyG^ JQ&$E$6BQA ^sygy:9C"Euuy+MW6:~)B^|$ %)š:rQ{llʃFPJ|B;F)eE|fJN\Wc\;v ፙ(Fz߂k-垛.ƪ {~"kQ ;0]fA 9Gqj R5\{kz@ĩ*ʲ_#|r#|"<4j CPDG+t\j@8C<" Gc]Es5_J4\ 4{] Ŵd_re6v. nF3PÃ~xG ^㐏`c4A+K嘯 7y~yI{Wyq@镣ռ8EO8C< I8e|7ްm. l/o$\/~윒W(Q=).^Oԗot"x,g1_$48EiTjHr04 <(B)/4 CԠw|ac>HL+!_NJ@@!.F 0N|b_x8$*b"JpT"-5jhf|#Fv=fK <򱐆HA2r8t ul`g:Q!3ٝDmd =O"\Unx6$(cəG6f|ab5!V7,e)*bQ|! b0  Kk)K^)KeR$q"Е5 0y PJ4qWlCy!'TQ2TŪYo "'BGˇS]K1%0( A`v+^׾ą,&BЇt) `3h4u0˂hc'bRa'Uڧ )ͲPӎ ny[b7r0BEQ*VkIO{NA8h)sK\;.V-*`1dη=,b2E&"R5*bV4`9R//w3FТ۱`|-pR`c4h%w"9S::tpkG+s;Eplyg@vF2b(#{F.|2`HrHd"qKya*Oi~Д&5yLnߜ5cubG7tLIDˇm!'.1*.FvӃ-=`Hժǁ5#W>M7zV[A IUfOhޙW>]XĆ 0{ ƴ|"IrE1yK/Sμ&ecDe‚J/bEhBI{z0:7Vmg?7̎(fͬf}˂ܮ9S(c>쉿5ot/Pk1<w7y^ $NS3Q( P?q> PZq1 JU `H=tA;ɛW. `B P ZAaGE`ԺLdCTڹGAU^*KIQ\Pۑ;My y@8x]`a՚КN XL=[UJhaOq)OI  J@TEU"+8 VM#具 j"a\(#2UHaU"aUV.Dpբ-ޢY "6Ё[圮/w_LN2 \^42c謡 0nҕ][EqcxY_:"HށלݎcڰOl]ܱ (E1jt{]mA:YvW!Wc`P)G6Hzd} H.JB1& Q:c$KK´{an`,cS%ON$TR2RS6 =eTni̢B!X%M"VNUrZ V[%\V.Z_xeB%s]%]B _`^"D`ږ_`eacVb*&(tX &5&=f<\`HW*ffE$Ym`OR&Xfj,]_gU*&MKie_ ݮ{zEqJl m rEffA,`PgnR\d>'p_QXYIqX쩉I 獭vvāPʉ^T؏-{Jy&؈1YmE}JB Y_ATπD1(cVًhbtШyƦH1I-˶t`qzl zT H֨R6i[ )zͥeZ̑&O^N,졂FI̳yzZƊiRH)a۠TGکVt[E%%2Lm"Um͍>P_jugAaU'[ JG,Ij)5Nͱ|_3擮H#\3M**1ɷN5u\3zkǩ鮸7+")}O?@cO6Al$>jNA+Ebfl?2׸tP,HdI.JVlB*RYPI˞xln̤a+"FMЂq%Q&QMmaTmj\mB'ւ֒-Kؒіx-oں-^-hGrmw!xA&GԵe\b@4l$$\\6"BD t.閮>VfY-e&jjrgf.hZЂ3$Ă&p)MnҮxY ˊ Ǵ菢f"0c.RBD` $\-X_FTL Rԣ]Ծ))3!˰֠f՗p)0mH$4C/q"MjqTnfէja0RH@,A .<YjMzgYb`jᘭqb2R,C3@@$"eYu0\M4Vk3^lkպ*Wq1m/D*B3Dp+c%gѝ$}Q2m14[ACA BK>#PJDHE?+F7! GtJôZtGA-sM4WFOP;oFOCJ#uR/uTuF<3XTOx*Fj%-ebfuh\fbGccr(;kIScVkV4Z#nnr֗5VRF5^Z+14b762FsuyEV5Wka_?uFq6]&747Ajhpxu]X6^cvPA_2i~hI/5g(@rLjq)+0)6/EHsOoGQj}Esw,|A|׷2oUSmvfk,wp;J^p(zpY\ Lʅ2 h l\ 세A(̏}!qx%o09à 6xXv.xK#?r 1'j)f}6,P1 X#bKGEBǔZ`0&,W_1F 2 iqCDD‘#^wj!.:jɞΚTOpa tay-zS*ؔ^w_豰! OE3C#z;NdM'">#慩[CMArE$**{M[HǴg܀" Źw;Ƽۋ*%rs[{qp,sr^DkV!`C|1>c9װ\Mt\| bȻ^HtLcc7\3zB |nW7F~u9?l6s66l]cdc5g+=m=Ai?97 σj;!3D++uWb!>W!>d`D >mƱb,!i>Wq~c\[_D<ZEHSum.4H zlD~3$8W>~=*D+3CBKSQ\3O?3X Wg Y5@?'_gxRD?@8`A&Txb!F8bE2*A9dI'QTeK/a$`B FX1>D9hQG&UiSdGWfպkW_FIp eY1-,{VN1Zzu_h@ɚ0L~K 6x wKp0R,׿?{+L2#$p4^ -#T0 AпI,DL@la"@@C1ȋ .vQo oNl'GLq3I6P+RWq^ ȓ'M6x/OS=2*!rA -P\ESb+0vke4pa:SQMu(?JUYi(HB_UprZMV,m- WL`6a*okgAuٍ!RY{}WwE^-a߅n[W)nXS}Xd6I.9NyAaj#aLf=Yy矁Z衉.裑Ng D駡歊 9[C[.N[n&a#h4B.F\Ci1+ 9!\c"5yd(\I/+ 9I^qf^LqLjZ HpbYdܑO^yыqf!&/ X^%e}p^ٿW$|Hh_?H.!- t-xGAb*I8`h Vd$,\d aí.. _Qv+[v6WjW8tҒtjsewٽv4kq@2 !Pp0@ Wa/s{o㛕JqfXGu X)^UxTSTՏҀ44Nr/OIșu#VUձ>]Y:q ~eOuޠw3&Qwu/I 7x/w!yO1yoAzя7}wa{Ϟq{.߁|~'݉|/-|O}o?7/w?}& 0p0/%p9.@b(05pq?90Epe FMK>˯DL+( TpNKHwkYCLv&|prЯ!! pÍ0 а<`+ ) ϫ A1 *!ʹ-ppyЯPqRK.x+ekaT@`!ѰQ3q K] ? >^Ѳ b1*  ++ !+ kӭ@όMqR` kPd+9ѯЋK ,"P:p`ԂV J ,N l Kh(Nah"l* `;&a`"3r#7W#52ء P,X: 'n Yr&-i(nN:bD  &QT l'*@¤R!s RREL`! +9RQ,ү%{'٫*2-܁JLg8AD2 , rB2h'3g$!s$O2%=33?SR+4<.- =R:2*s%.U%U8e% )d655V@".>`Ȣ < @v@lph,MʨA@vɆNS?3<ԯt?J`3͊04ړ&A׋< 8΀C L@ñ(,BҽT^t,FlFkȌDѓȌ,ҳI @;itC7L<T4ILBBiDEFļ=C8AȂF7,@dzKTȘ@tAHCCM*NoP @ԯ˼ AʲQgBJ HN4GKSIAuS7E]T%(StQ ځ;uqx :0-1ME <@(:Mt -ӊk(\jX5-5EqhN-]MWqtö*Z;-dҢUXկ^ 6յX5;b[9-]M@vPPU6vdv`'>VN e1EUd^ Q*MfmZ9vWG5[/iGwg+[5 h-hWҒ+m1_U^M㩛7j]J;a[ ߏHܟ>~~~~^h*~? Jb"!?%)-1?5_J.A?EIMQ?UY]a?eimq?uy!??????;pyinotify/docstrings/pyinotify.ProcessEvent-class.html0000644000175000017500000005453611273644742023002 0ustar ookoiookoi pyinotify.ProcessEvent
Module pyinotify :: Class ProcessEvent
[hide private]
[frames] | no frames]

Class ProcessEvent

source code


Process events objects, can be specialized via subclassing, thus its behavior can be overriden:

Note: you should not override __init__ in your subclass instead define a my_init() method, this method will be called from the constructor of this class with its optional parameters.

  1. Provide specialized individual methods, e.g. process_IN_DELETE for processing a precise type of event (e.g. IN_DELETE in this case).
  2. Or/and provide methods for processing events by 'family', e.g. process_IN_CLOSE method will process both IN_CLOSE_WRITE and IN_CLOSE_NOWRITE events (if process_IN_CLOSE_WRITE and process_IN_CLOSE_NOWRITE aren't defined though).
  3. Or/and override process_default for catching and processing all the remaining types of events.
Instance Methods [hide private]
 
__init__(self, pevent=None, **kargs)
Enable chaining of ProcessEvent instances.
source code
 
my_init(self, **kargs)
This method is called from base constructor ProcessEvent.__init__().
source code
bool
__call__(self, event)
To behave like a functor the object must be callable.
source code
 
nested_pevent(self) source code
 
process_IN_Q_OVERFLOW(self, event)
By default this method only reports warning messages, you can overredide it by subclassing ProcessEvent and implement your own process_IN_Q_OVERFLOW method.
source code
 
process_default(self, event)
Default processing event method.
source code

Inherited from _ProcessEvent: __repr__

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Class Variables [hide private]
  pevent = None
Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, pevent=None, **kargs)
(Constructor)

source code 

Enable chaining of ProcessEvent instances.

Parameters:
  • pevent (callable) - Optional callable object, will be called on event processing (before self).
  • kargs (dict) - This constructor is a implemented as a template method delegating its optionals keyworded arguments to the method my_init().
Overrides: object.__init__

my_init(self, **kargs)

source code 

This method is called from base constructor ProcessEvent.__init__(). This method is useless here and is meant to be redifined in a subclass of ProcessEvent. In effect, when subclassing just override this method if you want to provide custom initialization to your subclass' instance. You MUST pass keyword arguments though.

Parameters:
  • kargs (dict) - optional delegated arguments from __init__().

__call__(self, event)
(Call operator)

source code 

To behave like a functor the object must be callable. This method is a dispatch method. Its lookup order is:

  1. process_MASKNAME method
  2. process_FAMILY_NAME method
  3. otherwise calls process_default
Parameters:
  • event - Event to be processed.
Returns: bool
By convention when used from the ProcessEvent class:
  • Returning False or None (default value) means keep on executing next chained functors (see chain.py example).
  • Returning True instead means do not execute next processing functions.
Raises:
Overrides: _ProcessEvent.__call__
(inherited documentation)

process_IN_Q_OVERFLOW(self, event)

source code 

By default this method only reports warning messages, you can overredide it by subclassing ProcessEvent and implement your own process_IN_Q_OVERFLOW method. The actions you can take on receiving this event is either to update the variable max_queued_events in order to handle more simultaneous events or to modify your code in order to accomplish a better filtering diminishing the number of raised events. Because this method is defined, IN_Q_OVERFLOW will never get transmitted as arguments to process_default calls.

Parameters:
  • event (dict) - IN_Q_OVERFLOW event.

process_default(self, event)

source code 

Default processing event method. By default does nothing. Subclass ProcessEvent and redefine this method in order to modify its behavior.

Parameters:
  • event (Event instance) - Event to be processed. Can be of any type of events but IN_Q_OVERFLOW events (see method process_IN_Q_OVERFLOW).

pyinotify/docstrings/api-objects.txt0000644000175000017500000004001311273644743017263 0ustar ookoiookoipyinotify pyinotify-module.html pyinotify.IN_CREATE pyinotify-module.html#IN_CREATE pyinotify.compatibility_mode pyinotify-module.html#compatibility_mode pyinotify.IN_UNMOUNT pyinotify-module.html#IN_UNMOUNT pyinotify.max_queued_events pyinotify-module.html#max_queued_events pyinotify.COMPATIBILITY_MODE pyinotify-module.html#COMPATIBILITY_MODE pyinotify.IN_DELETE pyinotify-module.html#IN_DELETE pyinotify.IN_MODIFY pyinotify-module.html#IN_MODIFY pyinotify.IN_CLOSE_WRITE pyinotify-module.html#IN_CLOSE_WRITE pyinotify.name pyinotify-module.html#name pyinotify.logger_init pyinotify-module.html#logger_init pyinotify.IN_MOVE_SELF pyinotify-module.html#IN_MOVE_SELF pyinotify.LIBC_VERSION pyinotify-module.html#LIBC_VERSION pyinotify.valc pyinotify-module.html#valc pyinotify.IN_ONLYDIR pyinotify-module.html#IN_ONLYDIR pyinotify.attrname pyinotify-module.html#attrname pyinotify.glob1 pyinotify-module.html#glob1 pyinotify.glob0 pyinotify-module.html#glob0 pyinotify.IN_ISDIR pyinotify-module.html#IN_ISDIR pyinotify.MAGIC_CHECK pyinotify-module.html#MAGIC_CHECK pyinotify.LIBC pyinotify-module.html#LIBC pyinotify.log pyinotify-module.html#log pyinotify.val pyinotify-module.html#val pyinotify.max_user_watches pyinotify-module.html#max_user_watches pyinotify.IN_IGNORED pyinotify-module.html#IN_IGNORED pyinotify.__author__ pyinotify-module.html#__author__ pyinotify.IN_DONT_FOLLOW pyinotify-module.html#IN_DONT_FOLLOW pyinotify.ALL_EVENTS pyinotify-module.html#ALL_EVENTS pyinotify.IN_OPEN pyinotify-module.html#IN_OPEN pyinotify.IN_MOVED_FROM pyinotify-module.html#IN_MOVED_FROM pyinotify.IN_MOVED_TO pyinotify-module.html#IN_MOVED_TO pyinotify.IN_ONESHOT pyinotify-module.html#IN_ONESHOT pyinotify.command_line pyinotify-module.html#command_line pyinotify.__package__ pyinotify-module.html#__package__ pyinotify.max_user_instances pyinotify-module.html#max_user_instances pyinotify.IN_Q_OVERFLOW pyinotify-module.html#IN_Q_OVERFLOW pyinotify.has_magic pyinotify-module.html#has_magic pyinotify.IN_ATTRIB pyinotify-module.html#IN_ATTRIB pyinotify.IN_ACCESS pyinotify-module.html#IN_ACCESS pyinotify.flagc pyinotify-module.html#flagc pyinotify.IN_MASK_ADD pyinotify-module.html#IN_MASK_ADD pyinotify.IN_CLOSE_NOWRITE pyinotify-module.html#IN_CLOSE_NOWRITE pyinotify.iglob pyinotify-module.html#iglob pyinotify.IN_DELETE_SELF pyinotify-module.html#IN_DELETE_SELF pyinotify.AsyncNotifier pyinotify.AsyncNotifier-class.html pyinotify.Notifier.read_events pyinotify.Notifier-class.html#read_events pyinotify.Notifier.proc_fun pyinotify.Notifier-class.html#proc_fun pyinotify.Notifier._sleep pyinotify.Notifier-class.html#_sleep pyinotify.AsyncNotifier.__init__ pyinotify.AsyncNotifier-class.html#__init__ pyinotify.Notifier.process_events pyinotify.Notifier-class.html#process_events pyinotify.Notifier.append_event pyinotify.Notifier-class.html#append_event pyinotify.Notifier.stop pyinotify.Notifier-class.html#stop pyinotify.AsyncNotifier.handle_read pyinotify.AsyncNotifier-class.html#handle_read pyinotify.Notifier.check_events pyinotify.Notifier-class.html#check_events pyinotify.Notifier.loop pyinotify.Notifier-class.html#loop pyinotify.ChainIfTrue pyinotify.ChainIfTrue-class.html pyinotify.ChainIfTrue.my_init pyinotify.ChainIfTrue-class.html#my_init pyinotify.ProcessEvent.nested_pevent pyinotify.ProcessEvent-class.html#nested_pevent pyinotify.ProcessEvent.process_IN_Q_OVERFLOW pyinotify.ProcessEvent-class.html#process_IN_Q_OVERFLOW pyinotify.ProcessEvent.pevent pyinotify.ProcessEvent-class.html#pevent pyinotify._ProcessEvent.__repr__ pyinotify._ProcessEvent-class.html#__repr__ pyinotify.ChainIfTrue.process_default pyinotify.ChainIfTrue-class.html#process_default pyinotify.ProcessEvent.__call__ pyinotify.ProcessEvent-class.html#__call__ pyinotify.ProcessEvent.__init__ pyinotify.ProcessEvent-class.html#__init__ pyinotify.Color pyinotify.Color-class.html pyinotify.Color.simple pyinotify.Color-class.html#simple pyinotify.Color.yellow pyinotify.Color-class.html#yellow pyinotify.Color.blink pyinotify.Color-class.html#blink pyinotify.Color.blue pyinotify.Color-class.html#blue pyinotify.Color.purple pyinotify.Color-class.html#purple pyinotify.Color.invert pyinotify.Color-class.html#invert pyinotify.Color.punctuation pyinotify.Color-class.html#punctuation pyinotify.Color.class_name pyinotify.Color-class.html#class_name pyinotify.Color.black pyinotify.Color-class.html#black pyinotify.Color.red pyinotify.Color-class.html#red pyinotify.Color.bold pyinotify.Color-class.html#bold pyinotify.Color.normal pyinotify.Color-class.html#normal pyinotify.Color.cyan pyinotify.Color-class.html#cyan pyinotify.Color.uline pyinotify.Color-class.html#uline pyinotify.Color.field_name pyinotify.Color-class.html#field_name pyinotify.Color.green pyinotify.Color-class.html#green pyinotify.Color.field_value pyinotify.Color-class.html#field_value pyinotify.Event pyinotify.Event-class.html pyinotify._Event.__repr__ pyinotify._Event-class.html#__repr__ pyinotify.Event.__init__ pyinotify.Event-class.html#__init__ pyinotify.EventsCodes pyinotify.EventsCodes-class.html pyinotify.EventsCodes.IN_MOVED_FROM pyinotify.EventsCodes-class.html#IN_MOVED_FROM pyinotify.EventsCodes.FLAG_COLLECTIONS pyinotify.EventsCodes-class.html#FLAG_COLLECTIONS pyinotify.EventsCodes.IN_CREATE pyinotify.EventsCodes-class.html#IN_CREATE pyinotify.EventsCodes.IN_MOVED_TO pyinotify.EventsCodes-class.html#IN_MOVED_TO pyinotify.EventsCodes.IN_MOVE_SELF pyinotify.EventsCodes-class.html#IN_MOVE_SELF pyinotify.EventsCodes.ALL_FLAGS pyinotify.EventsCodes-class.html#ALL_FLAGS pyinotify.EventsCodes.IN_UNMOUNT pyinotify.EventsCodes-class.html#IN_UNMOUNT pyinotify.EventsCodes.IN_ONESHOT pyinotify.EventsCodes-class.html#IN_ONESHOT pyinotify.EventsCodes.IN_ONLYDIR pyinotify.EventsCodes-class.html#IN_ONLYDIR pyinotify.EventsCodes.IN_Q_OVERFLOW pyinotify.EventsCodes-class.html#IN_Q_OVERFLOW pyinotify.EventsCodes.IN_IGNORED pyinotify.EventsCodes-class.html#IN_IGNORED pyinotify.EventsCodes.IN_DELETE pyinotify.EventsCodes-class.html#IN_DELETE pyinotify.EventsCodes.OP_FLAGS pyinotify.EventsCodes-class.html#OP_FLAGS pyinotify.EventsCodes.IN_ATTRIB pyinotify.EventsCodes-class.html#IN_ATTRIB pyinotify.EventsCodes.IN_CLOSE_WRITE pyinotify.EventsCodes-class.html#IN_CLOSE_WRITE pyinotify.EventsCodes.IN_ACCESS pyinotify.EventsCodes-class.html#IN_ACCESS pyinotify.EventsCodes.maskname pyinotify.EventsCodes-class.html#maskname pyinotify.EventsCodes.IN_MODIFY pyinotify.EventsCodes-class.html#IN_MODIFY pyinotify.EventsCodes.ALL_VALUES pyinotify.EventsCodes-class.html#ALL_VALUES pyinotify.EventsCodes.IN_DONT_FOLLOW pyinotify.EventsCodes-class.html#IN_DONT_FOLLOW pyinotify.EventsCodes.IN_MASK_ADD pyinotify.EventsCodes-class.html#IN_MASK_ADD pyinotify.EventsCodes.SPECIAL_FLAGS pyinotify.EventsCodes-class.html#SPECIAL_FLAGS pyinotify.EventsCodes.IN_CLOSE_NOWRITE pyinotify.EventsCodes-class.html#IN_CLOSE_NOWRITE pyinotify.EventsCodes.IN_ISDIR pyinotify.EventsCodes-class.html#IN_ISDIR pyinotify.EventsCodes.IN_DELETE_SELF pyinotify.EventsCodes-class.html#IN_DELETE_SELF pyinotify.EventsCodes.ALL_EVENTS pyinotify.EventsCodes-class.html#ALL_EVENTS pyinotify.EventsCodes.EVENT_FLAGS pyinotify.EventsCodes-class.html#EVENT_FLAGS pyinotify.EventsCodes.IN_OPEN pyinotify.EventsCodes-class.html#IN_OPEN pyinotify.ExcludeFilter pyinotify.ExcludeFilter-class.html pyinotify.ExcludeFilter._match pyinotify.ExcludeFilter-class.html#_match pyinotify.ExcludeFilter.__call__ pyinotify.ExcludeFilter-class.html#__call__ pyinotify.ExcludeFilter._load_patterns pyinotify.ExcludeFilter-class.html#_load_patterns pyinotify.ExcludeFilter.__init__ pyinotify.ExcludeFilter-class.html#__init__ pyinotify.Notifier pyinotify.Notifier-class.html pyinotify.Notifier.read_events pyinotify.Notifier-class.html#read_events pyinotify.Notifier.check_events pyinotify.Notifier-class.html#check_events pyinotify.Notifier.proc_fun pyinotify.Notifier-class.html#proc_fun pyinotify.Notifier._sleep pyinotify.Notifier-class.html#_sleep pyinotify.Notifier.__init__ pyinotify.Notifier-class.html#__init__ pyinotify.Notifier.process_events pyinotify.Notifier-class.html#process_events pyinotify.Notifier.stop pyinotify.Notifier-class.html#stop pyinotify.Notifier.append_event pyinotify.Notifier-class.html#append_event pyinotify.Notifier.__daemonize pyinotify.Notifier-class.html#__daemonize pyinotify.Notifier.loop pyinotify.Notifier-class.html#loop pyinotify.NotifierError pyinotify.NotifierError-class.html pyinotify.NotifierError.__init__ pyinotify.NotifierError-class.html#__init__ pyinotify.PrintAllEvents pyinotify.PrintAllEvents-class.html pyinotify.PrintAllEvents.my_init pyinotify.PrintAllEvents-class.html#my_init pyinotify.ProcessEvent.nested_pevent pyinotify.ProcessEvent-class.html#nested_pevent pyinotify.ProcessEvent.process_IN_Q_OVERFLOW pyinotify.ProcessEvent-class.html#process_IN_Q_OVERFLOW pyinotify.ProcessEvent.pevent pyinotify.ProcessEvent-class.html#pevent pyinotify._ProcessEvent.__repr__ pyinotify._ProcessEvent-class.html#__repr__ pyinotify.PrintAllEvents.process_default pyinotify.PrintAllEvents-class.html#process_default pyinotify.ProcessEvent.__call__ pyinotify.ProcessEvent-class.html#__call__ pyinotify.ProcessEvent.__init__ pyinotify.ProcessEvent-class.html#__init__ pyinotify.ProcessEvent pyinotify.ProcessEvent-class.html pyinotify.ProcessEvent.my_init pyinotify.ProcessEvent-class.html#my_init pyinotify.ProcessEvent.nested_pevent pyinotify.ProcessEvent-class.html#nested_pevent pyinotify.ProcessEvent.process_IN_Q_OVERFLOW pyinotify.ProcessEvent-class.html#process_IN_Q_OVERFLOW pyinotify.ProcessEvent.pevent pyinotify.ProcessEvent-class.html#pevent pyinotify._ProcessEvent.__repr__ pyinotify._ProcessEvent-class.html#__repr__ pyinotify.ProcessEvent.process_default pyinotify.ProcessEvent-class.html#process_default pyinotify.ProcessEvent.__call__ pyinotify.ProcessEvent-class.html#__call__ pyinotify.ProcessEvent.__init__ pyinotify.ProcessEvent-class.html#__init__ pyinotify.ProcessEventError pyinotify.ProcessEventError-class.html pyinotify.ProcessEventError.__init__ pyinotify.ProcessEventError-class.html#__init__ pyinotify.PyinotifyError pyinotify.PyinotifyError-class.html pyinotify.PyinotifyLogger pyinotify.PyinotifyLogger-class.html pyinotify.PyinotifyLogger.makeRecord pyinotify.PyinotifyLogger-class.html#makeRecord pyinotify.Stats pyinotify.Stats-class.html pyinotify.Stats.dump pyinotify.Stats-class.html#dump pyinotify.Stats.__str__ pyinotify.Stats-class.html#__str__ pyinotify.Stats._stats_copy pyinotify.Stats-class.html#_stats_copy pyinotify.ProcessEvent.__init__ pyinotify.ProcessEvent-class.html#__init__ pyinotify.Stats.my_init pyinotify.Stats-class.html#my_init pyinotify.ProcessEvent.process_IN_Q_OVERFLOW pyinotify.ProcessEvent-class.html#process_IN_Q_OVERFLOW pyinotify.ProcessEvent.pevent pyinotify.ProcessEvent-class.html#pevent pyinotify.ProcessEvent.__call__ pyinotify.ProcessEvent-class.html#__call__ pyinotify.ProcessEvent.nested_pevent pyinotify.ProcessEvent-class.html#nested_pevent pyinotify.Stats.process_default pyinotify.Stats-class.html#process_default pyinotify.Stats.__repr__ pyinotify.Stats-class.html#__repr__ pyinotify.SysCtlINotify pyinotify.SysCtlINotify-class.html pyinotify.SysCtlINotify.set_val pyinotify.SysCtlINotify-class.html#set_val pyinotify.SysCtlINotify.value pyinotify.SysCtlINotify-class.html#value pyinotify.SysCtlINotify.get_val pyinotify.SysCtlINotify-class.html#get_val pyinotify.SysCtlINotify.__repr__ pyinotify.SysCtlINotify-class.html#__repr__ pyinotify.SysCtlINotify.inotify_attrs pyinotify.SysCtlINotify-class.html#inotify_attrs pyinotify.SysCtlINotify.__init__ pyinotify.SysCtlINotify-class.html#__init__ pyinotify.ThreadedNotifier pyinotify.ThreadedNotifier-class.html pyinotify.Notifier.read_events pyinotify.Notifier-class.html#read_events pyinotify.Notifier.check_events pyinotify.Notifier-class.html#check_events pyinotify.Notifier.proc_fun pyinotify.Notifier-class.html#proc_fun pyinotify.Notifier._sleep pyinotify.Notifier-class.html#_sleep pyinotify.ThreadedNotifier.__init__ pyinotify.ThreadedNotifier-class.html#__init__ pyinotify.Notifier.process_events pyinotify.Notifier-class.html#process_events pyinotify.ThreadedNotifier.run pyinotify.ThreadedNotifier-class.html#run pyinotify.ThreadedNotifier.stop pyinotify.ThreadedNotifier-class.html#stop pyinotify.Notifier.append_event pyinotify.Notifier-class.html#append_event pyinotify.ThreadedNotifier.loop pyinotify.ThreadedNotifier-class.html#loop pyinotify.UnicodeLogRecord pyinotify.UnicodeLogRecord-class.html pyinotify.UnicodeLogRecord.getMessage pyinotify.UnicodeLogRecord-class.html#getMessage pyinotify.UnicodeLogRecord.__init__ pyinotify.UnicodeLogRecord-class.html#__init__ pyinotify.UnsupportedLibcVersionError pyinotify.UnsupportedLibcVersionError-class.html pyinotify.UnsupportedLibcVersionError.__init__ pyinotify.UnsupportedLibcVersionError-class.html#__init__ pyinotify.UnsupportedPythonVersionError pyinotify.UnsupportedPythonVersionError-class.html pyinotify.UnsupportedPythonVersionError.__init__ pyinotify.UnsupportedPythonVersionError-class.html#__init__ pyinotify.Watch pyinotify.Watch-class.html pyinotify.Watch.__repr__ pyinotify.Watch-class.html#__repr__ pyinotify.Watch.__init__ pyinotify.Watch-class.html#__init__ pyinotify.WatchManager pyinotify.WatchManager-class.html pyinotify.WatchManager.__walk_rec pyinotify.WatchManager-class.html#__walk_rec pyinotify.WatchManager.__get_sub_rec pyinotify.WatchManager-class.html#__get_sub_rec pyinotify.WatchManager.watches pyinotify.WatchManager-class.html#watches pyinotify.WatchManager.del_watch pyinotify.WatchManager-class.html#del_watch pyinotify.WatchManager.__init__ pyinotify.WatchManager-class.html#__init__ pyinotify.WatchManager.rm_watch pyinotify.WatchManager-class.html#rm_watch pyinotify.WatchManager.get_wd pyinotify.WatchManager-class.html#get_wd pyinotify.WatchManager.update_watch pyinotify.WatchManager-class.html#update_watch pyinotify.WatchManager.__glob pyinotify.WatchManager-class.html#__glob pyinotify.WatchManager.add_watch pyinotify.WatchManager-class.html#add_watch pyinotify.WatchManager.__format_param pyinotify.WatchManager-class.html#__format_param pyinotify.WatchManager.get_path pyinotify.WatchManager-class.html#get_path pyinotify.WatchManager.watch_transient_file pyinotify.WatchManager-class.html#watch_transient_file pyinotify.WatchManager.__add_watch pyinotify.WatchManager-class.html#__add_watch pyinotify.WatchManager.get_watch pyinotify.WatchManager-class.html#get_watch pyinotify.WatchManager.get_fd pyinotify.WatchManager-class.html#get_fd pyinotify.WatchManagerError pyinotify.WatchManagerError-class.html pyinotify.WatchManagerError.__init__ pyinotify.WatchManagerError-class.html#__init__ pyinotify._Event pyinotify._Event-class.html pyinotify._Event.__repr__ pyinotify._Event-class.html#__repr__ pyinotify._Event.__init__ pyinotify._Event-class.html#__init__ pyinotify._ProcessEvent pyinotify._ProcessEvent-class.html pyinotify._ProcessEvent.__repr__ pyinotify._ProcessEvent-class.html#__repr__ pyinotify._ProcessEvent.__call__ pyinotify._ProcessEvent-class.html#__call__ pyinotify._RawEvent pyinotify._RawEvent-class.html pyinotify._Event.__repr__ pyinotify._Event-class.html#__repr__ pyinotify._RawEvent.__init__ pyinotify._RawEvent-class.html#__init__ pyinotify._SysProcessEvent pyinotify._SysProcessEvent-class.html pyinotify._SysProcessEvent.process_IN_IGNORED pyinotify._SysProcessEvent-class.html#process_IN_IGNORED pyinotify._SysProcessEvent.process_IN_MOVE_SELF pyinotify._SysProcessEvent-class.html#process_IN_MOVE_SELF pyinotify._SysProcessEvent.process_IN_MOVED_TO pyinotify._SysProcessEvent-class.html#process_IN_MOVED_TO pyinotify._SysProcessEvent.__init__ pyinotify._SysProcessEvent-class.html#__init__ pyinotify._SysProcessEvent.process_IN_Q_OVERFLOW pyinotify._SysProcessEvent-class.html#process_IN_Q_OVERFLOW pyinotify._SysProcessEvent.process_IN_MOVED_FROM pyinotify._SysProcessEvent-class.html#process_IN_MOVED_FROM pyinotify._SysProcessEvent.cleanup pyinotify._SysProcessEvent-class.html#cleanup pyinotify._ProcessEvent.__call__ pyinotify._ProcessEvent-class.html#__call__ pyinotify._SysProcessEvent.process_default pyinotify._SysProcessEvent-class.html#process_default pyinotify._SysProcessEvent.process_IN_CREATE pyinotify._SysProcessEvent-class.html#process_IN_CREATE pyinotify._ProcessEvent.__repr__ pyinotify._ProcessEvent-class.html#__repr__ pyinotify/docstrings/uml_class_diagram_for_pyinotif_12.gif0000644000175000017500000003312611273644742023556 0ustar ookoiookoiGIF87a|LBDTĤBDĂ\&$,"jd̢d^\bd",䮜t| vtdJDt<2,ĺĖ|^T64T2,vlTJDԪrtԒ RT| D:4Ě䶴|fd~t\F<Z\z|rt"$~t\4$rt\.,L쾼  D><$L><Ԧ̞ܾ|̖64Ԯ܌l&$.,^\vt,"$<24vt | D:<~|\FD4*,Ԧ̞TBDT:<$vtzt\JLrlTFDdNL|b\t^\jdlVT, H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷_"LÈ+^̸ǐ#Keh̹ϠCMӨSkNװ8۸s}66^#_wr_ܵMkǍf;_8;nw.N=}|>1^|hHA+Po|!C*0Q &'75(П`}#0"bV !x6p#K3 :nJHfa(`%bt`J9e@I9b#)i&*rxD;D$2&TX "F(uyfrfu9gw&'~蠅wh)무 mfmD&ZF#gy[0Rk nZ[*_8\\jfWmp\ܺ 5r<6nJm Q70T[z1!l+, [vh[!m1'"ȸ )EɞwvG씑p4/{sR'sASd #FDhԆlh]⪄+i0M1+>̃ ^k|n-7v|'*\o٤nWv'DFg)Ȉ7ZSQ)`hSbF<<ŷ>rI쵧(ئ~Zw[ow8uL`VW4'H0̠ zC dFH(\ W | gH8̡w@"Q>L8#:- HtX̢GX.zQ@DԢLj.~h6.Či:Q Q~;:hzh$BwL()JY?p9r$lQbh!7ɞ0*dbc0 Vl#+ve s\ 2\!4[ֆ:ӊf&858:Д8O (7Sm 8>8G>Izč(46,i?ʲ)B'PZVFsSыzKݨHђ,#hGMR4 gKgzT+N/cӛ~3; _zfUH Qˣ&tY*S)SZuIЀh$R HB5H:⑏w!qHS5SJ׵0f0pDN&5 FjR%-IƵu_*"nO״ViͲ64%*ʵMm\*3эc4KZbdIL^k _8Ҙc&<-dK]][7K8TfvVUnė;w*Ͻ1'(Nvw䅎y_HU~/}/hA*ޢ 2B n7ܕ gx氈}/1#NqNJl$X0Fb%"Lw@^ H"HN &3`Le@9rܑ:ЁB# '2ب2f<_N>i9 (J> 3F0B=Q+ǵRccT0s3Gm73G~6!$\]"g3wgS/"J1%.27f++q5`N j'r!&Wo c4/hv&,jWq<Z a0V2" `q3qq w(pR`)r*rWFkȡ`uS$&HNXvYsQs?Bw SgEgeviX^eȆAoJrntXȱwZy}whd8Ѷv3wTfqwrćXW|wDxg$xU1$yh(({xO7_n%y8VYU^VI2!DzjiĉTXW*XW{W*Tc_`PGXH|5lŲ}[ynQ5Af$ClhT~GG2x'5 sO2SgS\V@7\_QpPV ؤM9w+"$H9osGPXqh!_*N,8>3ӂ-@tbC8uEJH5qIp+Pt#R`hT POٕԥsaHPp5\N LmIei ŘIRIYEYƎxb19@h?HEiF@(@HiGySVBbL!ziF$'hˆA{&*5z"'b|1&xܘk)&7}Yr7bW)TxlK '͉w)ۡ.ʥr5+AC&9'cLq37u(Vpyg#J:N<> < ;#E=Hi'M< aRiHUxY%ꣷDa]_; mqمDv)? 0—_ %~jGz:nTyFjڨ$y?*ZxEN1ğPD SzIܶAyY[&zhX!MroIc)fʈjo"*yypVhEmF2}6]W ~!~ʭʬ mȡFLԆ5QnW%Хji"Jj"o0r91*.tկJ!H =KJ~1? JJYz^3kjHf۱;˳v>wH2tĩC;M=[\IUuT@VXR+v^`h7Yf`h$Aյm[Oj@j_t[_Pqs+~ʫ IRÜz|k{ 2|&XkRJEs}+ ַ2 ZaR{ հ<3hQkkD˒j/&1٦kiZ>i壼ѤG!WkQWvq۾z?˽++p H %{v<|Ra rwpr# L(g5sy{-̯ q!A,|4ˬ$1#iikB KԖ{'+SI=垪[lQ}qͦ1T̬zmm2 bAl~ ~H=]2)| +|G=U>ÊQ- AɲS$ɄʡStɷ},ˉ*s`˳R<6 u"Xel6 4l$جTլ͔OTW)+,ε»"?35lHuA;ûϘEhj$Nzm]j֪0ىk\|ںI]p1R~BԷ~yjI%mnhEu\K[m6AK*4P3uz 8\5Ŭ̒+ȑ<ɑa˸7IENLgہ_=_m_׵ &m3-]~Ql@^q J<1۸Q䡩L;mmǝ}b>+0Z<s%liF޸QQ~lnW%'i78_f!] ~A3뉎Mah3hvlԺj.l _S;AR `BmKvc*oַc &[&s>n5!r]KN.61䑗rA}Nb_=ϮU!̠>f;O_.1qE Q_Z"?$_/K ,.02?4_5J` 6<>/)OO G ` J00 Ln ʐSkj Š & J@  @ 0Аi tgp @X@ }g_ezaxU J p U Jh[V O~fJ}f\_e_Nvd7c*6?baZT?_؟ڏ>v(PAaVS_A@ DH@B  t e-^ĘQF=~RH%MDRJ-]SL5m.N yРDNTRM>UTU#C <yEF0jHnP+H. +lֳirmܹuͻ@߿G)ZZhҥMF:)Vre%03P(I $'&S]>*' *9G$R/;"G|n*^9/w;vPčOyу~V_|_+`_!Ȍ ( ?j!+ + 4"")F@0$p  ̄# гfFo1GҰN({hB;`,;#PZ9a1/%QG1$L3ϼ+4p@85 @.SB -<(P  8dS!;\ѧ_l4L4'RK/Ŕ%!Y6#B`>PN?u. +,8J3c.OStsOЄ9SQUSPs֠d"Z#}/Sg6Ziq.(㫰 0E-6۠&Ri<2@6ZL F{)1nW\k= ]ub]ifa^ +tb-xb!c?"/d1>YҐWfe9SC7~9gwyGj:h;gF::jj:k;l_F;mfm>{离nc:oIn\Z&x&xG~mgEw=zawz^z2z;?zGhmhs!2|?Y"AD@|C`>,!`OQ* `3/ZH~bTUUBLqPWmHi' UBPG.Ӆ$|#2(t,6щ48C$!\aE.{ #bD|cZb(FH(2 O`È̃Yp`B~bxiE GF6%mjKytd&5YH mu#79JRddm *n9d X"K9KZ͏"kKGv%/G_Rsf2XLcFʄ=3T49Lbӛ+Ԧg h`Eq'^79O3hC@ ChC2`*A~`<ڳf|!C! 07fL0dhH|1mYAZ|a+a S Zӝ(iPG5x _xvRÈ&d@BkH/$Dd2І?LZ[6YV= " =X00dX P:YБOs*H 8AF"p=Ý'+^)ZY=)@/aE{"aTMfGղָsm/jBVuP`7@xjo'"{\Ρ4$C-o|;w^}! ~'F\׿;%&UuT<9n3h]pWop, 1'FqUbX e+S\gBגJE$aB7zPE`A 58ҍT$i(d uX %կޅeD`hm}YVD`<,d/k}hO֫-lo۳ōpܝ+͸t݀kMxޓƉ @k[Ž.|Gxp7[W*w!9@>rp tl%yAq)qw%[aGm<7 ўsW =>z/gAa u8=pc<0O{Ҿ5z|oӯÍ"8N|qtGk^,ik8@ +@:  9:hC?[ӆUHP@@ =?  F@ vVA×{l?ۃ%9CB):dB&tB+D.B0D:,B’n>25lC793I`(%^sItAWEIhHd7l5c lh#5Ɣ/5KLKJ($gɋ`]`?PWp&tI3lF|ZphWG˜ZͰR^` HINWIM@V^єNtCkf8 08POdli]8bG,M#đFl 5ʝ_\0itLP %M8HPQX$Q>@d\Ĕu"LcxȈȥG8R0T58WKR-^R)K+mWIpR(Mh5(J@ P:N+ > P,QʤM .SqLixR $WhXYZ[U\}V˄fԨQ PtNnjLQL. 8SpbVTL#H$99{ʰ47(8*5<} PfeɌV 4MNj `R̈ǜ%XWMk8pWHI٤y]jWcNXPlju Uxu5hόZYp-Y8HΊpk0 $H873סπYq5MʤY5IHzT%mP!j[e(JEװmeSZLScT.k5j@dمhxlp GlKs]Q>}ѻ-),LU$O4qJN]O /0kp5eZτMĆ,L8$X=uQiIمf`NWK27(hPf-biphPJW gRĕM4% *͆6WQ9͔iUk,^Kg8WKmmKx'VRक़&LdpYHhV=ͅbXM2q_P[k%m^4( (JcX^@,cfYdم|57ZCnobZvde忰YHgʤ,ȂGQZfNZ6Nܖlfh0KncMbk%a94fĭE&huSk`hp>7ZenIH(KAv/M Am dl胤'fk^vn`>kIZh^ znIIif_yWKgi,8li7xe!iPfʔJX&]08jhZ@>Pj˙\seNenI-g-;>feљf9 \.PKqQt5bj\8xmgj ;fLXk1qvJ(h994(a€8nɉfpSjFg8VKnvօ.,k)eȆ&q̮L mp^XVk&Xqy~䖼^` G$ji?] Zl_x8HY-./01'273r_K@@9:;RxV'??r@'9'AЃVBgFw9_p&Ve(txMPQ'R7SGTWUgVw*pF@P\]^7XawuO'du( Pghu,mW\nvS0o`qrp qowuמS8xh ww{מct''yWw|cxugw&" ?7wo Gy1ypyQa W7'wg牟 O *#y{xtY` rv0 ryx Wi{zh/?*/{z6%+* `{z{0YH+A/[O{'j@*Y0z ٧)-߉7}ɇ @!x~O7gp9{Pzbw '`0G`_$` 1`0SRhq)#Ȑ"G,i2$ XabƂ17h;'wqj03EV b:0M3c L+ƅTZ|iA V1ZAk,.RL]'&Q +[_n%Yj_$\pp#G0S ._D2 &2%یΆ}<ä@c࿉Bvsc4ZCw,#%sӴZ |1|Qq7wFWgue?-D]j~om6$C~ߪΥh<@ 0Oy\AQPEZҺz޻A0. }@[Okb$#o?V |🿺?mDn`Fg(7;s^o( 7/c`L (> iʒ. tj8}vbض)p~V.$ @7 #.2 Duh%Z9(ͅ)<@FGmm;cbAp/wm7ҦĂf["D}΅4*1_0#AJm㈖9FY/CYFJB;SH6GFou4fHɝpg@E, rI)i7:K "&ut b iEn~3 /%$  2"(gNpa| `(UI ABos f8B0:?F T¦6I1P h;3P@~IKxϝXrg@WRT ]rKuE3#l+LHjRkUdixš~@œ)I$!#'PZQgj$Ex%L! eH-8Cj@H 0_*ZÎhXCO6h+aQ (HmqZX68ecLVIsA:ꕐ,8%RbUl| qͬnbF[ڻִ5]]+YUm.AI /'ۂnދ*78;n4K{[/0*ޤ030 x$_&ވl,9Ӹ_2\r0,p pB!3(1Wb%;9ypI wXZ~q$/yE62Lc*Ysf|b6gy嘝. z0?z Ek$33#-i~EHc:g6r;-j=kz5%g^:$]O8ԲKMSd^uf[}k]'0־2;lc3Ħ!-m–iO]6}l_o>+mk456̂;~5?b{"՞)SN6lp~m_8ăn /¥s8C.r9S򕳼.WyӼ69Γ4.( !F?:ғ3NЙs&@V:ֳs1WFл.f?5u_n;.ӽv;~;/?<3<#/S<3s API Documentation pyinotify/docstrings/pyinotify.PyinotifyError-class.html0000644000175000017500000002214611273644742023356 0ustar ookoiookoi pyinotify.PyinotifyError
Module pyinotify :: Class PyinotifyError
[hide private]
[frames] | no frames]

Class PyinotifyError

source code


Indicates exceptions raised by a Pyinotify class.

Instance Methods [hide private]

Inherited from exceptions.Exception: __init__, __new__

Inherited from exceptions.BaseException: __delattr__, __getattribute__, __getitem__, __getslice__, __reduce__, __repr__, __setattr__, __setstate__, __str__, __unicode__

Inherited from object: __format__, __hash__, __reduce_ex__, __sizeof__, __subclasshook__

Properties [hide private]

Inherited from exceptions.BaseException: args, message

Inherited from object: __class__

pyinotify/docstrings/uml_class_diagram_for_pyinotif_6.gif0000644000175000017500000000363011273644742023476 0ustar ookoiookoiGIF87aULBDĢ$"$tbddRTܲ<24rt\JL̪4&$lZ\亼D:< z|L:< TBD̢,"$jllVT䶴vtdNLԪ<.,tZ\쾼Ğ|bddVTܶD64vt\NL4*,侼D>< ~|$L>AA4(2Ci9aln[;,cfd , uꉩ NXPIA9@D OA.QFC R낵B*=F_`DUm׮ \o&n.¿ C Qt϶eQ_)6`,"| 3#cZ p~t !aΣ= DǺlE c'Z;9@X{ vO7\R5yEW{^xF3aC&x,AyύYYCP b*رF- :@ <̹G8x R-o$9PH | kWHľ"4`GApluCȔR4;n#2Gj>7;+>#/o+h_"7/CSꁧ" !D1R}*:ʪ*d+VMK#?z+b8?"x%VƅhMKVPt1hY*Hyd(>ܻ BC*XJ fN◿F 0AP*Z1k0"'&~iԾf#KdNFGy78Ԁw 3t MiZς6@idj+T۠lg@vMV5armvIܘ(JJБuz0Œz+c0H!ʀ](M1z0LgJӚ8ͩNwӚ @ PJԢHMRԦ:PT @;pyinotify/docstrings/pyinotify.ExcludeFilter-class.html0000644000175000017500000003045211273644742023110 0ustar ookoiookoi pyinotify.ExcludeFilter
Module pyinotify :: Class ExcludeFilter
[hide private]
[frames] | no frames]

Class ExcludeFilter

source code


ExcludeFilter is an exclusion filter.

Instance Methods [hide private]
 
__init__(self, arg_lst)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
source code
 
_load_patterns(self, dct) source code
 
_match(self, regex, path) source code
bool
__call__(self, path)
Returns: Return True if path has been matched and should be excluded, False otherwise.
source code

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, arg_lst)
(Constructor)

source code 

x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Parameters:
  • arg_lst (list or dict) - is either a list or dict of patterns: [pattern1, ..., patternn] {'filename1': (list1, listn), ...} where list1 is a list of patterns
Overrides: object.__init__

__call__(self, path)
(Call operator)

source code 
Parameters:
  • path (str) - Path to match against provided regexps.
Returns: bool
Return True if path has been matched and should be excluded, False otherwise.

pyinotify/docstrings/pyinotify.UnsupportedLibcVersionError-class.html0000644000175000017500000002635311273644742026060 0ustar ookoiookoi pyinotify.UnsupportedLibcVersionError
Module pyinotify :: Class UnsupportedLibcVersionError
[hide private]
[frames] | no frames]

Class UnsupportedLibcVersionError

source code


Raised on unsupported libc versions.

Instance Methods [hide private]
 
__init__(self, version)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
source code

Inherited from exceptions.Exception: __new__

Inherited from exceptions.BaseException: __delattr__, __getattribute__, __getitem__, __getslice__, __reduce__, __repr__, __setattr__, __setstate__, __str__, __unicode__

Inherited from object: __format__, __hash__, __reduce_ex__, __sizeof__, __subclasshook__

Properties [hide private]

Inherited from exceptions.BaseException: args, message

Inherited from object: __class__

Method Details [hide private]

__init__(self, version)
(Constructor)

source code 

x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Parameters:
  • version (string) - Current Libc version
Overrides: object.__init__

pyinotify/docstrings/uml_class_diagram_for_pyinotif_15.gif0000644000175000017500000000625311273644742023562 0ustar ookoiookoiGIF87aLBDĬ$"$tbddRTԪ<24rtܶ\JL4&$ ̄jllZ\D:<Ģz|쾼TJL侼4.,L:<̪ TBD,"$|bdlVTܲvt䶴dNL nlĞtZ\̢$ĴdVTԮD64vt\NL4*,  ԄnlD><~|<.,L>Z, }.ʈt8 \QP BT8w $ _wu].yfs-p < ٠'L@jBuz3& 1A(``@'h uց m*x@ Pp:&0CItp? 6Jb:f 4Ѡ&`:DQCR !@ E@u^nYA`9%:Ubr|9^2-Zy )Z((>u)V)S<̫*무I4뮼+k ŠB$FkJrT%TCi孷.m$FD:6yQK*V:+u v+(xiv_XȠ&6 ,@=Yi;عlP7(isQf P` d^eZq9ypEUq8o쯣{߇ =P1Ğ{5ӚF]RhT a!b뤳#<$jMD5h{0"-ލ-S5yΛO ,Ѓ@fB!yN3.bq닼^饲K"W%?.7O%٦(#o!g/t=>/9CO~F?/fXqX $ `7˗A"3E㟶bhB``F8 0,ѕ88hsŃzloϖB¬cY)<dmk3 0B7p=AR!MnItEB=чQkd0)=M⌓(CIVL*Wy[*Y,gIY.kl(s)]ޫB WFp_!".CՑoD"dD  P8A!;`|u[2gV.9dTǔEJC9s$[ h@'?xob%} Ή 29>rT|Yf6)@ n@% A#mС3":SN\44Iq} $(ء 7,S4qL%vGJ'8W0q4^T'_!F$0`=ֵdMh~g[\N"HO?h3JVp-X6p "d!f6T\*ge* _ȥՆPnBp.tpsoݯE5lsubX)k[wXiuN NA/V`Fغ~'[U&a~%ˊ,4;$-ZV>YȄV:V5];N.>3%ߣkQFLsk[[UĶn="ƨ|~/~t<>CK<ƒY-|pdP6)cPb!w$06g,t%xQsEctC[6brJ5*uZwU\A]hXdWqfiw '/{gD2xqxx =(8oB0z+cCAwV'9E{ V'[eB[AG7a|Z|x}gGa @u}%~'gX헇I8Xx؊h+0Xx؋ XxȘʸ،8Xxظ ؍8Xx蘎긎;pyinotify/docstrings/pyinotify.Event-class.html0000644000175000017500000002462711273644742021441 0ustar ookoiookoi pyinotify.Event
Module pyinotify :: Class Event
[hide private]
[frames] | no frames]

Class Event

source code


This class contains all the useful informations about the observed event. However, the presence of each field is not guaranteed and depends on the type of event. In effect, some fields are irrelevant for some kind of event (for example 'cookie' is meaningless for IN_CREATE whereas it is mandatory for IN_MOVE_TO).

The possible fields are:

  • wd (int): Watch Descriptor.
  • mask (int): Mask.
  • maskname (str): Readable event name.
  • path (str): path of the file or directory being watched.
  • name (str): Basename of the file or directory against which the event was raised in case where the watched directory is the parent directory. None if the event was raised on the watched item itself. This field is always provided even if the string is ''.
  • pathname (str): Concatenation of 'path' and 'name'.
  • src_pathname (str): Only present for IN_MOVED_TO events and only in the case where IN_MOVED_FROM events are watched too. Holds the source pathname from where pathname was moved from.
  • cookie (int): Cookie.
  • dir (bool): True if the event was raised against a directory.
Instance Methods [hide private]
 
__init__(self, raw)
Concretely, this is the raw event plus inferred infos.
source code

Inherited from _Event: __repr__

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, raw)
(Constructor)

source code 

Concretely, this is the raw event plus inferred infos.

Parameters:
  • dict_ - Set of attributes.
Overrides: object.__init__

pyinotify/docstrings/pyinotify._ProcessEvent-class.html0000644000175000017500000003255011273644743023132 0ustar ookoiookoi pyinotify._ProcessEvent
Module pyinotify :: Class _ProcessEvent
[hide private]
[frames] | no frames]

Class _ProcessEvent

source code


Abstract processing event class.

Instance Methods [hide private]
bool
__call__(self, event)
To behave like a functor the object must be callable.
source code
 
__repr__(self)
repr(x)
source code

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __init__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__call__(self, event)
(Call operator)

source code 

To behave like a functor the object must be callable. This method is a dispatch method. Its lookup order is:

  1. process_MASKNAME method
  2. process_FAMILY_NAME method
  3. otherwise calls process_default
Parameters:
  • event (Event object) - Event to be processed.
Returns: bool
By convention when used from the ProcessEvent class:
  • Returning False or None (default value) means keep on executing next chained functors (see chain.py example).
  • Returning True instead means do not execute next processing functions.
Raises:

__repr__(self)
(Representation operator)

source code 

repr(x)

Overrides: object.__repr__
(inherited documentation)

pyinotify/docstrings/pyinotify._Event-class.html0000644000175000017500000002704311273644743021574 0ustar ookoiookoi pyinotify._Event
Module pyinotify :: Class _Event
[hide private]
[frames] | no frames]

Class _Event

source code


Event structure, represent events raised by the system. This is the base class and should be subclassed.

Instance Methods [hide private]
 
__init__(self, dict_)
Attach attributes (contained in dict_) to self.
source code
str
__repr__(self)
Returns: Generic event string representation.
source code

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, dict_)
(Constructor)

source code 

Attach attributes (contained in dict_) to self.

Parameters:
  • dict_ (dictionary) - Set of attributes.
Overrides: object.__init__

__repr__(self)
(Representation operator)

source code 

repr(x)

Returns: str
Generic event string representation.
Overrides: object.__repr__

pyinotify/docstrings/toc.html0000644000175000017500000000235711273644742016005 0ustar ookoiookoi Table of Contents

Table of Contents


Everything

Modules

pyinotify

[hide private] pyinotify/docstrings/uml_class_diagram_for_pyinotif_14.gif0000644000175000017500000002064711273644742023564 0ustar ookoiookoiGIF87a[<.,lRLtbdbdĂLBD|vtdԦ\NLܲrdf\,&$d24BD\F<  |D:4z|,ԪlZ\ܾnl̞ĺTJDĢ|bT$"$L:4 D64TB<~|$dNDĖvljd4&$ĚdJDzlܪtZT̪|bdtD2,~trdԢ䲤vtjlNL\JL |24쾼̢L>4TF<Ԕ&$VTJL䶴,*$|Ğܮ|fdԦ64Ԯ侼vț\FDD:<̞TJL|b\L:< TBD$dNLzttZ\L>3ψu択 BO}D"(BmEiYBrv9J]*SrէH%*̔J~Qrک3V0]D1RѤVFJ|jXr%xIZ²-fiY֔"jm\纮V$tͫ^3cWu ,_:EMb:d'KZͬf7X,#hGKҚMb=KHu!D ڶUmwTBD#o/>$qȖZ"'sk:@C(,' =sRXa0EhBN4Vƺ .vx&ARi$D0C gierQU E ^ڥ&>=b+7$DW%A*X{ 'B1FٙUh{Le}!حudy`W 090c.HFmtN˳>πoNF;*}h' 4d͔6Ly4$ONzVjIM]d=tqAHV3\ՔP2岦 `A-لn\PA&j8@fpyub Ѐ Νn:]N,lZ}y+$R]#r8MxSpVgKR8v0r' ,PIa=tfkIB *AͬηBʼoПoÚARxߜ]1y 4l q6A%#N50:ǹ`y:]0.p$ f`@$iEbO/C ťDD߷OXB bTpCR*A I=s ;UuM0y2i? W1pJ|RVc҅0`)}yAԥ([tB5 {Gjf`ПbfS:6tc4Wc;cc=&rGSc6ut%0 *=uvՖyǗjGVےc0T͢UGvUX%CVdK-JV0d)(vqI2V/x-&D`R`0 /_T X,I 7v.HuFW\(2T`lvb|kH(."F#~ #HgzTYAFPsE`VFiֈT(>FgVi[Z{twqj7o62rtkh~k(F/+Bm5RzmVTxDtr*roŠp#p^p4Ph˘*]y=WL ruKW_˄_BMV(hx]he|#tW$`w'y6]{yz5z ȤzcuQ|xQ|~Wt&ҕtq}R7k8IGGbSv$SMI1t1A 7`HcHzcSLTP}9Xakقdky1Éd_UlaUR\s"Ruz㒗}jo-*..ɠ?bY% eCYAJ]کXƩ\ 6Tji=0pv /Zrԫ~1 *˒8ՙ&&2vqZC%ȶW*!a7ʍ @r@{Qh#z(~UmO:]@u1nut&#[e3T2nؚja`r~aF|캒n0P~ k$fSxd^rI &GqknImX u!@ XKNk$%vJ!1ҁ~эpuK vS7)K ۩$Iuwwn =jZxq AG$k6PB :0)ɷٝPiILYu)jj^YW ` N99xWO{;Z0)XjjwPnwt1D 0AʐJכ ( fY{z#yP!{E{8gIQQ0 $ \+" V}ڠ0 &"}Co ]v{Y[u$1<{IUjf8?Y2:()Q `Rb)FIEZ&P``Z `)@.  u0džU jn\uz[Wj*S_QQj{Aqۥh &@8U[ɦ`*JǪaaU Y@ GK|6[=$2eʴz@8wnIʂ\Ŧk8dnҖU]Z [z*._1|ںY"ȏl1HlWZj̵L\dmӈcuCϮ{i0}Sqs }88 =8'B1BQ9ѕC::7:3qc;;(5< @2S>s&>>L13?C??Q/C?#;b-d]֋rh$jnpׯ1tv}׊z|[׀=HQ؆m' ْؐ=ٔ]ٖ}٘8ٞ٠ڒ}- ڪڬڮڰ۲=۴]۶}۱ 03==]}ܾPnSۖ`]}ۼ ]ݨ 0 C۳`ǭݥ=߭*ۖMMm2ܯ ϝMv w0N)pܚ0 0)`߯O}0d^1^>+Pp=ߜp J:7195n} -L B p PM^0OJSZ. PXfNc/e~M LMR_>P>@SP|yn/{m 30 pM-0 ߟ+ p)`=R>ްn.^뺾}ݒ.=>N+ pX 03.؞ڎYԾ^8~^:kb.NN~KNs>_Q-# Zxznݭx^=ݾ} `]p !O;`-߬ ;q0-0EO0 )0 ".>#n0b0J ⫠dP%>`K ]/.m. 2Npf0X0_ sLN_D~ߕ0n_F?OG-vO>O 0T ^ɯȯ0 `ܫo t^@_0Z~AIA >QD-dHF=~RH%KBxaʔ$A W (eƝ h"\2RMVTU^划 O%P啠*;b͞EZmjF +*da]})FuX`p-Rb%ƍ^:-JX橆//`ΥM,Zj13]:ukڵE[l۽}ŭ[[޿g|ő7L0QZjx Rӫ>ӥʙ79M?X'83 -_p$֋Ρb/cﳔf#1)Aj@-ЄDNdA_#! ,` bl;dÑؓ HF eTE r,č}҃>~R n |+, c 2 3bmFLO4"OO,k6m Oo3iSO},I`B& | Aǟ;+*b(j.-4(Iahғj*>[ t,iq^Z‡Fߑu -i_S'>YcTB=Dh(fѢozRhGf1(Ðp$6hRy450DLRTխ»dZ5+щԤ6vUO%UG9 B"g5U̬8)Zi:-ѹ kٳ2 s1:y$M$I6ֶm1R|X`Iڲql4vWd*pk[-iSQxiK X\eT5iQ/LcVl(r 34qΚ ;ULANrc:3S`Ȏv3aZ,hN}p%u ' xHXixVI:eH[Gp|d?d"$FIbJ!C8Q#5 -KxbQcc=O픾*eȉaAQ 6+ kiu7h.t.۬J"!$\N|"N 98uVB +UVt.+1'bK82T^y2,ɋ8X~+ewlh^zXe.c}ol?J^ʲ/L}{@~|7χ~?}W׏yOt?~Gտ~?$@/*DTdt ;pyinotify/docstrings/uml_class_diagram_for_pyinotif_3.gif0000644000175000017500000001105411273644742023472 0ustar ookoiookoiGIF87ahLBDĤ$"$lfd̢dRT<24rtܲ \JL4&$|bdlZ\D:<亼̪z|̬jlL:< TBD,"$lVTvt䶴 dNL<.,ĞtZ\쾼Ԫ$Ģtbd̦dVTD64vtܶ  \NL4*,|fdD><侼~|nlL>iy-`s;v^Si&W"F |j&,c\=Kjp}sQ'O?_@ps @,d t&wrb (3 RtsGNpҙT;>@m0oF{jw%  xA> goSgH5qL*Ëc|5Ύ"؎( !Z_hş9AH "\L@^7I$%3gta$&C)O9wJ&J1-43dLyR0,ߴ'upDz ŸءSB}{oDl`FGe#:c*4_5 VjJK$;0!u IRQ,}zAR²W=jT Dlq]Vj:UzWDGKO hzS[4Gsy=L9E~'!!"nຊ5)G)@m`¾ժ eV%ZEa9)6ur%nL~-+Tx'JqduU`(4@Wušs!2,VP^GwK<#n7bbqT꣰j" LhGֲOC@ĂP){C8 hE+'oMk+ Vbo#8b'XزŮMe3g;n]ʋ^( шׅ5,A`fɎEISwʼPP:3=h" 8vt U}DږF-m0[LcMS94W;|ӠVfٕ15^E 7aTۄU Sz>:,~2%(xA]lQD` f^ ǰkYuuhE gDܮl)&}QiMęUpGq»oEtp]rBăKdY[&jrdW9E'|rP5Vo˩ϙeck Lq>c%tOR>ܬs]0rB++U8 rVZbg;M"y_m݁aw#؀[j/]F'Ks9:]v+UL=n*Ϩ{1KԦFx{[3D̦wӿZ7xLʾR/{Ғ.8wrCw|Rh1~Ȫ8NHPE绾P^#`i)D> "AyحyގT:1*#rD|Q'gI`g#QGygm`/?DjqG> "LRS|!@GGuvu`2848D:<1{(cׂʇuD|6Kkp  |A;0U{a$:a(\gwr/}qc4B$k7d>KAP~YeE=$e 0gd G~(5 LAQy5^rWGy2QOD)p%pe4 H^^tu& 8'uz^" ϓ-5_5rFfag9gGT#pÓOkXYsVTgNX$gg5#eE@6$0ȉۈE2Zr6bC6H*hAQoVt5}-1}/~Q  |7K@z艴77 4S/y"h&蒖&5)j>"U!P(T@$"gvv;AVJ!VfixgUE_}kp} Lvx٧BAЇF'(H8MGl.}X~H%fQHo91.CmrrAЊO(@bqS&)dOO8 Xeu=A=P?7Tֈ젍y Ynh$|'!d$i'?shprt4%u ?64 !$8 )%;0y =i9i?$<qnA SbhQy^Ɇa VUh@Qg_kpc"*".2dum9rilxM$OV$G$>d~;{*i)m6 L&cl՘芰8ɀ)sxij2؆q)H6ْ97gPPp GC>vrƎM~YL*I1fyZ> )*r򰑥j )ʍ( ,hjZu  :Ȋ.NƪvIJp|!8&J2*j2B#*"-B/:IbhdwI`H| F$Jyiڗ(ʪ3b pyinotify.Color
Module pyinotify :: Class Color
[hide private]
[frames] | no frames]

Class Color

source code


Internal class. Provide fancy colors used by string representations.

Instance Methods [hide private]

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __init__, __new__, __reduce__, __reduce_ex__, __repr__, __setattr__, __sizeof__, __str__, __subclasshook__

Static Methods [hide private]
 
punctuation(s)
Punctuation color.
source code
 
field_value(s)
Field value color.
source code
 
field_name(s)
Field name color.
source code
 
class_name(s)
Class name color.
source code
 
simple(s, color) source code
Class Variables [hide private]
  normal = '\x1b[0m'
  black = '\x1b[30m'
  red = '\x1b[31m'
  green = '\x1b[32m'
  yellow = '\x1b[33m'
  blue = '\x1b[34m'
  purple = '\x1b[35m'
  cyan = '\x1b[36m'
  bold = '\x1b[1m'
  uline = '\x1b[4m'
  blink = '\x1b[5m'
  invert = '\x1b[7m'
Properties [hide private]

Inherited from object: __class__

pyinotify/docstrings/toc-everything.html0000644000175000017500000002027711273644742020170 0ustar ookoiookoi Everything

Everything


All Classes

pyinotify.AsyncNotifier
pyinotify.ChainIfTrue
pyinotify.Color
pyinotify.Event
pyinotify.EventsCodes
pyinotify.ExcludeFilter
pyinotify.Notifier
pyinotify.NotifierError
pyinotify.PrintAllEvents
pyinotify.ProcessEvent
pyinotify.ProcessEventError
pyinotify.PyinotifyError
pyinotify.PyinotifyLogger
pyinotify.Stats
pyinotify.SysCtlINotify
pyinotify.ThreadedNotifier
pyinotify.UnicodeLogRecord
pyinotify.UnsupportedLibcVersionError
pyinotify.UnsupportedPythonVersionError
pyinotify.Watch
pyinotify.WatchManager
pyinotify.WatchManagerError

All Functions

pyinotify.command_line
pyinotify.compatibility_mode
pyinotify.glob0
pyinotify.glob1
pyinotify.has_magic
pyinotify.iglob
pyinotify.logger_init

All Variables

pyinotify.ALL_EVENTS
pyinotify.COMPATIBILITY_MODE
pyinotify.IN_ACCESS
pyinotify.IN_ATTRIB
pyinotify.IN_CLOSE_NOWRITE
pyinotify.IN_CLOSE_WRITE
pyinotify.IN_CREATE
pyinotify.IN_DELETE
pyinotify.IN_DELETE_SELF
pyinotify.IN_DONT_FOLLOW
pyinotify.IN_IGNORED
pyinotify.IN_ISDIR
pyinotify.IN_MASK_ADD
pyinotify.IN_MODIFY
pyinotify.IN_MOVED_FROM
pyinotify.IN_MOVED_TO
pyinotify.IN_MOVE_SELF
pyinotify.IN_ONESHOT
pyinotify.IN_ONLYDIR
pyinotify.IN_OPEN
pyinotify.IN_Q_OVERFLOW
pyinotify.IN_UNMOUNT
pyinotify.LIBC
pyinotify.LIBC_VERSION
pyinotify.MAGIC_CHECK
pyinotify.__author__
pyinotify.__package__
pyinotify.attrname
pyinotify.flagc
pyinotify.log
pyinotify.max_queued_events
pyinotify.max_user_instances
pyinotify.max_user_watches
pyinotify.name
pyinotify.val
pyinotify.valc

[hide private] pyinotify/docstrings/pyinotify.NotifierError-class.html0000644000175000017500000002612211273644742023141 0ustar ookoiookoi pyinotify.NotifierError
Module pyinotify :: Class NotifierError
[hide private]
[frames] | no frames]

Class NotifierError

source code


Notifier Exception. Raised on Notifier error.

Instance Methods [hide private]
 
__init__(self, err)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
source code

Inherited from exceptions.Exception: __new__

Inherited from exceptions.BaseException: __delattr__, __getattribute__, __getitem__, __getslice__, __reduce__, __repr__, __setattr__, __setstate__, __str__, __unicode__

Inherited from object: __format__, __hash__, __reduce_ex__, __sizeof__, __subclasshook__

Properties [hide private]

Inherited from exceptions.BaseException: args, message

Inherited from object: __class__

Method Details [hide private]

__init__(self, err)
(Constructor)

source code 

x.__init__(...) initializes x; see x.__class__.__doc__ for signature

Parameters:
  • err (string) - Exception string's description.
Overrides: object.__init__

pyinotify/docstrings/uml_class_diagram_for_pyinotif_26.gif0000644000175000017500000001300711273644743023560 0ustar ookoiookoiGIF87a`llRL4.,ĢtbdĂ<bd"$LB<ܦrdBDl$T.,Ė2,\NL  ~|̪,&$RL|f\~t\F<ܶܒĚD6,lZ\Ԧ*,,|\*,TJDvl><~t<2,$ 4*$t^TĆfd&$Ԭ|Ğ.,VTvt̴nl ~| Ď&$64Ԧ.,̞^\vtFD̖NLܜ><̦ԮLBD\FDD64Ԧ̞ TBDL:Y3iF/B[o' |Z),ă1ܰSƗ={e,$P@;,0,4l8\(G1@klqχ MF#J/-cOW-[RG\5Ɓu-<-hf9-t׭snk|uޛm 8p[֦itSmUIqe@%aW1C!M @y#; wgB9F9R@^4g̓QU*8'!3_^" 2*u#-3'YP0F՟ T MRpNwaVĠ!ai(fšĂ EPqQ_4Dʓ&k*Jj7WcKu)~$'0mXcG-L$'MRJcBhGkM_/Wd8|crL0sk̳6%{ܕ,`d4ܔ<_&0<[ݓ[!!KޫtW(Hz/{G(Bͯ~{^ 诀'@NC!3AP†(Q`Ä7\:B G GTC p,F_! I~ sAQj`A8 y##` Y,`` ϫ GXβ1)Wwƅ0+ ,a^4xmv,gùsf3{=W~>.mAz>4_2*}4*IHȴ7N{ӠA}eRԚր{հgMZָε'NMbNf'׿IMj[ˆvs2ml{F}n]s>=w ;1AB͕okCܾw agAw |6vpe<7{?_ƽqDX P"a6 L S@CJ(Bs -6n!<*8cg $7nރr0=5FQ<װ{FG~aЮv߻ _>ugYA p' 7BNL0m$P<^`#A(E"0xWRuqg X*8Qc']R?>@/~; |0#?R>KawaODFC=L` l@v {&(}r'~rrV` p 1grU.`& /t-N|Gt ,HzQ-q7&{@XBHJHmFx#KNhP(XUW^؄[]XacHQhgiJȆmooL}j(sxc onT` P <@ P_0%^k3P_ < `@0Zq%'`  5 ?` M8P_XX 5P_D dQi%P[ 0 Ս$  @c Q` hf &"Y`Q ' `F`R `Ǡ ~ vaQ @X_ m Y D&b"0`̀/p eר %~0[0%)bq ŀ RR/pA `!b0V 21 Ҡ%P[ ~`Q z oQ_hI7c;%0/ `9) k`0 iX &c@6BA VY_oPqvI @1qdId!a ٍ e5dP&e-1 pP{9 IUveYe[f-Qp ϐ F6fX6fPf!/'it`@a, Jy͐ (" iD D``E.pˀ,*π@i0 \  i;IfgpF1a,V tpQ 8^*$'Zg[ DjJgC15Z_D@^  kZYp@#VeږR71 Z_Y*` ih QY R 5 Z U%Z_q:ј\С ~a;Q l0坏ŞTӪڞZOv蚮V檮ZjVipi3j v10j˰{0)Ίgp3@ p8'0;l*;jPj8&1n,/)˳#:@>4CKPKFϠV۴UmR`Rx.\hek6.pKmj˴=l6@s lz9o&-AxlFl灻Vmw\kKl, Z`F̖A>  ;LxoC}-'lp6yÆ mpzֵ͆L`0ll[t0l ƫnwՆ,6qvx  :Pm[l]+l0z0y[2nK萾^ K|Kr<(sHx+K!7r%{tf@`ˁBGtF7s5xt* uP;lkyklx{,?gt G|{xw0׀x[|vmWl˻Xu7{_}pp ;{wywig7wqglA\C\lp B0C\ >[l|"l>+N(~&1-n"53=n Gqc!L"`!˘Z\Xb>d^ˆ1ajhnpr>t^v~x};pyinotify/docstrings/pyinotify.Watch-class.html0000644000175000017500000002472211273644742021422 0ustar ookoiookoi pyinotify.Watch
Module pyinotify :: Class Watch
[hide private]
[frames] | no frames]

Class Watch

source code


Represent a watch, i.e. a file or directory being watched.

Instance Methods [hide private]
 
__init__(self, **keys)
Initializations.
source code
str
__repr__(self)
Returns: String representation.
source code

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Properties [hide private]

Inherited from object: __class__

Method Details [hide private]

__init__(self, **keys)
(Constructor)

source code 

Initializations.

Parameters:
  • wd (int) - Watch descriptor.
  • path (str) - Path of the file or directory being watched.
  • mask (int) - Mask.
  • proc_fun () - Processing callable object.
  • auto_add (bool) - Automatically add watches on new directories.
Overrides: object.__init__

__repr__(self)
(Representation operator)

source code 

repr(x)

Returns: str
String representation.
Overrides: object.__repr__

pyinotify/ChangeLog_old0000644000175000017500000002360411042100440014531 0ustar ookoiookoi2008-03-31 ookoi * ChangeLog is now maintained directly with git: See http://git.dbzteam.org/?p=pyinotify.git;a=log;h=HEAD 2008-03-24 ookoi * Simulate IN_CREATE events on mkdir -p /d1/d2/[...]. Contributed by Thomas Kiley (tkiley@cs.uml.edu). * Notifier.loop() accepts a read_freq parameter. * Can detach and daemonize Notifier instances. * Delegates initialization to my_init(*kargs) when a subclass of ProcessEvent is instanciated. * Provides processing class and new option -s for displaying statistics about received events. * Implements simplified watch of transient files. * select.Poll timeout's value changed to None when called from Notifier and set to 10s when called from ThreadedNotifier. * Removed useless locking stuff from Watch. * Removed all trailing whitespaces. * Notifier provides a loop() method. * ProcessEvent instances can be chained. * Events names are directly accessible at pyinotify's scope. * Optionnaly load psyco. * New attribute 'pathname' in Event class. * print statements removed. Use logging module for debug messages and errors. * Implemented better representation __repr__ for classes Event and Watch. * Merged all .py files into pyinotify.py * Namespace limited to pyinotify. * Use ctypes instead of C code. 2007-07-10 ookoi * License of pyinotify 0.7.1 updated: GPLv2 or later. pyinotify-dev still remains GPLv2 only. * version 0.7.1 released. 2007-06-26 ookoi * src/pyinotify/pyinotify.py: reworking of EventsCodes (contributed by Darryl Dixon - darryl.dixon@winterhouseconsulting.com). * src/pyinotify/pyinotify.py: new -e command line option (contributed by Darryl Dixon - darryl.dixon@winterhouseconsulting.com). 2007-06-17 ookoi * src/pyinotify/inotify_syscalls.h: support hppa and mc68000. (submitted by Mikhail Gusarov - dottedmag@dottedmag.net). 2007-02-17 ookoi * version 0.7.0 released. * src/example/close.py: fix import statement. * src/pyinotify/pyinotify.py: raise OSError when inotify_init() fails (idea contributed by Mattias Wadman - mattias.wadman@gmail.com). * src/pyinotify/pyinotify.py: checks exception on polling (contributed by Mattias Wadman - mattias.wadman@gmail.com). * src/pyinotify/pyinotify.py: add_watch: by default do not make globbing (contributed by Mattias Wadman - mattias.wadman@gmail.com). * src/pyinotify/pyinotify.py: print errors only when verbose mode is set. * src/pyinotify/iglob.py: fix compatibility with Python 2.3 (contributed by Robin Wittler - r.wittler@buetow.org). 2006-11-03 ookoi * version 0.6.3 released. 2006-10-25 ookoi * src/pyinotify/pyinotify.py: fix mkdir -p foo/bar/bar.txt with auto_add (fix contributed by Will Muldrew - will.muldrew@gmail.com). 2006-09-04 ookoi * version 0.6.2 released. * src/pyinotify/iglob.py: added. * src/pyinotify/pyinotify.py: add_watch supports unix pathname pattern expansion (see http://www.python.org/doc/lib/module-glob.html). 2006-07-20 ookoi * version 0.6.1 released. * src/examples/pyinotifyfs/*: added. 2006-04-30 ookoi * version 0.6.0 released. * src/pyinotify/pyinotify.py: replace select by poll. * src/pyinotify/pyinotify.py: get event queue size (call ioctl). 2006-04-24 ookoi * src/tests/colorize.py: added. * src/tests/coverage.py: added. * src/tests/testcoverage.py: added. 2006-04-09 ookoi * src/pyinotify/pyinotify.py: function _print_err added. * src/pyinotify/pyinotify.py: new command lines option -a. * src/examples/rec.py: deprecated. * src/pyinotify/pyinotify.py: add_watch, update_watch, support option auto_add. * src/pyinotify/pyinotify.py: DEBUG renamed to VERBOSE. 2006-04-06 ookoi * src/tests/TestThreadedNotifier.py: updated. * src/tests/TestThreadedINotify.py: renamed to TestThreadedNotifier.py 2006-04-05 ookoi * src/pyinotify/pyinotify.py: new command lines options (-v, -r). * src/pyinotify/pyinotify.py: Watch, WatchManager added. * src/pyinotify/pyinotify.py: NotifierError, Notifier, ThreadedNotifier added. * src/pyinotify/pyinotify.py: _ProcessEvent, _SysProcessEvent added, ProcessEvent modified. * src/pyinotify/pyinotify.py: ProcessEventException renamed to ProcessEventError. * src/pyinotify/pyinotify.py: _Event, _RawEvent added, Event modified. * src/pyinotify/pyinotify.py: Queue renamed to _Queue. * src/pyinotify/pyinotify.py: support IN_ONLYDIR, IN_DONT_FOLLOW, IN_MASK_ADD. * src/pyinotify/pyinotify.py: SimpleINotify, ThreadedINotify, INotifyException removed. * src/pyinotify/pyinotify.py: major rewrite. 2006-03-30 ookoi * src/pyinotify/pyinotify.py: support for EventsCodes.IN_MOVE_SELF flag added. 2006-03-29 ookoi * version 0.5.2 released. * src/pyinotify/inotify_syscalls.h: defines for mips, sh64, frv and parisc added. 2006-03-27 ookoi * version 0.5.1 released. 2006-03-16 ookoi * src/pyinotify/inotify.py: olds inotify's paths supported. * src/pyinotify/pyinotify.py: event_check accepts a timeout parameter (submitted by Hans Ulrich Niedermann - debian@n-dimensional.de). 2006-03-02 ookoi * version 0.5.0 released. 2006-02-22 ookoi * src/pyinotify-demo.py: re-merged with src/pyinotify/pyinotify.py * src/pyinotify/__init__.py: now empty. 2006-02-16 ookoi * src/pyinotify/inotify.py: documented. 2006-02-13 ookoi * src/tests/testThreadedINotify.py: renamed to TestThreadedINotify.py. * src/tests/TestProcINotify.py: added. * src/pyinotify/inotify.py: added. * src/pyinotify/inotify_wrap.c: renamed to inotify.c. 2006-02-09 ookoi * version 0.4.5 released. * src/pyinotify/pyinotify.py: separated in src/pyinotify/pyinotify.py and src/pyinotify-demo.py. (proposed by Hans Ulrich Niedermann - debian@n-dimensional.de) * Makefile: new clean rule. (Hans Ulrich Niedermann - debian@n-dimensional.de) * src/inotify* src/pyinotify.py: moved to src/pyinotify/ (proposed by Hans Ulrich Niedermann - debian@n-dimensional.de) 2006-02-09 ookoi * version 0.4.4 released. * setup.py: install_lib cmd removes old components. 2006-02-08 ookoi * version 0.4.3 released. * src/tests/testThreadedINotify.py: can directly import pyinotify. * src/examples/*.py: can directly import pyinotify. 2006-02-06 ookoi * version 0.4.2 released. * setup.py: installs files in a subdir. * src/pyinotify.py: defines __all__ 2006-02-06 ookoi * version 0.4.1 released. * examples/, tests/: moved in src/ 2006-02-05 ookoi * version 0.4.0 released. 2006-02-03 ookoi * tests/simple.py, tests/generate.sh, tests/threaded.py: removed. * tests/testThreadedINotify.py: added. 2006-02-02 ookoi * src/pyinotify.py: update_watch, rm_watch only accept wd or list of wd. * src/pyinotify.py: add_watch, update_watch, rm_watch return dict. 2006-01-12 ookoi * version 0.3.3 released. 2006-01-09 ookoi * src/pyinotify.py: fix add watch on symbolic link with rec=True. 2006-01-04 ookoi * version 0.3.2 released. * examples/rec.py, examples/threaded_rec.py: added. 2005-12-30 ookoi * version 0.3.1 released. * src/pyinotify.py: class attribute 'length' removed from Event. 2005-12-28 ookoi * version 0.3.0 released. * src/inotify_wrap.c: doesn't wrap original exception. (thanks to Frdric PICA) * src/pyinotify.py: update_watch(), rm_watch(), add_watch() updated in SimpleINotify, rm_watch() returns list of wd removed. * src/pyinotify.py: get_wd(), get_path() added in SimpleINotify. 2005-12-26 ookoi * version 0.2.7 released * src/pyinotify.py: removes trailing null characters in Event.name (thanks to Frdric PICA) 2005-12-26 ookoi * version 0.2.6 released. * setup.py: supports commands build, clean, sdist and install. * autoconf, automake stuffs removed. 2005-12-26 ookoi * version 0.2.5 released. * src/pyinotify.py: not directly check events against IN_ISDIR, member isdir added in Event. (thanks to Radoslaw Stachowiak) * src/inotify_wrap.c, src/inotify_syscalls.c: added. * src/: swig stuff removed. 2005-12-24 ookoi * version 0.2.4 released. * pyinotify.py: _wd, _mask, _cookie, _length, _path, _name, members of class Event, renamed in wd, mask, cookie, length, path, name. 2005-12-24 ookoi * config/, tests/, examples/: autopath.py added. * src/*_tests.py: moved in tests/. * tests/: added. * src/*_example.py: moved in examples/. * examples/: added. 2005-12-21 ookoi * version 0.2.3 released. * close_example.py: added. * pyinotify.py: support processing methods like process_IN_CLOSE. 2005-12-20 ookoi * version 0.2.2 released. * pyinotify.py: EventsCodes.IN_CLOSE removed. * pyinotify.py, simple_tests.py, threaded_tests.py: EventsCodes.IN_ALL_EVENTS renammed to EventsCodes.ALL_EVENTS. 2005-12-20 ookoi * version 0.2.1 released. * pyinotify.py, simple_tests.py, threaded_tests.py: all occurrences of 0xffffffff replaced by EventsCodes.IN_ALL_EVENTS. (thanks to Mohamed Lrhazi) * pyinotify.py: EventsCodes.IN_ALL_EVENTS added. 2005-12-16 ookoi * version 0.2.0 released. * simple_example.py, threaded_example.py, process_example.py: added. * example.py: removed. * simple_tests.py, threaded_tests.py: added. * tests.py: removed. * pyinotify.py: INotify replaced by SimpleINotify and ThreadedINotify (thanks to Mark Williamson - mark.williamson@cl.cam.ac.uk for the idea). * pyinotify.py: removes Queue's size limitation.