Skip to content

Commit

Permalink
[#289] Converted backend.file.monitor into a runnable plugin.
Browse files Browse the repository at this point in the history
Closes: #289
  • Loading branch information
blacklight committed Dec 4, 2023
1 parent d484a34 commit 1843ab2
Show file tree
Hide file tree
Showing 16 changed files with 231 additions and 184 deletions.
2 changes: 0 additions & 2 deletions docs/source/backends.rst
Expand Up @@ -11,7 +11,6 @@ Backends
platypush/backend/button.flic.rst
platypush/backend/camera.pi.rst
platypush/backend/chat.telegram.rst
platypush/backend/file.monitor.rst
platypush/backend/foursquare.rst
platypush/backend/github.rst
platypush/backend/google.fit.rst
Expand All @@ -28,7 +27,6 @@ Backends
platypush/backend/nextcloud.rst
platypush/backend/nfc.rst
platypush/backend/nodered.rst
platypush/backend/ping.rst
platypush/backend/pushbullet.rst
platypush/backend/redis.rst
platypush/backend/scard.rst
Expand Down
5 changes: 0 additions & 5 deletions docs/source/platypush/backend/file.monitor.rst

This file was deleted.

5 changes: 0 additions & 5 deletions docs/source/platypush/backend/ping.rst

This file was deleted.

5 changes: 5 additions & 0 deletions docs/source/platypush/plugins/file.monitor.rst
@@ -0,0 +1,5 @@
``file.monitor``
================

.. automodule:: platypush.plugins.file.monitor
:members:
5 changes: 0 additions & 5 deletions docs/source/platypush/responses/ping.rst

This file was deleted.

1 change: 1 addition & 0 deletions docs/source/plugins.rst
Expand Up @@ -33,6 +33,7 @@ Plugins
platypush/plugins/esp.rst
platypush/plugins/ffmpeg.rst
platypush/plugins/file.rst
platypush/plugins/file.monitor.rst
platypush/plugins/foursquare.rst
platypush/plugins/google.calendar.rst
platypush/plugins/google.drive.rst
Expand Down
1 change: 0 additions & 1 deletion docs/source/responses.rst
Expand Up @@ -11,7 +11,6 @@ Responses
platypush/responses/chat.telegram.rst
platypush/responses/google.drive.rst
platypush/responses/pihole.rst
platypush/responses/ping.rst
platypush/responses/printer.cups.rst
platypush/responses/qrcode.rst
platypush/responses/ssh.rst
Expand Down
127 changes: 0 additions & 127 deletions platypush/backend/file/monitor/__init__.py

This file was deleted.

Empty file.
18 changes: 0 additions & 18 deletions platypush/backend/file/monitor/manifest.yaml

This file was deleted.

24 changes: 24 additions & 0 deletions platypush/config/config.yaml
Expand Up @@ -382,6 +382,30 @@ backend.http:
# - https://api.quantamagazine.org/feed/
###

###
# # The file monitor plugin can be used to track modifications to the
# # filesystem - for example, when a file or a directory is modified, created
# # or removed.
#
# file.monitor:
# paths:
# # Recursively monitor changes on the
# # ~/my-images folder that include all the files
# # matching a JPEG extension 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
# case_sensitive: false
# regexes:
# - '.*\\.jpe?g$'
# ignore_patterns:
# - '^tmp_.*'
# ignore_directories:
# - '__MACOSX'
###

###
# # Example configuration of a weather plugin
#
Expand Down
140 changes: 140 additions & 0 deletions platypush/plugins/file/monitor/__init__.py
@@ -0,0 +1,140 @@
from typing import Iterable, Dict, Optional, Union, Any

from watchdog.observers import Observer

from platypush.plugins import RunnablePlugin

from .entities.handlers import EventHandler
from .entities.resources import MonitoredResource, MonitoredPattern, MonitoredRegex


def event_handler_from_resource(
resource: Union[str, Dict[str, Any], MonitoredResource]
) -> Optional[EventHandler]:
"""
Create a file system event handler from a string, dictionary or
``MonitoredResource`` resource.
"""

if isinstance(resource, str):
res = MonitoredResource(resource)
elif isinstance(resource, dict):
if 'regexes' in resource or 'ignore_regexes' in resource:
res = MonitoredRegex(**resource)
elif (
'patterns' in resource
or 'ignore_patterns' in resource
or 'ignore_directories' in resource
):
res = MonitoredPattern(**resource)
else:
res = MonitoredResource(**resource)
else:
return None

return EventHandler.from_resource(res)


class FileMonitorPlugin(RunnablePlugin):
"""
A plugin to monitor changes to files and directories.
"""

def __init__(
self, paths: Iterable[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
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
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
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
file.monitor:
paths:
# Recursively monitor changes on the
# ~/my-images folder that include all the files
# matching a JPEG extension 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
case_sensitive: False
regexes:
- '.*\\.jpe?g$'
ignore_patterns:
- '^tmp_.*'
ignore_directories:
- '__MACOSX'
"""

super().__init__(**kwargs)
self._observer = Observer()

for path in paths:
handler = event_handler_from_resource(path)
if not handler:
continue

self._observer.schedule(
handler, handler.resource.path, recursive=handler.resource.recursive
)

def stop(self):
self._observer.stop()
self._observer.join()
super().stop()

def main(self):
self._observer.start()
self.wait_stop()
File renamed without changes.

0 comments on commit 1843ab2

Please sign in to comment.