diff --git a/CHANGELOG.md b/CHANGELOG.md index 941814af1c..8014cf5b69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,22 @@ # Changelog +## [Unreleased] + +- [[#281](https://git.platypush.tech/platypush/platypush/issues/281)] + replaced `warnings.warn` with `logging.warning`, as there is no easy and + reliable way of routing `warnings.warn` to `logging`. + +## [1.1.0] - 2024-06-06 + +- [[#405](https://git.platypush.tech/platypush/platypush/issues/405)] Fixed + timezone/timestamp rendering issues for `calendar.ical` events. +- [[#403]((https://git.platypush.tech/platypush/platypush/issues/403))] + Included inherited actions in plugins docs. + ## [1.0.7] - 2024-06-02 -- [#384] Added `assistant.openai` and `tts.openai` plugins. +- [[#384]((https://git.platypush.tech/platypush/platypush/issues/384))] Added + `assistant.openai` and `tts.openai` plugins. ## [1.0.6] - 2024-06-01 diff --git a/docs/source/conf.py b/docs/source/conf.py index d17417b3cf..c34efd8243 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -21,7 +21,7 @@ sys.path.insert(0, os.path.abspath("./_ext")) # -- Project information ----------------------------------------------------- project = 'Platypush' -copyright = '2017-2023, Fabio Manganiello' +copyright = '2017-2024, Fabio Manganiello' author = 'Fabio Manganiello ' # The short X.Y version @@ -199,6 +199,7 @@ intersphinx_mapping = {'python': ('https://docs.python.org/3', None)} autodoc_default_options = { 'members': True, 'show-inheritance': True, + 'inherited-members': True, } sys.path.insert(0, os.path.abspath('../..')) diff --git a/platypush/__init__.py b/platypush/__init__.py index b0c3a582f9..96f3cce5f4 100644 --- a/platypush/__init__.py +++ b/platypush/__init__.py @@ -23,7 +23,7 @@ when = hook __author__ = 'Fabio Manganiello ' -__version__ = '1.0.7' +__version__ = '1.1.0' __all__ = [ 'Application', 'Variable', diff --git a/platypush/backend/http/webapp/package-lock.json b/platypush/backend/http/webapp/package-lock.json index fe1e976c4b..0c1b78314f 100644 --- a/platypush/backend/http/webapp/package-lock.json +++ b/platypush/backend/http/webapp/package-lock.json @@ -11,14 +11,14 @@ "@fortawesome/fontawesome-free": "^6.5.2", "axios": "^1.6.8", "core-js": "^3.37.1", - "cronstrue": "^2.49.0", + "cronstrue": "^2.50.0", "highlight.js": "^11.9.0", "lato-font": "^3.0.0", "mitt": "^2.1.0", "register-service-worker": "^1.7.2", - "sass": "^1.75.0", + "sass": "^1.76.0", "sass-loader": "^10.5.2", - "vue": "^3.4.23", + "vue": "^3.4.24", "vue-router": "^4.3.2", "vue-skycons": "^4.3.4", "w3css": "^2.7.0" @@ -3080,12 +3080,12 @@ "dev": true }, "node_modules/@vue/compiler-core": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.23.tgz", - "integrity": "sha512-HAFmuVEwNqNdmk+w4VCQ2pkLk1Vw4XYiiyxEp3z/xvl14aLTUBw2OfVH3vBcx+FtGsynQLkkhK410Nah1N2yyQ==", + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.24.tgz", + "integrity": "sha512-vbW/tgbwJYj62N/Ww99x0zhFTkZDTcGh3uwJEuadZ/nF9/xuFMC4693P9r+3sxGXISABpDKvffY5ApH9pmdd1A==", "dependencies": { - "@babel/parser": "^7.24.1", - "@vue/shared": "3.4.23", + "@babel/parser": "^7.24.4", + "@vue/shared": "3.4.24", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" @@ -3103,37 +3103,37 @@ } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.23.tgz", - "integrity": "sha512-t0b9WSTnCRrzsBGrDd1LNR5HGzYTr7LX3z6nNBG+KGvZLqrT0mY6NsMzOqlVMBKKXKVuusbbB5aOOFgTY+senw==", + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.24.tgz", + "integrity": "sha512-4XgABML/4cNndVsQndG6BbGN7+EoisDwi3oXNovqL/4jdNhwvP8/rfRMTb6FxkxIxUUtg6AI1/qZvwfSjxJiWA==", "dependencies": { - "@vue/compiler-core": "3.4.23", - "@vue/shared": "3.4.23" + "@vue/compiler-core": "3.4.24", + "@vue/shared": "3.4.24" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.23.tgz", - "integrity": "sha512-fSDTKTfzaRX1kNAUiaj8JB4AokikzStWgHooMhaxyjZerw624L+IAP/fvI4ZwMpwIh8f08PVzEnu4rg8/Npssw==", + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.24.tgz", + "integrity": "sha512-nRAlJUK02FTWfA2nuvNBAqsDZuERGFgxZ8sGH62XgFSvMxO2URblzulExsmj4gFZ8e+VAyDooU9oAoXfEDNxTA==", "dependencies": { - "@babel/parser": "^7.24.1", - "@vue/compiler-core": "3.4.23", - "@vue/compiler-dom": "3.4.23", - "@vue/compiler-ssr": "3.4.23", - "@vue/shared": "3.4.23", + "@babel/parser": "^7.24.4", + "@vue/compiler-core": "3.4.24", + "@vue/compiler-dom": "3.4.24", + "@vue/compiler-ssr": "3.4.24", + "@vue/shared": "3.4.24", "estree-walker": "^2.0.2", - "magic-string": "^0.30.8", + "magic-string": "^0.30.10", "postcss": "^8.4.38", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.23.tgz", - "integrity": "sha512-hb6Uj2cYs+tfqz71Wj6h3E5t6OKvb4MVcM2Nl5i/z1nv1gjEhw+zYaNOV+Xwn+SSN/VZM0DgANw5TuJfxfezPg==", + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.24.tgz", + "integrity": "sha512-ZsAtr4fhaUFnVcDqwW3bYCSDwq+9Gk69q2r/7dAHDrOMw41kylaMgOP4zRnn6GIEJkQznKgrMOGPMFnLB52RbQ==", "dependencies": { - "@vue/compiler-dom": "3.4.23", - "@vue/shared": "3.4.23" + "@vue/compiler-dom": "3.4.24", + "@vue/shared": "3.4.24" } }, "node_modules/@vue/component-compiler-utils": { @@ -3206,48 +3206,48 @@ "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" }, "node_modules/@vue/reactivity": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.23.tgz", - "integrity": "sha512-GlXR9PL+23fQ3IqnbSQ8OQKLodjqCyoCrmdLKZk3BP7jN6prWheAfU7a3mrltewTkoBm+N7qMEb372VHIkQRMQ==", + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.24.tgz", + "integrity": "sha512-nup3fSYg4i4LtNvu9slF/HF/0dkMQYfepUdORBcMSsankzRPzE7ypAFurpwyRBfU1i7Dn1kcwpYsE1wETSh91g==", "dependencies": { - "@vue/shared": "3.4.23" + "@vue/shared": "3.4.24" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.23.tgz", - "integrity": "sha512-FeQ9MZEXoFzFkFiw9MQQ/FWs3srvrP+SjDKSeRIiQHIhtkzoj0X4rWQlRNHbGuSwLra6pMyjAttwixNMjc/xLw==", + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.24.tgz", + "integrity": "sha512-c7iMfj6cJMeAG3s5yOn9Rc5D9e2/wIuaozmGf/ICGCY3KV5H7mbTVdvEkd4ZshTq7RUZqj2k7LMJWVx+EBiY1g==", "dependencies": { - "@vue/reactivity": "3.4.23", - "@vue/shared": "3.4.23" + "@vue/reactivity": "3.4.24", + "@vue/shared": "3.4.24" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.23.tgz", - "integrity": "sha512-RXJFwwykZWBkMiTPSLEWU3kgVLNAfActBfWFlZd0y79FTUxexogd0PLG4HH2LfOktjRxV47Nulygh0JFXe5f9A==", + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.24.tgz", + "integrity": "sha512-uXKzuh/Emfad2Y7Qm0ABsLZZV6H3mAJ5ZVqmAOlrNQRf+T5mxpPGZBfec1hkP41t6h6FwF6RSGCs/gd8WbuySQ==", "dependencies": { - "@vue/runtime-core": "3.4.23", - "@vue/shared": "3.4.23", + "@vue/runtime-core": "3.4.24", + "@vue/shared": "3.4.24", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.23.tgz", - "integrity": "sha512-LDwGHtnIzvKFNS8dPJ1SSU5Gvm36p2ck8wCZc52fc3k/IfjKcwCyrWEf0Yag/2wTFUBXrqizfhK9c/mC367dXQ==", + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.24.tgz", + "integrity": "sha512-H+DLK4sQF6sRgzKyofmlEVBIV/9KrQU6HIV7nt6yIwSGGKvSwlV8pqJlebUKLpbXaNHugdSfAbP6YmXF69lxow==", "dependencies": { - "@vue/compiler-ssr": "3.4.23", - "@vue/shared": "3.4.23" + "@vue/compiler-ssr": "3.4.24", + "@vue/shared": "3.4.24" }, "peerDependencies": { - "vue": "3.4.23" + "vue": "3.4.24" } }, "node_modules/@vue/shared": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.23.tgz", - "integrity": "sha512-wBQ0gvf+SMwsCQOyusNw/GoXPV47WGd1xB5A1Pgzy0sQ3Bi5r5xm3n+92y3gCnB3MWqnRDdvfkRGxhKtbBRNgg==" + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.24.tgz", + "integrity": "sha512-BW4tajrJBM9AGAknnyEw5tO2xTmnqgup0VTnDAMcxYmqOX0RG0b9aSUGAbEKolD91tdwpA6oCwbltoJoNzpItw==" }, "node_modules/@vue/vue-loader-v15": { "name": "vue-loader", @@ -4701,9 +4701,10 @@ } }, "node_modules/cronstrue": { - "version": "2.49.0", - "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-2.49.0.tgz", - "integrity": "sha512-FWZBqdStQaPR8ZTBQGALh1EK9Hl1HcG70dyGvD1rKLPafFO3H73o38dz/e8YkIlbLn3JxmBI/f6Doe3Nh+DcEQ==", + "version": "2.50.0", + "resolved": "https://registry.npmjs.org/cronstrue/-/cronstrue-2.50.0.tgz", + "integrity": "sha512-ULYhWIonJzlScCCQrPUG5uMXzXxSixty4djud9SS37DoNxDdkeRocxzHuAo4ImRBUK+mAuU5X9TSwEDccnnuPg==", + "license": "MIT", "bin": { "cronstrue": "bin/cli.js" } @@ -10552,9 +10553,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.75.0.tgz", - "integrity": "sha512-ShMYi3WkrDWxExyxSZPst4/okE9ts46xZmJDSawJQrnte7M1V9fScVB+uNXOVKRBt0PggHOwoZcn8mYX4trnBw==", + "version": "1.76.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.76.0.tgz", + "integrity": "sha512-nc3LeqvF2FNW5xGF1zxZifdW3ffIz5aBb7I7tSvOoNu7z1RQ6pFt9MBuiPtjgaI62YWrM/txjWlOCFiGtf2xpw==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -11977,15 +11978,15 @@ } }, "node_modules/vue": { - "version": "3.4.23", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.23.tgz", - "integrity": "sha512-X1y6yyGJ28LMUBJ0k/qIeKHstGd+BlWQEOT40x3auJFTmpIhpbKLgN7EFsqalnJXq1Km5ybDEsp6BhuWKciUDg==", + "version": "3.4.24", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.24.tgz", + "integrity": "sha512-NPdx7dLGyHmKHGRRU5bMRYVE+rechR+KDU5R2tSTNG36PuMwbfAJ+amEvOAw7BPfZp5sQulNELSLm5YUkau+Sg==", "dependencies": { - "@vue/compiler-dom": "3.4.23", - "@vue/compiler-sfc": "3.4.23", - "@vue/runtime-dom": "3.4.23", - "@vue/server-renderer": "3.4.23", - "@vue/shared": "3.4.23" + "@vue/compiler-dom": "3.4.24", + "@vue/compiler-sfc": "3.4.24", + "@vue/runtime-dom": "3.4.24", + "@vue/server-renderer": "3.4.24", + "@vue/shared": "3.4.24" }, "peerDependencies": { "typescript": "*" diff --git a/platypush/backend/http/webapp/package.json b/platypush/backend/http/webapp/package.json index f8a9e28cc6..aa984179a6 100644 --- a/platypush/backend/http/webapp/package.json +++ b/platypush/backend/http/webapp/package.json @@ -11,14 +11,14 @@ "@fortawesome/fontawesome-free": "^6.5.2", "axios": "^1.6.8", "core-js": "^3.37.1", - "cronstrue": "^2.49.0", + "cronstrue": "^2.50.0", "highlight.js": "^11.9.0", "lato-font": "^3.0.0", "mitt": "^2.1.0", "register-service-worker": "^1.7.2", - "sass": "^1.75.0", + "sass": "^1.76.0", "sass-loader": "^10.5.2", - "vue": "^3.4.23", + "vue": "^3.4.24", "vue-router": "^4.3.2", "vue-skycons": "^4.3.4", "w3css": "^2.7.0" diff --git a/platypush/components.json.gz b/platypush/components.json.gz index e68a12f4a3..be01fa8415 100644 Binary files a/platypush/components.json.gz and b/platypush/components.json.gz differ diff --git a/platypush/plugins/__init__.py b/platypush/plugins/__init__.py index a1ed1eb0e0..edb33fc5dd 100644 --- a/platypush/plugins/__init__.py +++ b/platypush/plugins/__init__.py @@ -1,7 +1,6 @@ import asyncio import logging import threading -import warnings from abc import ABC, abstractmethod from functools import wraps @@ -168,11 +167,7 @@ class RunnablePlugin(Plugin): self._thread: Optional[threading.Thread] = None if kwargs.get('poll_seconds') is not None: - warnings.warn( - 'poll_seconds is deprecated, use poll_interval instead', - DeprecationWarning, - stacklevel=2, - ) + self.logger.warning('poll_seconds is deprecated, use poll_interval instead') if self.poll_interval is None: self.poll_interval = kwargs['poll_seconds'] diff --git a/platypush/plugins/calendar/ical/__init__.py b/platypush/plugins/calendar/ical/__init__.py index e71325a4e4..51f501fb63 100644 --- a/platypush/plugins/calendar/ical/__init__.py +++ b/platypush/plugins/calendar/ical/__init__.py @@ -1,7 +1,9 @@ import datetime -import requests from typing import Optional +import requests +from dateutil.tz import gettz + from platypush.plugins import Plugin, action from platypush.plugins.calendar import CalendarInterface from platypush.utils import utcnow @@ -21,19 +23,20 @@ class CalendarIcalPlugin(Plugin, CalendarInterface): self.url = url @staticmethod - def _convert_timestamp(event, attribute: str) -> Optional[str]: + def _convert_timestamp(event: dict, attribute: str) -> Optional[str]: t = event.get(attribute) if not t: - return + return None - if isinstance(t.dt, datetime.date): + if isinstance(t.dt, datetime.date) and not isinstance(t.dt, datetime.datetime): return datetime.datetime( - t.dt.year, t.dt.month, t.dt.day, tzinfo=datetime.timezone.utc + t.dt.year, t.dt.month, t.dt.day, tzinfo=gettz() ).isoformat() return ( - datetime.datetime.utcfromtimestamp(t.dt.timestamp()) - .replace(tzinfo=datetime.timezone.utc) + datetime.datetime.fromtimestamp(t.dt.timestamp()) + .replace(tzinfo=t.dt.tzinfo or gettz()) + .astimezone(datetime.timezone.utc) .isoformat() ) @@ -82,10 +85,10 @@ class CalendarIcalPlugin(Plugin, CalendarInterface): from icalendar import Calendar events = [] - response = requests.get(self.url) - assert response.ok, "HTTP error while getting events from {}: {}".format( - self.url, response.text - ) + response = requests.get(self.url, timeout=20) + assert ( + response.ok + ), f"HTTP error while getting events from {self.url}: {response.text}" calendar = Calendar.from_ical(response.text) for event in calendar.walk(): @@ -97,7 +100,8 @@ class CalendarIcalPlugin(Plugin, CalendarInterface): if ( event['status'] != 'cancelled' and event['end'].get('dateTime') - and event['end']['dateTime'] >= utcnow().isoformat() + and datetime.datetime.fromisoformat(event['end']['dateTime']) + >= utcnow() and ( ( only_participating diff --git a/platypush/plugins/light/hue/__init__.py b/platypush/plugins/light/hue/__init__.py index 1bc8769f11..7ee9434564 100644 --- a/platypush/plugins/light/hue/__init__.py +++ b/platypush/plugins/light/hue/__init__.py @@ -17,8 +17,6 @@ from typing import ( Set, Union, ) -import warnings - from platypush.config import Config from platypush.context import get_bus from platypush.entities import Entity, LightEntityManager @@ -86,11 +84,7 @@ class LightHuePlugin(RunnablePlugin, LightEntityManager): poll_seconds = kwargs.pop('poll_seconds', None) if poll_seconds is not None: - warnings.warn( - 'poll_seconds is deprecated, use poll_interval instead', - DeprecationWarning, - stacklevel=2, - ) + self.logger.warning('poll_seconds is deprecated, use poll_interval instead') if poll_interval is None: poll_interval = poll_seconds @@ -1156,12 +1150,16 @@ class LightHuePlugin(RunnablePlugin, LightEntityManager): temperature=entity.get('state', {}).get('ct'), colormode=entity.get('colormode'), reachable=entity.get('state', {}).get('reachable'), - x=entity['state']['xy'][0] - if entity.get('state', {}).get('xy') - else None, - y=entity['state']['xy'][1] - if entity.get('state', {}).get('xy') - else None, + x=( + entity['state']['xy'][0] + if entity.get('state', {}).get('xy') + else None + ), + y=( + entity['state']['xy'][1] + if entity.get('state', {}).get('xy') + else None + ), effect=entity.get('state', {}).get('effect'), **( { diff --git a/platypush/plugins/sensor/hcsr04/__init__.py b/platypush/plugins/sensor/hcsr04/__init__.py index 20cfe8a77f..3343e36948 100644 --- a/platypush/plugins/sensor/hcsr04/__init__.py +++ b/platypush/plugins/sensor/hcsr04/__init__.py @@ -1,7 +1,6 @@ from collections.abc import Collection import time from typing import List, Optional, Union -import warnings from platypush.context import get_bus from platypush.entities.distance import DistanceSensor @@ -45,10 +44,8 @@ class SensorHcsr04Plugin(GpioPlugin, SensorPlugin): measurement_interval = kwargs.pop('measurement_interval', None) if measurement_interval is not None: - warnings.warn( + self.logger.warning( 'measurement_interval is deprecated, use poll_interval instead', - DeprecationWarning, - stacklevel=2, ) poll_interval = measurement_interval diff --git a/platypush/plugins/sound/__init__.py b/platypush/plugins/sound/__init__.py index 5cfe958cab..8ead17a971 100644 --- a/platypush/plugins/sound/__init__.py +++ b/platypush/plugins/sound/__init__.py @@ -1,5 +1,4 @@ from dataclasses import asdict -import warnings from typing import Iterable, List, Optional, Union from platypush.plugins import RunnablePlugin, action @@ -184,10 +183,8 @@ class SoundPlugin(RunnablePlugin): blocksize = blocksize or self.output_blocksize if file: - warnings.warn( + self.logger.warning( 'file is deprecated, use resource instead', - DeprecationWarning, - stacklevel=1, ) if not resource: resource = file @@ -232,10 +229,8 @@ class SoundPlugin(RunnablePlugin): """ Deprecated alias for :meth:`.record`. """ - warnings.warn( + self.logger.warning( 'sound.stream_recording is deprecated, use sound.record instead', - DeprecationWarning, - stacklevel=1, ) return self.record(*args, **kwargs) @@ -319,10 +314,8 @@ class SoundPlugin(RunnablePlugin): """ Deprecated alias for :meth:`.record`. """ - warnings.warn( + self.logger.warning( 'sound.recordplay is deprecated, use sound.record with `play_audio=True` instead', - DeprecationWarning, - stacklevel=1, ) kwargs['play_audio'] = True @@ -398,10 +391,8 @@ class SoundPlugin(RunnablePlugin): Deprecated alias for :meth:`.status`. """ - warnings.warn( + self.logger.warning( 'sound.query_streams is deprecated, use sound.status instead', - DeprecationWarning, - stacklevel=1, ) return self.status() diff --git a/platypush/plugins/zwave/mqtt/__init__.py b/platypush/plugins/zwave/mqtt/__init__.py index 5846e5ab49..7aa56b9174 100644 --- a/platypush/plugins/zwave/mqtt/__init__.py +++ b/platypush/plugins/zwave/mqtt/__init__.py @@ -377,9 +377,11 @@ class ZwaveMqttPlugin( 'device_id': device_id.replace('0x', ''), 'name': node.get('name'), 'capabilities': capabilities, - 'manufacturer_id': f'0x{node["manufacturerId"]:04x}' - if node.get('manufacturerId') - else None, + 'manufacturer_id': ( + f'0x{node["manufacturerId"]:04x}' + if node.get('manufacturerId') + else None + ), 'manufacturer_name': node.get('manufacturer'), 'location': node.get('loc'), 'status': node.get('status'), @@ -397,12 +399,12 @@ class ZwaveMqttPlugin( 'is_security_device': node.get('supportsSecurity'), 'is_sleeping': node.get('ready') and node.get('status') == 'Asleep', 'last_update': cls._convert_timestamp(node.get('lastActive')), - 'product_id': f'0x{node["productId"]:04x}' - if node.get('productId') - else None, - 'product_type': f'0x{node["productType"]:04x}' - if node.get('productType') - else None, + 'product_id': ( + f'0x{node["productId"]:04x}' if node.get('productId') else None + ), + 'product_type': ( + f'0x{node["productType"]:04x}' if node.get('productType') else None + ), 'product_name': ' '.join( [node.get('productLabel', ''), node.get('productDescription', '')] ), @@ -1048,7 +1050,7 @@ class ZwaveMqttPlugin( """ Get the current status of the Z-Wave values. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values(**kwargs) @@ -1058,7 +1060,7 @@ class ZwaveMqttPlugin( """ Get the status of the controller. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ msg_queue: queue.Queue = queue.Queue() @@ -1105,7 +1107,7 @@ class ZwaveMqttPlugin( :param do_security: Whether to initialize the Network Key on the device if it supports the Security CC :param timeout: How long the inclusion process should last, in seconds (default: 30). Specify zero or null for no timeout. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ self._api_request( @@ -1128,7 +1130,7 @@ class ZwaveMqttPlugin( Remove a node from the network (or, better, start the exclusion process). :param timeout: How long the exclusion process should last, in seconds (default: 30). - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ self._api_request('startExclusion', **kwargs) @@ -1144,7 +1146,7 @@ class ZwaveMqttPlugin( :param node_id: Filter by node_id. :param node_name: Filter by node name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ if node_name: @@ -1162,7 +1164,7 @@ class ZwaveMqttPlugin( :param node_id: Filter by node_id. :param node_name: Filter by node name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ if node_name: @@ -1180,7 +1182,7 @@ class ZwaveMqttPlugin( :param node_id: Filter by node_id. :param node_name: Filter by node name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ if node_name: @@ -1194,7 +1196,7 @@ class ZwaveMqttPlugin( """ Request a neighbours list update. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ self._api_request('refreshNeighbors', **kwargs) @@ -1208,7 +1210,7 @@ class ZwaveMqttPlugin( :param node_id: Filter by node_id. :param node_name: Filter by node name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). :return: List of paired devices. Example output: @@ -1362,7 +1364,7 @@ class ZwaveMqttPlugin( } } - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ if node_id or node_name: @@ -1386,7 +1388,7 @@ class ZwaveMqttPlugin( :param new_name: New name for the node. :param node_id: Filter by node_id. :param node_name: Filter by current node name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ if node_name: @@ -1417,7 +1419,7 @@ class ZwaveMqttPlugin( :param location: Node location. :param node_id: Filter by node_id. :param node_name: Filter by current node name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ if node_name: @@ -1442,7 +1444,7 @@ class ZwaveMqttPlugin( Heal network by requesting nodes rediscover their neighbours. :param timeout: Duration of the healing process in seconds (default: 60). Set to zero or null for no timeout. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ self._api_request('beginHealingNetwork', **kwargs) @@ -1469,7 +1471,7 @@ class ZwaveMqttPlugin( :param value_label: Select value by [node_id/node_name, value_label] :param node_id: Select value by [node_id/node_name, value_label] :param node_name: Select value by [node_id/node_name, value_label] - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._get_value( @@ -1503,7 +1505,7 @@ class ZwaveMqttPlugin( :param value_label: Select value by [node_id/node_name, value_label] :param node_id: Select value by [node_id/node_name, value_label] :param node_name: Select value by [node_id/node_name, value_label] - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ # Compatibility layer with the .set_value format used by @@ -1558,7 +1560,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ if node_name: @@ -1575,7 +1577,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ self.node_heal(node_id=node_id, node_name=node_name, **kwargs) @@ -1590,7 +1592,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ self.node_heal(node_id=node_id, node_name=node_name, **kwargs) @@ -1604,7 +1606,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ if node_name: @@ -1620,7 +1622,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1639,7 +1641,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1663,7 +1665,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1679,7 +1681,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1695,7 +1697,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1715,7 +1717,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1735,7 +1737,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1755,7 +1757,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1771,7 +1773,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1787,7 +1789,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1803,7 +1805,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1830,7 +1832,7 @@ class ZwaveMqttPlugin( :param node_id: Select node by node_id. :param node_name: Select node by name. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ return self._filter_values( @@ -1842,7 +1844,7 @@ class ZwaveMqttPlugin( """ Get the groups on the network. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). :return: A list of the available groups. Example: @@ -1885,7 +1887,7 @@ class ZwaveMqttPlugin( """ Get the scenes configured on the network. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). :return: dict with the following format: @@ -1919,7 +1921,7 @@ class ZwaveMqttPlugin( Create a new scene. :param label: Scene label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ self._api_request('_createScene', label, **kwargs) @@ -1936,7 +1938,7 @@ class ZwaveMqttPlugin( :param scene_id: Select by scene_id. :param scene_label: Select by scene label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ scene = self._get_scene(scene_id=scene_id, scene_label=scene_label, **kwargs) @@ -1954,7 +1956,7 @@ class ZwaveMqttPlugin( :param scene_id: Select by scene_id. :param scene_label: Select by scene label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ scene = self._get_scene(scene_id=scene_id, scene_label=scene_label, **kwargs) @@ -1984,7 +1986,7 @@ class ZwaveMqttPlugin( :param node_name: Select value by [node_id/node_name, value_label] :param scene_id: Select scene by scene_id. :param scene_label: Select scene by scene label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ value = self._get_value( @@ -2032,7 +2034,7 @@ class ZwaveMqttPlugin( :param node_name: Select value by [node_id/node_name, value_label] :param scene_id: Select scene by scene_id. :param scene_label: Select scene by scene label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ value = self._get_value( @@ -2058,7 +2060,7 @@ class ZwaveMqttPlugin( :param scene_id: Select by scene_id. :param scene_label: Select by scene label. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ scene = self._get_scene(scene_id=scene_id, scene_label=scene_label, **kwargs) @@ -2078,7 +2080,7 @@ class ZwaveMqttPlugin( :param group_id: Group ID. :param node_id: Node ID to be added. :param endpoint: Add a specific endpoint of the node to the group (default: add a node association). - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ group = self._get_group(group_id, **kwargs) @@ -2102,7 +2104,7 @@ class ZwaveMqttPlugin( :param group_id: Group ID. :param node_id: Node ID to be added. :param endpoint: Node endpoint to remove (default: remove node association). - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ group = self._get_group(group_id, **kwargs) @@ -2128,7 +2130,7 @@ class ZwaveMqttPlugin( Turn on a switch on a device. :param device: ``id_on_network`` of the value to be switched on. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ self.set_value(data=True, id_on_network=device, **kwargs) @@ -2139,7 +2141,7 @@ class ZwaveMqttPlugin( Turn off a switch on a device. :param device: ``id_on_network`` of the value to be switched off. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ self.set_value(data=False, id_on_network=device, **kwargs) @@ -2152,7 +2154,7 @@ class ZwaveMqttPlugin( Toggle a switch on a device. :param device: ``id_on_network`` of the value to be toggled. - :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish`` + :param kwargs: Extra arguments to be passed to :meth:`platypush.plugins.mqtt.MqttPlugin.publish` (default: query the default configured device). """ value = self._get_value(id_on_network=device, use_cache=False, **kwargs) diff --git a/platypush/schemas/media/jellyfin.py b/platypush/schemas/media/jellyfin.py index c4fba21e2b..689c41c0be 100644 --- a/platypush/schemas/media/jellyfin.py +++ b/platypush/schemas/media/jellyfin.py @@ -1,4 +1,4 @@ -import warnings +import logging from marshmallow import Schema, fields, pre_dump, post_dump @@ -6,6 +6,8 @@ from platypush.context import get_plugin from . import MediaArtistSchema, MediaCollectionSchema, MediaVideoSchema +logger = logging.getLogger(__name__) + class JellyfinSchema(Schema): def __init__(self, *args, **kwargs): @@ -20,9 +22,10 @@ class JellyfinSchema(Schema): @post_dump def gen_img_url(self, data: dict, **_) -> dict: if 'image' in self.fields: + plugin = get_plugin('media.jellyfin') + assert plugin, 'The media.jellyfin plugin is not configured' data['image'] = ( - get_plugin('media.jellyfin').server - + f'/Items/{data["id"]}' # type: ignore + plugin.server + f'/Items/{data["id"]}' # type: ignore '/Images/Primary?fillHeight=333&fillWidth=222&quality=96' ) @@ -43,9 +46,8 @@ class JellyfinSchema(Schema): if not video_format: if not available_containers: - warnings.warn( - f'The media ID {data["Id"]} has no available video containers', - stacklevel=2, + logger.warning( + 'The media ID %s has no available video containers', data["Id"] ) return data diff --git a/setup.cfg b/setup.cfg index 54e27e4bde..89cc4c1f5c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.0.7 +current_version = 1.1.0 commit = True tag = True diff --git a/setup.py b/setup.py index 12cc9965db..710c39eb19 100755 --- a/setup.py +++ b/setup.py @@ -66,7 +66,7 @@ backend = pkg_files('platypush/backend') setup( name="platypush", - version="1.0.7", + version="1.1.0", author="Fabio Manganiello", author_email="fabio@manganiello.tech", description="Platypush service",