forked from platypush/platypush
[#61] Plugins actions refactoring
- Using `@action` annotation to indicate methods that are allowed to be executed as actions - The output and errors of an action are automatically wrapped into a `Response` object without any response build required on the plugin side
This commit is contained in:
parent
81a81312e3
commit
66d78c8615
42 changed files with 386 additions and 216 deletions
|
@ -60,6 +60,7 @@ class Config(object):
|
||||||
self._config = self._read_config_file(self._cfgfile)
|
self._config = self._read_config_file(self._cfgfile)
|
||||||
|
|
||||||
if 'token' in self._config:
|
if 'token' in self._config:
|
||||||
|
self._config['token'] = self._config['token']
|
||||||
self._config['token_hash'] = get_hash(self._config['token'])
|
self._config['token_hash'] = get_hash(self._config['token'])
|
||||||
|
|
||||||
if 'workdir' not in self._config:
|
if 'workdir' not in self._config:
|
||||||
|
|
|
@ -86,6 +86,11 @@ class EventAction(Request):
|
||||||
|
|
||||||
if 'target' not in action:
|
if 'target' not in action:
|
||||||
action['target'] = action['origin']
|
action['target'] = action['origin']
|
||||||
|
|
||||||
|
token = Config.get('token')
|
||||||
|
if token:
|
||||||
|
action['token'] = token
|
||||||
|
|
||||||
return super().build(action)
|
return super().build(action)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ class Request(Message):
|
||||||
raise RuntimeError('Response processed with errors: {}'.format(response))
|
raise RuntimeError('Response processed with errors: {}'.format(response))
|
||||||
|
|
||||||
logger.info('Processed response from plugin {}: {}'.
|
logger.info('Processed response from plugin {}: {}'.
|
||||||
format(plugin, response))
|
format(plugin, str(response)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Retry mechanism
|
# Retry mechanism
|
||||||
response = Response(output=None, errors=[str(e), traceback.format_exc()])
|
response = Response(output=None, errors=[str(e), traceback.format_exc()])
|
||||||
|
|
|
@ -1,13 +1,26 @@
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
import traceback
|
||||||
|
|
||||||
from platypush.config import Config
|
from platypush.config import Config
|
||||||
from platypush.message.response import Response
|
from platypush.message.response import Response
|
||||||
|
from platypush.utils import get_decorators
|
||||||
|
|
||||||
|
|
||||||
def action(f):
|
def action(f):
|
||||||
def _execute_action(*args, **kwargs):
|
def _execute_action(*args, **kwargs):
|
||||||
return f(*args, **kwargs)
|
output = None
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
output = f(*args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
if isinstance(args[0], Plugin):
|
||||||
|
args[0].logger.exception(e)
|
||||||
|
errors.append(str(e) + '\n' + traceback.format_exc())
|
||||||
|
|
||||||
|
return Response(output=output, errors=errors)
|
||||||
|
|
||||||
return _execute_action
|
return _execute_action
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +32,13 @@ class Plugin(object):
|
||||||
if 'logging' in kwargs:
|
if 'logging' in kwargs:
|
||||||
self.logger.setLevel(getattr(logging, kwargs['logging'].upper()))
|
self.logger.setLevel(getattr(logging, kwargs['logging'].upper()))
|
||||||
|
|
||||||
|
self.registered_actions = set(get_decorators(self.__class__).get('action', []))
|
||||||
|
|
||||||
def run(self, method, *args, **kwargs):
|
def run(self, method, *args, **kwargs):
|
||||||
|
if method not in self.registered_actions:
|
||||||
|
raise RuntimeError('{} is not a registered action on {}'.format(
|
||||||
|
method, self.__class__.__name__))
|
||||||
|
|
||||||
return getattr(self, method)(*args, **kwargs)
|
return getattr(self, method)(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from platypush.context import get_backend
|
from platypush.context import get_backend
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
class AssistantGooglePlugin(Plugin):
|
class AssistantGooglePlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
@ -14,21 +12,25 @@ class AssistantGooglePlugin(Plugin):
|
||||||
backend to programmatically control the conversation status.
|
backend to programmatically control the conversation status.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(*args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@action
|
||||||
def start_conversation(self):
|
def start_conversation(self):
|
||||||
"""
|
"""
|
||||||
Programmatically start a conversation with the assistant
|
Programmatically start a conversation with the assistant
|
||||||
"""
|
"""
|
||||||
assistant = get_backend('assistant.google')
|
assistant = get_backend('assistant.google')
|
||||||
assistant.start_conversation()
|
assistant.start_conversation()
|
||||||
return Response(output='', errors=[])
|
|
||||||
|
|
||||||
|
@action
|
||||||
def stop_conversation(self):
|
def stop_conversation(self):
|
||||||
"""
|
"""
|
||||||
Programmatically stop a running conversation with the assistant
|
Programmatically stop a running conversation with the assistant
|
||||||
"""
|
"""
|
||||||
assistant = get_backend('assistant.google')
|
assistant = get_backend('assistant.google')
|
||||||
assistant.stop_conversation()
|
assistant.stop_conversation()
|
||||||
return Response(output='', errors=[])
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from platypush.context import get_backend
|
from platypush.context import get_backend
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
class AssistantGooglePushtotalkPlugin(Plugin):
|
class AssistantGooglePushtotalkPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
@ -14,21 +12,24 @@ class AssistantGooglePushtotalkPlugin(Plugin):
|
||||||
:mod:`platypush.backend.assistant.google.pushtotalk` backend.
|
:mod:`platypush.backend.assistant.google.pushtotalk` backend.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(*args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@action
|
||||||
def start_conversation(self):
|
def start_conversation(self):
|
||||||
"""
|
"""
|
||||||
Programmatically start a conversation with the assistant
|
Programmatically start a conversation with the assistant
|
||||||
"""
|
"""
|
||||||
assistant = get_backend('assistant.google.pushtotalk')
|
assistant = get_backend('assistant.google.pushtotalk')
|
||||||
assistant.start_conversation()
|
assistant.start_conversation()
|
||||||
return Response(output='', errors=[])
|
|
||||||
|
|
||||||
|
@action
|
||||||
def stop_conversation(self):
|
def stop_conversation(self):
|
||||||
"""
|
"""
|
||||||
Programmatically stop a running conversation with the assistant
|
Programmatically stop a running conversation with the assistant
|
||||||
"""
|
"""
|
||||||
assistant = get_backend('assistant.google.pushtotalk')
|
assistant = get_backend('assistant.google.pushtotalk')
|
||||||
assistant.stop_conversation()
|
assistant.stop_conversation()
|
||||||
return Response(output='', errors=[])
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,7 @@ import importlib
|
||||||
|
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
|
|
||||||
from platypush.plugins import Plugin
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.message.response import Response
|
|
||||||
|
|
||||||
|
|
||||||
class CalendarInterface:
|
class CalendarInterface:
|
||||||
|
@ -64,6 +63,7 @@ class CalendarPlugin(Plugin, CalendarInterface):
|
||||||
self.calendars.append(getattr(module, class_name)(**calendar))
|
self.calendars.append(getattr(module, class_name)(**calendar))
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_upcoming_events(self, max_results=10):
|
def get_upcoming_events(self, max_results=10):
|
||||||
"""
|
"""
|
||||||
Get a list of upcoming events merging all the available calendars.
|
Get a list of upcoming events merging all the available calendars.
|
||||||
|
@ -116,7 +116,7 @@ class CalendarPlugin(Plugin, CalendarInterface):
|
||||||
else event['start']['date'] + 'T00:00:00+00:00'
|
else event['start']['date'] + 'T00:00:00+00:00'
|
||||||
))[:max_results]
|
))[:max_results]
|
||||||
|
|
||||||
return Response(output=events)
|
return events
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -9,8 +9,7 @@ import pytz
|
||||||
|
|
||||||
from icalendar import Calendar, Event
|
from icalendar import Calendar, Event
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.plugins import Plugin
|
|
||||||
from platypush.plugins.calendar import CalendarInterface
|
from platypush.plugins.calendar import CalendarInterface
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +60,7 @@ class IcalCalendarPlugin(Plugin, CalendarInterface):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_upcoming_events(self, max_results=10, only_participating=True):
|
def get_upcoming_events(self, max_results=10, only_participating=True):
|
||||||
"""
|
"""
|
||||||
Get the upcoming events. See
|
Get the upcoming events. See
|
||||||
|
@ -90,7 +90,7 @@ class IcalCalendarPlugin(Plugin, CalendarInterface):
|
||||||
else:
|
else:
|
||||||
self.logger.error("HTTP error while getting {}: {}".format(self.url, response))
|
self.logger.error("HTTP error while getting {}: {}".format(self.url, response))
|
||||||
|
|
||||||
return Response(output=events)
|
return events
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from platypush.context import get_backend
|
from platypush.context import get_backend
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
|
|
||||||
class CameraPiPlugin(Plugin):
|
class CameraPiPlugin(Plugin):
|
||||||
|
@ -15,22 +13,26 @@ class CameraPiPlugin(Plugin):
|
||||||
to programmatically control the status.
|
to programmatically control the status.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(*args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@action
|
||||||
def start_recording(self):
|
def start_recording(self):
|
||||||
"""
|
"""
|
||||||
Start recording
|
Start recording
|
||||||
"""
|
"""
|
||||||
camera = get_backend('camera.pi')
|
camera = get_backend('camera.pi')
|
||||||
camera.send_camera_action(camera.CameraAction.START_RECORDING)
|
camera.send_camera_action(camera.CameraAction.START_RECORDING)
|
||||||
return Response(output={'status':'ok'})
|
|
||||||
|
|
||||||
|
@action
|
||||||
def stop_recording(self):
|
def stop_recording(self):
|
||||||
"""
|
"""
|
||||||
Stop recording
|
Stop recording
|
||||||
"""
|
"""
|
||||||
camera = get_backend('camera.pi')
|
camera = get_backend('camera.pi')
|
||||||
camera.send_camera_action(camera.CameraAction.STOP_RECORDING)
|
camera.send_camera_action(camera.CameraAction.STOP_RECORDING)
|
||||||
return Response(output={'status':'ok'})
|
|
||||||
|
|
||||||
|
@action
|
||||||
def take_picture(self, image_file):
|
def take_picture(self, image_file):
|
||||||
"""
|
"""
|
||||||
Take a picture.
|
Take a picture.
|
||||||
|
@ -40,7 +42,7 @@ class CameraPiPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
camera = get_backend('camera.pi')
|
camera = get_backend('camera.pi')
|
||||||
camera.send_camera_action(camera.CameraAction.TAKE_PICTURE, image_file=image_file)
|
camera.send_camera_action(camera.CameraAction.TAKE_PICTURE, image_file=image_file)
|
||||||
return Response(output={'image_file':image_file})
|
return {'image_file': image_file}
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
|
|
||||||
from sqlalchemy import create_engine, Table, MetaData
|
from sqlalchemy import create_engine, Table, MetaData
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
from .. import Plugin
|
|
||||||
|
|
||||||
class DbPlugin(Plugin):
|
class DbPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
@ -40,6 +38,7 @@ class DbPlugin(Plugin):
|
||||||
else:
|
else:
|
||||||
return self.engine
|
return self.engine
|
||||||
|
|
||||||
|
@action
|
||||||
def execute(self, statement, engine=None, *args, **kwargs):
|
def execute(self, statement, engine=None, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Executes a raw SQL statement.
|
Executes a raw SQL statement.
|
||||||
|
@ -65,9 +64,8 @@ class DbPlugin(Plugin):
|
||||||
result = connection.execute(statement)
|
result = connection.execute(statement)
|
||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
return Response()
|
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def select(self, query, engine=None, *args, **kwargs):
|
def select(self, query, engine=None, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns rows (as a list of hashes) given a query.
|
Returns rows (as a list of hashes) given a query.
|
||||||
|
@ -119,9 +117,10 @@ class DbPlugin(Plugin):
|
||||||
for row in result.fetchall()
|
for row in result.fetchall()
|
||||||
]
|
]
|
||||||
|
|
||||||
return Response(output=rows)
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def insert(self, table, records, engine=None, *args, **kwargs):
|
def insert(self, table, records, engine=None, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Inserts records (as a list of hashes) into a table.
|
Inserts records (as a list of hashes) into a table.
|
||||||
|
@ -169,8 +168,6 @@ class DbPlugin(Plugin):
|
||||||
insert = table.insert().values(**record)
|
insert = table.insert().values(**record)
|
||||||
engine.execute(insert)
|
engine.execute(insert)
|
||||||
|
|
||||||
return Response()
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import os
|
||||||
|
|
||||||
from apiclient import discovery
|
from apiclient import discovery
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
from platypush.plugins.google import GooglePlugin
|
from platypush.plugins.google import GooglePlugin
|
||||||
from platypush.plugins.calendar import CalendarInterface
|
from platypush.plugins.calendar import CalendarInterface
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ class GoogleCalendarPlugin(GooglePlugin, CalendarInterface):
|
||||||
super().__init__(scopes=self.scopes, *args, **kwargs)
|
super().__init__(scopes=self.scopes, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_upcoming_events(self, max_results=10):
|
def get_upcoming_events(self, max_results=10):
|
||||||
"""
|
"""
|
||||||
Get the upcoming events. See
|
Get the upcoming events. See
|
||||||
|
|
|
@ -17,7 +17,7 @@ from email.mime.image import MIMEImage
|
||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
from platypush.plugins.google import GooglePlugin
|
from platypush.plugins.google import GooglePlugin
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ class GoogleMailPlugin(GooglePlugin):
|
||||||
super().__init__(scopes=self.scopes, *args, **kwargs)
|
super().__init__(scopes=self.scopes, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def compose(self, sender, to, subject, body, files=None):
|
def compose(self, sender, to, subject, body, files=None):
|
||||||
"""
|
"""
|
||||||
Compose a message.
|
Compose a message.
|
||||||
|
@ -91,9 +92,10 @@ class GoogleMailPlugin(GooglePlugin):
|
||||||
message = (service.users().messages().send(
|
message = (service.users().messages().send(
|
||||||
userId='me', body=body).execute())
|
userId='me', body=body).execute())
|
||||||
|
|
||||||
return Response(output=message)
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_labels(self):
|
def get_labels(self):
|
||||||
"""
|
"""
|
||||||
Returns the available labels on the GMail account
|
Returns the available labels on the GMail account
|
||||||
|
@ -101,7 +103,7 @@ class GoogleMailPlugin(GooglePlugin):
|
||||||
service = self._get_service()
|
service = self._get_service()
|
||||||
results = service.users().labels().list(userId='me').execute()
|
results = service.users().labels().list(userId='me').execute()
|
||||||
labels = results.get('labels', [])
|
labels = results.get('labels', [])
|
||||||
return Response(output=labels)
|
return labels
|
||||||
|
|
||||||
|
|
||||||
def _get_service(self):
|
def _get_service(self):
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
from platypush.plugins.google import GooglePlugin
|
from platypush.plugins.google import GooglePlugin
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ class GoogleMapsPlugin(GooglePlugin):
|
||||||
self.api_key = api_key
|
self.api_key = api_key
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_address_from_latlng(self, latitude, longitude):
|
def get_address_from_latlng(self, latitude, longitude):
|
||||||
"""
|
"""
|
||||||
Get an address information given lat/long
|
Get an address information given lat/long
|
||||||
|
@ -65,7 +66,7 @@ class GoogleMapsPlugin(GooglePlugin):
|
||||||
elif component_type == 'postal_code':
|
elif component_type == 'postal_code':
|
||||||
address['postal_code'] = addr_component['long_name']
|
address['postal_code'] = addr_component['long_name']
|
||||||
|
|
||||||
return Response(output=address)
|
return address
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
|
|
||||||
class GpioPlugin(Plugin):
|
class GpioPlugin(Plugin):
|
||||||
|
@ -17,6 +16,10 @@ class GpioPlugin(Plugin):
|
||||||
* **RPi.GPIO** (`pip install RPi.GPIO`)
|
* **RPi.GPIO** (`pip install RPi.GPIO`)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(*args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@action
|
||||||
def write(self, pin, val):
|
def write(self, pin, val):
|
||||||
"""
|
"""
|
||||||
Write a byte value to a pin.
|
Write a byte value to a pin.
|
||||||
|
@ -44,12 +47,13 @@ class GpioPlugin(Plugin):
|
||||||
gpio.setup(pin, gpio.OUT)
|
gpio.setup(pin, gpio.OUT)
|
||||||
gpio.output(pin, val)
|
gpio.output(pin, val)
|
||||||
|
|
||||||
return Response(output={
|
return {
|
||||||
'pin': pin,
|
'pin': pin,
|
||||||
'val': val,
|
'val': val,
|
||||||
'method': 'write',
|
'method': 'write',
|
||||||
})
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
def read(self, pin):
|
def read(self, pin):
|
||||||
"""
|
"""
|
||||||
Reads a value from a PIN.
|
Reads a value from a PIN.
|
||||||
|
@ -74,11 +78,11 @@ class GpioPlugin(Plugin):
|
||||||
gpio.setup(pin, gpio.IN)
|
gpio.setup(pin, gpio.IN)
|
||||||
val = gpio.input(pin)
|
val = gpio.input(pin)
|
||||||
|
|
||||||
return Response(output={
|
return {
|
||||||
'pin': pin,
|
'pin': pin,
|
||||||
'val': val,
|
'val': val,
|
||||||
'method': 'read',
|
'method': 'read',
|
||||||
})
|
}
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from platypush.plugins import Plugin
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
|
|
||||||
class GpioSensorPlugin(Plugin):
|
class GpioSensorPlugin(Plugin):
|
||||||
|
@ -10,6 +10,7 @@ class GpioSensorPlugin(Plugin):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@action
|
||||||
def get_measurement(self, *args, **kwargs):
|
def get_measurement(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Implemented by the subclasses.
|
Implemented by the subclasses.
|
||||||
|
@ -27,6 +28,7 @@ class GpioSensorPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('get_measurement should be implemented in a derived class')
|
raise NotImplementedError('get_measurement should be implemented in a derived class')
|
||||||
|
|
||||||
|
@action
|
||||||
def get_data(self, *args, **kwargs):
|
def get_data(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Alias for ``get_measurement``
|
Alias for ``get_measurement``
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
from platypush.plugins.gpio.sensor import GpioSensorPlugin
|
from platypush.plugins.gpio.sensor import GpioSensorPlugin
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ class GpioSensorDistancePlugin(GpioSensorPlugin):
|
||||||
gpio.output(self.trigger_pin, False)
|
gpio.output(self.trigger_pin, False)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_measurement(self):
|
def get_measurement(self):
|
||||||
"""
|
"""
|
||||||
Extends :func:`.GpioSensorPlugin.get_measurement`
|
Extends :func:`.GpioSensorPlugin.get_measurement`
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import enum
|
import enum
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
from platypush.plugins import action
|
||||||
from platypush.plugins.gpio.sensor import GpioSensorPlugin
|
from platypush.plugins.gpio.sensor import GpioSensorPlugin
|
||||||
from platypush.message.response import Response
|
|
||||||
|
|
||||||
|
|
||||||
class MCP3008Mode(enum.Enum):
|
class MCP3008Mode(enum.Enum):
|
||||||
|
@ -125,6 +125,7 @@ class GpioSensorMcp3008Plugin(GpioSensorPlugin):
|
||||||
return (value * self.Vdd) / 1023.0 if value is not None else None
|
return (value * self.Vdd) / 1023.0 if value is not None else None
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_measurement(self):
|
def get_measurement(self):
|
||||||
"""
|
"""
|
||||||
Returns a measurement from the sensors connected to the MCP3008 device.
|
Returns a measurement from the sensors connected to the MCP3008 device.
|
||||||
|
@ -164,7 +165,7 @@ class GpioSensorMcp3008Plugin(GpioSensorPlugin):
|
||||||
else:
|
else:
|
||||||
values[i] = value
|
values[i] = value
|
||||||
|
|
||||||
return Response(output=values)
|
return values
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -2,8 +2,7 @@ import enum
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.plugins import Plugin
|
|
||||||
from platypush.context import get_plugin
|
from platypush.context import get_plugin
|
||||||
from platypush.config import Config
|
from platypush.config import Config
|
||||||
|
|
||||||
|
@ -95,7 +94,7 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
value = None
|
value = None
|
||||||
|
|
||||||
while value is None:
|
while value is None:
|
||||||
value = plugin.get_measurement()
|
value = plugin.get_measurement().output
|
||||||
if time.time() - measure_start_time > timeout:
|
if time.time() - measure_start_time > timeout:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -127,6 +126,7 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
return direction
|
return direction
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def drive(self, direction):
|
def drive(self, direction):
|
||||||
"""
|
"""
|
||||||
Drive the motors in a certain direction.
|
Drive the motors in a certain direction.
|
||||||
|
@ -184,9 +184,10 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
self._drive_thread = threading.Thread(target=_run)
|
self._drive_thread = threading.Thread(target=_run)
|
||||||
self._drive_thread.start()
|
self._drive_thread.start()
|
||||||
|
|
||||||
return Response(output={'status': 'running', 'direction': direction})
|
return {'status': 'running', 'direction': direction}
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
Turns off the motors
|
Turns off the motors
|
||||||
|
@ -199,7 +200,7 @@ class GpioZeroborgPlugin(Plugin):
|
||||||
self.zb.MotorsOff()
|
self.zb.MotorsOff()
|
||||||
self.zb.ResetEpo()
|
self.zb.ResetEpo()
|
||||||
|
|
||||||
return Response(output={'status':'stopped'})
|
return {'status':'stopped'}
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
class HttpRequestPlugin(Plugin):
|
class HttpRequestPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
@ -41,6 +39,9 @@ class HttpRequestPlugin(Plugin):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(*args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _exec(self, method, url, output='text', **kwargs):
|
def _exec(self, method, url, output='text', **kwargs):
|
||||||
""" Available output types: text (default), json, binary """
|
""" Available output types: text (default), json, binary """
|
||||||
|
|
||||||
|
@ -51,9 +52,10 @@ class HttpRequestPlugin(Plugin):
|
||||||
|
|
||||||
if output == 'json': output = response.json()
|
if output == 'json': output = response.json()
|
||||||
if output == 'binary': output = response.content
|
if output == 'binary': output = response.content
|
||||||
return Response(output=output, errors=[])
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get(self, url, **kwargs):
|
def get(self, url, **kwargs):
|
||||||
"""
|
"""
|
||||||
Perform a GET request
|
Perform a GET request
|
||||||
|
@ -68,6 +70,7 @@ class HttpRequestPlugin(Plugin):
|
||||||
return self._exec(method='get', url=url, **kwargs)
|
return self._exec(method='get', url=url, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def post(self, url, **kwargs):
|
def post(self, url, **kwargs):
|
||||||
"""
|
"""
|
||||||
Perform a POST request
|
Perform a POST request
|
||||||
|
@ -82,6 +85,7 @@ class HttpRequestPlugin(Plugin):
|
||||||
return self._exec(method='post', url=url, **kwargs)
|
return self._exec(method='post', url=url, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def head(self, url, **kwargs):
|
def head(self, url, **kwargs):
|
||||||
"""
|
"""
|
||||||
Perform an HTTP HEAD request
|
Perform an HTTP HEAD request
|
||||||
|
@ -96,6 +100,7 @@ class HttpRequestPlugin(Plugin):
|
||||||
return self._exec(method='head', url=url, **kwargs)
|
return self._exec(method='head', url=url, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def put(self, url, **kwargs):
|
def put(self, url, **kwargs):
|
||||||
"""
|
"""
|
||||||
Perform a PUT request
|
Perform a PUT request
|
||||||
|
@ -110,6 +115,7 @@ class HttpRequestPlugin(Plugin):
|
||||||
return self._exec(method='put', url=url, **kwargs)
|
return self._exec(method='put', url=url, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def delete(self, url, **kwargs):
|
def delete(self, url, **kwargs):
|
||||||
"""
|
"""
|
||||||
Perform a DELETE request
|
Perform a DELETE request
|
||||||
|
@ -124,6 +130,7 @@ class HttpRequestPlugin(Plugin):
|
||||||
return self._exec(method='delete', url=url, **kwargs)
|
return self._exec(method='delete', url=url, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def options(self, url, **kwargs):
|
def options(self, url, **kwargs):
|
||||||
"""
|
"""
|
||||||
Perform an HTTP OPTIONS request
|
Perform an HTTP OPTIONS request
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import datetime
|
import datetime
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
|
|
||||||
|
from platypush.plugins import action
|
||||||
from platypush.plugins.http.request import HttpRequestPlugin
|
from platypush.plugins.http.request import HttpRequestPlugin
|
||||||
|
|
||||||
class HttpRequestOtaBookingPlugin(HttpRequestPlugin):
|
class HttpRequestOtaBookingPlugin(HttpRequestPlugin):
|
||||||
|
@ -12,6 +13,7 @@ class HttpRequestOtaBookingPlugin(HttpRequestPlugin):
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_reservations(self, day='today'):
|
def get_reservations(self, day='today'):
|
||||||
url = 'https://hub-api.booking.com/v1/hotels/{}/reservations' \
|
url = 'https://hub-api.booking.com/v1/hotels/{}/reservations' \
|
||||||
.format(self.hotel_id)
|
.format(self.hotel_id)
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import pylast
|
import pylast
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
from .. import Plugin
|
|
||||||
|
|
||||||
class LastfmPlugin(Plugin):
|
class LastfmPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
@ -42,6 +40,7 @@ class LastfmPlugin(Plugin):
|
||||||
password_hash = pylast.md5(self.password))
|
password_hash = pylast.md5(self.password))
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def scrobble(self, artist, title, album=None, **kwargs):
|
def scrobble(self, artist, title, album=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Scrobble a track to Last.FM
|
Scrobble a track to Last.FM
|
||||||
|
@ -61,8 +60,6 @@ class LastfmPlugin(Plugin):
|
||||||
timestamp = int(time.time()),
|
timestamp = int(time.time()),
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response()
|
|
||||||
|
|
||||||
|
|
||||||
def update_now_playing(self, artist, title, album=None, **kwargs):
|
def update_now_playing(self, artist, title, album=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -82,8 +79,6 @@ class LastfmPlugin(Plugin):
|
||||||
album = album,
|
album = album,
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response()
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,26 @@
|
||||||
from .. import Plugin
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
class LightPlugin(Plugin):
|
class LightPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
Abstract plugin to interface your logic with lights/bulbs.
|
Abstract plugin to interface your logic with lights/bulbs.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@action
|
||||||
def on(self):
|
def on(self):
|
||||||
""" Turn the light on """
|
""" Turn the light on """
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def off(self):
|
def off(self):
|
||||||
""" Turn the light off """
|
""" Turn the light off """
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def toggle(self):
|
def toggle(self):
|
||||||
""" Toggle the light status (on/off) """
|
""" Toggle the light status (on/off) """
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def status(self):
|
def status(self):
|
||||||
""" Get the light status """
|
""" Get the light status """
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
|
@ -8,9 +8,9 @@ from redis.exceptions import TimeoutError as QueueTimeoutError
|
||||||
from phue import Bridge
|
from phue import Bridge
|
||||||
|
|
||||||
from platypush.context import get_backend
|
from platypush.context import get_backend
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
|
from platypush.plugins.light import LightPlugin
|
||||||
|
|
||||||
from .. import LightPlugin
|
|
||||||
|
|
||||||
class LightHuePlugin(LightPlugin):
|
class LightHuePlugin(LightPlugin):
|
||||||
"""
|
"""
|
||||||
|
@ -75,6 +75,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
for g in groups:
|
for g in groups:
|
||||||
self.lights.extend([l.name for l in g.lights])
|
self.lights.extend([l.name for l in g.lights])
|
||||||
|
|
||||||
|
@action
|
||||||
def connect(self):
|
def connect(self):
|
||||||
"""
|
"""
|
||||||
Connect to the configured Hue bridge. If the device hasn't been paired
|
Connect to the configured Hue bridge. If the device hasn't been paired
|
||||||
|
@ -100,6 +101,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
self.logger.info('Bridge already connected')
|
self.logger.info('Bridge already connected')
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_scenes(self):
|
def get_scenes(self):
|
||||||
"""
|
"""
|
||||||
Get the available scenes on the devices.
|
Get the available scenes on the devices.
|
||||||
|
@ -129,9 +131,10 @@ class LightHuePlugin(LightPlugin):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(output=self.bridge.get_scene())
|
return self.bridge.get_scene()
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_lights(self):
|
def get_lights(self):
|
||||||
"""
|
"""
|
||||||
Get the configured lights.
|
Get the configured lights.
|
||||||
|
@ -170,9 +173,10 @@ class LightHuePlugin(LightPlugin):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(output=self.bridge.get_light())
|
return self.bridge.get_light()
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_groups(self):
|
def get_groups(self):
|
||||||
"""
|
"""
|
||||||
Get the list of configured light groups.
|
Get the list of configured light groups.
|
||||||
|
@ -222,7 +226,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(output=self.bridge.get_group())
|
return self.bridge.get_group()
|
||||||
|
|
||||||
|
|
||||||
def _exec(self, attr, *args, **kwargs):
|
def _exec(self, attr, *args, **kwargs):
|
||||||
|
@ -257,8 +261,8 @@ class LightHuePlugin(LightPlugin):
|
||||||
self.bridge = None
|
self.bridge = None
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
return Response(output='ok')
|
|
||||||
|
|
||||||
|
@action
|
||||||
def set_light(self, light, **kwargs):
|
def set_light(self, light, **kwargs):
|
||||||
"""
|
"""
|
||||||
Set a light (or lights) property.
|
Set a light (or lights) property.
|
||||||
|
@ -281,8 +285,8 @@ class LightHuePlugin(LightPlugin):
|
||||||
|
|
||||||
self.connect()
|
self.connect()
|
||||||
self.bridge.set_light(light, **kwargs)
|
self.bridge.set_light(light, **kwargs)
|
||||||
return Response(output='ok')
|
|
||||||
|
|
||||||
|
@action
|
||||||
def set_group(self, group, **kwargs):
|
def set_group(self, group, **kwargs):
|
||||||
"""
|
"""
|
||||||
Set a group (or groups) property.
|
Set a group (or groups) property.
|
||||||
|
@ -305,8 +309,8 @@ class LightHuePlugin(LightPlugin):
|
||||||
|
|
||||||
self.connect()
|
self.connect()
|
||||||
self.bridge.set_group(group, **kwargs)
|
self.bridge.set_group(group, **kwargs)
|
||||||
return Response(output='ok')
|
|
||||||
|
|
||||||
|
@action
|
||||||
def on(self, lights=[], groups=[]):
|
def on(self, lights=[], groups=[]):
|
||||||
"""
|
"""
|
||||||
Turn lights/groups on.
|
Turn lights/groups on.
|
||||||
|
@ -317,6 +321,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
|
|
||||||
return self._exec('on', True, lights=lights, groups=groups)
|
return self._exec('on', True, lights=lights, groups=groups)
|
||||||
|
|
||||||
|
@action
|
||||||
def off(self, lights=[], groups=[]):
|
def off(self, lights=[], groups=[]):
|
||||||
"""
|
"""
|
||||||
Turn lights/groups off.
|
Turn lights/groups off.
|
||||||
|
@ -327,6 +332,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
|
|
||||||
return self._exec('on', False, lights=lights, groups=groups)
|
return self._exec('on', False, lights=lights, groups=groups)
|
||||||
|
|
||||||
|
@action
|
||||||
def bri(self, value, lights=[], groups=[]):
|
def bri(self, value, lights=[], groups=[]):
|
||||||
"""
|
"""
|
||||||
Set lights/groups brightness.
|
Set lights/groups brightness.
|
||||||
|
@ -339,6 +345,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
return self._exec('bri', int(value) % (self.MAX_BRI+1),
|
return self._exec('bri', int(value) % (self.MAX_BRI+1),
|
||||||
lights=lights, groups=groups)
|
lights=lights, groups=groups)
|
||||||
|
|
||||||
|
@action
|
||||||
def sat(self, value, lights=[], groups=[]):
|
def sat(self, value, lights=[], groups=[]):
|
||||||
"""
|
"""
|
||||||
Set lights/groups saturation.
|
Set lights/groups saturation.
|
||||||
|
@ -351,6 +358,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
return self._exec('sat', int(value) % (self.MAX_SAT+1),
|
return self._exec('sat', int(value) % (self.MAX_SAT+1),
|
||||||
lights=lights, groups=groups)
|
lights=lights, groups=groups)
|
||||||
|
|
||||||
|
@action
|
||||||
def hue(self, value, lights=[], groups=[]):
|
def hue(self, value, lights=[], groups=[]):
|
||||||
"""
|
"""
|
||||||
Set lights/groups color hue.
|
Set lights/groups color hue.
|
||||||
|
@ -363,6 +371,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
return self._exec('hue', int(value) % (self.MAX_HUE+1),
|
return self._exec('hue', int(value) % (self.MAX_HUE+1),
|
||||||
lights=lights, groups=groups)
|
lights=lights, groups=groups)
|
||||||
|
|
||||||
|
@action
|
||||||
def scene(self, name, lights=[], groups=[]):
|
def scene(self, name, lights=[], groups=[]):
|
||||||
"""
|
"""
|
||||||
Set a scene by name.
|
Set a scene by name.
|
||||||
|
@ -374,6 +383,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
|
|
||||||
return self._exec('scene', name=name, lights=lights, groups=groups)
|
return self._exec('scene', name=name, lights=lights, groups=groups)
|
||||||
|
|
||||||
|
@action
|
||||||
def is_animation_running(self):
|
def is_animation_running(self):
|
||||||
"""
|
"""
|
||||||
:returns: True if there is an animation running, false otherwise.
|
:returns: True if there is an animation running, false otherwise.
|
||||||
|
@ -381,6 +391,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
|
|
||||||
return self.animation_thread is not None
|
return self.animation_thread is not None
|
||||||
|
|
||||||
|
@action
|
||||||
def stop_animation(self):
|
def stop_animation(self):
|
||||||
"""
|
"""
|
||||||
Stop a running animation if any
|
Stop a running animation if any
|
||||||
|
@ -389,6 +400,7 @@ class LightHuePlugin(LightPlugin):
|
||||||
if self.animation_thread and self.animation_thread.is_alive():
|
if self.animation_thread and self.animation_thread.is_alive():
|
||||||
self.redis.rpush(self.ANIMATION_CTRL_QUEUE_NAME, 'STOP')
|
self.redis.rpush(self.ANIMATION_CTRL_QUEUE_NAME, 'STOP')
|
||||||
|
|
||||||
|
@action
|
||||||
def animate(self, animation, duration=None,
|
def animate(self, animation, duration=None,
|
||||||
hue_range=[0, MAX_HUE], sat_range=[0, MAX_SAT],
|
hue_range=[0, MAX_HUE], sat_range=[0, MAX_SAT],
|
||||||
bri_range=[MAX_BRI-1, MAX_BRI], lights=None, groups=None,
|
bri_range=[MAX_BRI-1, MAX_BRI], lights=None, groups=None,
|
||||||
|
@ -529,7 +541,6 @@ class LightHuePlugin(LightPlugin):
|
||||||
self.stop_animation()
|
self.stop_animation()
|
||||||
self.animation_thread = Thread(target=_animate_thread, args=(lights,))
|
self.animation_thread = Thread(target=_animate_thread, args=(lights,))
|
||||||
self.animation_thread.start()
|
self.animation_thread.start()
|
||||||
return Response(output='ok')
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -2,10 +2,9 @@ import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from platypush.context import get_plugin
|
from platypush.context import get_plugin
|
||||||
from platypush.message.response import Response
|
|
||||||
from platypush.plugins.media import PlayerState
|
from platypush.plugins.media import PlayerState
|
||||||
|
|
||||||
from .. import Plugin
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
class MediaCtrlPlugin(Plugin):
|
class MediaCtrlPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
@ -76,9 +75,9 @@ class MediaCtrlPlugin(Plugin):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def play(self, url):
|
def play(self, url):
|
||||||
(type, resource) = self._get_type_and_resource_by_url(url)
|
(type, resource) = self._get_type_and_resource_by_url(url)
|
||||||
response = Response(output='', errors = [])
|
|
||||||
plugin_name = None
|
plugin_name = None
|
||||||
|
|
||||||
if type == 'mpd':
|
if type == 'mpd':
|
||||||
|
@ -99,11 +98,13 @@ class MediaCtrlPlugin(Plugin):
|
||||||
self.url = resource
|
self.url = resource
|
||||||
return self.plugin.play(resource)
|
return self.plugin.play(resource)
|
||||||
|
|
||||||
|
@action
|
||||||
def pause(self):
|
def pause(self):
|
||||||
plugin = self._get_playing_plugin()
|
plugin = self._get_playing_plugin()
|
||||||
if plugin: return plugin.pause()
|
if plugin: return plugin.pause()
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def stop(self):
|
def stop(self):
|
||||||
plugin = self._get_playing_plugin()
|
plugin = self._get_playing_plugin()
|
||||||
if plugin:
|
if plugin:
|
||||||
|
@ -112,36 +113,43 @@ class MediaCtrlPlugin(Plugin):
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def voldown(self):
|
def voldown(self):
|
||||||
plugin = self._get_playing_plugin()
|
plugin = self._get_playing_plugin()
|
||||||
if plugin: return plugin.voldown()
|
if plugin: return plugin.voldown()
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def volup(self):
|
def volup(self):
|
||||||
plugin = self._get_playing_plugin()
|
plugin = self._get_playing_plugin()
|
||||||
if plugin: return plugin.volup()
|
if plugin: return plugin.volup()
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def back(self):
|
def back(self):
|
||||||
plugin = self._get_playing_plugin()
|
plugin = self._get_playing_plugin()
|
||||||
if plugin: return plugin.back()
|
if plugin: return plugin.back()
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def forward(self):
|
def forward(self):
|
||||||
plugin = self._get_playing_plugin()
|
plugin = self._get_playing_plugin()
|
||||||
if plugin: return plugin.forward()
|
if plugin: return plugin.forward()
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def next(self):
|
def next(self):
|
||||||
plugin = self._get_playing_plugin()
|
plugin = self._get_playing_plugin()
|
||||||
if plugin: return plugin.next()
|
if plugin: return plugin.next()
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def previous(self):
|
def previous(self):
|
||||||
plugin = self._get_playing_plugin()
|
plugin = self._get_playing_plugin()
|
||||||
if plugin: return plugin.previous()
|
if plugin: return plugin.previous()
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def status(self):
|
def status(self):
|
||||||
plugin = self._get_playing_plugin()
|
plugin = self._get_playing_plugin()
|
||||||
if plugin: return plugin.status()
|
if plugin: return plugin.status()
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import rtmidi
|
import rtmidi
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
|
|
||||||
class MidiPlugin(Plugin):
|
class MidiPlugin(Plugin):
|
||||||
|
@ -39,6 +38,7 @@ class MidiPlugin(Plugin):
|
||||||
format(self.device_name))
|
format(self.device_name))
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def send_message(self, values, *args, **kwargs):
|
def send_message(self, values, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
:param values: Values is expected to be a list containing the MIDI command code and the command parameters - see reference at https://ccrma.stanford.edu/~craig/articles/linuxmidi/misc/essenmidi.html
|
:param values: Values is expected to be a list containing the MIDI command code and the command parameters - see reference at https://ccrma.stanford.edu/~craig/articles/linuxmidi/misc/essenmidi.html
|
||||||
|
@ -70,9 +70,9 @@ class MidiPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.midiout.send_message(values, *args, **kwargs)
|
self.midiout.send_message(values, *args, **kwargs)
|
||||||
return Response(output={'status':'ok'})
|
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def play_note(self, note, velocity, duration=0):
|
def play_note(self, note, velocity, duration=0):
|
||||||
"""
|
"""
|
||||||
Play a note with selected velocity and duration.
|
Play a note with selected velocity and duration.
|
||||||
|
@ -96,6 +96,7 @@ class MidiPlugin(Plugin):
|
||||||
self._played_notes.remove(note)
|
self._played_notes.remove(note)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def release_note(self, note):
|
def release_note(self, note):
|
||||||
"""
|
"""
|
||||||
Release a played note.
|
Release a played note.
|
||||||
|
@ -108,6 +109,7 @@ class MidiPlugin(Plugin):
|
||||||
self._played_notes.remove(note)
|
self._played_notes.remove(note)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def release_all_notes(self):
|
def release_all_notes(self):
|
||||||
"""
|
"""
|
||||||
Release all the notes being played.
|
Release all the notes being played.
|
||||||
|
|
|
@ -2,8 +2,7 @@ import json
|
||||||
import paho.mqtt.publish as publisher
|
import paho.mqtt.publish as publisher
|
||||||
|
|
||||||
from platypush.message import Message
|
from platypush.message import Message
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
|
|
||||||
class MqttPlugin(Plugin):
|
class MqttPlugin(Plugin):
|
||||||
|
@ -12,6 +11,7 @@ class MqttPlugin(Plugin):
|
||||||
with the MQTT protocol, see http://mqtt.org/
|
with the MQTT protocol, see http://mqtt.org/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@action
|
||||||
def send_message(self, topic, msg, host, port=1883, *args, **kwargs):
|
def send_message(self, topic, msg, host, port=1883, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Sends a message to a topic/channel.
|
Sends a message to a topic/channel.
|
||||||
|
@ -35,7 +35,6 @@ class MqttPlugin(Plugin):
|
||||||
except: pass
|
except: pass
|
||||||
|
|
||||||
publisher.single(topic, str(msg), hostname=host, port=port)
|
publisher.single(topic, str(msg), hostname=host, port=port)
|
||||||
return Response(output={'state': 'ok'})
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,33 +1,47 @@
|
||||||
from .. import Plugin
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
|
|
||||||
class MusicPlugin(Plugin):
|
class MusicPlugin(Plugin):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@action
|
||||||
def play(self):
|
def play(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def pause(self):
|
def pause(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def stop(self):
|
def stop(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def next(self):
|
def next(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def previous(self):
|
def previous(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def setvol(self, vol):
|
def setvol(self, vol):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def add(self, content):
|
def add(self, content):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def playlistadd(self, playlist):
|
def playlistadd(self, playlist):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def clear(self):
|
def clear(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def status(self):
|
def status(self):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import mpd
|
import mpd
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
|
from platypush.plugins.music import MusicPlugin
|
||||||
from .. import MusicPlugin
|
|
||||||
|
|
||||||
class MusicMpdPlugin(MusicPlugin):
|
class MusicMpdPlugin(MusicPlugin):
|
||||||
"""
|
"""
|
||||||
|
@ -29,6 +28,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
:type port: int
|
:type port: int
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
self.client = mpd.MPDClient(use_unicode=True)
|
self.client = mpd.MPDClient(use_unicode=True)
|
||||||
|
@ -36,8 +36,9 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
|
|
||||||
def _exec(self, method, *args, **kwargs):
|
def _exec(self, method, *args, **kwargs):
|
||||||
getattr(self.client, method)(*args, **kwargs)
|
getattr(self.client, method)(*args, **kwargs)
|
||||||
return self.status()
|
return self.status().output
|
||||||
|
|
||||||
|
@action
|
||||||
def play(self, resource=None):
|
def play(self, resource=None):
|
||||||
"""
|
"""
|
||||||
Play a resource by path/URI
|
Play a resource by path/URI
|
||||||
|
@ -51,6 +52,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
self.add(resource)
|
self.add(resource)
|
||||||
return self._exec('play')
|
return self._exec('play')
|
||||||
|
|
||||||
|
@action
|
||||||
def play_pos(self, pos):
|
def play_pos(self, pos):
|
||||||
"""
|
"""
|
||||||
Play a track in the current playlist by position number
|
Play a track in the current playlist by position number
|
||||||
|
@ -61,6 +63,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
|
|
||||||
return self._exec('play', pos)
|
return self._exec('play', pos)
|
||||||
|
|
||||||
|
@action
|
||||||
def pause(self):
|
def pause(self):
|
||||||
""" Pause playback """
|
""" Pause playback """
|
||||||
|
|
||||||
|
@ -68,31 +71,38 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
if status == 'play': return self._exec('pause')
|
if status == 'play': return self._exec('pause')
|
||||||
else: return self._exec('play')
|
else: return self._exec('play')
|
||||||
|
|
||||||
|
@action
|
||||||
def pause_if_playing(self):
|
def pause_if_playing(self):
|
||||||
""" Pause playback only if it's playing """
|
""" Pause playback only if it's playing """
|
||||||
|
|
||||||
status = self.status().output['state']
|
status = self.status().output['state']
|
||||||
if status == 'play': return self._exec('pause')
|
if status == 'play':
|
||||||
else: return Response(output={})
|
return self._exec('pause')
|
||||||
|
|
||||||
|
@action
|
||||||
def play_if_paused(self):
|
def play_if_paused(self):
|
||||||
""" Play only if it's paused (resume) """
|
""" Play only if it's paused (resume) """
|
||||||
|
|
||||||
status = self.status().output['state']
|
status = self.status().output['state']
|
||||||
if status == 'pause': return self._exec('play')
|
if status == 'pause':
|
||||||
else: return Response(output={})
|
return self._exec('play')
|
||||||
|
|
||||||
|
@action
|
||||||
def stop(self):
|
def stop(self):
|
||||||
""" Stop playback """
|
""" Stop playback """
|
||||||
|
|
||||||
return self._exec('stop')
|
return self._exec('stop')
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def play_or_stop(self):
|
def play_or_stop(self):
|
||||||
""" Play or stop (play state toggle) """
|
""" Play or stop (play state toggle) """
|
||||||
status = self.status().output['state']
|
status = self.status().output['state']
|
||||||
if status == 'play': return self._exec('stop')
|
if status == 'play':
|
||||||
else: return self._exec('play')
|
return self._exec('stop')
|
||||||
|
else:
|
||||||
|
return self._exec('play')
|
||||||
|
|
||||||
|
@action
|
||||||
def playid(self, track_id):
|
def playid(self, track_id):
|
||||||
"""
|
"""
|
||||||
Play a track by ID
|
Play a track by ID
|
||||||
|
@ -103,14 +113,17 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
|
|
||||||
return self._exec('playid', track_id)
|
return self._exec('playid', track_id)
|
||||||
|
|
||||||
|
@action
|
||||||
def next(self):
|
def next(self):
|
||||||
""" Play the next track """
|
""" Play the next track """
|
||||||
return self._exec('next')
|
return self._exec('next')
|
||||||
|
|
||||||
|
@action
|
||||||
def previous(self):
|
def previous(self):
|
||||||
""" Play the previous track """
|
""" Play the previous track """
|
||||||
return self._exec('previous')
|
return self._exec('previous')
|
||||||
|
|
||||||
|
@action
|
||||||
def setvol(self, vol):
|
def setvol(self, vol):
|
||||||
"""
|
"""
|
||||||
Set the volume
|
Set the volume
|
||||||
|
@ -120,6 +133,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
"""
|
"""
|
||||||
return self._exec('setvol', vol)
|
return self._exec('setvol', vol)
|
||||||
|
|
||||||
|
@action
|
||||||
def volup(self, delta=10):
|
def volup(self, delta=10):
|
||||||
"""
|
"""
|
||||||
Turn up the volume
|
Turn up the volume
|
||||||
|
@ -134,6 +148,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
self.setvol(str(new_volume))
|
self.setvol(str(new_volume))
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def voldown(self, delta=10):
|
def voldown(self, delta=10):
|
||||||
"""
|
"""
|
||||||
Turn down the volume
|
Turn down the volume
|
||||||
|
@ -148,6 +163,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
self.setvol(str(new_volume))
|
self.setvol(str(new_volume))
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def random(self, value=None):
|
def random(self, value=None):
|
||||||
"""
|
"""
|
||||||
Set shuffle mode
|
Set shuffle mode
|
||||||
|
@ -161,6 +177,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
value = 1 if value == 0 else 0
|
value = 1 if value == 0 else 0
|
||||||
return self._exec('random', value)
|
return self._exec('random', value)
|
||||||
|
|
||||||
|
@action
|
||||||
def repeat(self, value=None):
|
def repeat(self, value=None):
|
||||||
"""
|
"""
|
||||||
Set repeat mode
|
Set repeat mode
|
||||||
|
@ -174,6 +191,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
value = 1 if value == 0 else 0
|
value = 1 if value == 0 else 0
|
||||||
return self._exec('repeat', value)
|
return self._exec('repeat', value)
|
||||||
|
|
||||||
|
@action
|
||||||
def add(self, resource):
|
def add(self, resource):
|
||||||
"""
|
"""
|
||||||
Add a resource (track, album, artist, folder etc.) to the current playlist
|
Add a resource (track, album, artist, folder etc.) to the current playlist
|
||||||
|
@ -184,6 +202,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
|
|
||||||
return self._exec('add', resource)
|
return self._exec('add', resource)
|
||||||
|
|
||||||
|
@action
|
||||||
def load(self, playlist):
|
def load(self, playlist):
|
||||||
"""
|
"""
|
||||||
Load and play a playlist by name
|
Load and play a playlist by name
|
||||||
|
@ -195,10 +214,12 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
self._exec('load', playlist)
|
self._exec('load', playlist)
|
||||||
return self.play()
|
return self.play()
|
||||||
|
|
||||||
|
@action
|
||||||
def clear(self):
|
def clear(self):
|
||||||
""" Clear the current playlist """
|
""" Clear the current playlist """
|
||||||
return self._exec('clear')
|
return self._exec('clear')
|
||||||
|
|
||||||
|
@action
|
||||||
def seekcur(self, value):
|
def seekcur(self, value):
|
||||||
"""
|
"""
|
||||||
Seek to the specified position
|
Seek to the specified position
|
||||||
|
@ -209,16 +230,19 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
|
|
||||||
return self._exec('seekcur', value)
|
return self._exec('seekcur', value)
|
||||||
|
|
||||||
|
@action
|
||||||
def forward(self):
|
def forward(self):
|
||||||
""" Go forward by 15 seconds """
|
""" Go forward by 15 seconds """
|
||||||
|
|
||||||
return self._exec('seekcur', '+15')
|
return self._exec('seekcur', '+15')
|
||||||
|
|
||||||
|
@action
|
||||||
def back(self):
|
def back(self):
|
||||||
""" Go backward by 15 seconds """
|
""" Go backward by 15 seconds """
|
||||||
|
|
||||||
return self._exec('seekcur', '-15')
|
return self._exec('seekcur', '-15')
|
||||||
|
|
||||||
|
@action
|
||||||
def status(self):
|
def status(self):
|
||||||
"""
|
"""
|
||||||
:returns: The current state.
|
:returns: The current state.
|
||||||
|
@ -245,8 +269,9 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(output=self.client.status())
|
return self.client.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def currentsong(self):
|
def currentsong(self):
|
||||||
"""
|
"""
|
||||||
:returns: The currently played track.
|
:returns: The currently played track.
|
||||||
|
@ -277,8 +302,9 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
track['artist'] = m.group(1)
|
track['artist'] = m.group(1)
|
||||||
track['title'] = m.group(2)
|
track['title'] = m.group(2)
|
||||||
|
|
||||||
return Response(output=track)
|
return track
|
||||||
|
|
||||||
|
@action
|
||||||
def playlistinfo(self):
|
def playlistinfo(self):
|
||||||
"""
|
"""
|
||||||
:returns: The tracks in the current playlist as a list of dicts.
|
:returns: The tracks in the current playlist as a list of dicts.
|
||||||
|
@ -315,8 +341,9 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(output=self.client.playlistinfo())
|
return self.client.playlistinfo()
|
||||||
|
|
||||||
|
@action
|
||||||
def listplaylists(self):
|
def listplaylists(self):
|
||||||
"""
|
"""
|
||||||
:returns: The playlists available on the server as a list of dicts.
|
:returns: The playlists available on the server as a list of dicts.
|
||||||
|
@ -338,17 +365,18 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(output=sorted(self.client.listplaylists(),
|
return sorted(self.client.listplaylists(), key=lambda p: p['playlist'])
|
||||||
key=lambda p: p['playlist']))
|
|
||||||
|
|
||||||
|
@action
|
||||||
def lsinfo(self, uri=None):
|
def lsinfo(self, uri=None):
|
||||||
"""
|
"""
|
||||||
Returns the list of playlists and directories on the server
|
Returns the list of playlists and directories on the server
|
||||||
"""
|
"""
|
||||||
|
|
||||||
output = self.client.lsinfo(uri) if uri else self.client.lsinfo()
|
output = self.client.lsinfo(uri) if uri else self.client.lsinfo()
|
||||||
return Response(output=output)
|
return output
|
||||||
|
|
||||||
|
@action
|
||||||
def plchanges(self, version):
|
def plchanges(self, version):
|
||||||
"""
|
"""
|
||||||
Show what has changed on the current playlist since a specified playlist
|
Show what has changed on the current playlist since a specified playlist
|
||||||
|
@ -360,8 +388,9 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
:returns: A list of dicts representing the songs being added since the specified version
|
:returns: A list of dicts representing the songs being added since the specified version
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(output=self.client.plchanges(version))
|
return self.client.plchanges(version)
|
||||||
|
|
||||||
|
@action
|
||||||
def searchaddplaylist(self, name):
|
def searchaddplaylist(self, name):
|
||||||
"""
|
"""
|
||||||
Search and add a playlist by (partial or full) name
|
Search and add a playlist by (partial or full) name
|
||||||
|
@ -379,10 +408,9 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
self.client.clear()
|
self.client.clear()
|
||||||
self.client.load(playlists[0])
|
self.client.load(playlists[0])
|
||||||
self.client.play()
|
self.client.play()
|
||||||
return Response(output={'playlist': playlists[0]})
|
return {'playlist': playlists[0]}
|
||||||
|
|
||||||
return Response(output={})
|
|
||||||
|
|
||||||
|
@action
|
||||||
def find(self, filter, *args, **kwargs):
|
def find(self, filter, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Find in the database/library by filter.
|
Find in the database/library by filter.
|
||||||
|
@ -392,9 +420,9 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
:returns: list[dict]
|
:returns: list[dict]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(
|
return self.client.find(*filter, *args, **kwargs)
|
||||||
output=self.client.find(*filter, *args, **kwargs))
|
|
||||||
|
|
||||||
|
@action
|
||||||
def findadd(self, filter, *args, **kwargs):
|
def findadd(self, filter, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Find in the database/library by filter and add to the current playlist.
|
Find in the database/library by filter and add to the current playlist.
|
||||||
|
@ -404,9 +432,9 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
:returns: list[dict]
|
:returns: list[dict]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(
|
return self.client.findadd(*filter, *args, **kwargs)
|
||||||
output=self.client.findadd(*filter, *args, **kwargs))
|
|
||||||
|
|
||||||
|
@action
|
||||||
def search(self, filter, *args, **kwargs):
|
def search(self, filter, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Free search by filter.
|
Free search by filter.
|
||||||
|
@ -422,8 +450,9 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
items = sorted(items, key=lambda item:
|
items = sorted(items, key=lambda item:
|
||||||
0 if item['file'].startswith('spotify:') else 1)
|
0 if item['file'].startswith('spotify:') else 1)
|
||||||
|
|
||||||
return Response(output=items)
|
return items
|
||||||
|
|
||||||
|
@action
|
||||||
def searchadd(self, filter, *args, **kwargs):
|
def searchadd(self, filter, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Free search by filter and add the results to the current playlist.
|
Free search by filter and add the results to the current playlist.
|
||||||
|
@ -433,8 +462,7 @@ class MusicMpdPlugin(MusicPlugin):
|
||||||
:returns: list[dict]
|
:returns: list[dict]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(
|
return self.client.searchadd(*filter, *args, **kwargs)
|
||||||
output=self.client.searchadd(*filter, *args, **kwargs))
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@ import os
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from platypush.context import get_backend
|
from platypush.context import get_backend
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
|
|
||||||
class PushbulletPlugin(Plugin):
|
class PushbulletPlugin(Plugin):
|
||||||
|
@ -18,6 +17,7 @@ class PushbulletPlugin(Plugin):
|
||||||
* **requests** (``pip install requests``)
|
* **requests** (``pip install requests``)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@action
|
||||||
def send_push(self, **kwargs):
|
def send_push(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Send a push.
|
Send a push.
|
||||||
|
@ -40,9 +40,8 @@ class PushbulletPlugin(Plugin):
|
||||||
raise Exception('Pushbullet push failed with status {}: {}'.
|
raise Exception('Pushbullet push failed with status {}: {}'.
|
||||||
format(resp.status_code, resp.json()))
|
format(resp.status_code, resp.json()))
|
||||||
|
|
||||||
return Response(output={'status':'ok'})
|
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def send_file(self, filename):
|
def send_file(self, filename):
|
||||||
"""
|
"""
|
||||||
Send a file.
|
Send a file.
|
||||||
|
@ -83,11 +82,11 @@ class PushbulletPlugin(Plugin):
|
||||||
raise Exception('Pushbullet file push failed with status {}'.
|
raise Exception('Pushbullet file push failed with status {}'.
|
||||||
format(resp.status_code))
|
format(resp.status_code))
|
||||||
|
|
||||||
return Response(output={
|
return {
|
||||||
'filename': r['file_name'],
|
'filename': r['file_name'],
|
||||||
'type': r['file_type'],
|
'type': r['file_type'],
|
||||||
'url': r['file_url']
|
'url': r['file_url']
|
||||||
})
|
}
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from redis import Redis
|
from redis import Redis
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
|
|
||||||
class RedisPlugin(Plugin):
|
class RedisPlugin(Plugin):
|
||||||
|
@ -13,6 +12,7 @@ class RedisPlugin(Plugin):
|
||||||
* **redis** (``pip install redis``)
|
* **redis** (``pip install redis``)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@action
|
||||||
def send_message(self, queue, msg, *args, **kwargs):
|
def send_message(self, queue, msg, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Send a message to a Redis queu.
|
Send a message to a Redis queu.
|
||||||
|
@ -32,7 +32,6 @@ class RedisPlugin(Plugin):
|
||||||
|
|
||||||
redis = Redis(*args, **kwargs)
|
redis = Redis(*args, **kwargs)
|
||||||
redis.rpush(queue, msg)
|
redis.rpush(queue, msg)
|
||||||
return Response(output={'state': 'ok'})
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import json
|
import json
|
||||||
import serial
|
import serial
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
from .. import Plugin
|
|
||||||
|
|
||||||
|
|
||||||
class SerialPlugin(Plugin):
|
class SerialPlugin(Plugin):
|
||||||
|
@ -60,6 +58,7 @@ class SerialPlugin(Plugin):
|
||||||
|
|
||||||
return output.decode().strip()
|
return output.decode().strip()
|
||||||
|
|
||||||
|
@action
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
"""
|
"""
|
||||||
Reads JSON data from the serial device and returns it as a message
|
Reads JSON data from the serial device and returns it as a message
|
||||||
|
@ -78,7 +77,7 @@ class SerialPlugin(Plugin):
|
||||||
self.logger.warning('Invalid JSON message from {}: {}'.
|
self.logger.warning('Invalid JSON message from {}: {}'.
|
||||||
format(self.device, data))
|
format(self.device, data))
|
||||||
|
|
||||||
return Response(output=data)
|
return data
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.message.response import Response
|
||||||
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
from .. import Plugin
|
|
||||||
|
|
||||||
class ShellPlugin(Plugin):
|
class ShellPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
Plugin to run custom shell commands.
|
Plugin to run custom shell commands.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@action
|
||||||
def exec(self, cmd):
|
def exec(self, cmd):
|
||||||
"""
|
"""
|
||||||
Execute a command.
|
Execute a command.
|
||||||
|
@ -19,16 +20,12 @@ class ShellPlugin(Plugin):
|
||||||
:returns: A response object where the ``output`` field will contain the command output as a string, and the ``errors`` field will contain whatever was sent to stderr.
|
:returns: A response object where the ``output`` field will contain the command output as a string, and the ``errors`` field will contain whatever was sent to stderr.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
output = None
|
|
||||||
errors = []
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
output = subprocess.check_output(
|
return subprocess.check_output(
|
||||||
cmd, stderr=subprocess.STDOUT, shell=True).decode('utf-8')
|
cmd, stderr=subprocess.STDOUT, shell=True).decode('utf-8')
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
errors = [e.output.decode('utf-8')]
|
raise RuntimeError(e.output.decode('utf-8'))
|
||||||
|
|
||||||
return Response(output=output, errors=errors)
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,29 @@
|
||||||
from .. import Plugin
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
class SwitchPlugin(Plugin):
|
class SwitchPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
Abstract class for interacting with switch devices
|
Abstract class for interacting with switch devices
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@action
|
||||||
def on(self, args):
|
def on(self, args):
|
||||||
""" Turn the device on """
|
""" Turn the device on """
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def off(self, args):
|
def off(self, args):
|
||||||
""" Turn the device off """
|
""" Turn the device off """
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def toggle(self, args):
|
def toggle(self, args):
|
||||||
""" Toggle the device status (on/off) """
|
""" Toggle the device status (on/off) """
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
def status(self):
|
def status(self):
|
||||||
""" Get the device state """
|
""" Get the device state """
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
|
@ -4,9 +4,8 @@ import time
|
||||||
|
|
||||||
from bluetooth.ble import DiscoveryService, GATTRequester
|
from bluetooth.ble import DiscoveryService, GATTRequester
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
|
from platypush.plugins.switch import SwitchPlugin
|
||||||
from .. import SwitchPlugin
|
|
||||||
|
|
||||||
class Scanner(object):
|
class Scanner(object):
|
||||||
service_uuid = '1bc5d5a5-0200b89f-e6114d22-000da2cb'
|
service_uuid = '1bc5d5a5-0200b89f-e6114d22-000da2cb'
|
||||||
|
@ -112,6 +111,7 @@ class SwitchSwitchbotPlugin(SwitchPlugin):
|
||||||
:type devices: dict
|
:type devices: dict
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
self.bt_interface = bt_interface
|
self.bt_interface = bt_interface
|
||||||
self.connect_timeout = connect_timeout if connect_timeout else 5
|
self.connect_timeout = connect_timeout if connect_timeout else 5
|
||||||
self.scan_timeout = scan_timeout if scan_timeout else 2
|
self.scan_timeout = scan_timeout if scan_timeout else 2
|
||||||
|
@ -119,15 +119,12 @@ class SwitchSwitchbotPlugin(SwitchPlugin):
|
||||||
|
|
||||||
|
|
||||||
def _run(self, device, command=None):
|
def _run(self, device, command=None):
|
||||||
output = None
|
|
||||||
errors = []
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# XXX this requires sudo and it's executed in its own process
|
# XXX this requires sudo and it's executed in its own process
|
||||||
# because the Switchbot plugin requires root privileges to send
|
# because the Switchbot plugin requires root privileges to send
|
||||||
# raw bluetooth messages on the interface. Make sure that the user
|
# raw bluetooth messages on the interface. Make sure that the user
|
||||||
# that runs platypush has the right permissions to run this with sudo
|
# that runs platypush has the right permissions to run this with sudo
|
||||||
output = subprocess.check_output((
|
return subprocess.check_output((
|
||||||
'sudo python3 -m platypush.plugins.switch.switchbot ' +
|
'sudo python3 -m platypush.plugins.switch.switchbot ' +
|
||||||
'--device {} ' +
|
'--device {} ' +
|
||||||
('--interface {} '.format(self.bt_interface) if self.bt_interface else '') +
|
('--interface {} '.format(self.bt_interface) if self.bt_interface else '') +
|
||||||
|
@ -135,11 +132,10 @@ class SwitchSwitchbotPlugin(SwitchPlugin):
|
||||||
('--{} '.format(command) if command else '')).format(device),
|
('--{} '.format(command) if command else '')).format(device),
|
||||||
stderr=subprocess.STDOUT, shell=True).decode('utf-8')
|
stderr=subprocess.STDOUT, shell=True).decode('utf-8')
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
errors = [e.output.decode('utf-8')]
|
raise RuntimeError(e.output.decode('utf-8'))
|
||||||
|
|
||||||
return Response(output=output, errors=errors)
|
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def press(self, device):
|
def press(self, device):
|
||||||
"""
|
"""
|
||||||
Send a press button command to a device
|
Send a press button command to a device
|
||||||
|
@ -149,6 +145,7 @@ class SwitchSwitchbotPlugin(SwitchPlugin):
|
||||||
"""
|
"""
|
||||||
return self._run(device)
|
return self._run(device)
|
||||||
|
|
||||||
|
@action
|
||||||
def on(self, device):
|
def on(self, device):
|
||||||
"""
|
"""
|
||||||
Send a press-on button command to a device
|
Send a press-on button command to a device
|
||||||
|
@ -158,6 +155,7 @@ class SwitchSwitchbotPlugin(SwitchPlugin):
|
||||||
"""
|
"""
|
||||||
return self._run(device, 'on')
|
return self._run(device, 'on')
|
||||||
|
|
||||||
|
@action
|
||||||
def off(self, device):
|
def off(self, device):
|
||||||
"""
|
"""
|
||||||
Send a press-off button command to a device
|
Send a press-off button command to a device
|
||||||
|
@ -167,25 +165,17 @@ class SwitchSwitchbotPlugin(SwitchPlugin):
|
||||||
"""
|
"""
|
||||||
return self._run(device, 'off')
|
return self._run(device, 'off')
|
||||||
|
|
||||||
|
@action
|
||||||
def scan(self):
|
def scan(self):
|
||||||
""" Scan for available Switchbot devices nearby """
|
""" Scan for available Switchbot devices nearby """
|
||||||
output = None
|
|
||||||
errors = []
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print('sudo python3 -m platypush.plugins.switch.switchbot --scan ' +
|
return subprocess.check_output(
|
||||||
('--interface {} '.format(self.bt_interface) if self.bt_interface else '') +
|
|
||||||
('--scan-timeout {} '.format(self.scan_timeout) if self.scan_timeout else ''))
|
|
||||||
|
|
||||||
output = subprocess.check_output(
|
|
||||||
'sudo python3 -m platypush.plugins.switch.switchbot --scan ' +
|
'sudo python3 -m platypush.plugins.switch.switchbot --scan ' +
|
||||||
('--interface {} '.format(self.bt_interface) if self.bt_interface else '') +
|
('--interface {} '.format(self.bt_interface) if self.bt_interface else '') +
|
||||||
('--scan-timeout {} '.format(self.scan_timeout) if self.scan_timeout else ''),
|
('--scan-timeout {} '.format(self.scan_timeout) if self.scan_timeout else ''),
|
||||||
stderr=subprocess.STDOUT, shell=True).decode('utf-8')
|
stderr=subprocess.STDOUT, shell=True).decode('utf-8')
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
errors = [e.output.decode('utf-8')]
|
raise RuntimeError(e.output.decode('utf-8'))
|
||||||
|
|
||||||
return Response(output=output, errors=errors)
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from pyHS100 import Discover
|
from pyHS100 import Discover
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
from platypush.plugins.switch import SwitchPlugin
|
from platypush.plugins.switch import SwitchPlugin
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ class SwitchTplinkPlugin(SwitchPlugin):
|
||||||
_ip_to_dev = {}
|
_ip_to_dev = {}
|
||||||
_alias_to_dev = {}
|
_alias_to_dev = {}
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _scan(self):
|
def _scan(self):
|
||||||
devices = Discover.discover()
|
devices = Discover.discover()
|
||||||
|
@ -46,6 +48,7 @@ class SwitchTplinkPlugin(SwitchPlugin):
|
||||||
raise RuntimeError('Device {} not found'.format(device))
|
raise RuntimeError('Device {} not found'.format(device))
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def status(self):
|
def status(self):
|
||||||
"""
|
"""
|
||||||
:returns: The available device over the network as a
|
:returns: The available device over the network as a
|
||||||
|
@ -61,8 +64,9 @@ class SwitchTplinkPlugin(SwitchPlugin):
|
||||||
} for (ip, dev) in self._scan().items()
|
} for (ip, dev) in self._scan().items()
|
||||||
} }
|
} }
|
||||||
|
|
||||||
return Response(output=devices)
|
return devices
|
||||||
|
|
||||||
|
@action
|
||||||
def on(self, device):
|
def on(self, device):
|
||||||
"""
|
"""
|
||||||
Turn on a device
|
Turn on a device
|
||||||
|
@ -73,9 +77,10 @@ class SwitchTplinkPlugin(SwitchPlugin):
|
||||||
|
|
||||||
device = self._get_device(device)
|
device = self._get_device(device)
|
||||||
device.turn_on()
|
device.turn_on()
|
||||||
return Response(output={'status':'on'})
|
return {'status':'on'}
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def off(self, device):
|
def off(self, device):
|
||||||
"""
|
"""
|
||||||
Turn off a device
|
Turn off a device
|
||||||
|
@ -86,9 +91,10 @@ class SwitchTplinkPlugin(SwitchPlugin):
|
||||||
|
|
||||||
device = self._get_device(device)
|
device = self._get_device(device)
|
||||||
device.turn_off()
|
device.turn_off()
|
||||||
return Response(output={'status':'off'})
|
return {'status':'off'}
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def toggle(self, device):
|
def toggle(self, device):
|
||||||
"""
|
"""
|
||||||
Toggle the state of a device (on/off)
|
Toggle the state of a device (on/off)
|
||||||
|
@ -104,7 +110,7 @@ class SwitchTplinkPlugin(SwitchPlugin):
|
||||||
else:
|
else:
|
||||||
device.turn_on()
|
device.turn_on()
|
||||||
|
|
||||||
return Response(output={'status': 'off' if device.is_off else 'on'})
|
return {'status': 'off' if device.is_off else 'on'}
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from ouimeaux.environment import Environment, UnknownDevice
|
from ouimeaux.environment import Environment, UnknownDevice
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
|
from platypush.plugins.switch import SwitchPlugin
|
||||||
|
|
||||||
from .. import SwitchPlugin
|
|
||||||
|
|
||||||
class SwitchWemoPlugin(SwitchPlugin):
|
class SwitchWemoPlugin(SwitchPlugin):
|
||||||
"""
|
"""
|
||||||
|
@ -20,8 +20,8 @@ class SwitchWemoPlugin(SwitchPlugin):
|
||||||
:param discovery_seconds: Discovery time when scanning for devices (default: 3)
|
:param discovery_seconds: Discovery time when scanning for devices (default: 3)
|
||||||
:type discovery_seconds: int
|
:type discovery_seconds: int
|
||||||
"""
|
"""
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
self.discovery_seconds=discovery_seconds
|
self.discovery_seconds=discovery_seconds
|
||||||
self.env = Environment()
|
self.env = Environment()
|
||||||
self.env.start()
|
self.env.start()
|
||||||
|
@ -33,6 +33,7 @@ class SwitchWemoPlugin(SwitchPlugin):
|
||||||
self.env.discover(seconds=self.discovery_seconds)
|
self.env.discover(seconds=self.discovery_seconds)
|
||||||
self.devices = self.env.devices
|
self.devices = self.env.devices
|
||||||
|
|
||||||
|
@action
|
||||||
def get_devices(self):
|
def get_devices(self):
|
||||||
"""
|
"""
|
||||||
Get the list of available devices
|
Get the list of available devices
|
||||||
|
@ -57,8 +58,8 @@ class SwitchWemoPlugin(SwitchPlugin):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
self.refresh_devices()
|
self.refresh_devices()
|
||||||
return Response(
|
return {
|
||||||
output = { 'devices': [
|
'devices': [
|
||||||
{
|
{
|
||||||
'host': dev.host,
|
'host': dev.host,
|
||||||
'name': dev.name,
|
'name': dev.name,
|
||||||
|
@ -67,8 +68,8 @@ class SwitchWemoPlugin(SwitchPlugin):
|
||||||
'serialnumber': dev.serialnumber,
|
'serialnumber': dev.serialnumber,
|
||||||
}
|
}
|
||||||
for (name, dev) in self.devices.items()
|
for (name, dev) in self.devices.items()
|
||||||
] }
|
]
|
||||||
)
|
}
|
||||||
|
|
||||||
def _exec(self, method, device, *args, **kwargs):
|
def _exec(self, method, device, *args, **kwargs):
|
||||||
if device not in self.devices:
|
if device not in self.devices:
|
||||||
|
@ -81,9 +82,9 @@ class SwitchWemoPlugin(SwitchPlugin):
|
||||||
dev = self.devices[device]
|
dev = self.devices[device]
|
||||||
getattr(dev, method)(*args, **kwargs)
|
getattr(dev, method)(*args, **kwargs)
|
||||||
|
|
||||||
resp = {'device': device, 'state': dev.get_state()}
|
return {'device': device, 'state': dev.get_state()}
|
||||||
return Response(output=json.dumps(resp))
|
|
||||||
|
|
||||||
|
@action
|
||||||
def on(self, device):
|
def on(self, device):
|
||||||
"""
|
"""
|
||||||
Turn a switch on
|
Turn a switch on
|
||||||
|
@ -93,6 +94,7 @@ class SwitchWemoPlugin(SwitchPlugin):
|
||||||
"""
|
"""
|
||||||
return self._exec('on', device)
|
return self._exec('on', device)
|
||||||
|
|
||||||
|
@action
|
||||||
def off(self, device):
|
def off(self, device):
|
||||||
"""
|
"""
|
||||||
Turn a switch off
|
Turn a switch off
|
||||||
|
@ -102,6 +104,7 @@ class SwitchWemoPlugin(SwitchPlugin):
|
||||||
"""
|
"""
|
||||||
return self._exec('off', device)
|
return self._exec('off', device)
|
||||||
|
|
||||||
|
@action
|
||||||
def toggle(self, device):
|
def toggle(self, device):
|
||||||
"""
|
"""
|
||||||
Toggle the state of a switch (on/off)
|
Toggle the state of a switch (on/off)
|
||||||
|
|
|
@ -2,8 +2,7 @@ import subprocess
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
from platypush.message.response import Response
|
from platypush.message.response import Response
|
||||||
|
from platypush.plugins import Plugin, action
|
||||||
from .. import Plugin
|
|
||||||
|
|
||||||
class TtsPlugin(Plugin):
|
class TtsPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
@ -18,6 +17,7 @@ class TtsPlugin(Plugin):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.lang=lang
|
self.lang=lang
|
||||||
|
|
||||||
|
@action
|
||||||
def say(self, phrase, lang=None):
|
def say(self, phrase, lang=None):
|
||||||
"""
|
"""
|
||||||
Say a phrase
|
Say a phrase
|
||||||
|
@ -41,12 +41,10 @@ class TtsPlugin(Plugin):
|
||||||
}))]
|
}))]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
output = subprocess.check_output(
|
return subprocess.check_output(
|
||||||
cmd, stderr=subprocess.STDOUT, shell=True).decode('utf-8')
|
cmd, stderr=subprocess.STDOUT, shell=True).decode('utf-8')
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
errors = [e.output.decode('utf-8')]
|
raise RuntimeError(e.output.decode('utf-8'))
|
||||||
|
|
||||||
return Response(output=output, errors=errors)
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.plugins import Plugin
|
|
||||||
|
|
||||||
|
|
||||||
class VariablePlugin(Plugin):
|
class VariablePlugin(Plugin):
|
||||||
|
@ -12,6 +11,7 @@ class VariablePlugin(Plugin):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self._variables = {}
|
self._variables = {}
|
||||||
|
|
||||||
|
@action
|
||||||
def get(self, name, default_value=None):
|
def get(self, name, default_value=None):
|
||||||
"""
|
"""
|
||||||
Get the value of a variable by name.
|
Get the value of a variable by name.
|
||||||
|
@ -24,8 +24,9 @@ class VariablePlugin(Plugin):
|
||||||
:returns: A map in the format ``{"<name>":"<value>"}``
|
:returns: A map in the format ``{"<name>":"<value>"}``
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return Response(output={name: self._variables.get(name, default_value)})
|
return {name: self._variables.get(name, default_value)}
|
||||||
|
|
||||||
|
@action
|
||||||
def set(self, **kwargs):
|
def set(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Set a variable or a set of variables.
|
Set a variable or a set of variables.
|
||||||
|
@ -35,8 +36,9 @@ class VariablePlugin(Plugin):
|
||||||
|
|
||||||
for (name, value) in kwargs.items():
|
for (name, value) in kwargs.items():
|
||||||
self._variables[name] = value
|
self._variables[name] = value
|
||||||
return Response(output=kwargs)
|
return kwargs
|
||||||
|
|
||||||
|
@action
|
||||||
def unset(self, name):
|
def unset(self, name):
|
||||||
"""
|
"""
|
||||||
Unset a variable by name if it's set
|
Unset a variable by name if it's set
|
||||||
|
@ -46,9 +48,6 @@ class VariablePlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
if name in self._variables:
|
if name in self._variables:
|
||||||
del self._variables[name]
|
del self._variables[name]
|
||||||
return Response(output={'status':'ok'})
|
|
||||||
else:
|
|
||||||
return Response(output={'status':'not_found'})
|
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -12,11 +12,11 @@ from omxplayer import OMXPlayer
|
||||||
|
|
||||||
from platypush.context import get_backend
|
from platypush.context import get_backend
|
||||||
from platypush.plugins.media import PlayerState
|
from platypush.plugins.media import PlayerState
|
||||||
from platypush.message.response import Response
|
|
||||||
from platypush.message.event.video import VideoPlayEvent, VideoPauseEvent, \
|
from platypush.message.event.video import VideoPlayEvent, VideoPauseEvent, \
|
||||||
VideoStopEvent, NewPlayingVideoEvent
|
VideoStopEvent, NewPlayingVideoEvent
|
||||||
|
|
||||||
from .. import Plugin
|
from platypush.plugins import Plugin, action
|
||||||
|
|
||||||
|
|
||||||
class VideoOmxplayerPlugin(Plugin):
|
class VideoOmxplayerPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
@ -83,6 +83,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
self.videos_queue = []
|
self.videos_queue = []
|
||||||
self.torrent_ports = torrent_ports if torrent_ports else self.default_torrent_ports
|
self.torrent_ports = torrent_ports if torrent_ports else self.default_torrent_ports
|
||||||
|
|
||||||
|
@action
|
||||||
def play(self, resource):
|
def play(self, resource):
|
||||||
"""
|
"""
|
||||||
Play a resource.
|
Play a resource.
|
||||||
|
@ -105,9 +106,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
self.videos_queue = resources
|
self.videos_queue = resources
|
||||||
resource = self.videos_queue.pop(0)
|
resource = self.videos_queue.pop(0)
|
||||||
else:
|
else:
|
||||||
error = 'Unable to download torrent {}'.format(resource)
|
raise RuntimeError('Unable to download torrent {}'.format(resource))
|
||||||
self.logger.warning(error)
|
|
||||||
return Response(errors=[error])
|
|
||||||
|
|
||||||
self.logger.info('Playing {}'.format(resource))
|
self.logger.info('Playing {}'.format(resource))
|
||||||
|
|
||||||
|
@ -130,10 +129,12 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
|
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def pause(self):
|
def pause(self):
|
||||||
""" Pause the playback """
|
""" Pause the playback """
|
||||||
if self.player: self.player.play_pause()
|
if self.player: self.player.play_pause()
|
||||||
|
|
||||||
|
@action
|
||||||
def stop(self):
|
def stop(self):
|
||||||
""" Stop the playback """
|
""" Stop the playback """
|
||||||
if self.player:
|
if self.player:
|
||||||
|
@ -143,30 +144,35 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
|
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def voldown(self):
|
def voldown(self):
|
||||||
""" Volume down by 10% """
|
""" Volume down by 10% """
|
||||||
if self.player:
|
if self.player:
|
||||||
self.player.set_volume(max(-6000, self.player.volume()-1000))
|
self.player.set_volume(max(-6000, self.player.volume()-1000))
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def volup(self):
|
def volup(self):
|
||||||
""" Volume up by 10% """
|
""" Volume up by 10% """
|
||||||
if self.player:
|
if self.player:
|
||||||
self.player.set_volume(min(0, self.player.volume()+1000))
|
self.player.set_volume(min(0, self.player.volume()+1000))
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def back(self):
|
def back(self):
|
||||||
""" Back by 30 seconds """
|
""" Back by 30 seconds """
|
||||||
if self.player:
|
if self.player:
|
||||||
self.player.seek(-30)
|
self.player.seek(-30)
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def forward(self):
|
def forward(self):
|
||||||
""" Forward by 30 seconds """
|
""" Forward by 30 seconds """
|
||||||
if self.player:
|
if self.player:
|
||||||
self.player.seek(+30)
|
self.player.seek(+30)
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def next(self):
|
def next(self):
|
||||||
""" Play the next track/video """
|
""" Play the next track/video """
|
||||||
if self.player:
|
if self.player:
|
||||||
|
@ -176,19 +182,19 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
video = self.videos_queue.pop(0)
|
video = self.videos_queue.pop(0)
|
||||||
return self.play(video)
|
return self.play(video)
|
||||||
|
|
||||||
return Response(output={'status': 'no media'}, errors = [])
|
@action
|
||||||
|
|
||||||
|
|
||||||
def hide_subtitles(self):
|
def hide_subtitles(self):
|
||||||
""" Hide the subtitles """
|
""" Hide the subtitles """
|
||||||
if self.player: self.player.hide_subtitles()
|
if self.player: self.player.hide_subtitles()
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def hide_video(self):
|
def hide_video(self):
|
||||||
""" Hide the video """
|
""" Hide the video """
|
||||||
if self.player: self.player.hide_video()
|
if self.player: self.player.hide_video()
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def is_playing(self):
|
def is_playing(self):
|
||||||
"""
|
"""
|
||||||
:returns: True if it's playing, False otherwise
|
:returns: True if it's playing, False otherwise
|
||||||
|
@ -197,6 +203,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
if self.player: return self.player.is_playing()
|
if self.player: return self.player.is_playing()
|
||||||
else: return False
|
else: return False
|
||||||
|
|
||||||
|
@action
|
||||||
def load(self, resource, pause=False):
|
def load(self, resource, pause=False):
|
||||||
"""
|
"""
|
||||||
Load a resource/video in the player.
|
Load a resource/video in the player.
|
||||||
|
@ -208,21 +215,26 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
if self.player: self.player.load(resource, pause)
|
if self.player: self.player.load(resource, pause)
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def metadata(self):
|
def metadata(self):
|
||||||
""" Get the metadata of the current video """
|
""" Get the metadata of the current video """
|
||||||
if self.player: return Response(output=self.player.metadata())
|
if self.player:
|
||||||
|
return self.player.metadata()
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def mute(self):
|
def mute(self):
|
||||||
""" Mute the player """
|
""" Mute the player """
|
||||||
if self.player: self.player.mute()
|
if self.player: self.player.mute()
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def unmute(self):
|
def unmute(self):
|
||||||
""" Unmute the player """
|
""" Unmute the player """
|
||||||
if self.player: self.player.unmute()
|
if self.player: self.player.unmute()
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def seek(self, relative_position):
|
def seek(self, relative_position):
|
||||||
"""
|
"""
|
||||||
Seek backward/forward by the specified number of seconds
|
Seek backward/forward by the specified number of seconds
|
||||||
|
@ -234,6 +246,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
if self.player: self.player.seek(relative_position)
|
if self.player: self.player.seek(relative_position)
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def set_position(self, position):
|
def set_position(self, position):
|
||||||
"""
|
"""
|
||||||
Seek backward/forward to the specified absolute position
|
Seek backward/forward to the specified absolute position
|
||||||
|
@ -245,6 +258,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
if self.player: self.player.set_seek(position)
|
if self.player: self.player.set_seek(position)
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def set_volume(self, volume):
|
def set_volume(self, volume):
|
||||||
"""
|
"""
|
||||||
Set the volume
|
Set the volume
|
||||||
|
@ -258,6 +272,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
if self.player: self.player.set_volume(volume)
|
if self.player: self.player.set_volume(volume)
|
||||||
return self.status()
|
return self.status()
|
||||||
|
|
||||||
|
@action
|
||||||
def status(self):
|
def status(self):
|
||||||
"""
|
"""
|
||||||
Get the current player state.
|
Get the current player state.
|
||||||
|
@ -285,7 +300,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
elif state == 'stopped': state = PlayerState.STOP.value
|
elif state == 'stopped': state = PlayerState.STOP.value
|
||||||
elif state == 'paused': state = PlayerState.PAUSE.value
|
elif state == 'paused': state = PlayerState.PAUSE.value
|
||||||
|
|
||||||
return Response(output=json.dumps({
|
return {
|
||||||
'source': self.player.get_source(),
|
'source': self.player.get_source(),
|
||||||
'state': state,
|
'state': state,
|
||||||
'volume': self.player.volume(),
|
'volume': self.player.volume(),
|
||||||
|
@ -293,12 +308,13 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
'duration': self.player.duration(),
|
'duration': self.player.duration(),
|
||||||
'width': self.player.width(),
|
'width': self.player.width(),
|
||||||
'height': self.player.height(),
|
'height': self.player.height(),
|
||||||
}))
|
}
|
||||||
else:
|
else:
|
||||||
return Response(output=json.dumps({
|
return {
|
||||||
'state': PlayerState.STOP.value
|
'state': PlayerState.STOP.value
|
||||||
}))
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
def send_message(self, msg):
|
def send_message(self, msg):
|
||||||
try:
|
try:
|
||||||
redis = get_backend('redis')
|
redis = get_backend('redis')
|
||||||
|
@ -311,16 +327,19 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
|
|
||||||
redis.send_message(msg)
|
redis.send_message(msg)
|
||||||
|
|
||||||
|
@action
|
||||||
def on_play(self):
|
def on_play(self):
|
||||||
def _f(player):
|
def _f(player):
|
||||||
self.send_message(VideoPlayEvent(video=self.player.get_source()))
|
self.send_message(VideoPlayEvent(video=self.player.get_source()))
|
||||||
return _f
|
return _f
|
||||||
|
|
||||||
|
@action
|
||||||
def on_pause(self):
|
def on_pause(self):
|
||||||
def _f(player):
|
def _f(player):
|
||||||
self.send_message(VideoPauseEvent(video=self.player.get_source()))
|
self.send_message(VideoPauseEvent(video=self.player.get_source()))
|
||||||
return _f
|
return _f
|
||||||
|
|
||||||
|
@action
|
||||||
def on_stop(self):
|
def on_stop(self):
|
||||||
def _f(player):
|
def _f(player):
|
||||||
self.send_message(VideoStopEvent())
|
self.send_message(VideoStopEvent())
|
||||||
|
@ -335,6 +354,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
self.player.pauseEvent += self.on_pause()
|
self.player.pauseEvent += self.on_pause()
|
||||||
self.player.stopEvent += self.on_stop()
|
self.player.stopEvent += self.on_stop()
|
||||||
|
|
||||||
|
@action
|
||||||
def search(self, query, types=None, queue_results=False, autoplay=False):
|
def search(self, query, types=None, queue_results=False, autoplay=False):
|
||||||
"""
|
"""
|
||||||
Perform a video search.
|
Perform a video search.
|
||||||
|
@ -376,7 +396,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
elif autoplay:
|
elif autoplay:
|
||||||
self.play(results[0]['url'])
|
self.play(results[0]['url'])
|
||||||
|
|
||||||
return Response(output=results)
|
return results
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _is_video_file(cls, filename):
|
def _is_video_file(cls, filename):
|
||||||
|
@ -388,6 +408,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
|
|
||||||
return is_video
|
return is_video
|
||||||
|
|
||||||
|
@action
|
||||||
def file_search(self, query):
|
def file_search(self, query):
|
||||||
results = []
|
results = []
|
||||||
query_tokens = [_.lower() for _ in re.split('\s+', query.strip())]
|
query_tokens = [_.lower() for _ in re.split('\s+', query.strip())]
|
||||||
|
@ -413,8 +434,9 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
'title': f,
|
'title': f,
|
||||||
})
|
})
|
||||||
|
|
||||||
return Response(output=results)
|
return results
|
||||||
|
|
||||||
|
@action
|
||||||
def youtube_search(self, query):
|
def youtube_search(self, query):
|
||||||
self.logger.info('Searching YouTube for "{}"'.format(query))
|
self.logger.info('Searching YouTube for "{}"'.format(query))
|
||||||
|
|
||||||
|
@ -439,7 +461,7 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
self.logger.info('{} YouTube video results for the search query "{}"'
|
self.logger.info('{} YouTube video results for the search query "{}"'
|
||||||
.format(len(results), query))
|
.format(len(results), query))
|
||||||
|
|
||||||
return Response(output=results)
|
return results
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -476,8 +498,9 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
for _ in json.loads(request.read())['MovieList']
|
for _ in json.loads(request.read())['MovieList']
|
||||||
]
|
]
|
||||||
|
|
||||||
return Response(output=results)
|
return results
|
||||||
|
|
||||||
|
@action
|
||||||
def download_torrent(self, magnet):
|
def download_torrent(self, magnet):
|
||||||
"""
|
"""
|
||||||
Download a torrent to ``download_dir`` by Magnet URI
|
Download a torrent to ``download_dir`` by Magnet URI
|
||||||
|
@ -538,9 +561,10 @@ class VideoOmxplayerPlugin(Plugin):
|
||||||
|
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
return Response(output=files)
|
return files
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
def get_torrent_state(self):
|
def get_torrent_state(self):
|
||||||
return self.torrent_state
|
return self.torrent_state
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,8 @@ import urllib3
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
|
from platypush.plugins import Plugin, action
|
||||||
from platypush.plugins.media import PlayerState
|
from platypush.plugins.media import PlayerState
|
||||||
from platypush.message.response import Response
|
|
||||||
|
|
||||||
from .. import Plugin
|
|
||||||
|
|
||||||
class VideoTorrentcastPlugin(Plugin):
|
class VideoTorrentcastPlugin(Plugin):
|
||||||
def __init__(self, server='localhost', port=9090, *args, **kwargs):
|
def __init__(self, server='localhost', port=9090, *args, **kwargs):
|
||||||
|
@ -14,6 +12,7 @@ class VideoTorrentcastPlugin(Plugin):
|
||||||
self.port = port
|
self.port = port
|
||||||
self.state = PlayerState.STOP.value
|
self.state = PlayerState.STOP.value
|
||||||
|
|
||||||
|
@action
|
||||||
def play(self, url):
|
def play(self, url):
|
||||||
request = urllib.request.urlopen(
|
request = urllib.request.urlopen(
|
||||||
'http://{}:{}/play/'.format(self.server, self.port),
|
'http://{}:{}/play/'.format(self.server, self.port),
|
||||||
|
@ -23,24 +22,27 @@ class VideoTorrentcastPlugin(Plugin):
|
||||||
)
|
)
|
||||||
|
|
||||||
self.state = PlayerState.PLAY.value
|
self.state = PlayerState.PLAY.value
|
||||||
return Response(output=request.read())
|
return request.read()
|
||||||
|
|
||||||
|
@action
|
||||||
def pause(self):
|
def pause(self):
|
||||||
http = urllib3.PoolManager()
|
http = urllib3.PoolManager()
|
||||||
request = http.request('POST',
|
request = http.request('POST',
|
||||||
'http://{}:{}/pause/'.format(self.server, self.port))
|
'http://{}:{}/pause/'.format(self.server, self.port))
|
||||||
|
|
||||||
self.state = PlayerState.PAUSE.value
|
self.state = PlayerState.PAUSE.value
|
||||||
return Response(output=request.read())
|
return request.read()
|
||||||
|
|
||||||
|
@action
|
||||||
def stop(self):
|
def stop(self):
|
||||||
http = urllib3.PoolManager()
|
http = urllib3.PoolManager()
|
||||||
request = http.request('POST',
|
request = http.request('POST',
|
||||||
'http://{}:{}/stop/'.format(self.server, self.port))
|
'http://{}:{}/stop/'.format(self.server, self.port))
|
||||||
|
|
||||||
self.state = PlayerState.STOP.value
|
self.state = PlayerState.STOP.value
|
||||||
return Response(output=request.read())
|
return request.read()
|
||||||
|
|
||||||
|
@action
|
||||||
def search(self, query):
|
def search(self, query):
|
||||||
request = urllib.request.urlopen(urllib.request.Request(
|
request = urllib.request.urlopen(urllib.request.Request(
|
||||||
'https://api.apidomain.info/list?' + urllib.parse.urlencode({
|
'https://api.apidomain.info/list?' + urllib.parse.urlencode({
|
||||||
|
@ -56,8 +58,9 @@ class VideoTorrentcastPlugin(Plugin):
|
||||||
)
|
)
|
||||||
|
|
||||||
results = json.loads(request.read())
|
results = json.loads(request.read())
|
||||||
return Response(output=results)
|
return results
|
||||||
|
|
||||||
|
@action
|
||||||
def search_and_play(self, query):
|
def search_and_play(self, query):
|
||||||
response = self.search(query)
|
response = self.search(query)
|
||||||
if not response.output['MovieList']:
|
if not response.output['MovieList']:
|
||||||
|
@ -71,13 +74,20 @@ class VideoTorrentcastPlugin(Plugin):
|
||||||
|
|
||||||
return self.play(magnet)
|
return self.play(magnet)
|
||||||
|
|
||||||
def voldown(self): return Response(output='Unsupported method')
|
@action
|
||||||
def volup(self): return Response(output='Unsupported method')
|
def voldown(self): raise NotImplementedError()
|
||||||
def back(self): return Response(output='Unsupported method')
|
|
||||||
def forward(self): return Response(output='Unsupported method')
|
|
||||||
|
|
||||||
def status(self):
|
@action
|
||||||
return Response(output={ 'state': self.state })
|
def volup(self): raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
|
def back(self): raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
|
def forward(self): raise NotImplementedError()
|
||||||
|
|
||||||
|
@action
|
||||||
|
def status(self): return { 'state': self.state }
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from platypush.message.response import Response
|
from platypush.plugins import action
|
||||||
from platypush.plugins.http.request import HttpRequestPlugin
|
from platypush.plugins.http.request import HttpRequestPlugin
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ class WeatherForecastPlugin(HttpRequestPlugin):
|
||||||
format(self.darksky_token, (lat or self.lat), (long or self.long),
|
format(self.darksky_token, (lat or self.lat), (long or self.long),
|
||||||
self.units)
|
self.units)
|
||||||
|
|
||||||
|
@action
|
||||||
def get_current_weather(self, lat=None, long=None, **kwargs):
|
def get_current_weather(self, lat=None, long=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Get the current weather.
|
Get the current weather.
|
||||||
|
@ -83,8 +84,9 @@ class WeatherForecastPlugin(HttpRequestPlugin):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
response = self.get(self._get_url(lat, long))
|
response = self.get(self._get_url(lat, long))
|
||||||
return Response(output=response.output['currently'])
|
return response.output['currently']
|
||||||
|
|
||||||
|
@action
|
||||||
def get_hourly_forecast(self, lat=None, long=None, **kwargs):
|
def get_hourly_forecast(self, lat=None, long=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Get the hourly forecast.
|
Get the hourly forecast.
|
||||||
|
@ -146,8 +148,9 @@ class WeatherForecastPlugin(HttpRequestPlugin):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
response = self.get(self._get_url(lat, long))
|
response = self.get(self._get_url(lat, long))
|
||||||
return Response(output=response.output['hourly'])
|
return response.output['hourly']
|
||||||
|
|
||||||
|
@action
|
||||||
def get_daily_forecast(self, lat=None, long=None, **kwargs):
|
def get_daily_forecast(self, lat=None, long=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Get the daily forecast.
|
Get the daily forecast.
|
||||||
|
@ -250,7 +253,7 @@ class WeatherForecastPlugin(HttpRequestPlugin):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
response = self.get(self._get_url(lat, long))
|
response = self.get(self._get_url(lat, long))
|
||||||
return Response(output=response.output['daily'])
|
return response.output['daily']
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import ast
|
||||||
import errno
|
import errno
|
||||||
import hashlib
|
import hashlib
|
||||||
import importlib
|
import importlib
|
||||||
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
|
@ -67,8 +69,32 @@ def clear_timeout():
|
||||||
|
|
||||||
|
|
||||||
def get_hash(s):
|
def get_hash(s):
|
||||||
|
""" Get the SHA256 hash hexdigest of a string input """
|
||||||
return hashlib.sha256(s.encode('utf-8')).hexdigest()
|
return hashlib.sha256(s.encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def get_decorators(cls):
|
||||||
|
target = cls
|
||||||
|
decorators = {}
|
||||||
|
|
||||||
|
def visit_FunctionDef(node):
|
||||||
|
# decorators[node.name] = []
|
||||||
|
for n in node.decorator_list:
|
||||||
|
name = ''
|
||||||
|
if isinstance(n, ast.Call):
|
||||||
|
name = n.func.attr if isinstance(n.func, ast.Attribute) else n.func.id
|
||||||
|
else:
|
||||||
|
name = n.attr if isinstance(n, ast.Attribute) else n.id
|
||||||
|
|
||||||
|
decorators[name] = decorators.get(name, [])
|
||||||
|
# decorators[node.name].append(name)
|
||||||
|
decorators[name].append(node.name)
|
||||||
|
|
||||||
|
node_iter = ast.NodeVisitor()
|
||||||
|
node_iter.visit_FunctionDef = visit_FunctionDef
|
||||||
|
node_iter.visit(ast.parse(inspect.getsource(target)))
|
||||||
|
return decorators
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue