extend README.md

This commit is contained in:
2020-11-02 17:55:15 +01:00
parent b27c1bc623
commit 2ddcd16acd
3 changed files with 75 additions and 23 deletions

View File

@@ -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.

View File

@@ -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)