platypush/platypush/backend/file/monitor/__init__.py

109 lines
4.1 KiB
Python

from typing import List, Dict, Union, Any
from watchdog.observers import Observer
from platypush.backend import Backend
from .entities.handlers import EventHandlerFactory
from .entities.resources import MonitoredResource
class FileMonitorBackend(Backend):
"""
This backend monitors changes to local files and directories using the Watchdog API.
Triggers:
* :class:`platypush.message.event.file.FileSystemCreateEvent` if a resource is created.
* :class:`platypush.message.event.file.FileSystemDeleteEvent` if a resource is removed.
* :class:`platypush.message.event.file.FileSystemModifyEvent` if a resource is modified.
Requires:
* **watchdog** (``pip install watchdog``)
"""
def __init__(self, paths: List[Union[str, Dict[str, Any], MonitoredResource]], **kwargs):
"""
:param paths: List of paths to monitor. Paths can either be expressed in any of the following ways:
- Simple strings. In this case, paths will be interpreted as absolute references to a file or a directory
to monitor. Example:
.. code-block:: yaml
backend.file.monitor:
paths:
# Monitor changes on the /tmp folder
- /tmp
# Monitor changes on /etc/passwd
- /etc/passwd
- Path with monitoring properties expressed as a key-value object. Example showing the supported attributes:
.. code-block:: yaml
backend.file.monitor:
paths:
# Monitor changes on the /tmp folder and its subfolders
- path: /tmp
recursive: True
- Path with pattern-based search criteria for the files to monitor and exclude. Example:
.. code-block:: yaml
backend.file.monitor:
paths:
# Recursively monitor changes on the ~/my-project folder that include all
# *.py files, excluding those whose name starts with tmp_ and
# all the files contained in the __pycache__ folders
- path: ~/my-project
recursive: True
patterns:
- "*.py"
ignore_patterns:
- "tmp_*"
ignore_directories:
- "__pycache__"
- Path with regex-based search criteria for the files to monitor and exclude. Example:
.. code-block:: yaml
backend.file.monitor:
paths:
# Recursively monitor changes on the ~/my-images folder that include all
# the files matching the "\.jpe?g$" pattern in case-insensitive mode,
# excluding those whose name starts with tmp_ and
# all the files contained in the __MACOSX folders
- path: ~/my-images
recursive: True
regexes:
- ".*\.jpe?g$"
ignore_patterns:
- "^tmp_.*"
ignore_directories:
- "__MACOSX"
"""
super().__init__(**kwargs)
self._observer = Observer()
for path in paths:
handler = EventHandlerFactory.from_resource(path)
self._observer.schedule(handler, handler.resource.path, recursive=handler.resource.recursive)
def run(self):
super().run()
self.logger.info('Initializing file monitor backend')
self._observer.start()
self.wait_stop()
def on_stop(self):
self.logger.info('Stopping file monitor backend')
self._observer.stop()
self._observer.join()
self.logger.info('Stopped file monitor backend')