diff --git a/platypush/backend/http/__init__.py b/platypush/backend/http/__init__.py
index cb77e470..2d78fb7e 100644
--- a/platypush/backend/http/__init__.py
+++ b/platypush/backend/http/__init__.py
@@ -25,6 +25,9 @@ class HttpBackend(Backend):
websocket_ping_tries = 3
websocket_ping_timeout = 60.0
+ hidden_plugins = {
+ 'assistant.google'
+ }
def __init__(self, port=8008, websocket_port=8009, disable_websocket=False,
token=None, **kwargs):
@@ -98,13 +101,17 @@ class HttpBackend(Backend):
def index():
configured_plugins = Config.get_plugins()
enabled_plugins = {}
+ hidden_plugins = {}
for plugin, conf in configured_plugins.items():
template_file = os.path.join('plugins', plugin + '.html')
if os.path.isfile(os.path.join(template_dir, template_file)):
- enabled_plugins[plugin] = conf
+ if plugin in self.hidden_plugins:
+ hidden_plugins[plugin] = conf
+ else:
+ enabled_plugins[plugin] = conf
- return render_template('index.html', plugins=enabled_plugins,
+ return render_template('index.html', plugins=enabled_plugins, hidden_plugins=hidden_plugins,
token=self.token, websocket_port=self.websocket_port)
diff --git a/platypush/backend/http/static/css/application.css b/platypush/backend/http/static/css/application.css
index 2dab9f30..46663d87 100644
--- a/platypush/backend/http/static/css/application.css
+++ b/platypush/backend/http/static/css/application.css
@@ -144,3 +144,66 @@ button[disabled] {
text-align: right !important;
}
+#notification-container {
+ position: fixed;
+ bottom: 0;
+ right: 0;
+ width: 25em;
+}
+
+ #notification-container > .notification {
+ background: rgba(180,245,188,0.85);
+ border: 1px solid #bbb;
+ border-radius: 5px;
+ margin-bottom: 1rem;
+ margin-right: 1rem;
+ cursor: pointer;
+ display: none;
+ }
+
+ #notification-container > .notification:hover {
+ background: rgba(160,235,168,0.9);
+ }
+
+ #notification-container * > .notification-title {
+ padding: 4px 10px;
+ font-weight: bold;
+ text-transform: capitalize;
+ line-height: 30px;
+ letter-spacing: .1rem;
+ }
+
+ #notification-container * > .notification-body {
+ height: 6em;
+ overflow: hidden;
+ padding-bottom: 1rem;
+ letter-spacing: .05rem;
+ }
+
+ #notification-container * > .notification-text {
+ margin-left: 0 !important;
+ }
+
+ #notification-container * > .notification-image {
+ height: 100%;
+ text-align: center;
+ padding-top: .6em;
+ padding-bottom: .6em;
+ }
+
+ #notification-container * > .notification-image-item {
+ width: 100%;
+ height: 100%;
+ margin: auto;
+ }
+
+ #notification-container * > .fa.notification-image-item {
+ margin-top: .8em;
+ margin-left: .2em;
+ font-size: 25px;
+ }
+
+#hidden-plugins-container > .plugin {
+ display: none;
+}
+
diff --git a/platypush/backend/http/static/css/assistant.google.css b/platypush/backend/http/static/css/assistant.google.css
new file mode 100644
index 00000000..e69de29b
diff --git a/platypush/backend/http/static/js/application.js b/platypush/backend/http/static/js/application.js
index 5604e133..b841bffe 100644
--- a/platypush/backend/http/static/js/application.js
+++ b/platypush/backend/http/static/js/application.js
@@ -176,3 +176,112 @@ $(document).ready(function() {
init();
});
+function execute(request, onSuccess, onError, onComplete) {
+ request['target'] = 'localhost';
+ return $.ajax({
+ type: 'POST',
+ url: '/execute',
+ contentType: 'application/json',
+ dataType: 'json',
+ data: JSON.stringify(request),
+ complete: function() {
+ if (onComplete) {
+ onComplete();
+ }
+ },
+ error: function(xhr, status, error) {
+ if (onError) {
+ onError(xhr, status, error);
+ }
+ },
+ success: function(response, status, xhr) {
+ if (onSuccess) {
+ onSuccess(response, status, xhr);
+ }
+ },
+ beforeSend: function(xhr) {
+ if (window.token) {
+ xhr.setRequestHeader('X-Token', window.token);
+ }
+ },
+ });
+}
+
+function createNotification(options) {
+ var $notificationContainer = $('#notification-container');
+ var $notification = $('
').addClass('notification');
+ var $title = $('').addClass('notification-title');
+ var timeout = 'timeout' in options ? options.timeout : 10000;
+
+ if ('title' in options) {
+ $title.text(options.title);
+ }
+
+ var $body = $('').addClass('notification-body');
+ var $imgDiv = $('').addClass('notification-image').addClass('three columns');
+ var $img = $('').addClass('fa fa-bell').addClass('three columns').addClass('notification-image-item');
+ var $text = $('').addClass('notification-text').addClass('nine columns')
+
+ if ('image' in options) {
+ $img = $('
').attr('src', options.image);
+ } else if ('icon' in options) {
+ $img.removeClass('fa-bell').addClass('fa-' + options.icon);
+ }
+
+ if ('text' in options) {
+ $text.text(options.text);
+ } else if ('html' in options) {
+ $text.html(options.html);
+ }
+
+ $img.appendTo($imgDiv);
+ $imgDiv.appendTo($body);
+ $text.appendTo($body);
+
+ var clickHandler;
+ var removeTimeoutId;
+
+ var removeNotification = function() {
+ $notification.fadeOut(300, function() {
+ $notification.remove();
+ });
+ };
+
+ var setRemoveTimeout = function() {
+ if (timeout) {
+ removeTimeoutId = setTimeout(removeNotification, timeout);
+ }
+ };
+
+ setRemoveTimeout();
+
+ if ('onclick' in options) {
+ clickHandler = options.onclick;
+ } else {
+ clickHandler = removeNotification;
+ }
+
+ $notification.on('click', clickHandler);
+ $notification.hover(
+ // on hover start
+ function() {
+ if (removeTimeoutId) {
+ clearTimeout(removeTimeoutId);
+ removeTimeoutId = undefined;
+ }
+ },
+
+ // on hover end
+ function() {
+ if (timeout) {
+ setRemoveTimeout();
+ }
+ }
+ );
+
+ $title.appendTo($notification);
+ $body.appendTo($notification);
+ $notification.prependTo($notificationContainer);
+ $notification.fadeIn();
+}
+
diff --git a/platypush/backend/http/static/js/assistant.google.js b/platypush/backend/http/static/js/assistant.google.js
new file mode 100644
index 00000000..7d01e25c
--- /dev/null
+++ b/platypush/backend/http/static/js/assistant.google.js
@@ -0,0 +1,36 @@
+$(document).ready(function() {
+ var onEvent = function(event) {
+ switch (event.args.type) {
+ case 'platypush.message.event.assistant.ConversationStartEvent':
+ createNotification({
+ 'text': 'Assistant listening',
+ 'icon': 'microphone',
+ });
+
+ break;
+
+ case 'platypush.message.event.assistant.SpeechRecognizedEvent':
+ createNotification({
+ 'title': 'Speech recognized',
+ 'text': event.args.phrase,
+ 'icon': 'microphone',
+ });
+
+ break;
+
+ case 'platypush.message.event.assistant.ConversationEndEvent':
+ break;
+ }
+ };
+
+ var initEvents = function() {
+ window.registerEventListener(onEvent);
+ };
+
+ var init = function() {
+ initEvents();
+ };
+
+ init();
+});
+
diff --git a/platypush/backend/http/static/js/gpio.zeroborg.js b/platypush/backend/http/static/js/gpio.zeroborg.js
index 9ac18227..037e0f81 100644
--- a/platypush/backend/http/static/js/gpio.zeroborg.js
+++ b/platypush/backend/http/static/js/gpio.zeroborg.js
@@ -3,37 +3,6 @@ $(document).ready(function() {
$controlsContainer = $('.zb-controls-container'),
curDirection = undefined;
- var execute = function(request, onSuccess, onError, onComplete) {
- request['target'] = 'localhost';
- return $.ajax({
- type: 'POST',
- url: '/execute',
- contentType: 'application/json',
- dataType: 'json',
- data: JSON.stringify(request),
- complete: function() {
- if (onComplete) {
- onComplete();
- }
- },
- error: function(xhr, status, error) {
- if (onError) {
- onError(xhr, status, error);
- }
- },
- success: function(response, status, xhr) {
- if (onSuccess) {
- onSuccess(response, status, xhr);
- }
- },
- beforeSend: function(xhr) {
- if (window.token) {
- xhr.setRequestHeader('X-Token', window.token);
- }
- },
- });
- };
-
var initBindings = function() {
$controlsContainer.on('mousedown touchstart', '.zb-ctrl-btn[data-direction]', function() {
var direction = $(this).data('direction');
diff --git a/platypush/backend/http/static/js/light.hue.js b/platypush/backend/http/static/js/light.hue.js
index d1d8a96b..e1d009f4 100644
--- a/platypush/backend/http/static/js/light.hue.js
+++ b/platypush/backend/http/static/js/light.hue.js
@@ -6,37 +6,6 @@ $(document).ready(function() {
$lightsList = $('#lights-list'),
$scenesList = $('#scenes-list');
- var execute = function(request, onSuccess, onError, onComplete) {
- request['target'] = 'localhost';
- return $.ajax({
- type: 'POST',
- url: '/execute',
- contentType: 'application/json',
- dataType: 'json',
- data: JSON.stringify(request),
- complete: function() {
- if (onComplete) {
- onComplete();
- }
- },
- error: function(xhr, status, error) {
- if (onError) {
- onError(xhr, status, error);
- }
- },
- success: function(response, status, xhr) {
- if (onSuccess) {
- onSuccess(response, status, xhr);
- }
- },
- beforeSend: function(xhr) {
- if (window.token) {
- xhr.setRequestHeader('X-Token', window.token);
- }
- },
- });
- };
-
var createPowerToggleElement = function(data) {
var id = data['type'] + '_' + data['id'];
var $powerToggle = $('').addClass('toggle toggle--push light-ctrl-switch-container');
diff --git a/platypush/backend/http/static/js/music.mpd.js b/platypush/backend/http/static/js/music.mpd.js
index 3608c6a4..7613e716 100644
--- a/platypush/backend/http/static/js/music.mpd.js
+++ b/platypush/backend/http/static/js/music.mpd.js
@@ -16,37 +16,6 @@ $(document).ready(function() {
$resetSearchBtn = $('#music-search-reset');
$doSearchBtns = $('.do-search-btns');
- var execute = function(request, onSuccess, onError, onComplete) {
- request['target'] = 'localhost';
- $.ajax({
- type: 'POST',
- url: '/execute',
- contentType: 'application/json',
- dataType: 'json',
- data: JSON.stringify(request),
- complete: function() {
- if (onComplete) {
- onComplete();
- }
- },
- error: function(xhr, status, error) {
- if (onError) {
- onError(xhr, status, error);
- }
- },
- success: function(response, status, xhr) {
- if (onSuccess) {
- onSuccess(response, status, xhr);
- }
- },
- beforeSend: function(xhr) {
- if (window.token) {
- xhr.setRequestHeader('X-Token', window.token);
- }
- },
- });
- };
-
var formatMinutes = function(time) {
if (typeof time === 'string') {
time = parseInt(time);
@@ -198,10 +167,17 @@ $(document).ready(function() {
var onEvent = function(event) {
switch (event.args.type) {
+ case 'platypush.message.event.music.NewPlayingTrackEvent':
+ createNotification({
+ 'icon': 'play',
+ 'html': '' + ('artist' in event.args.track ? event.args.track.artist : '')
+ + '
'
+ + ('title' in event.args.track ? event.args.track.title : '[No name]'),
+ });
+
case 'platypush.message.event.music.MusicStopEvent':
case 'platypush.message.event.music.MusicPlayEvent':
case 'platypush.message.event.music.MusicPauseEvent':
- case 'platypush.message.event.music.NewPlayingTrackEvent':
updateControls(status=event.args.status, track=event.args.track);
break;
diff --git a/platypush/backend/http/static/js/tts.js b/platypush/backend/http/static/js/tts.js
index 2b46af89..bac32f32 100644
--- a/platypush/backend/http/static/js/tts.js
+++ b/platypush/backend/http/static/js/tts.js
@@ -2,37 +2,6 @@ $(document).ready(function() {
var $container = $('#tts-container'),
$ttsForm = $('#tts-form');
- var execute = function(request, onSuccess, onError, onComplete) {
- request['target'] = 'localhost';
- return $.ajax({
- type: 'POST',
- url: '/execute',
- contentType: 'application/json',
- dataType: 'json',
- data: JSON.stringify(request),
- complete: function() {
- if (onComplete) {
- onComplete();
- }
- },
- error: function(xhr, status, error) {
- if (onError) {
- onError(xhr, status, error);
- }
- },
- success: function(response, status, xhr) {
- if (onSuccess) {
- onSuccess(response, status, xhr);
- }
- },
- beforeSend: function(xhr) {
- if (window.token) {
- xhr.setRequestHeader('X-Token', window.token);
- }
- },
- });
- };
-
var initBindings = function() {
$ttsForm.on('submit', function(event) {
var formData = $(this).serializeArray().reduce(function(obj, item) {
diff --git a/platypush/backend/http/templates/index.html b/platypush/backend/http/templates/index.html
index 281f84e8..0eeaca6a 100644
--- a/platypush/backend/http/templates/index.html
+++ b/platypush/backend/http/templates/index.html
@@ -57,6 +57,17 @@
{% endfor %}
+
+
+
+
+ {% for plugin in hidden_plugins.keys()|sort() %}
+ {% set configuration = plugins[plugin] %}
+
+ {% include 'plugins/' + plugin + '.html' %}
+
+ {% endfor %}
+
diff --git a/platypush/backend/http/templates/plugins/assistant.google.html b/platypush/backend/http/templates/plugins/assistant.google.html
new file mode 100644
index 00000000..a6e62c1d
--- /dev/null
+++ b/platypush/backend/http/templates/plugins/assistant.google.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/platypush/backend/http/templates/plugins/tts.html b/platypush/backend/http/templates/plugins/tts.html
index e33391fb..9d00b9fb 100644
--- a/platypush/backend/http/templates/plugins/tts.html
+++ b/platypush/backend/http/templates/plugins/tts.html
@@ -6,12 +6,12 @@
-