Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/malthe/macfsevents
Thread-based interface to file system observation primitives.
https://github.com/malthe/macfsevents
Last synced: 7 days ago
JSON representation
Thread-based interface to file system observation primitives.
- Host: GitHub
- URL: https://github.com/malthe/macfsevents
- Owner: malthe
- License: bsd-2-clause
- Created: 2009-11-27T15:40:24.000Z (about 15 years ago)
- Default Branch: master
- Last Pushed: 2024-04-19T05:49:37.000Z (8 months ago)
- Last Synced: 2024-12-08T16:11:48.021Z (16 days ago)
- Language: Python
- Homepage:
- Size: 87.9 KB
- Stars: 66
- Watchers: 10
- Forks: 27
- Open Issues: 13
-
Metadata Files:
- Readme: README.rst
- Changelog: CHANGES.rst
- License: LICENSE.txt
Awesome Lists containing this project
README
.. contents::
Overview
========.. role:: mod(emphasis)
:mod:`MacFSEvents` is a Python library that provides thread-safe
directory observation primitives using callbacks. It wraps the Mac OS
X ``FSEvents`` API in a C-extension.Requirements:
- Mac OS X 10.5+ (Leopard)
- Python 2.7+This software was written by Malthe Borch . The
:mod:`pyfsevents` module by Nicolas Dumazet was used for reference... image:: https://travis-ci.org/malthe/macfsevents.svg
:target: https://travis-ci.org/malthe/macfseventsWhy?
----At this time of writing there are four other libraries that integrate
with the ``FSEvents`` API:**watchdog**:
This library actually builds on the code in :mod:`MacFSEvents` (this
project), but currently does not support Python 3 (though this
should happen soon). It also includes shell utilities.**pyobjc-framework-FSEvents**
These use the PyObjC bridge infrastructure which most applications
do not need.**pyfsevents**
Not thread-safe (API is not designed to support it).
**fsevents**
Obsolete bindings to the socket API by John Sutherland.
The :mod:`MacFSEvents` library provides a clean API and has full test
coverage.Note that :mod:`pyfsevents` has bindings to the file descriptor
observation primitives. This is not currently implemented by the
present library.License
-------Made available as-is under the BSD License.
Usage
=====To observe a directory structure (recursively) under ``path``, we set
up an observer thread and schedule an event stream::from fsevents import Observer
observer = Observer()
observer.start()def callback(FileEvent):
...from fsevents import Stream
stream = Stream(callback, path)
observer.schedule(stream)Streams can observe any number of paths; simply pass them as
positional arguments (or using the ``*`` operator)::stream = Stream(callback, *paths)
To start the observer in its own thread, use the ``start`` method::
observer.start()
To start the observer in the current thread, use the ``run`` method
(it will block the thread until stopped from another thread)::observer.run()
The callback function will be called when an event occurs.
Depending on the stream, the callback will have different signitures:a) the standard stream (with callback and paths) will call callback with
parameters callback(path, mask) where path is the directory where a file
changed and mask can be decoded using FS_FLAG* and FS_ITEM* constants [#]_.
a convenience class Mask has a __str__ function to get a text representation
of the flags.
b) the stream is created with ``ids = True`` keyword parameter. In this case the call
is callback(path, mask, id). The id can be used in the ``since`` keyword
parameter of another stream object to also recieve historic events (that
happened before the stream became active)
c) if ``file_events`` is kwarg set to True, a
``FileEvent`` instance is passed to the callback and has 3 attributes:
``mask``, ``cookie`` and ``name``. ``name`` parameter contains the path
at which the event happened (may be a subdirectory) while ``mask``
parameter is the event mask. this mimicks ``inotify`` behaviour.
see also below.To stop observation, simply unschedule the stream and stop the
observer::observer.unschedule(stream)
observer.stop()While the observer thread will automatically join your main thread at
this point, it doesn't hurt to be explicit about this::observer.join()
We often want to know about events on a file level; to receive file
events instead of path events, pass in ``file_events=True`` to the
stream constructor::def callback(event):
...stream = Stream(callback, path, file_events=True)
The event object mimick the file events of the ``inotify`` kernel
extension available in newer linux kernels. It has the following
attributes:``mask``
The mask field is a bitmask representing the event that occurred.``cookie``
The cookie field is a unique identifier linking together two related but separate events. It is used to link together an ``IN_MOVED_FROM`` and an ``IN_MOVED_TO`` event.``name``
The name field contains the name of the object to which the event occurred. This is the absolute filename.Note that the logic to implement file events is implemented in Python;
a snapshot of the observed file system hierarchies is maintained and
used to monitor file events... [#] See `FSEventStreamEventFlags `_ for a reference. To check for a particular mask, use the *bitwise and* operator ``&``.