New media webplugin WIP

This commit is contained in:
Fabio Manganiello 2019-06-22 19:05:17 +02:00
parent 2da6d7d866
commit 1964f74f19
8 changed files with 99 additions and 11 deletions

View file

@ -1,8 +1,5 @@
import logging import logging
from .file import FileHandler
class MediaHandler: class MediaHandler:
""" """
Abstract class to manage media handlers that can be streamed over the HTTP Abstract class to manage media handlers that can be streamed over the HTTP
@ -63,6 +60,8 @@ class MediaHandler:
yield (attr, getattr(self, attr)) yield (attr, getattr(self, attr))
from .file import FileHandler
__all__ = ['MediaHandler', 'FileHandler'] __all__ = ['MediaHandler', 'FileHandler']

View file

@ -38,6 +38,17 @@ MediaHandlers.file = Vue.extend({
}, },
methods: { methods: {
matchesUrl: function(url) {
return !!url.match('^(file://)?/');
},
getMetadata: function(url) {
return {
url: url,
title: url.split('/').pop(),
};
},
play: function(item) { play: function(item) {
this.bus.$emit('play', 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,
};
},
},
});

View file

@ -32,6 +32,19 @@ MediaHandlers.torrent = Vue.extend({
}, },
methods: { methods: {
matchesUrl: function(url) {
return !!(
url.match('^magnet:?') ||
url.match('^https?://.*\.torrent$') ||
url.match('^(file://)?/.*\.torrent$')
);
},
getMetadata: function(url) {
// TODO
return {};
},
play: function(item) { play: function(item) {
}, },

View file

@ -32,6 +32,15 @@ MediaHandlers.youtube = Vue.extend({
}, },
methods: { methods: {
matchesUrl: function(url) {
return !!(url.match('^https?://(www\.)?youtube.com/') || url.match('^https?://youtu.be/'));
},
getMetadata: function(url) {
// TODO
return {};
},
play: function(item) { play: function(item) {
}, },

View file

@ -60,13 +60,29 @@ Vue.component('media', {
}, },
onResultsReady: function(results) { 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++) { for (const [handlerType, handler] of Object.entries(MediaHandlers)) {
results[i].handler = MediaHandlers[results[i].type]; 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.results = results;
this.loading.results = false;
}, },
play: async function(item) { play: async function(item) {

View file

@ -21,7 +21,7 @@ MediaPlayers.browser = Vue.extend({
iconClass: { iconClass: {
type: String, type: String,
default: 'fa fa-laptop', default: 'fa fa-browser',
}, },
}, },

View file

@ -19,10 +19,31 @@ Vue.component('media-search', {
}, },
methods: { methods: {
search: async function(event) { isUrl: function(query) {
const types = Object.entries(this.types).filter(t => t[1]).map(t => t[0]); const match = query.match('^([^:]+)://');
var results = []; 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.searching = true;
this.bus.$emit('results-loading'); this.bus.$emit('results-loading');

View file

@ -10,7 +10,7 @@
</button> </button>
<input type="text" name="query" v-model.lazy.trim="query" <input type="text" name="query" v-model.lazy.trim="query"
:disabled="searching" placeholder="Search query or video URL"> :disabled="searching" placeholder="Search query or media URL">
<button type="submit" :disabled="searching" title="Search"> <button type="submit" :disabled="searching" title="Search">
<i class="fa fa-search"></i> <i class="fa fa-search"></i>