ydl_api_ng/params/userscript.js

242 lines
7.9 KiB
JavaScript

// ==UserScript==
// @name ydl_api_ng
// @match http*://*/*
// @grant GM_registerMenuCommand
// @grant GM_xmlhttpRequest
// @grant GM_notification
// ==/UserScript==
(function () {
'use strict';
const key_mapping = "0123456789abcdefghijklmnopqrstuvwxyz";
// CUSTOMIZE HERE
const default_host = 'http://localhost:5011';
const notificationTimeout = 5000;
const userToken = null;
// STOP COSTUMIZE HERE
const format_date = function (date) {
const year = date.getFullYear();
const month = `${date.getMonth() + 1}`.padStart(2, "0");
const day = `${date.getDate()}`.padStart(2, "0");
const hours = `${date.getHours()}`.padStart(2, "0");
const minutes = `${date.getMinutes()}`.padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}`;
}
const find_url_in_mapping = function (site_mapping) {
const current_url = window.location.href;
for (let site of site_mapping) {
for (let url of site.url) {
if (current_url.includes(url)) {
return site.presets;
}
}
}
return null;
}
const build_url = function (preset) {
const url = new URL(preset.route.route);
url.searchParams.append('url', window.location.href);
if (userToken !== null) {
url.searchParams.append('token', userToken);
}
if (preset.query_params !== undefined) {
Object.entries(preset.query_params).forEach(([key, value]) => {
url.searchParams.append(key, value);
});
}
return url.href;
};
const launch_request = function (preset) {
const notificationOptions = {};
const effective_method = preset.method !== undefined ? preset.method : preset.route.method;
let data = {};
let headers = {};
if (preset.body !== undefined) {
data = JSON.stringify(preset.body());
headers = {
"Content-Type": "application/json",
};
}
GM_xmlhttpRequest({
method: effective_method,
headers: headers,
data: data,
url: build_url(preset),
onerror: function () {
notificationOptions.title = `Download failed`;
notificationOptions.text = `Host seams unreachable, is the server up ?`;
GM_notification(notificationOptions);
},
onload: function (response) {
notificationOptions.title = `Unknown error`;
notificationOptions.text = `An unknown response code has been found`;
notificationOptions.timeout = null;
const status_code = preset.route.return_code[response.status]
if (status_code !== undefined) {
notificationOptions.title = status_code.title;
notificationOptions.text = status_code.text;
notificationOptions.timeout = status_code.timeout;
}
GM_notification(notificationOptions);
}
});
};
// CUSTOMIZE HERE
const routes = {
download: {
route: default_host + '/download',
method: 'GET',
return_code: {
200: {
title: 'Download launched',
text: 'Downloading',
timeout: notificationTimeout
},
202: {
title: 'Download launched',
text: 'Download not checked. Some files may not be downloaded',
timeout: notificationTimeout
},
206: {
title: 'Download launched',
text: 'Some presets failed download check',
timeout: notificationTimeout
},
400: {
title: 'Bad request',
text: 'An error append during parameters validation',
timeout: null
},
401: {
title: 'Authentication failed',
text: 'The server requires an user token or the provided token is wrong',
timeout: null
},
403: {
title: 'Unauthorized',
text: 'You are not allowed to use this api',
timeout: null
}
}
},
programmation: {
route: default_host + '/programmation',
method: 'POST',
return_code: {
200: {
title: 'Programmation added',
text: '',
timeout: notificationTimeout
},
400: {
title: 'Invalid programmation',
text: 'Some parameters are wrong',
timeout: null
},
401: {
title: 'Authentication failed',
text: 'The server requires an user token or the provided token is wrong',
timeout: null
},
403: {
title: 'Unauthorized',
text: 'You are not allowed to use this api',
timeout: null
},
409: {
title: 'Non supported',
text: 'This feature require redis enabled on the server',
timeout: null
}
}
}
}
const presets = {
'default': {name: 'Default', route: routes.download},
'best': {name: 'Best', route: routes.download, query_params: {presets: 'BEST'}},
'720p': {name: '720p', route: routes.download, query_params: {presets: 'HD'}},
'audio': {name: 'Audio', route: routes.download, query_params: {presets: 'AUDIO'}},
'best+audio': {name: 'Best + Audio', route: routes.download, query_params: {presets: 'BEST,AUDIO'}},
'samples': {
name: 'Samples', route: routes.programmation, body: () => {
const end_date = new Date();
end_date.setMonth(end_date.getMonth() + 1);
return {
planning: {
recurrence_cron: `${Math.floor(Math.random() * 15)}/15 * * * *`,
recording_duration: 2,
recording_stops_at_end: true,
recording_restarts_during_duration: false,
recurrence_end_date: format_date(end_date)
},
};
},
},
'spy': {
name: 'Spy', route: routes.programmation, body: () => {
return {};
},
},
'1hour': {
name: '1 hour', route: routes.download, method: 'POST', body: () => {
return {
programmation: {
planning: {
recording_duration: 60,
},
},
};
},
},
};
const site_mapping = [
{
url: ['youtube.com', 'youtu.be'],
presets: ['best', '720p', 'audio', 'best+audio'],
},
];
// STOP COSTUMIZE HERE
let effective_presets = find_url_in_mapping(site_mapping);
if (effective_presets == null) {
effective_presets = Object.keys(presets);
}
effective_presets.forEach((preset, index) => {
const preset_object = presets[preset];
if (preset_object !== undefined) {
let key = null;
if (index < key_mapping.length) {
key = key_mapping[index];
}
GM_registerMenuCommand(preset_object.name, () => {
launch_request(preset_object);
}, key);
}
});
})();