extend README.md
This commit is contained in:
56
README.md
56
README.md
@@ -11,26 +11,60 @@ pip install pyinotifyd
|
|||||||
```
|
```
|
||||||
* Modify /etc/pyinotifyd/config.py according to your needs.
|
* Modify /etc/pyinotifyd/config.py according to your needs.
|
||||||
|
|
||||||
## Global configuration
|
# Configuration
|
||||||
The config file is written in Python syntax. pyinotifyd reads config options from a dictionary named **pyinotifyd_config**.
|
The config file is written in Python syntax. pyinotifyd reads and executes its content, which means you can add custom Python code to the config file.
|
||||||
This is the default configuration:
|
|
||||||
|
To pass config options to pyinotifyd, define a dictionary named **pyinotifyd_config**.
|
||||||
|
This is the default:
|
||||||
```python
|
```python
|
||||||
pyinotifyd_config = {
|
pyinotifyd_config = {
|
||||||
# List of watches, description below
|
# List of watches, see description below
|
||||||
"watches": [],
|
"watches": [],
|
||||||
# Set the loglevel (see https://docs.python.org/3/library/logging.html#levels)
|
|
||||||
|
# Loglevel (see https://docs.python.org/3/library/logging.html#levels)
|
||||||
"loglevel": logging.INFO,
|
"loglevel": logging.INFO,
|
||||||
# Set the timeout to wait for pending tasks to complete during shutdown
|
|
||||||
|
# Timeout to wait for pending tasks to complete during shutdown
|
||||||
"shutdown_timeout": 30
|
"shutdown_timeout": 30
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## Watch configuration
|
|
||||||
A Watch is defined as a dictionary which contains the config options:
|
## Schedulers
|
||||||
|
pyinotifyd comes with different schedulers to schedule tasks with an optional delay. The advantages of using a scheduler are consistent logging and the possibility to cancel delayed tasks.
|
||||||
|
|
||||||
|
### TaskScheduler
|
||||||
|
This scheduler is used to run Python functions.
|
||||||
|
|
||||||
|
class TaskScheduler(*job, delay=0, files=True, dirs=False, logname="TaskScheduler"*)
|
||||||
|
Return a TaskScheduler object configured to call the Python function *job* with a delay of *delay* seconds. Use *files* and *dirs* to define if *job* is called for events on files and/or directories. Log messages with *logname*.
|
||||||
|
|
||||||
|
### ShellScheduler
|
||||||
|
|
||||||
|
## Watches
|
||||||
|
A Watch is defined as a dictionary.
|
||||||
|
This is the default:
|
||||||
```python
|
```python
|
||||||
{
|
{
|
||||||
"path": "/tmp",
|
# path to watch, globbing is allowed
|
||||||
"rec": True,
|
"path": "",
|
||||||
"auto_add": True,
|
|
||||||
|
# set to True to add a watch on each subdirectory
|
||||||
|
"rec": False,
|
||||||
|
|
||||||
|
# set to True to automatically add watches on newly created directories in watched parent path
|
||||||
|
"auto_add": False,
|
||||||
|
|
||||||
|
# dictionary which contains the event map, see description below
|
||||||
"event_map": {}
|
"event_map": {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Event maps
|
||||||
|
An event map is defined as a dictionary. It is used to map different event types to Python functions. Those functions are called with the event-object a task-id as positional arguments if an event is received. It is possible to set a list of functions to run multiple tasks on a single event. If an event type is not present in the map or None is given, the event type is ignored.
|
||||||
|
This is an example:
|
||||||
|
```python
|
||||||
|
{
|
||||||
|
"IN_CLOSE_NOWRITE": [s1.schedule, s2.schedule],
|
||||||
|
"IN_CLOSE_WRITE": s1.schedule
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
Binary file not shown.
@@ -69,10 +69,14 @@ class Task:
|
|||||||
class TaskScheduler:
|
class TaskScheduler:
|
||||||
def __init__(self, job, delay=0, files=True, dirs=False,
|
def __init__(self, job, delay=0, files=True, dirs=False,
|
||||||
logname="TaskScheduler"):
|
logname="TaskScheduler"):
|
||||||
self._delay = delay
|
assert callable(job), f"job: expected callable, got {type(job)}"
|
||||||
self._files = files
|
|
||||||
self._dirs = dirs
|
|
||||||
self._job = job
|
self._job = job
|
||||||
|
assert isinstance(delay, int), f"delay: expected {type(int)}, got {type(delay)}"
|
||||||
|
self._delay = delay
|
||||||
|
assert isinstance(files, bool), f"files: expected {type(bool)}, got {type(files)}"
|
||||||
|
self._files = files
|
||||||
|
assert isinstance(dirs, bool), f"dirs: expected {type(bool)}, got {type(dirs)}"
|
||||||
|
self._dirs = dirs
|
||||||
self._tasks = {}
|
self._tasks = {}
|
||||||
self._log = logging.getLogger(logname)
|
self._log = logging.getLogger(logname)
|
||||||
|
|
||||||
@@ -121,6 +125,7 @@ class TaskScheduler:
|
|||||||
class ShellScheduler(TaskScheduler):
|
class ShellScheduler(TaskScheduler):
|
||||||
def __init__(self, cmd, job=None, logname="ShellScheduler",
|
def __init__(self, cmd, job=None, logname="ShellScheduler",
|
||||||
*args, **kwargs):
|
*args, **kwargs):
|
||||||
|
assert isinstance(cmd, str), f"cmd: expected {type('')}, got {type(cmd)}"
|
||||||
self._cmd = cmd
|
self._cmd = cmd
|
||||||
super().__init__(*args, job=self.job, logname=logname, **kwargs)
|
super().__init__(*args, job=self.job, logname=logname, **kwargs)
|
||||||
|
|
||||||
@@ -285,15 +290,19 @@ def main():
|
|||||||
print(f"pyinotifyd ({__version__})")
|
print(f"pyinotifyd ({__version__})")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
cfg = {
|
cfg = {"watches": [],
|
||||||
"watches": [],
|
|
||||||
"loglevel": logging.INFO,
|
"loglevel": logging.INFO,
|
||||||
"shutdown_timeout": 30}
|
"shutdown_timeout": 30}
|
||||||
|
|
||||||
|
try:
|
||||||
cfg_vars = {"pyinotifyd_config": cfg}
|
cfg_vars = {"pyinotifyd_config": cfg}
|
||||||
with open(args.config, "r") as c:
|
with open(args.config, "r") as c:
|
||||||
exec(c.read(), globals(), cfg_vars)
|
exec(c.read(), globals(), cfg_vars)
|
||||||
|
|
||||||
cfg.update(cfg_vars["pyinotifyd_config"])
|
cfg.update(cfg_vars["pyinotifyd_config"])
|
||||||
|
except Exception as e:
|
||||||
|
print(f"error in config file: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
console = logging.StreamHandler()
|
console = logging.StreamHandler()
|
||||||
formatter = logging.Formatter(
|
formatter = logging.Formatter(
|
||||||
@@ -313,7 +322,15 @@ def main():
|
|||||||
wm = pyinotify.WatchManager()
|
wm = pyinotify.WatchManager()
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
notifiers = []
|
notifiers = []
|
||||||
for watch in cfg["watches"]:
|
for watchcfg in cfg["watches"]:
|
||||||
|
watch = {"path": "",
|
||||||
|
"rec": False,
|
||||||
|
"auto_add": False,
|
||||||
|
"event_map": {}}
|
||||||
|
watch.update(watchcfg)
|
||||||
|
if not watch["path"]:
|
||||||
|
continue
|
||||||
|
|
||||||
mask = False
|
mask = False
|
||||||
handler = pyinotify.ProcessEvent()
|
handler = pyinotify.ProcessEvent()
|
||||||
for flag, values in watch["event_map"].items():
|
for flag, values in watch["event_map"].items():
|
||||||
@@ -350,6 +367,7 @@ def main():
|
|||||||
|
|
||||||
loop.run_until_complete(shutdown(timeout=cfg["shutdown_timeout"]))
|
loop.run_until_complete(shutdown(timeout=cfg["shutdown_timeout"]))
|
||||||
loop.close()
|
loop.close()
|
||||||
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user