From 26ee3fc75c93bc6c41d2a51894d75a9c90670821 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Mon, 1 Jul 2019 22:26:04 +0200 Subject: [PATCH] Changed nav bar text to icons --- platypush/backend/http/templates/nav.html | 24 ++++++++++- platypush/plugins/__init__.py | 1 - platypush/plugins/adafruit/io.py | 52 ++++++++++++++--------- platypush/plugins/music/mpd/__init__.py | 1 + platypush/plugins/music/snapcast.py | 2 +- platypush/plugins/tts/__init__.py | 11 +++-- platypush/plugins/tts/google.py | 1 + platypush/utils/__init__.py | 29 ++++++++++++- 8 files changed, 91 insertions(+), 30 deletions(-) diff --git a/platypush/backend/http/templates/nav.html b/platypush/backend/http/templates/nav.html index 83968be36..b340f52e4 100644 --- a/platypush/backend/http/templates/nav.html +++ b/platypush/backend/http/templates/nav.html @@ -1,9 +1,27 @@ +{% + with pluginIcons = { + 'light.hue': 'fa fa-lightbulb', + 'media.mplayer': 'fa fa-film', + 'media.mpv': 'fa fa-film', + 'media.omxplayer': 'fa fa-film', + 'media.vlc': 'fa fa-film', + 'music.mpd': 'fa fa-music', + 'music.snapcast': 'fa fa-volume-up', + 'tts': 'fa fa-comment', + 'tts.google': 'fa fa-comment', + } +%} + +{% endwith %} + diff --git a/platypush/plugins/__init__.py b/platypush/plugins/__init__.py index 43677735d..2ac59461d 100644 --- a/platypush/plugins/__init__.py +++ b/platypush/plugins/__init__.py @@ -48,7 +48,6 @@ class Plugin(EventGenerator): .get('action', []) ) - def run(self, method, *args, **kwargs): if method not in self.registered_actions: raise RuntimeError('{} is not a registered action on {}'.format( diff --git a/platypush/plugins/adafruit/io.py b/platypush/plugins/adafruit/io.py index 27e8b2a03..23a7009be 100644 --- a/platypush/plugins/adafruit/io.py +++ b/platypush/plugins/adafruit/io.py @@ -8,10 +8,10 @@ from Adafruit_IO import Client from Adafruit_IO.errors import ThrottlingError from platypush.context import get_backend -from platypush.message import Message from platypush.plugins import Plugin, action -data_throttler_lock = Lock() +data_throttler_lock = None + class AdafruitIoPlugin(Plugin): """ @@ -49,7 +49,7 @@ class AdafruitIoPlugin(Plugin): _DATA_THROTTLER_QUEUE = 'platypush/adafruit.io' - def __init__(self, username, key, throttle_seconds=None, *args, **kwargs): + def __init__(self, username, key, throttle_seconds=None, **kwargs): """ :param username: Your Adafruit username :type username: str @@ -57,33 +57,39 @@ class AdafruitIoPlugin(Plugin): :param key: Your Adafruit IO key :type key: str - :param throttle_seconds: If set, then instead of sending the values directly over ``send`` the plugin will first collect all the samples within the specified period and then dispatch them to Adafruit IO. You may want to set it if you have data sources providing a lot of data points and you don't want to hit the throttling limitations of Adafruit. + :param throttle_seconds: If set, then instead of sending the values directly over ``send`` the plugin will + first collect all the samples within the specified period and then dispatch them to Adafruit IO. + You may want to set it if you have data sources providing a lot of data points and you don't want to hit + the throttling limitations of Adafruit. :type throttle_seconds: float """ - super().__init__(*args, **kwargs) + global data_throttler_lock + super().__init__(**kwargs) self._username = username self._key = key self.aio = Client(username=username, key=key) self.throttle_seconds = throttle_seconds + if not data_throttler_lock: + data_throttler_lock = Lock() + if self.throttle_seconds and not data_throttler_lock.locked(): - redis = self._get_redis() + self._get_redis() self.logger.info('Starting Adafruit IO throttler thread') data_throttler_lock.acquire(False) self.data_throttler = Thread(target=self._data_throttler()) self.data_throttler.start() - - def _get_redis(self): + @staticmethod + def _get_redis(): from redis import Redis redis_args = get_backend('redis').redis_args redis_args['socket_timeout'] = 1 return Redis(**redis_args) - def _data_throttler(self): from redis.exceptions import TimeoutError as QueueTimeoutError @@ -104,7 +110,7 @@ class AdafruitIoPlugin(Plugin): pass if data and (last_processed_batch_timestamp is None or - time.time() - last_processed_batch_timestamp >= self.throttle_seconds): + time.time() - last_processed_batch_timestamp >= self.throttle_seconds): last_processed_batch_timestamp = time.time() self.logger.info('Processing feeds batch for Adafruit IO') @@ -115,7 +121,8 @@ class AdafruitIoPlugin(Plugin): try: self.send(feed, value, enqueue=False) except ThrottlingError: - self.logger.warning('Adafruit IO throttling threshold hit, taking a nap before retrying') + self.logger.warning('Adafruit IO throttling threshold hit, taking a nap ' + + 'before retrying') time.sleep(self.throttle_seconds) data = {} @@ -135,7 +142,9 @@ class AdafruitIoPlugin(Plugin): :param value: Value to send :type value: Numeric or string - :param enqueue: If throttle_seconds is set, this method by default will append values to the throttling queue to be periodically flushed instead of sending the message directly. In such case, pass enqueue=False to override the behaviour and send the message directly instead. + :param enqueue: If throttle_seconds is set, this method by default will append values to the throttling queue + to be periodically flushed instead of sending the message directly. In such case, pass enqueue=False to + override the behaviour and send the message directly instead. :type enqueue: bool """ @@ -145,8 +154,7 @@ class AdafruitIoPlugin(Plugin): else: # Otherwise send it to the Redis queue to be picked up by the throttler thread redis = self._get_redis() - redis.rpush(self._DATA_THROTTLER_QUEUE, json.dumps({feed:value})) - + redis.rpush(self._DATA_THROTTLER_QUEUE, json.dumps({feed: value})) @action def send_location_data(self, feed, lat, lon, ele, value): @@ -169,12 +177,19 @@ class AdafruitIoPlugin(Plugin): :type value: Numeric or string """ - self.aio.send_location_data(feed=feed, value=value, lat=lat, lon=lon, ele=ele) + self.aio.send_data(feed=feed, value=value, metadata={ + 'lat': lat, + 'lon': lon, + 'ele': ele, + }) @classmethod def _cast_value(cls, value): - try: value = float(value) - except: pass + try: + value = float(value) + except ValueError: + pass + return value def _convert_data_to_dict(self, *data): @@ -188,7 +203,6 @@ class AdafruitIoPlugin(Plugin): } for i in data ] - @action def receive(self, feed, limit=1): """ @@ -243,7 +257,7 @@ class AdafruitIoPlugin(Plugin): :type feed: str :param data_id: Data point ID to remove - :type data_id: int + :type data_id: str """ self.aio.delete(feed, data_id) diff --git a/platypush/plugins/music/mpd/__init__.py b/platypush/plugins/music/mpd/__init__.py index f8574931a..c3601c9e2 100644 --- a/platypush/plugins/music/mpd/__init__.py +++ b/platypush/plugins/music/mpd/__init__.py @@ -6,6 +6,7 @@ import time from platypush.plugins import action from platypush.plugins.music import MusicPlugin + class MusicMpdPlugin(MusicPlugin): """ This plugin allows you to interact with an MPD/Mopidy music server. MPD diff --git a/platypush/plugins/music/snapcast.py b/platypush/plugins/music/snapcast.py index 9c227f4ab..cb12b95fc 100644 --- a/platypush/plugins/music/snapcast.py +++ b/platypush/plugins/music/snapcast.py @@ -29,7 +29,7 @@ class MusicSnapcastPlugin(Plugin): :type port: int """ - super().__init__(*args, **kwargs) + super().__init__(**kwargs) self.host = host self.port = port diff --git a/platypush/plugins/tts/__init__.py b/platypush/plugins/tts/__init__.py index ddd32495e..7a61c6260 100644 --- a/platypush/plugins/tts/__init__.py +++ b/platypush/plugins/tts/__init__.py @@ -3,6 +3,7 @@ import urllib.parse from platypush.plugins import Plugin, action + class TtsPlugin(Plugin): """ Default Text-to-Speech plugin. It leverages Google Translate. @@ -28,15 +29,13 @@ class TtsPlugin(Plugin): :type language: str """ if language is None: language=self.lang - output = None - errors = [] cmd = ['mplayer -ao alsa -really-quiet -noconsolecontrols ' + '"http://translate.google.com/translate_tts?{}"' .format(urllib.parse.urlencode({ - 'ie' : 'UTF-8', - 'client' : 'tw-ob', - 'tl' : language, - 'q' : text, + 'ie': 'UTF-8', + 'client': 'tw-ob', + 'tl': language, + 'q': text, }))] try: diff --git a/platypush/plugins/tts/google.py b/platypush/plugins/tts/google.py index d67e1e452..db3b7ce00 100644 --- a/platypush/plugins/tts/google.py +++ b/platypush/plugins/tts/google.py @@ -6,6 +6,7 @@ from google.cloud import texttospeech from platypush.plugins import Plugin, action + class TtsGooglePlugin(Plugin): """ Advanced text-to-speech engine that leverages the Google Cloud TTS API. diff --git a/platypush/utils/__init__.py b/platypush/utils/__init__.py index 292ac15ee..dad6a6fbd 100644 --- a/platypush/utils/__init__.py +++ b/platypush/utils/__init__.py @@ -12,6 +12,7 @@ import urllib.request logger = logging.getLogger(__name__) + def get_module_and_method_from_action(action): """ Input : action=music.mpd.play Output : ('music.mpd', 'play') """ @@ -19,7 +20,7 @@ def get_module_and_method_from_action(action): tokens = action.split('.') module_name = str.join('.', tokens[:-1]) method_name = tokens[-1:][0] - return (module_name, method_name) + return module_name, method_name def get_message_class_by_type(msgtype): @@ -49,6 +50,32 @@ def get_event_class_by_type(type): return getattr(event_module, type.split('.')[-1]) +def get_plugin_module_by_name(plugin_name): + """ Gets the module of a plugin by name (e.g. "music.mpd" or "media.vlc") """ + + module_name = 'platypush.plugins.' + plugin_name + try: + return importlib.import_module('platypush.plugins.' + plugin_name) + except ImportError as e: + logger.error('Cannot import {}: {}'.format(module_name, str(e))) + return None + + +def get_plugin_class_by_name(plugin_name): + """ Gets the class of a plugin by name (e.g. "music.mpd" or "media.vlc") """ + + module = get_plugin_module_by_name(plugin_name) + if not module: + return + + class_name = getattr(module, ''.join([_.capitalize() for _ in plugin_name.split('.')]) + 'Plugin') + try: + return getattr(module, ''.join([_.capitalize() for _ in plugin_name.split('.')]) + 'Plugin') + except Exception as e: + logger.error('Cannot import class {}: {}'.format(class_name, str(e))) + return None + + def set_timeout(seconds, on_timeout): """ Set a function to be called if timeout expires without being cleared.