Skip to content

Commit

Permalink
[#311] Docs deps autogen sphinx plugin.
Browse files Browse the repository at this point in the history
Added an `add_dependencies` plugin to the Sphinx build process that
parses the manifest files of the scanned backends and plugins and
automatically generates the documentation for the required dependencies
and triggered events.

This means that those dependencies are no longer required to be listed
in the docstring of the class itself.

Also in this commit:

- Black/LINT for some integrations that hadn't been touched in a long
  time.

- Deleted some leftovers from previous refactors (deprecated
  `backend.mqtt`, `backend.zwave.mqtt`, `backend.http.request.rss`).

- Deleted deprecated `inotify` backend - replaced by `file.monitor` (see
  #289).
  • Loading branch information
blacklight committed Oct 1, 2023
1 parent 5ac66ea commit 50eaba7
Show file tree
Hide file tree
Showing 165 changed files with 5,161 additions and 4,721 deletions.
2 changes: 1 addition & 1 deletion .drone.yml
Expand Up @@ -49,7 +49,7 @@ steps:

commands:
- echo "Installing required build dependencies"
- apk add --update --no-cache make py3-sphinx py3-pip py3-paho-mqtt
- apk add --update --no-cache make py3-sphinx py3-pip py3-paho-mqtt py3-yaml
- pip install -U hid sphinx-rtd-theme sphinx-book-theme
- pip install .
- mkdir -p /docs/current
Expand Down
100 changes: 100 additions & 0 deletions docs/source/_ext/add_dependencies.py
@@ -0,0 +1,100 @@
import os
import re

import yaml

from sphinx.application import Sphinx


def add_events(source: list[str], manifest: dict, idx: int) -> int:
events = manifest.get('events', [])
if not events:
return idx

source.insert(
idx,
'Triggered events\n----------------\n\n'
+ '\n'.join(f'\t- :class:`{event}`' for event in events)
+ '\n\n',
)

return idx + 1


def add_install_deps(source: list[str], manifest: dict, idx: int) -> int:
install_deps = manifest.get('install', {})
install_cmds = {
'pip': 'pip install',
'Alpine': 'apk add',
'Arch Linux': 'pacman -S',
'Debian': 'apt install',
'Fedora': 'yum install',
}

parsed_deps = {
'pip': install_deps.get('pip', []),
'Alpine': install_deps.get('apk', []),
'Arch Linux': install_deps.get('pacman', []),
'Debian': install_deps.get('apt', []),
'Fedora': install_deps.get('dnf', install_deps.get('yum', [])),
}

if not any(parsed_deps.values()):
return idx

source.insert(idx, 'Dependencies\n^^^^^^^^^^^^\n\n')
idx += 1

for env, deps in parsed_deps.items():
if deps:
install_cmd = install_cmds[env]
source.insert(
idx,
f'**{env}**\n\n'
+ '.. code-block:: bash\n\n\t'
+ f'{install_cmd} '
+ ' '.join(deps)
+ '\n\n',
)

idx += 1

return idx


def parse_dependencies(_: Sphinx, doc: str, source: list[str]):
if not (source and re.match(r'^platypush/(backend|plugins)/.*', doc)):
return

src = [src.split('\n') for src in source][0]
if len(src) < 3:
return

base_path = os.path.abspath(
os.path.join(os.path.dirname(os.path.relpath(__file__)), '..', '..', '..')
)
manifest_file = os.path.join(
base_path,
*doc.split(os.sep)[:-1],
*doc.split(os.sep)[-1].split('.'),
'manifest.yaml',
)
if not os.path.isfile(manifest_file):
return

with open(manifest_file) as f:
manifest: dict = yaml.safe_load(f).get('manifest', {})

idx = add_install_deps(src, manifest, idx=3)
add_events(src, manifest, idx=idx)
source[0] = '\n'.join(src)


def setup(app: Sphinx):
app.connect('source-read', parse_dependencies)

return {
'version': '0.1',
'parallel_read_safe': True,
'parallel_write_safe': True,
}
3 changes: 0 additions & 3 deletions docs/source/backends.rst
Expand Up @@ -20,15 +20,13 @@ Backends
platypush/backend/google.pubsub.rst
platypush/backend/gps.rst
platypush/backend/http.rst
platypush/backend/inotify.rst
platypush/backend/joystick.rst
platypush/backend/joystick.jstest.rst
platypush/backend/joystick.linux.rst
platypush/backend/kafka.rst
platypush/backend/log.http.rst
platypush/backend/mail.rst
platypush/backend/midi.rst
platypush/backend/mqtt.rst
platypush/backend/music.mopidy.rst
platypush/backend/music.mpd.rst
platypush/backend/music.snapcast.rst
Expand All @@ -52,4 +50,3 @@ Backends
platypush/backend/weather.darksky.rst
platypush/backend/weather.openweathermap.rst
platypush/backend/wiimote.rst
platypush/backend/zwave.mqtt.rst
1 change: 1 addition & 0 deletions docs/source/conf.py
Expand Up @@ -52,6 +52,7 @@
'sphinx.ext.githubpages',
'sphinx_rtd_theme',
'sphinx_marshmallow',
'add_dependencies',
]

# Add any paths that contain templates here, relative to this directory.
Expand Down
6 changes: 0 additions & 6 deletions docs/source/platypush/backend/inotify.rst

This file was deleted.

6 changes: 0 additions & 6 deletions docs/source/platypush/backend/mqtt.rst

This file was deleted.

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

This file was deleted.

6 changes: 0 additions & 6 deletions docs/source/platypush/plugins/http.request.rss.rst

This file was deleted.

1 change: 0 additions & 1 deletion docs/source/plugins.rst
Expand Up @@ -50,7 +50,6 @@ Plugins
platypush/plugins/graphite.rst
platypush/plugins/hid.rst
platypush/plugins/http.request.rst
platypush/plugins/http.request.rss.rst
platypush/plugins/http.webpage.rst
platypush/plugins/ifttt.rst
platypush/plugins/inputs.rst
Expand Down
26 changes: 13 additions & 13 deletions platypush/backend/adafruit/io/__init__.py
Expand Up @@ -2,23 +2,17 @@

from platypush.backend import Backend
from platypush.context import get_plugin
from platypush.message.event.adafruit import ConnectedEvent, DisconnectedEvent, \
FeedUpdateEvent
from platypush.message.event.adafruit import (
ConnectedEvent,
DisconnectedEvent,
FeedUpdateEvent,
)


class AdafruitIoBackend(Backend):
"""
Backend that listens to messages received over the Adafruit IO message queue
Triggers:
* :class:`platypush.message.event.adafruit.ConnectedEvent` when the
backend connects to the Adafruit queue
* :class:`platypush.message.event.adafruit.DisconnectedEvent` when the
backend disconnects from the Adafruit queue
* :class:`platypush.message.event.adafruit.FeedUpdateEvent` when an
update event is received on a monitored feed
Requires:
* The :class:`platypush.plugins.adafruit.io.AdafruitIoPlugin` plugin to
Expand All @@ -33,6 +27,7 @@ def __init__(self, feeds, *args, **kwargs):

super().__init__(*args, **kwargs)
from Adafruit_IO import MQTTClient

self.feeds = feeds
self._client: Optional[MQTTClient] = None

Expand All @@ -41,6 +36,7 @@ def _init_client(self):
return

from Adafruit_IO import MQTTClient

plugin = get_plugin('adafruit.io')
if not plugin:
raise RuntimeError('Adafruit IO plugin not configured')
Expand Down Expand Up @@ -80,8 +76,11 @@ def _handler(client, feed, data):
def run(self):
super().run()

self.logger.info(('Initialized Adafruit IO backend, listening on ' +
'feeds {}').format(self.feeds))
self.logger.info(
('Initialized Adafruit IO backend, listening on ' + 'feeds {}').format(
self.feeds
)
)

while not self.should_stop():
try:
Expand All @@ -94,4 +93,5 @@ def run(self):
self.logger.exception(e)
self._client = None


# vim:sw=4:ts=4:et:

0 comments on commit 50eaba7

Please sign in to comment.