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
|
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']
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -21,7 +21,7 @@ MediaPlayers.browser = Vue.extend({
|
||||||
|
|
||||||
iconClass: {
|
iconClass: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'fa fa-laptop',
|
default: 'fa fa-browser',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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');
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue