diff --git a/platypush/backend/http/media/handlers/__init__.py b/platypush/backend/http/media/handlers/__init__.py
index 717fbb3ce..8c1f05e83 100644
--- a/platypush/backend/http/media/handlers/__init__.py
+++ b/platypush/backend/http/media/handlers/__init__.py
@@ -1,8 +1,5 @@
import logging
-from .file import FileHandler
-
-
class MediaHandler:
"""
Abstract class to manage media handlers that can be streamed over the HTTP
@@ -63,6 +60,8 @@ class MediaHandler:
yield (attr, getattr(self, attr))
+from .file import FileHandler
+
__all__ = ['MediaHandler', 'FileHandler']
diff --git a/platypush/backend/http/static/js/plugins/media/handlers/file.js b/platypush/backend/http/static/js/plugins/media/handlers/file.js
index 0275ddb41..6d71ce231 100644
--- a/platypush/backend/http/static/js/plugins/media/handlers/file.js
+++ b/platypush/backend/http/static/js/plugins/media/handlers/file.js
@@ -38,6 +38,17 @@ MediaHandlers.file = Vue.extend({
},
methods: {
+ matchesUrl: function(url) {
+ return !!url.match('^(file://)?/');
+ },
+
+ getMetadata: function(url) {
+ return {
+ url: url,
+ title: url.split('/').pop(),
+ };
+ },
+
play: function(item) {
this.bus.$emit('play', item);
},
@@ -53,3 +64,22 @@ MediaHandlers.file = Vue.extend({
},
});
+MediaHandlers.generic = MediaHandlers.file.extend({
+ props: {
+ bus: { type: Object },
+ iconClass: {
+ type: String,
+ default: 'fa fa-globe',
+ },
+ },
+
+ methods: {
+ getMetadata: function(url) {
+ return {
+ url: url,
+ title: url,
+ };
+ },
+ },
+});
+
diff --git a/platypush/backend/http/static/js/plugins/media/handlers/torrent.js b/platypush/backend/http/static/js/plugins/media/handlers/torrent.js
index d5211bff9..490fe0299 100644
--- a/platypush/backend/http/static/js/plugins/media/handlers/torrent.js
+++ b/platypush/backend/http/static/js/plugins/media/handlers/torrent.js
@@ -32,6 +32,19 @@ MediaHandlers.torrent = Vue.extend({
},
methods: {
+ matchesUrl: function(url) {
+ return !!(
+ url.match('^magnet:?') ||
+ url.match('^https?://.*\.torrent$') ||
+ url.match('^(file://)?/.*\.torrent$')
+ );
+ },
+
+ getMetadata: function(url) {
+ // TODO
+ return {};
+ },
+
play: function(item) {
},
diff --git a/platypush/backend/http/static/js/plugins/media/handlers/youtube.js b/platypush/backend/http/static/js/plugins/media/handlers/youtube.js
index 1b5270533..99925ba8f 100644
--- a/platypush/backend/http/static/js/plugins/media/handlers/youtube.js
+++ b/platypush/backend/http/static/js/plugins/media/handlers/youtube.js
@@ -32,6 +32,15 @@ MediaHandlers.youtube = Vue.extend({
},
methods: {
+ matchesUrl: function(url) {
+ return !!(url.match('^https?://(www\.)?youtube.com/') || url.match('^https?://youtu.be/'));
+ },
+
+ getMetadata: function(url) {
+ // TODO
+ return {};
+ },
+
play: function(item) {
},
diff --git a/platypush/backend/http/static/js/plugins/media/index.js b/platypush/backend/http/static/js/plugins/media/index.js
index 4745c90cf..97753eda5 100644
--- a/platypush/backend/http/static/js/plugins/media/index.js
+++ b/platypush/backend/http/static/js/plugins/media/index.js
@@ -60,13 +60,29 @@ Vue.component('media', {
},
onResultsReady: function(results) {
- this.loading.results = false;
+ for (const result of results) {
+ if (result.type && MediaHandlers[result.type]) {
+ result.handler = MediaHandlers[result.type];
+ } else {
+ result.type = 'generic';
+ result.handler = MediaHandlers.generic;
- for (var i=0; i < results.length; i++) {
- results[i].handler = MediaHandlers[results[i].type];
+ for (const [handlerType, handler] of Object.entries(MediaHandlers)) {
+ if (handler.matchesUrl && handler.matchesUrl(result.url)) {
+ result.type = handlerType;
+ result.handler = handler;
+ break;
+ }
+ }
+ }
+
+ Object.entries(result.handler.getMetadata(result.url)).forEach(entry => {
+ Vue.set(result, entry[0], entry[1]);
+ });
}
this.results = results;
+ this.loading.results = false;
},
play: async function(item) {
diff --git a/platypush/backend/http/static/js/plugins/media/players/browser.js b/platypush/backend/http/static/js/plugins/media/players/browser.js
index 0ceb18b04..fd8bd3ff3 100644
--- a/platypush/backend/http/static/js/plugins/media/players/browser.js
+++ b/platypush/backend/http/static/js/plugins/media/players/browser.js
@@ -21,7 +21,7 @@ MediaPlayers.browser = Vue.extend({
iconClass: {
type: String,
- default: 'fa fa-laptop',
+ default: 'fa fa-browser',
},
},
diff --git a/platypush/backend/http/static/js/plugins/media/search.js b/platypush/backend/http/static/js/plugins/media/search.js
index 09262bf3f..15520f40c 100644
--- a/platypush/backend/http/static/js/plugins/media/search.js
+++ b/platypush/backend/http/static/js/plugins/media/search.js
@@ -19,10 +19,31 @@ Vue.component('media-search', {
},
methods: {
- search: async function(event) {
- const types = Object.entries(this.types).filter(t => t[1]).map(t => t[0]);
- var results = [];
+ isUrl: function(query) {
+ const match = query.match('^([^:]+)://');
+ if (match) {
+ let protocol = match[1];
+ if (protocol === 'https')
+ protocol = 'http';
+ return protocol;
+ }
+ },
+
+ search: async function(event) {
+ const types = Object.entries(this.types).filter(t => t[0] !== 'generic' && t[1]).map(t => t[0]);
+ const protocol = this.isUrl(this.query);
+
+ if (protocol) {
+ this.bus.$emit('results-ready', [{
+ type: protocol,
+ url: this.query,
+ }]);
+
+ return;
+ }
+
+ var results = [];
this.searching = true;
this.bus.$emit('results-loading');
diff --git a/platypush/backend/http/templates/plugins/media/search.html b/platypush/backend/http/templates/plugins/media/search.html
index 887bfaae9..bb1f44958 100644
--- a/platypush/backend/http/templates/plugins/media/search.html
+++ b/platypush/backend/http/templates/plugins/media/search.html
@@ -10,7 +10,7 @@
+ :disabled="searching" placeholder="Search query or media URL">