2021-03-14 00:07:17 +01:00
|
|
|
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
|
2021-03-14 01:09:01 +01:00
|
|
|
# the files matching a JPEG extension in case-insensitive mode,
|
2021-03-14 00:07:17 +01:00
|
|
|
# excluding those whose name starts with tmp_ and
|
|
|
|
# all the files contained in the __MACOSX folders
|
|
|
|
- path: ~/my-images
|
|
|
|
recursive: True
|
2021-03-14 01:09:01 +01:00
|
|
|
case_sensitive: False
|
2021-03-14 00:07:17 +01:00
|
|
|
regexes:
|
2021-03-14 01:09:01 +01:00
|
|
|
- '.*\.jpe?g$'
|
2021-03-14 00:07:17 +01:00
|
|
|
ignore_patterns:
|
2021-03-14 01:09:01 +01:00
|
|
|
- '^tmp_.*'
|
2021-03-14 00:07:17 +01:00
|
|
|
ignore_directories:
|
2021-03-14 01:09:01 +01:00
|
|
|
- '__MACOSX'
|
2021-03-14 00:07:17 +01:00
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
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')
|