summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Martini <seb@dbzteam.org>2010-09-15 22:06:34 +0200
committerSebastien Martini <seb@dbzteam.org>2010-09-15 22:06:34 +0200
commit4c84343ee0d6bcecb44d1fa081bebd65d45e3f57 (patch)
treeb8f358c19f92dcda423d3d6b65a880dc2fae97df
parent300fb3f5333d7ffbc5bcef8ff89cb24bf2ace20c (diff)
downloadpyinotify-4c84343ee0d6bcecb44d1fa081bebd65d45e3f57.tar.gz
Generated documentation 0.9.0+.
-rw-r--r--ACKS35
-rw-r--r--COPYING19
-rw-r--r--ChangeLog_old410
-rw-r--r--Makefile (renamed from python2/Makefile)3
-rw-r--r--NEWS_old277
-rw-r--r--README33
-rw-r--r--api-objects.txt (renamed from python2/docstrings/api-objects.txt)0
-rw-r--r--class-tree.html (renamed from python2/docstrings/class-tree.html)2
-rw-r--r--crarr.png (renamed from python2/docstrings/crarr.png)bin340 -> 340 bytes
-rw-r--r--epydoc.css (renamed from python2/docstrings/epydoc.css)0
-rw-r--r--epydoc.js (renamed from python2/docstrings/epydoc.js)0
-rw-r--r--frames.html (renamed from python2/docstrings/frames.html)0
-rw-r--r--help.html (renamed from python2/docstrings/help.html)2
-rw-r--r--identifier-index.html (renamed from python2/docstrings/identifier-index.html)2
-rw-r--r--[l---------]index.html18
-rw-r--r--module-tree.html (renamed from python2/docstrings/module-tree.html)2
-rw-r--r--pyinotify-module.html (renamed from python2/docstrings/pyinotify-module.html)4
-rw-r--r--pyinotify-pysrc.html (renamed from python2/docstrings/pyinotify-pysrc.html)2
-rw-r--r--pyinotify.AsyncNotifier-class.html (renamed from python2/docstrings/pyinotify.AsyncNotifier-class.html)20
-rw-r--r--pyinotify.ChainIfTrue-class.html (renamed from python2/docstrings/pyinotify.ChainIfTrue-class.html)2
-rw-r--r--pyinotify.ColoredOutputFormat-class.html (renamed from python2/docstrings/pyinotify.ColoredOutputFormat-class.html)2
-rw-r--r--pyinotify.Event-class.html (renamed from python2/docstrings/pyinotify.Event-class.html)2
-rw-r--r--pyinotify.EventsCodes-class.html (renamed from python2/docstrings/pyinotify.EventsCodes-class.html)2
-rw-r--r--pyinotify.ExcludeFilter-class.html (renamed from python2/docstrings/pyinotify.ExcludeFilter-class.html)2
-rw-r--r--pyinotify.Notifier-class.html (renamed from python2/docstrings/pyinotify.Notifier-class.html)2
-rw-r--r--pyinotify.NotifierError-class.html (renamed from python2/docstrings/pyinotify.NotifierError-class.html)6
-rw-r--r--pyinotify.PrintAllEvents-class.html (renamed from python2/docstrings/pyinotify.PrintAllEvents-class.html)2
-rw-r--r--pyinotify.ProcessEvent-class.html (renamed from python2/docstrings/pyinotify.ProcessEvent-class.html)28
-rw-r--r--pyinotify.ProcessEventError-class.html (renamed from python2/docstrings/pyinotify.ProcessEventError-class.html)6
-rw-r--r--pyinotify.PyinotifyError-class.html (renamed from python2/docstrings/pyinotify.PyinotifyError-class.html)40
-rw-r--r--pyinotify.PyinotifyLogger-class.html (renamed from python2/docstrings/pyinotify.PyinotifyLogger-class.html)2
-rw-r--r--pyinotify.RawOutputFormat-class.html (renamed from python2/docstrings/pyinotify.RawOutputFormat-class.html)2
-rw-r--r--pyinotify.Stats-class.html (renamed from python2/docstrings/pyinotify.Stats-class.html)2
-rw-r--r--pyinotify.SysCtlINotify-class.html (renamed from python2/docstrings/pyinotify.SysCtlINotify-class.html)2
-rw-r--r--pyinotify.ThreadedNotifier-class.html (renamed from python2/docstrings/pyinotify.ThreadedNotifier-class.html)2
-rw-r--r--pyinotify.UnicodeLogRecord-class.html (renamed from python2/docstrings/pyinotify.UnicodeLogRecord-class.html)2
-rw-r--r--pyinotify.UnsupportedLibcVersionError-class.html (renamed from python2/docstrings/pyinotify.UnsupportedLibcVersionError-class.html)6
-rw-r--r--pyinotify.UnsupportedPythonVersionError-class.html (renamed from python2/docstrings/pyinotify.UnsupportedPythonVersionError-class.html)6
-rw-r--r--pyinotify.Watch-class.html (renamed from python2/docstrings/pyinotify.Watch-class.html)2
-rw-r--r--pyinotify.WatchManager-class.html (renamed from python2/docstrings/pyinotify.WatchManager-class.html)6
-rw-r--r--pyinotify.WatchManagerError-class.html (renamed from python2/docstrings/pyinotify.WatchManagerError-class.html)2
-rw-r--r--pyinotify._Event-class.html (renamed from python2/docstrings/pyinotify._Event-class.html)2
-rw-r--r--pyinotify._ProcessEvent-class.html (renamed from python2/docstrings/pyinotify._ProcessEvent-class.html)18
-rw-r--r--pyinotify._RawEvent-class.html (renamed from python2/docstrings/pyinotify._RawEvent-class.html)2
-rw-r--r--pyinotify._SysProcessEvent-class.html (renamed from python2/docstrings/pyinotify._SysProcessEvent-class.html)2
-rwxr-xr-xpyinotify.py (renamed from python2/pyinotify.py)2
-rw-r--r--python2/docstrings/index.html17
-rw-r--r--python2/docstrings/uml_class_diagram_for_pyinotif_10.gifbin9570 -> 0 bytes
-rw-r--r--python2/docstrings/uml_class_diagram_for_pyinotif_12.gifbin14803 -> 0 bytes
-rw-r--r--python2/docstrings/uml_class_diagram_for_pyinotif_22.gifbin11290 -> 0 bytes
-rw-r--r--python2/docstrings/uml_class_diagram_for_pyinotif_27.gifbin5602 -> 0 bytes
-rwxr-xr-xpython2/examples/autocompile.py58
-rw-r--r--python2/examples/chain.py40
-rw-r--r--python2/examples/coalesce.py35
-rw-r--r--python2/examples/daemon.py48
-rw-r--r--python2/examples/exclude.lst12
-rw-r--r--python2/examples/exclude.py30
-rw-r--r--python2/examples/loop.py13
-rw-r--r--python2/examples/not_quiet.py36
-rw-r--r--python2/examples/stats.py23
-rw-r--r--python2/examples/stats_threaded.py46
-rw-r--r--python2/examples/transient_file.py26
-rwxr-xr-xpython2/examples/transient_file.sh8
-rw-r--r--python2/examples/tutorial_asyncnotifier.py21
-rw-r--r--python2/examples/tutorial_notifier.py21
-rw-r--r--python2/examples/tutorial_threadednotifier.py25
-rw-r--r--python2/examples/unicode.py22
-rw-r--r--python3/Makefile14
-rwxr-xr-xpython3/pyinotify.py2141
-rw-r--r--redirect.html (renamed from python2/docstrings/redirect.html)0
-rwxr-xr-xsetup.py54
-rw-r--r--toc-everything.html (renamed from python2/docstrings/toc-everything.html)0
-rw-r--r--toc-pyinotify-module.html (renamed from python2/docstrings/toc-pyinotify-module.html)0
-rw-r--r--toc.html (renamed from python2/docstrings/toc.html)0
-rw-r--r--uml_class_diagram_for_pyinotif.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif.gif)bin24874 -> 24874 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_10.gifbin0 -> 9559 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_11.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_11.gif)bin8468 -> 8468 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_12.gifbin0 -> 14507 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_13.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_13.gif)bin16797 -> 16797 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_14.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_14.gif)bin5748 -> 5748 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_15.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_15.gif)bin8621 -> 8621 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_16.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_16.gif)bin3284 -> 3284 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_17.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_17.gif)bin15622 -> 15622 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_18.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_18.gif)bin5528 -> 5528 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_19.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_19.gif)bin9480 -> 9480 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_2.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_2.gif)bin7632 -> 7632 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_20.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_20.gif)bin9342 -> 9342 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_21.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_21.gif)bin2880 -> 2880 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_22.gifbin0 -> 11235 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_23.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_23.gif)bin7975 -> 7975 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_24.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_24.gif)bin3820 -> 3820 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_25.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_25.gif)bin2946 -> 2946 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_26.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_26.gif)bin6832 -> 6832 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_27.gifbin0 -> 5587 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_28.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_28.gif)bin4010 -> 4010 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_29.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_29.gif)bin11495 -> 11495 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_3.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_3.gif)bin5527 -> 5527 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_4.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_4.gif)bin3178 -> 3178 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_5.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_5.gif)bin6391 -> 6391 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_6.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_6.gif)bin1992 -> 1992 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_7.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_7.gif)bin10234 -> 10234 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_8.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_8.gif)bin8310 -> 8310 bytes
-rw-r--r--uml_class_diagram_for_pyinotif_9.gif (renamed from python2/docstrings/uml_class_diagram_for_pyinotif_9.gif)bin7831 -> 7831 bytes
103 files changed, 112 insertions, 3561 deletions
diff --git a/ACKS b/ACKS
deleted file mode 100644
index 6645f06..0000000
--- a/ACKS
+++ /dev/null
@@ -1,35 +0,0 @@
-Acknowledgements
-----------------
-
-Andrey Rahmatullin wrar@altlinux.org
-Colin Blackburn colin@ximenes.org.uk
-cruxic@gmail.com
-Darryl Dixon darryl.dixon@winterhouseconsulting.com
-Doug Fort dougfort@dougfort.com
-Facundo Batista facundo@canonical.com
-forest@alittletooquiet.net
-Frédéric Pica frederic.pica@gmail.com
-Guido Trotter ultrotter@quaqua.net
-Guillermo Gonzalez guillermo.gonzalez@canonical.com
-Hans Ulrich Niedermann debian@n-dimensional.de
-Henri Tuhola
-John Feuerstein john@feurix.com
-Jonathan Ballet jonathan.ballet@securactive.net
-knurxs@gmx.de
-Linda Octalina linda_octa@yahoo.com
-Mark Williamson mark.williamson@cl.cam.ac.uk
-Matt Brown deadguysfrom@gmail.com
-Matteo Lanza matteo.lanza@gmail.com
-Mattias Wadman mattias.wadman@gmail.com
-Matthew Webber Matthew.Webber@diamond.ac.uk
-Mikhail Gusarov dottedmag@dottedmag.net
-Mohamed Lrhazi lrhazi@gmail.com
-prologic@shortcircuit.net.au
-Radoslaw Stachowiak rstachowiak@gmail.com
-Robin Wittler r.wittler@buetow.org, robin.wittler@credativ.de
-stromnov@gmail.com
-Terje Røsten terje.rosten@ntnu.no
-Thomas Kiley tkiley@cs.uml.edu
-Will Muldrew will.muldrew@gmail.com
-
-And every anonymous or forgotten contributor
diff --git a/COPYING b/COPYING
deleted file mode 100644
index edb195e..0000000
--- a/COPYING
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2010 Sebastien Martini <seb@dbzteam.org>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/ChangeLog_old b/ChangeLog_old
deleted file mode 100644
index e5cbc4f..0000000
--- a/ChangeLog_old
+++ /dev/null
@@ -1,410 +0,0 @@
-2008-03-31 ookoi <ookoi@mars>
-
- * ChangeLog is now maintained directly with git:
- See http://git.dbzteam.org/?p=pyinotify.git;a=log;h=HEAD
-
-2008-03-24 ookoi <ookoi@sundae>
-
- * 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 <ookoi@sundae>
-
- * 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 <ookoi@sundae>
-
- * 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 <ookoi@mars>
-
- * src/pyinotify/inotify_syscalls.h: support hppa and mc68000.
- (submitted by Mikhail Gusarov - dottedmag@dottedmag.net).
-
-2007-02-17 ookoi <ookoi@mars>
-
- * 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 <ookoi@mars>
-
- * version 0.6.3 released.
-
-2006-10-25 ookoi <ookoi@mars>
-
- * 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 <ookoi@mars>
-
- * 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 <ookoi@mars>
-
- * version 0.6.1 released.
-
- * src/examples/pyinotifyfs/*: added.
-
-2006-04-30 ookoi <ookoi@mars>
-
- * 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 <ookoi@chocopops>
-
- * src/tests/colorize.py: added.
-
- * src/tests/coverage.py: added.
-
- * src/tests/testcoverage.py: added.
-
-2006-04-09 ookoi <ookoi@chocopops>
-
- * 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 <ookoi@chocopops>
-
- * src/tests/TestThreadedNotifier.py: updated.
-
- * src/tests/TestThreadedINotify.py: renamed to TestThreadedNotifier.py
-
-2006-04-05 ookoi <ookoi@chocopops>
-
- * 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 <ookoi@X2>
-
- * src/pyinotify/pyinotify.py: support for EventsCodes.IN_MOVE_SELF
- flag added.
-
-2006-03-29 ookoi <ookoi@X2>
-
- * version 0.5.2 released.
-
- * src/pyinotify/inotify_syscalls.h: defines for mips, sh64,
- frv and parisc added.
-
-2006-03-27 ookoi <ookoi@X2>
-
- * version 0.5.1 released.
-
-2006-03-16 ookoi <ookoi@X2>
-
- * 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 <ookoi@X2>
-
- * version 0.5.0 released.
-
-2006-02-22 ookoi <ookoi@X2>
-
- * src/pyinotify-demo.py: re-merged with src/pyinotify/pyinotify.py
-
- * src/pyinotify/__init__.py: now empty.
-
-2006-02-16 ookoi <ookoi@X2>
-
- * src/pyinotify/inotify.py: documented.
-
-2006-02-13 ookoi <ookoi@X2>
-
- * 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 <ookoi@X2>
-
- * 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 <ookoi@X2>
-
- * version 0.4.4 released.
-
- * setup.py: install_lib cmd removes old components.
-
-2006-02-08 ookoi <ookoi@X2>
-
- * version 0.4.3 released.
-
- * src/tests/testThreadedINotify.py: can directly import pyinotify.
-
- * src/examples/*.py: can directly import pyinotify.
-
-2006-02-06 ookoi <ookoi@X2>
-
- * version 0.4.2 released.
-
- * setup.py: installs files in a subdir.
-
- * src/pyinotify.py: defines __all__
-
-2006-02-06 ookoi <ookoi@X2>
-
- * version 0.4.1 released.
-
- * examples/, tests/: moved in src/
-
-2006-02-05 ookoi <ookoi@X2>
-
- * version 0.4.0 released.
-
-2006-02-03 ookoi <ookoi@X2>
-
- * tests/simple.py, tests/generate.sh, tests/threaded.py: removed.
-
- * tests/testThreadedINotify.py: added.
-
-2006-02-02 ookoi <ookoi@X2>
-
- * 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 <ookoi@X2>
-
- * version 0.3.3 released.
-
-2006-01-09 ookoi <ookoi@X2>
-
- * src/pyinotify.py: fix add watch on symbolic link with rec=True.
-
-2006-01-04 ookoi <ookoi@X2>
-
- * version 0.3.2 released.
-
- * examples/rec.py, examples/threaded_rec.py: added.
-
-2005-12-30 ookoi <ookoi@X2>
-
- * version 0.3.1 released.
-
- * src/pyinotify.py: class attribute 'length' removed from Event.
-
-2005-12-28 ookoi <ookoi@X2>
-
- * version 0.3.0 released.
-
- * src/inotify_wrap.c: doesn't wrap original exception. (thanks to
- Frédéric 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 <ookoi@X2>
-
- * version 0.2.7 released
-
- * src/pyinotify.py: removes trailing null characters in Event.name
- (thanks to Frédéric PICA)
-
-2005-12-26 ookoi <ookoi@X2>
-
- * version 0.2.6 released.
-
- * setup.py: supports commands build, clean, sdist and install.
-
- * autoconf, automake stuffs removed.
-
-2005-12-26 ookoi <ookoi@X2>
-
- * 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 <ookoi@X2>
-
- * 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 <ookoi@X2>
-
- * 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 <ookoi@X2>
-
- * version 0.2.3 released.
-
- * close_example.py: added.
-
- * pyinotify.py: support processing methods like process_IN_CLOSE.
-
-2005-12-20 ookoi <ookoi@X2>
-
- * 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 <ookoi@X2>
-
- * 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 <ookoi@X2>
-
- * 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.
-
diff --git a/python2/Makefile b/Makefile
index 7667585..faef521 100644
--- a/python2/Makefile
+++ b/Makefile
@@ -1,8 +1,7 @@
EPYDOC=epydoc
-DSTDOC=docstrings
doc: clean-doc
- $(EPYDOC) --html --graph=all -v -o $(DSTDOC) pyinotify.py
+ $(EPYDOC) --html --graph=all -v -o . pyinotify.py
clean-doc:
rm -rf $(DSTDOC)
diff --git a/NEWS_old b/NEWS_old
deleted file mode 100644
index a154fe9..0000000
--- a/NEWS_old
+++ /dev/null
@@ -1,277 +0,0 @@
-Changes 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.
-
-
diff --git a/README b/README
deleted file mode 100644
index d8e4330..0000000
--- a/README
+++ /dev/null
@@ -1,33 +0,0 @@
-==== Pyinotify ====
-
-License: MIT License
-Project URL: http://trac.dbzteam.org/pyinotify/
-
-
-==== Dependencies ====
-
-- Linux >= 2.6.13
-- Python (CPython) >= 2.4
-- Libc with inotify support (usually version >= 2.4 for GLibc)
-- ctypes (part of the standard library since Python 2.5)
-- Epydoc (optional, used to generate html documentation from docstrings)
-
-
-==== Install ====
-
--> Install from the distributed tarball
- # Choose your Python interpreter: either python, python2.6, python3.0,..
- # Replacing XXX accordingly with your previous choice type:
- $ sudo pythonXXX setup.py install
-
--> OR install with "Easy Install" (currently seems to work only for Python2)
- $ wget http://peak.telecommunity.com/dist/ez_setup.py
- $ sudo python ez_setup.py
- $ sudo easy_install pyinotify
-
-
-==== Watch a directory ====
-
-Install pyinotify and run this command from a shell:
-
- $ python -m pyinotify -v /my-dir-to-watch
diff --git a/python2/docstrings/api-objects.txt b/api-objects.txt
index 3f35780..3f35780 100644
--- a/python2/docstrings/api-objects.txt
+++ b/api-objects.txt
diff --git a/python2/docstrings/class-tree.html b/class-tree.html
index 3d8715a..28fec75 100644
--- a/python2/docstrings/class-tree.html
+++ b/class-tree.html
@@ -238,7 +238,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/crarr.png b/crarr.png
index 26b43c5..26b43c5 100644
--- a/python2/docstrings/crarr.png
+++ b/crarr.png
Binary files differ
diff --git a/python2/docstrings/epydoc.css b/epydoc.css
index 86d4170..86d4170 100644
--- a/python2/docstrings/epydoc.css
+++ b/epydoc.css
diff --git a/python2/docstrings/epydoc.js b/epydoc.js
index e787dbc..e787dbc 100644
--- a/python2/docstrings/epydoc.js
+++ b/epydoc.js
diff --git a/python2/docstrings/frames.html b/frames.html
index d2f3830..d2f3830 100644
--- a/python2/docstrings/frames.html
+++ b/frames.html
diff --git a/python2/docstrings/help.html b/help.html
index 72e647d..47dd0f5 100644
--- a/python2/docstrings/help.html
+++ b/help.html
@@ -246,7 +246,7 @@ page was last updated. </p>
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/identifier-index.html b/identifier-index.html
index d983c0c..8eaef78 100644
--- a/python2/docstrings/identifier-index.html
+++ b/identifier-index.html
@@ -711,7 +711,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/index.html b/index.html
index d258d0f..d2f3830 120000..100644
--- a/index.html
+++ b/index.html
@@ -1 +1,17 @@
-python2/docstrings/index.html \ No newline at end of file
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
+ "DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title> API Documentation </title>
+</head>
+<frameset cols="20%,80%">
+ <frameset rows="30%,70%">
+ <frame src="toc.html" name="moduleListFrame"
+ id="moduleListFrame" />
+ <frame src="toc-everything.html" name="moduleFrame"
+ id="moduleFrame" />
+ </frameset>
+ <frame src="pyinotify-module.html" name="mainFrame" id="mainFrame" />
+</frameset>
+</html>
diff --git a/python2/docstrings/module-tree.html b/module-tree.html
index 1f38f66..7916cb1 100644
--- a/python2/docstrings/module-tree.html
+++ b/module-tree.html
@@ -83,7 +83,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify-module.html b/pyinotify-module.html
index c12be8a..207b354 100644
--- a/python2/docstrings/pyinotify-module.html
+++ b/pyinotify-module.html
@@ -448,7 +448,7 @@
<td width="15%" align="right" valign="top" class="summary">
<span class="summary-type">&nbsp;</span>
</td><td class="summary">
- <a name="LIBC"></a><span class="summary-name">LIBC</span> = <code title="&lt;CDLL 'libc.so.6', handle 2b4292ed7970 at 207d410&gt;">&lt;CDLL 'libc.so.6', handle 2b4292ed7970 at 207d410&gt;</code>
+ <a name="LIBC"></a><span class="summary-name">LIBC</span> = <code title="&lt;CDLL 'libc.so.6', handle 2b93c4470970 at 1944410&gt;">&lt;CDLL 'libc.so.6', handle 2b93c4470970 at 1944410&gt;</code>
</td>
</tr>
<tr>
@@ -802,7 +802,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify-pysrc.html b/pyinotify-pysrc.html
index c4da3ef..14a3b34 100644
--- a/python2/docstrings/pyinotify-pysrc.html
+++ b/pyinotify-pysrc.html
@@ -2563,7 +2563,7 @@ expandto(location.href);
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:51 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:14 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.AsyncNotifier-class.html b/pyinotify.AsyncNotifier-class.html
index 730fa5f..f291658 100644
--- a/python2/docstrings/pyinotify.AsyncNotifier-class.html
+++ b/pyinotify.AsyncNotifier-class.html
@@ -63,15 +63,6 @@
<area shape="rect" href="pyinotify.AsyncNotifier-class.html" title="This notifier inherits from asyncore.file_dispatcher in order to be able to use pyinotify along with the asyncore framework." alt="" coords="16,659,699,723"/>
<area shape="rect" href="javascript:void(0);" title="asyncore.file_dispatcher.set_file" alt="" coords="148,544,289,563"/>
<area shape="rect" href="javascript:void(0);" title="asyncore.file_dispatcher" alt="" coords="147,519,291,564"/>
-<area shape="rect" href="pyinotify.Notifier-class.html#append_event" title="Append a raw event to the event queue." alt="" coords="343,479,649,497"/>
-<area shape="rect" href="pyinotify.Notifier-class.html#proc_fun" title="pyinotify.Notifier.proc_fun" alt="" coords="343,497,649,516"/>
-<area shape="rect" href="pyinotify.Notifier-class.html#coalesce_events" title="Coalescing events." alt="" coords="343,516,649,535"/>
-<area shape="rect" href="pyinotify.Notifier-class.html#check_events" title="Check for new events available to read, blocks up to timeout milliseconds." alt="" coords="343,535,649,553"/>
-<area shape="rect" href="pyinotify.Notifier-class.html#read_events" title="Read events from device, build _RawEvents, and enqueue them." alt="" coords="343,553,649,572"/>
-<area shape="rect" href="pyinotify.Notifier-class.html#process_events" title="Routine for processing events from queue by calling their associated &#160;proccessing method (an instance of ProcessEvent)." alt="" coords="343,572,649,591"/>
-<area shape="rect" href="pyinotify.Notifier-class.html#loop" title="Events are read only one time every min(read_freq, timeout) seconds at best and only if the size to read is &gt;= threshold." alt="" coords="343,591,649,609"/>
-<area shape="rect" href="pyinotify.Notifier-class.html#stop" title="Close inotify&#39;s instance (close its file descriptor)." alt="" coords="343,609,649,628"/>
-<area shape="rect" href="pyinotify.Notifier-class.html" title="Read notifications, process events." alt="" coords="341,453,651,629"/>
<area shape="rect" href="javascript:void(0);" title="asyncore.dispatcher.debug" alt="" coords="116,28,321,47"/>
<area shape="rect" href="javascript:void(0);" title="asyncore.dispatcher.connected" alt="" coords="116,47,321,65"/>
<area shape="rect" href="javascript:void(0);" title="asyncore.dispatcher.accepting" alt="" coords="116,65,321,84"/>
@@ -93,6 +84,15 @@
<area shape="rect" href="javascript:void(0);" title="asyncore.dispatcher.send" alt="" coords="116,367,321,385"/>
<area shape="rect" href="javascript:void(0);" title="asyncore.dispatcher.handle_close" alt="" coords="116,404,321,423"/>
<area shape="rect" href="javascript:void(0);" title="asyncore.dispatcher" alt="" coords="115,11,323,424"/>
+<area shape="rect" href="pyinotify.Notifier-class.html#append_event" title="Append a raw event to the event queue." alt="" coords="343,479,649,497"/>
+<area shape="rect" href="pyinotify.Notifier-class.html#proc_fun" title="pyinotify.Notifier.proc_fun" alt="" coords="343,497,649,516"/>
+<area shape="rect" href="pyinotify.Notifier-class.html#coalesce_events" title="Coalescing events." alt="" coords="343,516,649,535"/>
+<area shape="rect" href="pyinotify.Notifier-class.html#check_events" title="Check for new events available to read, blocks up to timeout milliseconds." alt="" coords="343,535,649,553"/>
+<area shape="rect" href="pyinotify.Notifier-class.html#read_events" title="Read events from device, build _RawEvents, and enqueue them." alt="" coords="343,553,649,572"/>
+<area shape="rect" href="pyinotify.Notifier-class.html#process_events" title="Routine for processing events from queue by calling their associated &#160;proccessing method (an instance of ProcessEvent)." alt="" coords="343,572,649,591"/>
+<area shape="rect" href="pyinotify.Notifier-class.html#loop" title="Events are read only one time every min(read_freq, timeout) seconds at best and only if the size to read is &gt;= threshold." alt="" coords="343,591,649,609"/>
+<area shape="rect" href="pyinotify.Notifier-class.html#stop" title="Close inotify&#39;s instance (close its file descriptor)." alt="" coords="343,609,649,628"/>
+<area shape="rect" href="pyinotify.Notifier-class.html" title="Read notifications, process events." alt="" coords="341,453,651,629"/>
</map>
<img src="uml_class_diagram_for_pyinotif.gif" alt='' usemap="#uml_class_diagram_for_pyinotif" ismap="ismap" class="graph-without-title" />
</center>
@@ -395,7 +395,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.ChainIfTrue-class.html b/pyinotify.ChainIfTrue-class.html
index 1cd9176..394e9c1 100644
--- a/python2/docstrings/pyinotify.ChainIfTrue-class.html
+++ b/pyinotify.ChainIfTrue-class.html
@@ -310,7 +310,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.ColoredOutputFormat-class.html b/pyinotify.ColoredOutputFormat-class.html
index c83d711..515898d 100644
--- a/python2/docstrings/pyinotify.ColoredOutputFormat-class.html
+++ b/pyinotify.ColoredOutputFormat-class.html
@@ -228,7 +228,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.Event-class.html b/pyinotify.Event-class.html
index f7ff201..2351e3d 100644
--- a/python2/docstrings/pyinotify.Event-class.html
+++ b/pyinotify.Event-class.html
@@ -263,7 +263,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.EventsCodes-class.html b/pyinotify.EventsCodes-class.html
index 064874a..801b754 100644
--- a/python2/docstrings/pyinotify.EventsCodes-class.html
+++ b/pyinotify.EventsCodes-class.html
@@ -694,7 +694,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.ExcludeFilter-class.html b/pyinotify.ExcludeFilter-class.html
index f6e8a80..bd61e8b 100644
--- a/python2/docstrings/pyinotify.ExcludeFilter-class.html
+++ b/pyinotify.ExcludeFilter-class.html
@@ -317,7 +317,7 @@ Examples:
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.Notifier-class.html b/pyinotify.Notifier-class.html
index 3e79650..8df6f39 100644
--- a/python2/docstrings/pyinotify.Notifier-class.html
+++ b/pyinotify.Notifier-class.html
@@ -628,7 +628,7 @@ stdin, stdout, stderr: files associated to common streams.
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.NotifierError-class.html b/pyinotify.NotifierError-class.html
index a75b10e..f3dfe90 100644
--- a/python2/docstrings/pyinotify.NotifierError-class.html
+++ b/pyinotify.NotifierError-class.html
@@ -61,6 +61,8 @@
<area shape="rect" href="pyinotify.NotifierError-class.html#__init__" title="x.__init__(...) initializes x; see x.__class__.__doc__ for signature" alt="" coords="44,447,145,465"/>
<area shape="rect" href="pyinotify.NotifierError-class.html" title="Notifier Exception." alt="" coords="43,421,147,467"/>
<area shape="rect" href="pyinotify.PyinotifyError-class.html" title="Indicates exceptions raised by a Pyinotify class." alt="" coords="53,360,136,392"/>
+<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="32,311,157,329"/>
+<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="31,285,159,331"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.args" alt="" coords="17,28,172,47"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.message" alt="" coords="17,47,172,65"/>
<area shape="rect" href="javascript:void(0);" title="x.__delattr__(&#39;name&#39;) &lt;==&gt; del x.name" alt="" coords="17,68,172,87"/>
@@ -74,8 +76,6 @@
<area shape="rect" href="javascript:void(0);" title="str(x)" alt="" coords="17,217,172,236"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.__unicode__" alt="" coords="17,236,172,255"/>
<area shape="rect" href="javascript:void(0);" title="Common base class for all exceptions" alt="" coords="16,11,173,256"/>
-<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="32,311,157,329"/>
-<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="31,285,159,331"/>
</map>
<img src="uml_class_diagram_for_pyinotif_8.gif" alt='' usemap="#uml_class_diagram_for_pyinotif_8" ismap="ismap" class="graph-without-title" />
</center>
@@ -248,7 +248,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.PrintAllEvents-class.html b/pyinotify.PrintAllEvents-class.html
index 4290fed..f9fb332 100644
--- a/python2/docstrings/pyinotify.PrintAllEvents-class.html
+++ b/pyinotify.PrintAllEvents-class.html
@@ -315,7 +315,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.ProcessEvent-class.html b/pyinotify.ProcessEvent-class.html
index 494659f..244e4c0 100644
--- a/python2/docstrings/pyinotify.ProcessEvent-class.html
+++ b/pyinotify.ProcessEvent-class.html
@@ -58,19 +58,19 @@
<h1 class="epydoc">Class ProcessEvent</h1><p class="nomargin-top"><span class="codelink"><a href="pyinotify-pysrc.html#ProcessEvent">source&nbsp;code</a></span></p>
<center>
<center> <map id="uml_class_diagram_for_pyinotif_10" name="uml_class_diagram_for_pyinotif_10">
-<area shape="rect" href="pyinotify.ProcessEvent-class.html#pevent" title="pyinotify.ProcessEvent.pevent" alt="" coords="48,103,285,121"/>
-<area shape="rect" href="pyinotify.ProcessEvent-class.html#__init__" title="Enable chaining of ProcessEvent instances." alt="" coords="48,124,285,143"/>
-<area shape="rect" href="pyinotify.ProcessEvent-class.html#my_init" title="This method is called from ProcessEvent.__init__()." alt="" coords="48,143,285,161"/>
-<area shape="rect" href="pyinotify.ProcessEvent-class.html#__call__" title="To behave like a functor the object must be callable." alt="" coords="48,161,285,180"/>
-<area shape="rect" href="pyinotify.ProcessEvent-class.html#nested_pevent" title="pyinotify.ProcessEvent.nested_pevent" alt="" coords="48,180,285,199"/>
-<area shape="rect" href="pyinotify.ProcessEvent-class.html#process_IN_Q_OVERFLOW" title="By default this method only reports warning messages, you can overredide it by subclassing ProcessEvent and implement your own process_IN_Q_OVERFLOW &#160;method." alt="" coords="48,199,285,217"/>
-<area shape="rect" href="pyinotify.ProcessEvent-class.html#process_default" title="Default processing event method." alt="" coords="48,217,285,236"/>
-<area shape="rect" href="pyinotify.ProcessEvent-class.html" title="Process events objects, can be specialized via subclassing, thus its behavior can be overriden:" alt="" coords="47,85,287,237"/>
-<area shape="rect" href="pyinotify.ChainIfTrue-class.html" title="Makes conditional chaining depending on the result of the nested processing instance." alt="" coords="16,267,93,293"/>
-<area shape="rect" href="pyinotify.Stats-class.html" title="Compute and display trivial statistics about processed events." alt="" coords="144,267,189,293"/>
-<area shape="rect" href="pyinotify.PrintAllEvents-class.html" title="Dummy class used to print events strings representations." alt="" coords="240,267,336,293"/>
-<area shape="rect" href="pyinotify._ProcessEvent-class.html#__repr__" title="repr(x)" alt="" coords="123,36,211,55"/>
-<area shape="rect" href="pyinotify._ProcessEvent-class.html" title="Abstract processing event class." alt="" coords="121,11,212,56"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html#pevent" title="pyinotify.ProcessEvent.pevent" alt="" coords="67,103,304,121"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html#__init__" title="Enable chaining of ProcessEvent instances." alt="" coords="67,124,304,143"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html#my_init" title="This method is called from ProcessEvent.__init__()." alt="" coords="67,143,304,161"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html#__call__" title="To behave like a functor the object must be callable." alt="" coords="67,161,304,180"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html#nested_pevent" title="pyinotify.ProcessEvent.nested_pevent" alt="" coords="67,180,304,199"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html#process_IN_Q_OVERFLOW" title="By default this method only reports warning messages, you can overredide it by subclassing ProcessEvent and implement your own process_IN_Q_OVERFLOW &#160;method." alt="" coords="67,199,304,217"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html#process_default" title="Default processing event method." alt="" coords="67,217,304,236"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html" title="Process events objects, can be specialized via subclassing, thus its behavior can be overriden:" alt="" coords="65,85,305,237"/>
+<area shape="rect" href="pyinotify.PrintAllEvents-class.html" title="Dummy class used to print events strings representations." alt="" coords="16,267,112,293"/>
+<area shape="rect" href="pyinotify.Stats-class.html" title="Compute and display trivial statistics about processed events." alt="" coords="163,267,208,293"/>
+<area shape="rect" href="pyinotify.ChainIfTrue-class.html" title="Makes conditional chaining depending on the result of the nested processing instance." alt="" coords="259,267,336,293"/>
+<area shape="rect" href="pyinotify._ProcessEvent-class.html#__repr__" title="repr(x)" alt="" coords="141,36,229,55"/>
+<area shape="rect" href="pyinotify._ProcessEvent-class.html" title="Abstract processing event class." alt="" coords="140,11,231,56"/>
</map>
<img src="uml_class_diagram_for_pyinotif_10.gif" alt='' usemap="#uml_class_diagram_for_pyinotif_10" ismap="ismap" class="graph-without-title" />
</center>
@@ -516,7 +516,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:49 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:12 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.ProcessEventError-class.html b/pyinotify.ProcessEventError-class.html
index b6ae7bf..33df06c 100644
--- a/python2/docstrings/pyinotify.ProcessEventError-class.html
+++ b/pyinotify.ProcessEventError-class.html
@@ -61,6 +61,8 @@
<area shape="rect" href="pyinotify.ProcessEventError-class.html#__init__" title="x.__init__(...) initializes x; see x.__class__.__doc__ for signature" alt="" coords="40,447,149,465"/>
<area shape="rect" href="pyinotify.ProcessEventError-class.html" title="ProcessEventError Exception." alt="" coords="39,421,151,467"/>
<area shape="rect" href="pyinotify.PyinotifyError-class.html" title="Indicates exceptions raised by a Pyinotify class." alt="" coords="53,360,136,392"/>
+<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="32,311,157,329"/>
+<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="31,285,159,331"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.args" alt="" coords="17,28,172,47"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.message" alt="" coords="17,47,172,65"/>
<area shape="rect" href="javascript:void(0);" title="x.__delattr__(&#39;name&#39;) &lt;==&gt; del x.name" alt="" coords="17,68,172,87"/>
@@ -74,8 +76,6 @@
<area shape="rect" href="javascript:void(0);" title="str(x)" alt="" coords="17,217,172,236"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.__unicode__" alt="" coords="17,236,172,255"/>
<area shape="rect" href="javascript:void(0);" title="Common base class for all exceptions" alt="" coords="16,11,173,256"/>
-<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="32,311,157,329"/>
-<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="31,285,159,331"/>
</map>
<img src="uml_class_diagram_for_pyinotif_11.gif" alt='' usemap="#uml_class_diagram_for_pyinotif_11" ismap="ismap" class="graph-without-title" />
</center>
@@ -248,7 +248,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.PyinotifyError-class.html b/pyinotify.PyinotifyError-class.html
index 65f15e3..54d4ef3 100644
--- a/python2/docstrings/pyinotify.PyinotifyError-class.html
+++ b/pyinotify.PyinotifyError-class.html
@@ -58,27 +58,27 @@
<h1 class="epydoc">Class PyinotifyError</h1><p class="nomargin-top"><span class="codelink"><a href="pyinotify-pysrc.html#PyinotifyError">source&nbsp;code</a></span></p>
<center>
<center> <map id="uml_class_diagram_for_pyinotif_12" name="uml_class_diagram_for_pyinotif_12">
-<area shape="rect" href="pyinotify.PyinotifyError-class.html" title="Indicates exceptions raised by a Pyinotify class." alt="" coords="368,379,451,411"/>
<area shape="rect" href="pyinotify.ProcessEventError-class.html" title="ProcessEventError Exception." alt="" coords="16,440,139,467"/>
+<area shape="rect" href="javascript:void(0);" title="x.__init__(...) initializes x; see x.__class__.__doc__ for signature" alt="" coords="323,311,448,329"/>
+<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="323,329,448,348"/>
+<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="321,285,449,349"/>
+<area shape="rect" href="pyinotify.PyinotifyError-class.html" title="Indicates exceptions raised by a Pyinotify class." alt="" coords="344,379,427,411"/>
<area shape="rect" href="pyinotify.UnsupportedPythonVersionError-class.html" title="Raised on unsupported Python versions." alt="" coords="189,440,389,467"/>
-<area shape="rect" href="pyinotify.UnsupportedLibcVersionError-class.html" title="Raised when libc couldn&#39;t be loaded or when inotify functions werent provided." alt="" coords="440,440,621,467"/>
-<area shape="rect" href="pyinotify.NotifierError-class.html" title="Notifier Exception." alt="" coords="672,440,755,467"/>
-<area shape="rect" href="javascript:void(0);" title="x.__init__(...) initializes x; see x.__class__.__doc__ for signature" alt="" coords="347,311,472,329"/>
-<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="347,329,472,348"/>
-<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="345,285,473,349"/>
-<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.args" alt="" coords="332,28,487,47"/>
-<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.message" alt="" coords="332,47,487,65"/>
-<area shape="rect" href="javascript:void(0);" title="x.__delattr__(&#39;name&#39;) &lt;==&gt; del x.name" alt="" coords="332,68,487,87"/>
-<area shape="rect" href="javascript:void(0);" title="x.__getattribute__(&#39;name&#39;) &lt;==&gt; x.name" alt="" coords="332,87,487,105"/>
-<area shape="rect" href="javascript:void(0);" title="x[y]" alt="" coords="332,105,487,124"/>
-<area shape="rect" href="javascript:void(0);" title="x[i:j]" alt="" coords="332,124,487,143"/>
-<area shape="rect" href="javascript:void(0);" title="helper for pickle" alt="" coords="332,143,487,161"/>
-<area shape="rect" href="javascript:void(0);" title="repr(x)" alt="" coords="332,161,487,180"/>
-<area shape="rect" href="javascript:void(0);" title="x.__setattr__(&#39;name&#39;, value) &lt;==&gt; x.name = value" alt="" coords="332,180,487,199"/>
-<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.__setstate__" alt="" coords="332,199,487,217"/>
-<area shape="rect" href="javascript:void(0);" title="str(x)" alt="" coords="332,217,487,236"/>
-<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.__unicode__" alt="" coords="332,236,487,255"/>
-<area shape="rect" href="javascript:void(0);" title="Common base class for all exceptions" alt="" coords="331,11,488,256"/>
+<area shape="rect" href="pyinotify.NotifierError-class.html" title="Notifier Exception." alt="" coords="440,440,523,467"/>
+<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.args" alt="" coords="308,28,463,47"/>
+<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.message" alt="" coords="308,47,463,65"/>
+<area shape="rect" href="javascript:void(0);" title="x.__delattr__(&#39;name&#39;) &lt;==&gt; del x.name" alt="" coords="308,68,463,87"/>
+<area shape="rect" href="javascript:void(0);" title="x.__getattribute__(&#39;name&#39;) &lt;==&gt; x.name" alt="" coords="308,87,463,105"/>
+<area shape="rect" href="javascript:void(0);" title="x[y]" alt="" coords="308,105,463,124"/>
+<area shape="rect" href="javascript:void(0);" title="x[i:j]" alt="" coords="308,124,463,143"/>
+<area shape="rect" href="javascript:void(0);" title="helper for pickle" alt="" coords="308,143,463,161"/>
+<area shape="rect" href="javascript:void(0);" title="repr(x)" alt="" coords="308,161,463,180"/>
+<area shape="rect" href="javascript:void(0);" title="x.__setattr__(&#39;name&#39;, value) &lt;==&gt; x.name = value" alt="" coords="308,180,463,199"/>
+<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.__setstate__" alt="" coords="308,199,463,217"/>
+<area shape="rect" href="javascript:void(0);" title="str(x)" alt="" coords="308,217,463,236"/>
+<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.__unicode__" alt="" coords="308,236,463,255"/>
+<area shape="rect" href="javascript:void(0);" title="Common base class for all exceptions" alt="" coords="307,11,464,256"/>
+<area shape="rect" href="pyinotify.UnsupportedLibcVersionError-class.html" title="Raised when libc couldn&#39;t be loaded or when inotify functions werent provided." alt="" coords="573,440,755,467"/>
</map>
<img src="uml_class_diagram_for_pyinotif_12.gif" alt='' usemap="#uml_class_diagram_for_pyinotif_12" ismap="ismap" class="graph-without-title" />
</center>
@@ -186,7 +186,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.PyinotifyLogger-class.html b/pyinotify.PyinotifyLogger-class.html
index 809db03..4be51d2 100644
--- a/python2/docstrings/pyinotify.PyinotifyLogger-class.html
+++ b/pyinotify.PyinotifyLogger-class.html
@@ -269,7 +269,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.RawOutputFormat-class.html b/pyinotify.RawOutputFormat-class.html
index 1f78081..fe8fffb 100644
--- a/python2/docstrings/pyinotify.RawOutputFormat-class.html
+++ b/pyinotify.RawOutputFormat-class.html
@@ -313,7 +313,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.Stats-class.html b/pyinotify.Stats-class.html
index a424925..da86f71 100644
--- a/python2/docstrings/pyinotify.Stats-class.html
+++ b/pyinotify.Stats-class.html
@@ -445,7 +445,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.SysCtlINotify-class.html b/pyinotify.SysCtlINotify-class.html
index 89a8816..8573ae9 100644
--- a/python2/docstrings/pyinotify.SysCtlINotify-class.html
+++ b/pyinotify.SysCtlINotify-class.html
@@ -467,7 +467,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.ThreadedNotifier-class.html b/pyinotify.ThreadedNotifier-class.html
index 408ff0c..3ea38e6 100644
--- a/python2/docstrings/pyinotify.ThreadedNotifier-class.html
+++ b/pyinotify.ThreadedNotifier-class.html
@@ -439,7 +439,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.UnicodeLogRecord-class.html b/pyinotify.UnicodeLogRecord-class.html
index 4367d4a..737d05e 100644
--- a/python2/docstrings/pyinotify.UnicodeLogRecord-class.html
+++ b/pyinotify.UnicodeLogRecord-class.html
@@ -237,7 +237,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.UnsupportedLibcVersionError-class.html b/pyinotify.UnsupportedLibcVersionError-class.html
index e70fa60..97b9cd4 100644
--- a/python2/docstrings/pyinotify.UnsupportedLibcVersionError-class.html
+++ b/pyinotify.UnsupportedLibcVersionError-class.html
@@ -61,6 +61,8 @@
<area shape="rect" href="pyinotify.UnsupportedLibcVersionError-class.html#__init__" title="x.__init__(...) initializes x; see x.__class__.__doc__ for signature" alt="" coords="17,447,185,465"/>
<area shape="rect" href="pyinotify.UnsupportedLibcVersionError-class.html" title="Raised when libc couldn&#39;t be loaded or when inotify functions werent provided." alt="" coords="16,421,187,467"/>
<area shape="rect" href="pyinotify.PyinotifyError-class.html" title="Indicates exceptions raised by a Pyinotify class." alt="" coords="60,360,143,392"/>
+<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="39,311,164,329"/>
+<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="37,285,165,331"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.args" alt="" coords="24,28,179,47"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.message" alt="" coords="24,47,179,65"/>
<area shape="rect" href="javascript:void(0);" title="x.__delattr__(&#39;name&#39;) &lt;==&gt; del x.name" alt="" coords="24,68,179,87"/>
@@ -74,8 +76,6 @@
<area shape="rect" href="javascript:void(0);" title="str(x)" alt="" coords="24,217,179,236"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.__unicode__" alt="" coords="24,236,179,255"/>
<area shape="rect" href="javascript:void(0);" title="Common base class for all exceptions" alt="" coords="23,11,180,256"/>
-<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="39,311,164,329"/>
-<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="37,285,165,331"/>
</map>
<img src="uml_class_diagram_for_pyinotif_19.gif" alt='' usemap="#uml_class_diagram_for_pyinotif_19" ismap="ismap" class="graph-without-title" />
</center>
@@ -244,7 +244,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.UnsupportedPythonVersionError-class.html b/pyinotify.UnsupportedPythonVersionError-class.html
index b50aca8..da9290c 100644
--- a/python2/docstrings/pyinotify.UnsupportedPythonVersionError-class.html
+++ b/pyinotify.UnsupportedPythonVersionError-class.html
@@ -61,6 +61,8 @@
<area shape="rect" href="pyinotify.UnsupportedPythonVersionError-class.html#__init__" title="x.__init__(...) initializes x; see x.__class__.__doc__ for signature" alt="" coords="17,447,204,465"/>
<area shape="rect" href="pyinotify.UnsupportedPythonVersionError-class.html" title="Raised on unsupported Python versions." alt="" coords="16,421,205,467"/>
<area shape="rect" href="pyinotify.PyinotifyError-class.html" title="Indicates exceptions raised by a Pyinotify class." alt="" coords="69,360,152,392"/>
+<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="48,311,173,329"/>
+<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="47,285,175,331"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.args" alt="" coords="33,28,188,47"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.message" alt="" coords="33,47,188,65"/>
<area shape="rect" href="javascript:void(0);" title="x.__delattr__(&#39;name&#39;) &lt;==&gt; del x.name" alt="" coords="33,68,188,87"/>
@@ -74,8 +76,6 @@
<area shape="rect" href="javascript:void(0);" title="str(x)" alt="" coords="33,217,188,236"/>
<area shape="rect" href="javascript:void(0);" title="exceptions.BaseException.__unicode__" alt="" coords="33,236,188,255"/>
<area shape="rect" href="javascript:void(0);" title="Common base class for all exceptions" alt="" coords="32,11,189,256"/>
-<area shape="rect" href="javascript:void(0);" title="exceptions.Exception.__new__" alt="" coords="48,311,173,329"/>
-<area shape="rect" href="javascript:void(0);" title="Common base class for all non&#45;exit exceptions." alt="" coords="47,285,175,331"/>
</map>
<img src="uml_class_diagram_for_pyinotif_20.gif" alt='' usemap="#uml_class_diagram_for_pyinotif_20" ismap="ismap" class="graph-without-title" />
</center>
@@ -248,7 +248,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.Watch-class.html b/pyinotify.Watch-class.html
index 0911717..06ee1e0 100644
--- a/python2/docstrings/pyinotify.Watch-class.html
+++ b/pyinotify.Watch-class.html
@@ -278,7 +278,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.WatchManager-class.html b/pyinotify.WatchManager-class.html
index e4fb016..283d63a 100644
--- a/python2/docstrings/pyinotify.WatchManager-class.html
+++ b/pyinotify.WatchManager-class.html
@@ -105,7 +105,7 @@
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr>
<td><span class="summary-sig"><a href="pyinotify.WatchManager-class.html#__init__" class="summary-sig-name">__init__</a>(<span class="summary-sig-arg">self</span>,
- <span class="summary-sig-arg">exclude_filter</span>=<span class="summary-sig-default">&lt;function &lt;lambda&gt; at 0x2083410&gt;</span>)</span><br />
+ <span class="summary-sig-arg">exclude_filter</span>=<span class="summary-sig-default">&lt;function &lt;lambda&gt; at 0x194a410&gt;</span>)</span><br />
Initialization: init inotify, init watch manager dictionary.</td>
<td align="right" valign="top">
<span class="codelink"><a href="pyinotify-pysrc.html#WatchManager.__init__">source&nbsp;code</a></span>
@@ -508,7 +508,7 @@
<table width="100%" cellpadding="0" cellspacing="0" border="0">
<tr valign="top"><td>
<h3 class="epydoc"><span class="sig"><span class="sig-name">__init__</span>(<span class="sig-arg">self</span>,
- <span class="sig-arg">exclude_filter</span>=<span class="sig-default">&lt;function &lt;lambda&gt; at 0x2083410&gt;</span>)</span>
+ <span class="sig-arg">exclude_filter</span>=<span class="sig-default">&lt;function &lt;lambda&gt; at 0x194a410&gt;</span>)</span>
<br /><em class="fname">(Constructor)</em>
</h3>
</td><td align="right" valign="top"
@@ -1030,7 +1030,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify.WatchManagerError-class.html b/pyinotify.WatchManagerError-class.html
index 6af294c..67b82e1 100644
--- a/python2/docstrings/pyinotify.WatchManagerError-class.html
+++ b/pyinotify.WatchManagerError-class.html
@@ -252,7 +252,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:50 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:13 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify._Event-class.html b/pyinotify._Event-class.html
index b8733b8..b50ed8d 100644
--- a/python2/docstrings/pyinotify._Event-class.html
+++ b/pyinotify._Event-class.html
@@ -315,7 +315,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:51 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:14 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify._ProcessEvent-class.html b/pyinotify._ProcessEvent-class.html
index 9b1e696..075a436 100644
--- a/python2/docstrings/pyinotify._ProcessEvent-class.html
+++ b/pyinotify._ProcessEvent-class.html
@@ -58,8 +58,8 @@
<h1 class="epydoc">Class _ProcessEvent</h1><p class="nomargin-top"><span class="codelink"><a href="pyinotify-pysrc.html#_ProcessEvent">source&nbsp;code</a></span></p>
<center>
<div class="private"><center> <map id="uml_class_diagram_for_pyinotif_26" name="uml_class_diagram_for_pyinotif_26">
-<area shape="rect" href="pyinotify.ProcessEvent-class.html" title="Process events objects, can be specialized via subclassing, thus its behavior can be overriden:" alt="" coords="155,104,248,131"/>
<area shape="rect" href="pyinotify.PrintAllEvents-class.html" title="Dummy class used to print events strings representations." alt="" coords="16,160,112,187"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html" title="Process events objects, can be specialized via subclassing, thus its behavior can be overriden:" alt="" coords="155,104,248,131"/>
<area shape="rect" href="pyinotify.ChainIfTrue-class.html" title="Makes conditional chaining depending on the result of the nested processing instance." alt="" coords="163,160,240,187"/>
<area shape="rect" href="pyinotify.Stats-class.html" title="Compute and display trivial statistics about processed events." alt="" coords="291,160,336,187"/>
<area shape="rect" href="pyinotify._ProcessEvent-class.html#__call__" title="To behave like a functor the object must be callable." alt="" coords="221,36,341,55"/>
@@ -70,13 +70,13 @@
<img src="uml_class_diagram_for_pyinotif_26.gif" alt='' usemap="#uml_class_diagram_for_pyinotif_26" ismap="ismap" class="graph-without-title" />
</center></div>
<div class="public" style="display:none"><center> <map id="uml_class_diagram_for_pyinotif_27" name="uml_class_diagram_for_pyinotif_27">
-<area shape="rect" href="pyinotify._ProcessEvent-class.html#__call__" title="To behave like a functor the object must be callable." alt="" coords="107,36,227,55"/>
-<area shape="rect" href="pyinotify._ProcessEvent-class.html#__repr__" title="repr(x)" alt="" coords="107,55,227,73"/>
-<area shape="rect" href="pyinotify._ProcessEvent-class.html" title="Abstract processing event class." alt="" coords="105,11,228,75"/>
-<area shape="rect" href="pyinotify.ProcessEvent-class.html" title="Process events objects, can be specialized via subclassing, thus its behavior can be overriden:" alt="" coords="120,104,213,131"/>
-<area shape="rect" href="pyinotify.ChainIfTrue-class.html" title="Makes conditional chaining depending on the result of the nested processing instance." alt="" coords="16,160,93,187"/>
-<area shape="rect" href="pyinotify.Stats-class.html" title="Compute and display trivial statistics about processed events." alt="" coords="144,160,189,187"/>
-<area shape="rect" href="pyinotify.PrintAllEvents-class.html" title="Dummy class used to print events strings representations." alt="" coords="240,160,336,187"/>
+<area shape="rect" href="pyinotify._ProcessEvent-class.html#__call__" title="To behave like a functor the object must be callable." alt="" coords="125,36,245,55"/>
+<area shape="rect" href="pyinotify._ProcessEvent-class.html#__repr__" title="repr(x)" alt="" coords="125,55,245,73"/>
+<area shape="rect" href="pyinotify._ProcessEvent-class.html" title="Abstract processing event class." alt="" coords="124,11,247,75"/>
+<area shape="rect" href="pyinotify.ProcessEvent-class.html" title="Process events objects, can be specialized via subclassing, thus its behavior can be overriden:" alt="" coords="139,104,232,131"/>
+<area shape="rect" href="pyinotify.PrintAllEvents-class.html" title="Dummy class used to print events strings representations." alt="" coords="16,160,112,187"/>
+<area shape="rect" href="pyinotify.Stats-class.html" title="Compute and display trivial statistics about processed events." alt="" coords="163,160,208,187"/>
+<area shape="rect" href="pyinotify.ChainIfTrue-class.html" title="Makes conditional chaining depending on the result of the nested processing instance." alt="" coords="259,160,336,187"/>
</map>
<img src="uml_class_diagram_for_pyinotif_27.gif" alt='' usemap="#uml_class_diagram_for_pyinotif_27" ismap="ismap" class="graph-without-title" />
</center></div>
@@ -302,7 +302,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:51 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:14 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify._RawEvent-class.html b/pyinotify._RawEvent-class.html
index 02f807e..0c2c3d3 100644
--- a/python2/docstrings/pyinotify._RawEvent-class.html
+++ b/pyinotify._RawEvent-class.html
@@ -277,7 +277,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:51 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:14 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/docstrings/pyinotify._SysProcessEvent-class.html b/pyinotify._SysProcessEvent-class.html
index 67054e9..c736554 100644
--- a/python2/docstrings/pyinotify._SysProcessEvent-class.html
+++ b/pyinotify._SysProcessEvent-class.html
@@ -472,7 +472,7 @@
<table border="0" cellpadding="0" cellspacing="0" width="100%%">
<tr>
<td align="left" class="footer">
- Generated by Epydoc 3.0.1 on Wed Sep 15 21:46:51 2010
+ Generated by Epydoc 3.0.1 on Wed Sep 15 22:06:14 2010
</td>
<td align="right" class="footer">
<a target="mainFrame" href="http://epydoc.sourceforge.net"
diff --git a/python2/pyinotify.py b/pyinotify.py
index 32e2f22..eb55f7d 100755
--- a/python2/pyinotify.py
+++ b/pyinotify.py
@@ -91,7 +91,7 @@ except ImportError:
__author__ = "seb@dbzteam.org (Sebastien Martini)"
-__version__ = "0.9.0"
+__version__ = "git.current.python2"
__metaclass__ = type # Use new-style classes by default
diff --git a/python2/docstrings/index.html b/python2/docstrings/index.html
deleted file mode 100644
index d2f3830..0000000
--- a/python2/docstrings/index.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
- "DTD/xhtml1-frameset.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
- <title> API Documentation </title>
-</head>
-<frameset cols="20%,80%">
- <frameset rows="30%,70%">
- <frame src="toc.html" name="moduleListFrame"
- id="moduleListFrame" />
- <frame src="toc-everything.html" name="moduleFrame"
- id="moduleFrame" />
- </frameset>
- <frame src="pyinotify-module.html" name="mainFrame" id="mainFrame" />
-</frameset>
-</html>
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_10.gif b/python2/docstrings/uml_class_diagram_for_pyinotif_10.gif
deleted file mode 100644
index 7421354..0000000
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_10.gif
+++ /dev/null
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_12.gif b/python2/docstrings/uml_class_diagram_for_pyinotif_12.gif
deleted file mode 100644
index d27301b..0000000
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_12.gif
+++ /dev/null
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_22.gif b/python2/docstrings/uml_class_diagram_for_pyinotif_22.gif
deleted file mode 100644
index f0611ff..0000000
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_22.gif
+++ /dev/null
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_27.gif b/python2/docstrings/uml_class_diagram_for_pyinotif_27.gif
deleted file mode 100644
index 8f74334..0000000
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_27.gif
+++ /dev/null
Binary files differ
diff --git a/python2/examples/autocompile.py b/python2/examples/autocompile.py
deleted file mode 100755
index eed13c3..0000000
--- a/python2/examples/autocompile.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/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)
diff --git a/python2/examples/chain.py b/python2/examples/chain.py
deleted file mode 100644
index 5f110ee..0000000
--- a/python2/examples/chain.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Example: monitors events and logs them into a log file.
-#
-import pyinotify
-
-class Log(pyinotify.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(pyinotify.ProcessEvent):
- def process_IN_MODIFY(self, event):
- print 'IN_MODIFY'
-
-class Empty(pyinotify.ProcessEvent):
- def my_init(self, msg):
- self._msg = msg
-
- def process_default(self, event):
- print self._msg
-
-
-# pyinotify.log.setLevel(10)
-fo = file('/var/log/pyinotify_log', 'w')
-try:
- wm = pyinotify.WatchManager()
- # It is important to pass named extra arguments like 'fileobj'.
- handler = Empty(TrackModifications(Log(fileobj=fo)), msg='Outer chained method')
- notifier = pyinotify.Notifier(wm, default_proc_fun=handler)
- wm.add_watch('/tmp', pyinotify.ALL_EVENTS)
- notifier.loop()
-finally:
- fo.close()
diff --git a/python2/examples/coalesce.py b/python2/examples/coalesce.py
deleted file mode 100644
index e54feb6..0000000
--- a/python2/examples/coalesce.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Example: coalesce events.
-#
-import pyinotify
-
-# For instance when this example is run with this command:
-# cd /tmp && echo "test" > test && echo "test" >> test
-#
-# It will give the following result when notifier.coalesce_events(False) is called
-# (default behavior, same as if we had not called this method):
-#
-# <Event dir=False mask=0x100 maskname=IN_CREATE name=test path=/tmp pathname=/tmp/test wd=1 >
-# <Event dir=False mask=0x20 maskname=IN_OPEN name=test path=/tmp pathname=/tmp/test wd=1 >
-# <Event dir=False mask=0x2 maskname=IN_MODIFY name=test path=/tmp pathname=/tmp/test wd=1 >
-# <Event dir=False mask=0x8 maskname=IN_CLOSE_WRITE name=test path=/tmp pathname=/tmp/test wd=1 >
-# <Event dir=False mask=0x20 maskname=IN_OPEN name=test path=/tmp pathname=/tmp/test wd=1 >
-# <Event dir=False mask=0x2 maskname=IN_MODIFY name=test path=/tmp pathname=/tmp/test wd=1 >
-# <Event dir=False mask=0x8 maskname=IN_CLOSE_WRITE name=test path=/tmp pathname=/tmp/test wd=1 >
-#
-# And will give the following result when notifier.coalesce_events() is called:
-#
-# <Event dir=False mask=0x100 maskname=IN_CREATE name=test path=/tmp pathname=/tmp/test wd=1 >
-# <Event dir=False mask=0x20 maskname=IN_OPEN name=test path=/tmp pathname=/tmp/test wd=1 >
-# <Event dir=False mask=0x2 maskname=IN_MODIFY name=test path=/tmp pathname=/tmp/test wd=1 >
-# <Event dir=False mask=0x8 maskname=IN_CLOSE_WRITE name=test path=/tmp pathname=/tmp/test wd=1 >
-
-wm = pyinotify.WatchManager()
-# Put an arbitrary large value (10 seconds) to aggregate together a larger
-# chunk of events. For instance if you repeat several times a given action
-# on the same file its events will be coalesced into a single event and only
-# one event of this type will be reported (for this period).
-notifier = pyinotify.Notifier(wm, read_freq=10)
-# Enable coalescing of events.
-notifier.coalesce_events()
-wm.add_watch('/tmp', pyinotify.ALL_EVENTS)
-notifier.loop()
diff --git a/python2/examples/daemon.py b/python2/examples/daemon.py
deleted file mode 100644
index e1e9ac1..0000000
--- a/python2/examples/daemon.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Example: daemonize pyinotify's notifier.
-#
-# Requires Python >= 2.5
-import functools
-import sys
-import pyinotify
-
-class Counter(object):
- """
- Simple counter.
- """
- def __init__(self):
- self.count = 0
- def plusone(self):
- self.count += 1
-
-def on_loop(notifier, counter):
- """
- Dummy function called after each event loop, this method only
- ensures the child process eventually exits (after 5 iterations).
- """
- if counter.count > 4:
- # Loops 5 times then exits.
- sys.stdout.write("Exit\n")
- notifier.stop()
- sys.exit(0)
- else:
- sys.stdout.write("Loop %d\n" % counter.count)
- counter.plusone()
-
-wm = pyinotify.WatchManager()
-notifier = pyinotify.Notifier(wm)
-wm.add_watch('/tmp', pyinotify.ALL_EVENTS)
-on_loop_func = functools.partial(on_loop, counter=Counter())
-
-# Notifier instance spawns a new process when daemonize is set to True. This
-# child process' PID is written to /tmp/pyinotify.pid (it also automatically
-# deletes it when it exits normally). If no custom pid_file is provided it
-# would write it more traditionally under /var/run/. Note that in both cases
-# the caller must ensure the pid file doesn't exist when this method is called
-# othewise it will raise an exception. /tmp/stdout.txt is used as stdout
-# stream thus traces of events will be written in it. callback is the above
-# function and will be called after each event loop.
-try:
- notifier.loop(daemonize=True, callback=on_loop_func,
- pid_file='/tmp/pyinotify.pid', stdout='/tmp/stdout.txt')
-except pyinotify.NotifierError, err:
- print >> sys.stderr, err
diff --git a/python2/examples/exclude.lst b/python2/examples/exclude.lst
deleted file mode 100644
index 7e81272..0000000
--- a/python2/examples/exclude.lst
+++ /dev/null
@@ -1,12 +0,0 @@
-# File associated to exclude.py
-#
-# List of patterns using regexps as defined into re standard module.
-# These regexps are matched against submitted paths with re.match().
-
-# Put only one pattern by line.
-^/etc/apache[2]?/
-^/etc/rc.*
-^/etc/hostname
-^/etc/hosts
-^/etc/(fs|m)tab
-^/etc/cron\..*
diff --git a/python2/examples/exclude.py b/python2/examples/exclude.py
deleted file mode 100644
index 4f12960..0000000
--- a/python2/examples/exclude.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Example: exclude items from being monitored.
-#
-import os
-import pyinotify
-
-wm = pyinotify.WatchManager()
-notifier = pyinotify.Notifier(wm)
-
-### Method 1:
-# Exclude patterns from file
-excl_file = os.path.join(os.getcwd(), 'exclude.lst')
-excl = pyinotify.ExcludeFilter(excl_file)
-# Add watches
-res = wm.add_watch(['/etc/hostname', '/etc/cups', '/etc/rc0.d'],
- pyinotify.ALL_EVENTS, rec=True, exclude_filter=excl)
-
-### Method 2 (Equivalent)
-# Exclude patterns from list
-excl_lst = ['^/etc/apache[2]?/',
- '^/etc/rc.*',
- '^/etc/hostname',
- '^/etc/hosts',
- '^/etc/(fs|m)tab',
- '^/etc/cron\..*']
-excl = pyinotify.ExcludeFilter(excl_lst)
-# Add watches
-res = wm.add_watch(['/etc/hostname', '/etc/cups', '/etc/rc0.d'],
- pyinotify.ALL_EVENTS, rec=True, exclude_filter=excl)
-
-#notifier.loop()
diff --git a/python2/examples/loop.py b/python2/examples/loop.py
deleted file mode 100644
index 48c81ad..0000000
--- a/python2/examples/loop.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Example: loops monitoring events forever.
-#
-import pyinotify
-
-# Instanciate a new WatchManager (will be used to store watches).
-wm = pyinotify.WatchManager()
-# Associate this WatchManager with a Notifier (will be used to report and
-# process events).
-notifier = pyinotify.Notifier(wm)
-# Add a new watch on /tmp for ALL_EVENTS.
-wm.add_watch('/tmp', pyinotify.ALL_EVENTS)
-# Loop forever and handle events.
-notifier.loop()
diff --git a/python2/examples/not_quiet.py b/python2/examples/not_quiet.py
deleted file mode 100644
index 3b24db2..0000000
--- a/python2/examples/not_quiet.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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
-
diff --git a/python2/examples/stats.py b/python2/examples/stats.py
deleted file mode 100644
index 2e8c94b..0000000
--- a/python2/examples/stats.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Example: prints statistics.
-#
-import pyinotify
-
-class Identity(pyinotify.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 = pyinotify.WatchManager()
-# Stats is a subclass of ProcessEvent provided by pyinotify
-# for computing basics statistics.
-s = pyinotify.Stats()
-notifier = pyinotify.Notifier(wm, default_proc_fun=Identity(s), read_freq=5)
-wm.add_watch('/tmp/', pyinotify.ALL_EVENTS, rec=True, auto_add=True)
-notifier.loop(callback=on_loop)
diff --git a/python2/examples/stats_threaded.py b/python2/examples/stats_threaded.py
deleted file mode 100644
index 309f63a..0000000
--- a/python2/examples/stats_threaded.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Example: prints statistics (threaded version).
-#
-import time
-import pyinotify
-
-# 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(pyinotify.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 = pyinotify.WatchManager()
-s1 = pyinotify.Stats() # Stats is a subclass of ProcessEvent
-notifier1 = pyinotify.ThreadedNotifier(wm1, default_proc_fun=Identity(s1))
-notifier1.start()
-wm1.add_watch('/tmp/', pyinotify.ALL_EVENTS, rec=True, auto_add=True)
-
-# Thread #2
-wm2 = pyinotify.WatchManager()
-s2 = pyinotify.Stats() # Stats is a subclass of ProcessEvent
-notifier2 = pyinotify.ThreadedNotifier(wm2, default_proc_fun=Identity(s2))
-notifier2.start()
-wm2.add_watch('/var/log/', pyinotify.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
diff --git a/python2/examples/transient_file.py b/python2/examples/transient_file.py
deleted file mode 100644
index 3df2a97..0000000
--- a/python2/examples/transient_file.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Example: monitors transient files.
-#
-# Run this code, then run transient_file.sh in another shell.
-import pyinotify
-
-class ProcessTransientFile(pyinotify.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 = pyinotify.WatchManager()
-notifier = pyinotify.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', pyinotify.IN_MODIFY, ProcessTransientFile)
-notifier.loop()
diff --git a/python2/examples/transient_file.sh b/python2/examples/transient_file.sh
deleted file mode 100755
index 50f50c8..0000000
--- a/python2/examples/transient_file.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/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
diff --git a/python2/examples/tutorial_asyncnotifier.py b/python2/examples/tutorial_asyncnotifier.py
deleted file mode 100644
index 0e98a8b..0000000
--- a/python2/examples/tutorial_asyncnotifier.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# AsyncNotifier example from tutorial
-#
-# See: http://trac.dbzteam.org/pyinotify/wiki/Tutorial
-#
-import asyncore
-import pyinotify
-
-wm = pyinotify.WatchManager() # Watch Manager
-mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE # watched events
-
-class EventHandler(pyinotify.ProcessEvent):
- def process_IN_CREATE(self, event):
- print "Creating:", event.pathname
-
- def process_IN_DELETE(self, event):
- print "Removing:", event.pathname
-
-notifier = pyinotify.AsyncNotifier(wm, EventHandler())
-wdd = wm.add_watch('/tmp', mask, rec=True)
-
-asyncore.loop()
diff --git a/python2/examples/tutorial_notifier.py b/python2/examples/tutorial_notifier.py
deleted file mode 100644
index ad67473..0000000
--- a/python2/examples/tutorial_notifier.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Notifier example from tutorial
-#
-# See: http://trac.dbzteam.org/pyinotify/wiki/Tutorial
-#
-import pyinotify
-
-wm = pyinotify.WatchManager() # Watch Manager
-mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE # watched events
-
-class EventHandler(pyinotify.ProcessEvent):
- def process_IN_CREATE(self, event):
- print "Creating:", event.pathname
-
- def process_IN_DELETE(self, event):
- print "Removing:", event.pathname
-
-handler = EventHandler()
-notifier = pyinotify.Notifier(wm, handler)
-wdd = wm.add_watch('/tmp', mask, rec=True)
-
-notifier.loop()
diff --git a/python2/examples/tutorial_threadednotifier.py b/python2/examples/tutorial_threadednotifier.py
deleted file mode 100644
index f1eb6c8..0000000
--- a/python2/examples/tutorial_threadednotifier.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# ThreadedNotifier example from tutorial
-#
-# See: http://trac.dbzteam.org/pyinotify/wiki/Tutorial
-#
-import pyinotify
-
-wm = pyinotify.WatchManager() # Watch Manager
-mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE # watched events
-
-class EventHandler(pyinotify.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 = pyinotify.ThreadedNotifier(wm, EventHandler())
-notifier.start()
-
-wdd = wm.add_watch('/tmp', mask, rec=True)
-wm.rm_watch(wdd.values())
-
-notifier.stop()
diff --git a/python2/examples/unicode.py b/python2/examples/unicode.py
deleted file mode 100644
index ec0d36f..0000000
--- a/python2/examples/unicode.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- coding: utf-8 -*-
-import os
-import sys
-import pyinotify
-
-
-# create path
-#path = u'/tmp/test\u0444'
-path = '/tmp/testф'
-path = unicode(path, sys.getfilesystemencoding())
-
-if not os.path.isdir(path):
- os.mkdir(path)
-
-pyinotify.log.setLevel(10)
-wm = pyinotify.WatchManager()
-notifier = pyinotify.Notifier(wm)
-
-wdd = wm.add_watch(path, pyinotify.IN_OPEN)
-wm.update_watch(wdd[path], pyinotify.ALL_EVENTS)
-
-notifier.loop()
diff --git a/python3/Makefile b/python3/Makefile
deleted file mode 100644
index 7667585..0000000
--- a/python3/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-EPYDOC=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 {} \;
diff --git a/python3/pyinotify.py b/python3/pyinotify.py
deleted file mode 100755
index acee931..0000000
--- a/python3/pyinotify.py
+++ /dev/null
@@ -1,2141 +0,0 @@
-#!/usr/bin/env python
-
-# pyinotify.py - python interface to inotify
-# Copyright (c) 2010 Sebastien Martini <seb@dbzteam.org>
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-"""
-pyinotify
-
-@author: Sebastien Martini
-@license: MIT License
-@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 3.0') % version)
-
-
-class UnsupportedLibcVersionError(PyinotifyError):
- """
- Raised when libc couldn't be loaded or when inotify functions werent
- provided.
- """
- def __init__(self):
- err = 'libc does not provide required inotify support'
- PyinotifyError.__init__(self, err)
-
-
-# Check Python version
-import sys
-if sys.version < '3.0':
- 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
-import glob
-import locale
-
-try:
- from functools import reduce
-except ImportError:
- pass # Will fail on Python 2.4 which has reduce() builtin anyway.
-
-__author__ = "seb@dbzteam.org (Sebastien Martini)"
-
-__version__ = "0.9.0"
-
-
-# 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 = None
-
-def strerrno():
- code = ctypes.get_errno()
- return '%s (%s)' % (os.strerror(code), errno.errorcode[code])
-
-def load_libc():
- global LIBC
-
- libc = None
- try:
- libc = ctypes.util.find_library('c')
- except OSError as err:
- pass # Will attemp to load it with None anyway.
- except IOError as err:
- pass
-
- LIBC = ctypes.CDLL(libc, use_errno=True)
-
- # Check that libc has needed functions inside.
- if (not hasattr(LIBC, 'inotify_init') or
- not hasattr(LIBC, 'inotify_add_watch') or
- not hasattr(LIBC, 'inotify_rm_watch')):
- raise UnsupportedLibcVersionError()
-
-load_libc()
-
-
-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
-
-
-# Logging
-def logger_init():
- """Initialize logger instance."""
- log = logging.getLogger("pyinotify")
- console_handler = logging.StreamHandler()
- console_handler.setFormatter(
- logging.Formatter("[%(asctime)s %(name)s %(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)
-
-
-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.items():
- # 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.items():
- globals()[name] = val
- EventsCodes.ALL_VALUES[val] = name
-
-
-# all 'normal' events
-ALL_EVENTS = reduce(lambda x, y: x | y, EventsCodes.OP_FLAGS.values())
-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_.items():
- 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, str) and not value:
- value = "''"
- s += ' %s%s%s' % (output_format.field_name(attr),
- output_format.punctuation('='),
- output_format.field_value(value))
-
- s = '%s%s%s %s' % (output_format.punctuation('<'),
- output_format.class_name(self.__class__.__name__),
- s,
- output_format.punctuation('>'))
- return s
-
- def __str__(self):
- return repr(self)
-
-
-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
- """
- # Use this variable to cache the result of str(self), this object
- # is immutable.
- self._str = None
- # name: remove trailing '\0'
- d = {'wd': wd,
- 'mask': mask,
- 'cookie': cookie,
- 'name': name.rstrip('\0')}
- _Event.__init__(self, d)
- log.debug(str(self))
-
- def __str__(self):
- if self._str is None:
- self._str = _Event.__str__(self)
- return self._str
-
-
-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 as err:
- # Usually it is not an error some events are perfectly valids
- # despite the lack of these attributes.
- log.debug(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 list(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)
- created_dir = os.path.join(watch_.path, raw_event.name)
- if watch_.auto_add and not watch_.exclude_filter(created_dir):
- addw = self._watch_manager.add_watch
- # The newly monitored directory inherits attributes from its
- # parent directory.
- addw_ret = addw(created_dir, watch_.mask,
- proc_fun=watch_.proc_fun,
- rec=False, auto_add=watch_.auto_add,
- exclude_filter=watch_.exclude_filter)
-
- # 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.
- created_dir_wd = addw_ret.get(created_dir)
- if (created_dir_wd is not None) and created_dir_wd > 0:
- for name in os.listdir(created_dir):
- inner = os.path.join(created_dir, name)
- if (os.path.isdir(inner) and
- self._watch_manager.get_wd(inner) is None):
- # Generate (simulate) creation event for sub
- # directories.
- rawevent = _RawEvent(created_dir_wd,
- 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 and
- not watch_.exclude_filter(dst_path)):
- # We got a diretory that's "moved in" from an unknown source and
- # auto_add is enabled. Manually add watches to the inner subtrees.
- # The newly monitored directory inherits attributes from its
- # parent directory.
- self._watch_manager.add_watch(dst_path, watch_.mask,
- proc_fun=watch_.proc_fun,
- rec=True, auto_add=True,
- exclude_filter=watch_.exclude_filter)
- 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
- # add the separator to the source path to avoid overlapping
- # path issue when testing with startswith()
- src_path += os.path.sep
- src_path_len = len(src_path)
- # 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.values():
- 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:])
- 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 automatically from the
- constructor of this class with its optionals 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 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 ProcessEvent.__init__(). This method is
- empty here and must be redefined to be useful. In effect, if you
- need to specifically initialize your subclass' instance then you
- just have to override this method in your subclass. Then all the
- keyworded arguments passed to ProcessEvent.__init__() will be
- transmitted as parameters to this method. Beware 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(str(event))
- self._out.write('\n')
- self._out.flush()
-
-
-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' % (output_format.field_name(ev),
- output_format.field_value(value)))
- s = '<%s%s >' % (output_format.class_name(self.__class__.__name__),
- ''.join(l))
- return s
-
- def dump(self, filename):
- """
- Dumps statistics.
-
- @param filename: filename where stats will be dumped, filename is
- created and must not exist prior to this call.
- @type filename: string
- """
- flags = os.O_WRONLY|os.O_CREAT|os.O_NOFOLLOW|os.O_EXCL
- fd = os.open(filename, flags, 0o0600)
- os.write(fd, bytes(self.__str__(), locale.getpreferredencoding()))
- os.close(fd)
-
- def __str__(self, scale=45):
- stats = self._stats_copy()
- if not stats:
- return ''
-
- m = max(stats.values())
- unity = scale / m
- fmt = '%%-26s%%-%ds%%s' % (len(output_format.field_value('@' * scale))
- + 1)
- def func(x):
- return fmt % (output_format.field_name(x[0]),
- output_format.field_value('@' * int(x[1] * unity)),
- output_format.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=None, 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. If None, a new
- instance of PrintAllEvents will be assigned.
- @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 may 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
- if default_proc_fun is None:
- self._default_proc_fun = PrintAllEvents()
- # Loop parameters
- self._read_freq = read_freq
- self._threshold = threshold
- self._timeout = timeout
- # Coalesce events option
- self._coalesce = False
- # set of str(raw_event), only used when coalesce option is True
- self._eventset = set()
-
- 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 coalesce_events(self, coalesce=True):
- """
- Coalescing events. Events are usually processed by batchs, their size
- depend on various factors. Thus, before processing them, events received
- from inotify are aggregated in a fifo queue. If this coalescing
- option is enabled events are filtered based on their unicity, only
- unique events are enqueued, doublons are discarded. An event is unique
- when the combination of its fields (wd, mask, cookie, name) is unique
- among events of a same batch. After a batch of events is processed any
- events is accepted again. By default this option is disabled, you have
- to explictly call this function to turn it on.
-
- @param coalesce: Optional new coalescing value. True by default.
- @type coalesce: Bool
- """
- self._coalesce = coalesce
- if not coalesce:
- self._eventset.clear()
-
- 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 as err:
- if err.errno == 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 as 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 and fname_len
- wd, mask, cookie, fname_len = struct.unpack('iIII',
- r[rsum:rsum+s_size])
- # Retrieve name
- bname, = struct.unpack('%ds' % fname_len,
- r[rsum + s_size:rsum + s_size + fname_len])
- # FIXME: should we explictly call sys.getdefaultencoding() here ??
- uname = bname.decode()
- rawevent = _RawEvent(wd, mask, cookie, uname)
- if self._coalesce:
- # Only enqueue new (unique) events.
- raweventstr = str(rawevent)
- if raweventstr not in self._eventset:
- self._eventset.add(raweventstr)
- self._eventq.append(rawevent)
- else:
- self._eventq.append(rawevent)
- 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)
- if watch_ is None:
- # Not really sure how we ended up here, nor how we should
- # handle these types of events and if it is appropriate to
- # completly skip them (like we are doing here).
- log.warning("Unable to retrieve Watch object associated to %s",
- repr(raw_event))
- continue
- 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
- if self._coalesce:
- self._eventset.clear()
-
- def __daemonize(self, pid_file=None, stdin=os.devnull, stdout=os.devnull,
- stderr=os.devnull):
- """
- pid_file: file where the pid will be written. If pid_file=None the pid
- is written to /var/run/<sys.argv[0]|pyinotify>.pid, if
- pid_file=False no pid_file is written.
- stdin, stdout, stderr: files associated to common streams.
- """
- if pid_file is None:
- dirname = '/var/run/'
- basename = os.path.basename(sys.argv[0]) or 'pyinotify'
- pid_file = os.path.join(dirname, basename + '.pid')
-
- if pid_file != False and os.path.lexists(pid_file):
- err = 'Cannot daemonize: pid file %s already exists.' % pid_file
- raise NotifierError(err)
-
- 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(0o022)
- 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, 0o0600)
- os.dup2(fd_out, 1)
- fd_err = os.open(stderr, os.O_WRONLY|os.O_CREAT, 0o0600)
- os.dup2(fd_err, 2)
-
- # Detach task
- fork_daemon()
-
- # Write pid
- if pid_file != False:
- flags = os.O_WRONLY|os.O_CREAT|os.O_NOFOLLOW|os.O_EXCL
- fd_pid = os.open(pid_file, flags, 0o0600)
- os.write(fd_pid, bytes(str(os.getpid()) + '\n',
- locale.getpreferredencoding()))
- os.close(fd_pid)
- # Register unlink function
- 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 one time every min(read_freq, timeout)
- seconds at best and only if the size to read is >= threshold.
- After this method returns it must not be called again for the same
- instance.
-
- @param callback: Functor called after each event processing iteration.
- Expects to receive the notifier object (self) as first
- parameter. If this function returns True the loop is
- immediately terminated otherwise the loop method keeps
- looping.
- @type callback: callable object or function
- @param daemonize: This thread is daemonized if set to True.
- @type daemonize: boolean
- @param args: Optional and relevant only if daemonize is True. Remaining
- keyworded arguments are directly passed to daemonize see
- __daemonize() method. If pid_file=None or is set to a
- pathname the caller must ensure the file does not exist
- before this method is called otherwise an exception
- pyinotify.NotifierError will be raised. If pid_file=False
- it is still daemonized but the pid is not written in any
- file.
- @type args: various
- """
- if daemonize:
- self.__daemonize(**args)
-
- # Read and process events forever
- while 1:
- try:
- self.process_events()
- if (callback is not None) and (callback(self) is True):
- break
- ref_time = time.time()
- # check_events is blocking
- if self.check_events():
- self._sleep(ref_time)
- self.read_events()
- except KeyboardInterrupt:
- # Stop monitoring if sigint is caught (Control-C).
- log.debug('Pyinotify stops monitoring.')
- break
- # Close internals
- self.stop()
-
-
- def stop(self):
- """
- Close inotify's instance (close its file descriptor).
- It destroys all existing watches, pending events,...
- This method is automatically called at the end of loop().
- """
- 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=None, 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. See base class.
- @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], b'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=None, 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, wd, path, mask, proc_fun, auto_add, exclude_filter):
- """
- 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
- @param exclude_filter: Boolean function, used to exclude new
- directories from being automatically watched.
- See WatchManager.__init__
- @type exclude_filter: callable object
- """
- self.wd = wd
- self.path = path
- self.mask = mask
- self.proc_fun = proc_fun
- self.auto_add = auto_add
- self.exclude_filter = exclude_filter
- self.dir = os.path.isdir(self.path)
-
- def __repr__(self):
- """
- @return: String representation.
- @rtype: str
- """
- s = ' '.join(['%s%s%s' % (output_format.field_name(attr),
- output_format.punctuation('='),
- output_format.field_value(getattr(self,
- attr))) \
- for attr in self.__dict__ if not attr.startswith('_')])
-
- s = '%s%s %s %s' % (output_format.punctuation('<'),
- output_format.class_name(self.__class__.__name__),
- s,
- output_format.punctuation('>'))
- return s
-
-
-class ExcludeFilter:
- """
- ExcludeFilter is an exclusion filter.
- """
- def __init__(self, arg_lst):
- """
- Examples:
- ef1 = ExcludeFilter(["^/etc/rc.*", "^/etc/hostname"])
- ef2 = ExcludeFilter("/my/path/exclude.lst")
- Where exclude.lst contains:
- ^/etc/rc.*
- ^/etc/hostname
-
- @param arg_lst: is either a list of patterns or a filename from which
- patterns will be loaded.
- @type arg_lst: list of str or str
- """
- if isinstance(arg_lst, str):
- lst = self._load_patterns_from_file(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_from_file(self, filename):
- lst = []
- with open(filename, 'r') as file_obj:
- for line in file_obj.readlines():
- # Trim leading an trailing whitespaces
- pattern = line.strip()
- if not pattern or pattern.startswith('#'):
- continue
- lst.append(pattern)
- 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: callable object
- """
- 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:
- err = 'Cannot initialize new instance of inotify Errno=%s'
- raise OSError(err % strerrno())
-
- def close(self):
- """
- Close inotify's file descriptor, this action will also automatically
- remove (i.e. stop watching) all its associated watch descriptors.
- After a call to this method the WatchManager's instance become useless
- and cannot be reused, a new instance must then be instanciated. It
- makes sense to call this method in few situations for instance if
- several independant WatchManager must be instanciated or if all watches
- must be removed and no other watches need to be added.
- """
- os.close(self._fd)
-
- 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 as 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 __format_path(self, path):
- """
- Format path to its internal (stored in watch manager) representation.
- """
- # path must be a unicode string (str) and is just normalized.
- return os.path.normpath(path)
-
- def __add_watch(self, path, mask, proc_fun, auto_add, exclude_filter):
- """
- Add a watch on path, build a Watch object and insert it in the
- watch manager dictionary. Return the wd value.
- """
- path = self.__format_path(path)
- # path to a bytes string. This conversion seems to be required because
- # ctypes.create_string_buffer seems to manipulate bytes
- # strings representations internally.
- # Moreover it seems that LIBC.inotify_add_watch does not work very
- # well when it receives an ctypes.create_unicode_buffer instance as
- # argument. However wd are _always_ indexed with their original
- # unicode paths in wmd.
- byte_path = path.encode(sys.getfilesystemencoding())
- wd_ = LIBC.inotify_add_watch(self._fd,
- ctypes.create_string_buffer(byte_path),
- mask)
- if wd_ < 0:
- return wd_
- watch_ = Watch(wd=wd_, path=path, mask=mask, proc_fun=proc_fun,
- auto_add=auto_add, exclude_filter=exclude_filter)
- self._wmd[wd_] = watch_
- log.debug('New %s', watch_)
- return wd_
-
- def __glob(self, path, do_glob):
- if do_glob:
- return glob.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.
- All |path| components _must_ be str (i.e. unicode) objects.
- If |path| is already watched it is ignored, but if it is called with
- option rec=True a watch is put on each one of its not-watched
- subdirectory.
-
- @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: predicate (boolean function), which returns
- True if the current path must be excluded
- from being watched. This argument has
- precedence over exclude_filter passed to
- the class' constructor.
- @type exclude_filter: callable object
- @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 or was already
- watched 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):
- # Require that path be a unicode string
- if not isinstance(npath, str):
- ret_[path] = -3
- continue
-
- # 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 self.get_wd(rpath) is not None:
- # We decide to ignore paths already inserted into
- # the watch manager. Need to be removed with rm_watch()
- # first. Or simply call update_watch() to update it.
- continue
- if not exclude_filter(rpath):
- wd = ret_[rpath] = self.__add_watch(rpath, mask,
- proc_fun,
- auto_add,
- exclude_filter)
- if wd < 0:
- err = 'add_watch: cannot watch %s WD=%d Errno=%s'
- err = err % (rpath, wd, strerrno())
- 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 is not None:
- # 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
- # apath is always stored as unicode string so encode it to
- # bytes.
- byte_path = apath.encode(sys.getfilesystemencoding())
- wd_ = addw(self._fd, ctypes.create_string_buffer(byte_path),
- mask)
- if wd_ < 0:
- ret_[awd] = False
- err = 'update_watch: cannot update %s WD=%d Errno=%s'
- err = err % (apath, wd_, strerrno())
- 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_.auto_add = 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 = self.__format_path(path)
- for iwd in self._wmd.items():
- if iwd[1].path == path:
- return iwd[0]
-
- 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_ is not None:
- return watch_.path
-
- 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 Errno=%s' % (awd,
- strerrno())
- if quiet:
- log.error(err)
- continue
- raise WatchManagerError(err, ret_)
-
- # Remove watch from our dictionary
- if awd in self._wmd:
- del self._wmd[awd]
- 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):
- if getattr(event, 'name') is None:
- return False
- 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,
- exclude_filter=lambda path: False)
-
-
-class RawOutputFormat:
- """
- Format string representations.
- """
- def __init__(self, format=None):
- self.format = format or {}
-
- def simple(self, s, attribute):
- if not isinstance(s, str):
- s = str(s)
- return (self.format.get(attribute, '') + s +
- self.format.get('normal', ''))
-
- def punctuation(self, s):
- """Punctuation color."""
- return self.simple(s, 'normal')
-
- def field_value(self, s):
- """Field value color."""
- return self.simple(s, 'purple')
-
- def field_name(self, s):
- """Field name color."""
- return self.simple(s, 'blue')
-
- def class_name(self, s):
- """Class name color."""
- return self.format.get('red', '') + self.simple(s, 'bold')
-
-output_format = RawOutputFormat()
-
-class ColoredOutputFormat(RawOutputFormat):
- """
- Format colored string representations.
- """
- def __init__(self):
- f = {'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'}
- RawOutputFormat.__init__(self, f)
-
-
-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")
- parser.add_option("-V", "--version", action="store_true",
- dest="version", help="Pyinotify version")
- parser.add_option("-f", "--raw-format", action="store_true",
- dest="raw_format",
- help="Disable enhanced output format.")
-
- (options, args) = parser.parse_args()
-
- if options.verbose:
- log.setLevel(10)
-
- if options.version:
- print(__version__)
-
- if not options.raw_format:
- global output_format
- output_format = ColoredOutputFormat()
-
- 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):
- sys.stdout.write(repr(s.proc_fun()))
- sys.stdout.write('\n')
- sys.stdout.write(str(s.proc_fun()))
- sys.stdout.write('\n')
- sys.stdout.flush()
- 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()
diff --git a/python2/docstrings/redirect.html b/redirect.html
index 132834b..132834b 100644
--- a/python2/docstrings/redirect.html
+++ b/redirect.html
diff --git a/setup.py b/setup.py
deleted file mode 100755
index d3ad459..0000000
--- a/setup.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-
-# check Python's version
-import sys
-if sys.version < '2.4':
- sys.stderr.write('This module requires at least Python 2.4\n')
- sys.exit(1)
-
-# import statements
-from distutils.core import setup, Extension
-from distutils.util import get_platform
-
-# debug
-DISTUTILS_DEBUG = False
-
-# get platform
-platform = get_platform()
-
-# check linux platform
-if not platform.startswith('linux'):
- sys.stderr.write("inotify is not available under %s\n" % platform)
- sys.exit(1)
-
-classif = [
- 'Environment :: Console',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: MIT License',
- 'Natural Language :: English',
- 'Operating System :: POSIX :: Linux',
- 'Programming Language :: Python',
- 'Topic :: Software Development :: Libraries',
- 'Topic :: System :: Monitoring'
- ]
-
-if sys.version_info[0] >= 3:
- package_dir = {'': 'python3'}
-else:
- package_dir = {'': 'python2'}
-
-setup(
- name='pyinotify',
- version='0.9.0',
- description='Linux filesystem events monitoring',
- author='Sebastien Martini',
- author_email='sebastien.martini@gmail.com',
- license='MIT License',
- platforms='Linux',
- classifiers=classif,
- url='http://trac.dbzteam.org/pyinotify',
- download_url='http://seb.dbzteam.org/pub/pyinotify/releases/pyinotify-0.9.0.tar.gz',
- py_modules=['pyinotify'],
- package_dir=package_dir,
- packages=[''],
- )
diff --git a/python2/docstrings/toc-everything.html b/toc-everything.html
index 9d5df29..9d5df29 100644
--- a/python2/docstrings/toc-everything.html
+++ b/toc-everything.html
diff --git a/python2/docstrings/toc-pyinotify-module.html b/toc-pyinotify-module.html
index 4575263..4575263 100644
--- a/python2/docstrings/toc-pyinotify-module.html
+++ b/toc-pyinotify-module.html
diff --git a/python2/docstrings/toc.html b/toc.html
index a08ff58..a08ff58 100644
--- a/python2/docstrings/toc.html
+++ b/toc.html
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif.gif b/uml_class_diagram_for_pyinotif.gif
index 81c21fd..81c21fd 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif.gif
+++ b/uml_class_diagram_for_pyinotif.gif
Binary files differ
diff --git a/uml_class_diagram_for_pyinotif_10.gif b/uml_class_diagram_for_pyinotif_10.gif
new file mode 100644
index 0000000..9914f19
--- /dev/null
+++ b/uml_class_diagram_for_pyinotif_10.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_11.gif b/uml_class_diagram_for_pyinotif_11.gif
index 9abfa1d..9abfa1d 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_11.gif
+++ b/uml_class_diagram_for_pyinotif_11.gif
Binary files differ
diff --git a/uml_class_diagram_for_pyinotif_12.gif b/uml_class_diagram_for_pyinotif_12.gif
new file mode 100644
index 0000000..a5ae2db
--- /dev/null
+++ b/uml_class_diagram_for_pyinotif_12.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_13.gif b/uml_class_diagram_for_pyinotif_13.gif
index f3992ab..f3992ab 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_13.gif
+++ b/uml_class_diagram_for_pyinotif_13.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_14.gif b/uml_class_diagram_for_pyinotif_14.gif
index bf6a062..bf6a062 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_14.gif
+++ b/uml_class_diagram_for_pyinotif_14.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_15.gif b/uml_class_diagram_for_pyinotif_15.gif
index 41cb487..41cb487 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_15.gif
+++ b/uml_class_diagram_for_pyinotif_15.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_16.gif b/uml_class_diagram_for_pyinotif_16.gif
index b7ae5bc..b7ae5bc 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_16.gif
+++ b/uml_class_diagram_for_pyinotif_16.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_17.gif b/uml_class_diagram_for_pyinotif_17.gif
index a3a11d6..a3a11d6 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_17.gif
+++ b/uml_class_diagram_for_pyinotif_17.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_18.gif b/uml_class_diagram_for_pyinotif_18.gif
index 29a62d1..29a62d1 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_18.gif
+++ b/uml_class_diagram_for_pyinotif_18.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_19.gif b/uml_class_diagram_for_pyinotif_19.gif
index 28dba93..28dba93 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_19.gif
+++ b/uml_class_diagram_for_pyinotif_19.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_2.gif b/uml_class_diagram_for_pyinotif_2.gif
index 8a565ae..8a565ae 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_2.gif
+++ b/uml_class_diagram_for_pyinotif_2.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_20.gif b/uml_class_diagram_for_pyinotif_20.gif
index b244c17..b244c17 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_20.gif
+++ b/uml_class_diagram_for_pyinotif_20.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_21.gif b/uml_class_diagram_for_pyinotif_21.gif
index 01ee6ca..01ee6ca 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_21.gif
+++ b/uml_class_diagram_for_pyinotif_21.gif
Binary files differ
diff --git a/uml_class_diagram_for_pyinotif_22.gif b/uml_class_diagram_for_pyinotif_22.gif
new file mode 100644
index 0000000..a197586
--- /dev/null
+++ b/uml_class_diagram_for_pyinotif_22.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_23.gif b/uml_class_diagram_for_pyinotif_23.gif
index ead2832..ead2832 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_23.gif
+++ b/uml_class_diagram_for_pyinotif_23.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_24.gif b/uml_class_diagram_for_pyinotif_24.gif
index 7b9da91..7b9da91 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_24.gif
+++ b/uml_class_diagram_for_pyinotif_24.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_25.gif b/uml_class_diagram_for_pyinotif_25.gif
index 2cb7fb6..2cb7fb6 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_25.gif
+++ b/uml_class_diagram_for_pyinotif_25.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_26.gif b/uml_class_diagram_for_pyinotif_26.gif
index 63410a2..63410a2 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_26.gif
+++ b/uml_class_diagram_for_pyinotif_26.gif
Binary files differ
diff --git a/uml_class_diagram_for_pyinotif_27.gif b/uml_class_diagram_for_pyinotif_27.gif
new file mode 100644
index 0000000..2d9d208
--- /dev/null
+++ b/uml_class_diagram_for_pyinotif_27.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_28.gif b/uml_class_diagram_for_pyinotif_28.gif
index a061d1a..a061d1a 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_28.gif
+++ b/uml_class_diagram_for_pyinotif_28.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_29.gif b/uml_class_diagram_for_pyinotif_29.gif
index 93fed3a..93fed3a 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_29.gif
+++ b/uml_class_diagram_for_pyinotif_29.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_3.gif b/uml_class_diagram_for_pyinotif_3.gif
index ac6e914..ac6e914 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_3.gif
+++ b/uml_class_diagram_for_pyinotif_3.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_4.gif b/uml_class_diagram_for_pyinotif_4.gif
index c155eaa..c155eaa 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_4.gif
+++ b/uml_class_diagram_for_pyinotif_4.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_5.gif b/uml_class_diagram_for_pyinotif_5.gif
index 809845f..809845f 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_5.gif
+++ b/uml_class_diagram_for_pyinotif_5.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_6.gif b/uml_class_diagram_for_pyinotif_6.gif
index 7ed4b60..7ed4b60 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_6.gif
+++ b/uml_class_diagram_for_pyinotif_6.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_7.gif b/uml_class_diagram_for_pyinotif_7.gif
index 682fad7..682fad7 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_7.gif
+++ b/uml_class_diagram_for_pyinotif_7.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_8.gif b/uml_class_diagram_for_pyinotif_8.gif
index c1598e1..c1598e1 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_8.gif
+++ b/uml_class_diagram_for_pyinotif_8.gif
Binary files differ
diff --git a/python2/docstrings/uml_class_diagram_for_pyinotif_9.gif b/uml_class_diagram_for_pyinotif_9.gif
index 1c40eee..1c40eee 100644
--- a/python2/docstrings/uml_class_diagram_for_pyinotif_9.gif
+++ b/uml_class_diagram_for_pyinotif_9.gif
Binary files differ