New media webplugin WIP
This commit is contained in:
parent
2da6d7d866
commit
1964f74f19
8 changed files with 99 additions and 11 deletions
|
@ -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']
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -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) {
|
||||
},
|
||||
|
||||
|
|
|
@ -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) {
|
||||
},
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -21,7 +21,7 @@ MediaPlayers.browser = Vue.extend({
|
|||
|
||||
iconClass: {
|
||||
type: String,
|
||||
default: 'fa fa-laptop',
|
||||
default: 'fa fa-browser',
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</button>
|
||||
|
||||
<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">
|
||||
<i class="fa fa-search"></i>
|
||||
|
|
Loading…
Reference in a new issue