Skip to content

Commit 7045a3e

Browse files
committed
Convert README.rst to README.md and modernize
This includes an update to use the Github badge.
1 parent 5389d13 commit 7045a3e

5 files changed

Lines changed: 79 additions & 92 deletions

File tree

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
include inotify/resources/requirements.txt
2-
include inotify/resources/README.rst
2+
include inotify/resources/README.md

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
inotify/resources/README.md

README.rst

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 74 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
|Build\_Status|
2-
|Coverage\_Status|
1+
[![Unit Testing](https://github.com/dsoprea/PyInotify/actions/workflows/push_event_workflow.yml/badge.svg)](https://github.com/dsoprea/PyInotify/actions/workflows/push_event_workflow.yml)
32

4-
========
5-
Overview
6-
========
3+
# Overview
74

85
*inotify* functionality is available from the Linux kernel and allows you to register one or more directories for watching, and to simply block and wait for notification events. This is obviously far more efficient than polling one or more directories to determine if anything has changed. This is available in the Linux kernel as of version 2.6 .
96

@@ -12,105 +9,103 @@ We've designed this library to act as a generator. All you have to do is loop, a
129
**This project is unrelated to the *PyInotify* project that existed prior to this one (this project began in 2015). That project is defunct and no longer available.**
1310

1411

15-
==========
16-
Installing
17-
==========
12+
# Installing
1813

19-
Install via *pip*::
14+
Install via *pip*:
2015

21-
$ sudo pip install inotify
16+
```
17+
$ sudo pip install inotify
18+
```
2219

2320

24-
=======
25-
Example
26-
=======
21+
# Example
2722

2823
Code for monitoring a simple, flat path (see "Recursive Watching" for watching a hierarchical structure):
24+
```python
25+
import inotify.adapters
2926

30-
.. code-block:: python
27+
def _main():
28+
i = inotify.adapters.Inotify()
3129

32-
import inotify.adapters
30+
i.add_watch('/tmp')
3331

34-
def _main():
35-
i = inotify.adapters.Inotify()
36-
37-
i.add_watch('/tmp')
38-
39-
with open('/tmp/test_file', 'w'):
40-
pass
41-
42-
for event in i.event_gen(yield_nones=False):
43-
(_, type_names, path, filename) = event
44-
45-
print("PATH=[{}] FILENAME=[{}] EVENT_TYPES={}".format(
46-
path, filename, type_names))
47-
48-
if __name__ == '__main__':
49-
_main()
50-
51-
Output::
32+
with open('/tmp/test_file', 'w'):
33+
pass
5234

53-
PATH=[/tmp] FILENAME=[test_file] EVENT_TYPES=['IN_MODIFY']
54-
PATH=[/tmp] FILENAME=[test_file] EVENT_TYPES=['IN_OPEN']
55-
PATH=[/tmp] FILENAME=[test_file] EVENT_TYPES=['IN_CLOSE_WRITE']
56-
^CTraceback (most recent call last):
57-
File "inotify_test.py", line 18, in <module>
58-
_main()
59-
File "inotify_test.py", line 11, in _main
60-
for event in i.event_gen(yield_nones=False):
61-
File "/home/dustin/development/python/pyinotify/inotify/adapters.py", line 202, in event_gen
62-
events = self.__epoll.poll(block_duration_s)
63-
KeyboardInterrupt
35+
for event in i.event_gen(yield_nones=False):
36+
(_, type_names, path, filename) = event
37+
38+
print("PATH=[{}] FILENAME=[{}] EVENT_TYPES={}".format(
39+
path, filename, type_names))
40+
41+
if __name__ == '__main__':
42+
_main()
43+
```
44+
45+
Output:
46+
```
47+
PATH=[/tmp] FILENAME=[test_file] EVENT_TYPES=['IN_MODIFY']
48+
PATH=[/tmp] FILENAME=[test_file] EVENT_TYPES=['IN_OPEN']
49+
PATH=[/tmp] FILENAME=[test_file] EVENT_TYPES=['IN_CLOSE_WRITE']
50+
^CTraceback (most recent call last):
51+
File "inotify_test.py", line 18, in <module>
52+
_main()
53+
File "inotify_test.py", line 11, in _main
54+
for event in i.event_gen(yield_nones=False):
55+
File "/home/dustin/development/python/pyinotify/inotify/adapters.py", line 202, in event_gen
56+
events = self.__epoll.poll(block_duration_s)
57+
KeyboardInterrupt
58+
```
6459

6560
Note that this works quite nicely, but, in the event that you don't want to be driven by the loop, you can also provide a timeout and then even flatten the output of the generator directly to a list:
6661

67-
.. code-block:: python
68-
69-
import inotify.adapters
62+
```python
63+
import inotify.adapters
7064

71-
def _main():
72-
i = inotify.adapters.Inotify()
65+
def _main():
66+
i = inotify.adapters.Inotify()
7367

74-
i.add_watch('/tmp')
68+
i.add_watch('/tmp')
7569

76-
with open('/tmp/test_file', 'w'):
77-
pass
70+
with open('/tmp/test_file', 'w'):
71+
pass
7872

79-
events = i.event_gen(yield_nones=False, timeout_s=1)
80-
events = list(events)
73+
events = i.event_gen(yield_nones=False, timeout_s=1)
74+
events = list(events)
8175

82-
print(events)
76+
print(events)
8377

84-
if __name__ == '__main__':
85-
_main()
78+
if __name__ == '__main__':
79+
_main()
80+
```
8681

87-
This will return everything that's happened since the last time you ran it (artificially formatted here)::
82+
This will return everything that's happened since the last time you ran it (artificially formatted here):
8883

89-
[
90-
(_INOTIFY_EVENT(wd=1, mask=2, cookie=0, len=16), ['IN_MODIFY'], '/tmp', u'test_file'),
91-
(_INOTIFY_EVENT(wd=1, mask=32, cookie=0, len=16), ['IN_OPEN'], '/tmp', u'test_file'),
92-
(_INOTIFY_EVENT(wd=1, mask=8, cookie=0, len=16), ['IN_CLOSE_WRITE'], '/tmp', u'test_file')
93-
]
84+
```python
85+
[
86+
(_INOTIFY_EVENT(wd=1, mask=2, cookie=0, len=16), ['IN_MODIFY'], '/tmp', u'test_file'),
87+
(_INOTIFY_EVENT(wd=1, mask=32, cookie=0, len=16), ['IN_OPEN'], '/tmp', u'test_file'),
88+
(_INOTIFY_EVENT(wd=1, mask=8, cookie=0, len=16), ['IN_CLOSE_WRITE'], '/tmp', u'test_file')
89+
]
90+
```
9491

9592
**Note that the event-loop will automatically register new directories to be watched, so, if you will create new directories and then potentially delete them, between calls, and are only retrieving the events in batches (like above) then you might experience issues. See the parameters for `event_gen()` for options to handle this scenario.**
9693

9794

98-
==================
99-
Recursive Watching
100-
==================
95+
# Recursive Watching
10196

10297
There is also the ability to add a recursive watch on a path.
10398

10499
Example:
105100

106-
.. code-block:: python
101+
```python
102+
i = inotify.adapters.InotifyTree('/tmp/watch_tree')
107103

108-
i = inotify.adapters.InotifyTree('/tmp/watch_tree')
104+
for event in i.event_gen():
105+
# Do stuff...
109106

110-
for event in i.event_gen():
111-
# Do stuff...
112-
113-
pass
107+
pass
108+
```
114109

115110
This will immediately recurse through the directory tree and add watches on all subdirectories. New directories will automatically have watches added for them and deleted directories will be cleaned-up.
116111

@@ -120,9 +115,7 @@ The other differences from the standard functionality:
120115
- Even if you provide a very restrictive mask that doesn't allow for directory create/delete events, the *IN_ISDIR*, *IN_CREATE*, and *IN_DELETE* flags will still be seen.
121116

122117

123-
=====
124-
Notes
125-
=====
118+
# Notes
126119

127120
- **IMPORTANT:** Recursively monitoring paths is **not** a functionality provided by the kernel. Rather, we artificially implement it. As directory-created events are received, we create watches for the child directories on-the-fly. This means that there is potential for a race condition: if a directory is created and a file or directory is created inside before you (using the `event_gen()` loop) have a chance to observe it, then you are going to have a problem: If it is a file, then you will miss the events related to its creation, but, if it is a directory, then not only will you miss those creation events but this library will also miss them and not be able to add a watch for them. If you are dealing with a **large number of hierarchical directory creations** and have the ability to be aware new directories via a secondary channel with some lead time before any files are populated *into* them, you can take advantage of this and call `add_watch()` manually. In this case there is limited value in using `InotifyTree()`/`InotifyTree()` instead of just `Inotify()` but this choice is left to you.
128121

@@ -135,16 +128,11 @@ Notes
135128
- Calling `remove_watch()` is not strictly necessary. The *inotify* resources is automatically cleaned-up, which would clean-up all watch resources as well.
136129

137130

138-
=======
139-
Testing
140-
=======
141-
142-
Install the testing dependencies and use nose2 to run the tests::
131+
# Testing
143132

144-
$ pip install -r requirements-testing.txt
145-
$ ./test.sh
133+
Install the testing dependencies and use nose2 to run the tests:
146134

147-
.. |Build_Status| image:: https://travis-ci.org/dsoprea/PyInotify.svg?branch=master
148-
:target: https://travis-ci.org/dsoprea/PyInotify
149-
.. |Coverage_Status| image:: https://coveralls.io/repos/github/dsoprea/PyInotify/badge.svg?branch=master
150-
:target: https://coveralls.io/github/dsoprea/PyInotify?branch=master
135+
```
136+
$ pip install -r requirements-testing.txt
137+
$ ./test.sh
138+
```

setup.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import setuptools
22
import os
33

4-
with open(os.path.join('inotify', 'resources', 'README.rst')) as f:
4+
with open(os.path.join('inotify', 'resources', 'README.md')) as f:
55
_LONG_DESCRIPTION = f.read()
66

77
with open(os.path.join('inotify', 'resources', 'requirements.txt')) as f:
@@ -15,8 +15,7 @@
1515
version='0.2.11',
1616
description=_DESCRIPTION,
1717
long_description=_LONG_DESCRIPTION,
18-
classifiers=[
19-
],
18+
long_description_content_type='text/markdown',
2019
keywords='inotify',
2120
author='Dustin Oprea',
2221
author_email='myselfasunder@gmail.com',
@@ -28,7 +27,7 @@
2827
install_requires=_INSTALL_REQUIRES,
2928
package_data={
3029
'inotify': [
31-
'resources/README.rst',
30+
'resources/README.md',
3231
'resources/requirements.txt',
3332
]
3433
},

0 commit comments

Comments
 (0)