mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-03-24 21:50:59 +03:00
Added UI for managing tasks
Added ability to schedule tasks based on timestamp Fixed mismatched types between frontend and openapi yaml Simplified imports for several backend components
This commit is contained in:
@@ -28,6 +28,7 @@ const youtubedl = require('youtube-dl');
|
||||
const logger = require('./logger');
|
||||
const config_api = require('./config.js');
|
||||
const downloader_api = require('./downloader');
|
||||
const tasks_api = require('./tasks');
|
||||
const subscriptions_api = require('./subscriptions');
|
||||
const categories_api = require('./categories');
|
||||
const twitch_api = require('./twitch');
|
||||
@@ -60,9 +61,6 @@ const admin_token = '4241b401-7236-493e-92b5-b72696b9d853';
|
||||
config_api.initialize();
|
||||
db_api.initialize(db, users_db);
|
||||
auth_api.initialize(db_api);
|
||||
downloader_api.initialize(db_api);
|
||||
subscriptions_api.initialize(db_api, downloader_api);
|
||||
categories_api.initialize(db_api);
|
||||
|
||||
// Set some defaults
|
||||
db.defaults(
|
||||
@@ -1878,6 +1876,54 @@ app.post('/api/cancelDownload', optionalJwt, async (req, res) => {
|
||||
res.send({success: success});
|
||||
});
|
||||
|
||||
// tasks
|
||||
|
||||
app.post('/api/getTasks', optionalJwt, async (req, res) => {
|
||||
const tasks = await db_api.getRecords('tasks');
|
||||
for (let task of tasks) {
|
||||
if (task['schedule']) task['next_invocation'] = tasks_api.TASKS[task['key']]['job'].nextInvocation().getTime();
|
||||
}
|
||||
res.send({tasks: tasks});
|
||||
});
|
||||
|
||||
app.post('/api/getTask', optionalJwt, async (req, res) => {
|
||||
const task_key = req.body.task_key;
|
||||
const task = await db_api.getRecord('tasks', {key: task_key});
|
||||
if (task['schedule']) task['next_invocation'] = tasks_api.TASKS[task_key]['job'].nextInvocation().getTime();
|
||||
res.send({task: task});
|
||||
});
|
||||
|
||||
app.post('/api/runTask', optionalJwt, async (req, res) => {
|
||||
const task_key = req.body.task_key;
|
||||
const task = await db_api.getRecord('tasks', {key: task_key});
|
||||
|
||||
let success = true;
|
||||
if (task['running'] || task['confirming']) success = false;
|
||||
else await tasks_api.executeRun(task_key);
|
||||
|
||||
res.send({success: success});
|
||||
});
|
||||
|
||||
app.post('/api/confirmTask', optionalJwt, async (req, res) => {
|
||||
const task_key = req.body.task_key;
|
||||
const task = await db_api.getRecord('tasks', {key: task_key});
|
||||
|
||||
let success = true;
|
||||
if (task['running'] || task['confirming'] || !task['data']) success = false;
|
||||
else await tasks_api.executeConfirm(task_key);
|
||||
|
||||
res.send({success: success});
|
||||
});
|
||||
|
||||
app.post('/api/updateTaskSchedule', optionalJwt, async (req, res) => {
|
||||
const task_key = req.body.task_key;
|
||||
const new_schedule = req.body.new_schedule;
|
||||
|
||||
await tasks_api.updateTaskSchedule(task_key, new_schedule);
|
||||
|
||||
res.send({success: true});
|
||||
});
|
||||
|
||||
// logs management
|
||||
|
||||
app.post('/api/logs', optionalJwt, async function(req, res) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const config_api = require('../config');
|
||||
const consts = require('../consts');
|
||||
const logger = require('../logger');
|
||||
const db_api = require('../db');
|
||||
|
||||
const jwt = require('jsonwebtoken');
|
||||
const { uuid } = require('uuidv4');
|
||||
@@ -12,15 +13,12 @@ var JwtStrategy = require('passport-jwt').Strategy,
|
||||
ExtractJwt = require('passport-jwt').ExtractJwt;
|
||||
|
||||
// other required vars
|
||||
let db_api = null;
|
||||
let SERVER_SECRET = null;
|
||||
let JWT_EXPIRATION = null;
|
||||
let opts = null;
|
||||
let saltRounds = null;
|
||||
|
||||
exports.initialize = function(db_api) {
|
||||
setDB(db_api);
|
||||
|
||||
exports.initialize = function() {
|
||||
/*************************
|
||||
* Authentication module
|
||||
************************/
|
||||
@@ -51,10 +49,6 @@ exports.initialize = function(db_api) {
|
||||
}));
|
||||
}
|
||||
|
||||
function setDB(input_db_api) {
|
||||
db_api = input_db_api;
|
||||
}
|
||||
|
||||
exports.passport = require('passport');
|
||||
|
||||
exports.passport.serializeUser(function(user, done) {
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
const utils = require('./utils');
|
||||
const logger = require('./logger');
|
||||
|
||||
var db_api = null;
|
||||
|
||||
function setDB(input_db_api) { db_api = input_db_api }
|
||||
|
||||
function initialize(input_db_api) {
|
||||
setDB(input_db_api);
|
||||
}
|
||||
|
||||
const db_api = require('./db');
|
||||
/*
|
||||
|
||||
Categories:
|
||||
@@ -137,7 +129,6 @@ function applyCategoryRules(file_json, rules, category_name) {
|
||||
// }
|
||||
|
||||
module.exports = {
|
||||
initialize: initialize,
|
||||
categorize: categorize,
|
||||
getCategories: getCategories,
|
||||
getCategoriesAsPlaylists: getCategoriesAsPlaylists
|
||||
|
||||
@@ -14,26 +14,19 @@ const twitch_api = require('./twitch');
|
||||
const { create } = require('xmlbuilder2');
|
||||
const categories_api = require('./categories');
|
||||
const utils = require('./utils');
|
||||
|
||||
let db_api = null;
|
||||
const db_api = require('./db');
|
||||
|
||||
const mutex = new Mutex();
|
||||
let should_check_downloads = true;
|
||||
|
||||
const archivePath = path.join(__dirname, 'appdata', 'archives');
|
||||
|
||||
function setDB(input_db_api) { db_api = input_db_api }
|
||||
|
||||
exports.initialize = (input_db_api) => {
|
||||
setDB(input_db_api);
|
||||
categories_api.initialize(db_api);
|
||||
if (db_api.database_initialized) {
|
||||
setupDownloads();
|
||||
} else {
|
||||
db_api.database_initialized_bs.subscribe(init => {
|
||||
if (init) setupDownloads();
|
||||
});
|
||||
}
|
||||
if (db_api.database_initialized) {
|
||||
setupDownloads();
|
||||
} else {
|
||||
db_api.database_initialized_bs.subscribe(init => {
|
||||
if (init) setupDownloads();
|
||||
});
|
||||
}
|
||||
|
||||
exports.createDownload = async (url, type, options, user_uid = null, sub_id = null, sub_name = null) => {
|
||||
|
||||
@@ -8,15 +8,8 @@ const logger = require('./logger');
|
||||
|
||||
const debugMode = process.env.YTDL_MODE === 'debug';
|
||||
|
||||
let db_api = null;
|
||||
let downloader_api = null;
|
||||
|
||||
function setDB(input_db_api) { db_api = input_db_api }
|
||||
|
||||
function initialize(input_db_api, input_downloader_api) {
|
||||
setDB(input_db_api);
|
||||
downloader_api = input_downloader_api;
|
||||
}
|
||||
const db_api = require('./db');
|
||||
const downloader_api = require('./downloader');
|
||||
|
||||
async function subscribe(sub, user_uid = null) {
|
||||
const result_obj = {
|
||||
@@ -542,7 +535,6 @@ module.exports = {
|
||||
unsubscribe : unsubscribe,
|
||||
deleteSubscriptionFile : deleteSubscriptionFile,
|
||||
getVideosForSub : getVideosForSub,
|
||||
initialize : initialize,
|
||||
updateSubscriptionPropertyMultiple : updateSubscriptionPropertyMultiple,
|
||||
generateOptionsForSubscriptionDownload: generateOptionsForSubscriptionDownload
|
||||
}
|
||||
|
||||
@@ -31,7 +31,21 @@ const TASKS = {
|
||||
}
|
||||
|
||||
function scheduleJob(task_key, schedule) {
|
||||
return scheduler.scheduleJob(schedule, async () => {
|
||||
// schedule has to be converted from our format to one node-schedule can consume
|
||||
let converted_schedule = null;
|
||||
if (schedule['type'] === 'timestamp') {
|
||||
converted_schedule = new Date(schedule['data']['timestamp']);
|
||||
} else if (schedule['type'] === 'recurring') {
|
||||
const dayOfWeek = schedule['data']['dayOfWeek'] ? schedule['data']['dayOfWeek'] : null;
|
||||
const hour = schedule['data']['hour'] ? schedule['data']['hour'] : null;
|
||||
const minute = schedule['data']['minute'] ? schedule['data']['minute'] : null;
|
||||
converted_schedule = new scheduler.RecurrenceRule(null, null, null, dayOfWeek, hour, minute);
|
||||
} else {
|
||||
logger.error(`Failed to schedule job '${task_key}' as the type '${schedule['type']}' is invalid.`)
|
||||
return null;
|
||||
}
|
||||
|
||||
return scheduler.scheduleJob(converted_schedule, async () => {
|
||||
const task_state = await db_api.getRecord('tasks', {key: task_key});
|
||||
if (task_state['running'] || task_state['confirming']) {
|
||||
logger.verbose(`Skipping running task ${task_state['key']} as it is already in progress.`);
|
||||
@@ -43,15 +57,24 @@ function scheduleJob(task_key, schedule) {
|
||||
});
|
||||
}
|
||||
|
||||
exports.initialize = async () => {
|
||||
if (db_api.database_initialized) {
|
||||
setupTasks();
|
||||
} else {
|
||||
db_api.database_initialized_bs.subscribe(init => {
|
||||
if (init) setupTasks();
|
||||
});
|
||||
}
|
||||
|
||||
const setupTasks = async () => {
|
||||
const tasks_keys = Object.keys(TASKS);
|
||||
for (let i = 0; i < tasks_keys.length; i++) {
|
||||
const task_key = tasks_keys[i];
|
||||
const task_in_db = await db_api.getRecord('tasks', {key: task_key});
|
||||
if (!task_in_db) {
|
||||
// insert task into table if missing
|
||||
// insert task metadata into table if missing
|
||||
await db_api.insertRecordIntoTable('tasks', {
|
||||
key: task_key,
|
||||
title: TASKS[task_key]['title'],
|
||||
last_ran: null,
|
||||
last_confirmed: null,
|
||||
running: false,
|
||||
@@ -85,12 +108,15 @@ exports.executeTask = async (task_key) => {
|
||||
}
|
||||
|
||||
exports.executeRun = async (task_key) => {
|
||||
logger.verbose(`Running task ${task_key}`);
|
||||
await db_api.updateRecord('tasks', {key: task_key}, {running: true});
|
||||
const data = await TASKS[task_key].run();
|
||||
await db_api.updateRecord('tasks', {key: task_key}, {data: data, last_ran: Date.now()/1000, running: false});
|
||||
logger.verbose(`Finished running task ${task_key}`);
|
||||
}
|
||||
|
||||
exports.executeConfirm = async (task_key) => {
|
||||
logger.verbose(`Confirming task ${task_key}`);
|
||||
if (!TASKS[task_key]['confirm']) {
|
||||
return null;
|
||||
}
|
||||
@@ -98,10 +124,12 @@ exports.executeConfirm = async (task_key) => {
|
||||
const task_obj = await db_api.getRecord('tasks', {key: task_key});
|
||||
const data = task_obj['data'];
|
||||
await TASKS[task_key].confirm(data);
|
||||
await db_api.updateRecord('tasks', {key: task_key}, {confirming: false, last_confirmed: Date.now()/1000});
|
||||
await db_api.updateRecord('tasks', {key: task_key}, {confirming: false, last_confirmed: Date.now()/1000, data: null});
|
||||
logger.verbose(`Finished confirming task ${task_key}`);
|
||||
}
|
||||
|
||||
exports.updateTaskSchedule = async (task_key, schedule) => {
|
||||
logger.verbose(`Updating schedule for task ${task_key}`);
|
||||
await db_api.updateRecord('tasks', {key: task_key}, {schedule: schedule});
|
||||
if (TASKS[task_key]['job']) {
|
||||
TASKS[task_key]['job'].cancel();
|
||||
|
||||
Reference in New Issue
Block a user