Merge branch 'Tzahi12345:master' into master

This commit is contained in:
Glassed Silver
2022-04-26 04:25:50 +02:00
committed by GitHub
9 changed files with 82 additions and 30 deletions

View File

@@ -16,7 +16,7 @@ paths:
- downloader - downloader
summary: Download video file summary: Download video file
description: |- description: |-
Downloads a video file with the given URL. Will include global args if they exist. Downloads a file with the given URL. Will include global args if they exist.
HTTP requests will return once the video file download completes. In the future, it will (by default) return once the download starts, and a separate API call will be used for checking the download status. HTTP requests will return once the video file download completes. In the future, it will (by default) return once the download starts, and a separate API call will be used for checking the download status.
@@ -41,7 +41,7 @@ paths:
post: post:
tags: tags:
- downloader - downloader
summary: Download video file summary: Generates arguments used to download file
description: Generates args, used for checking what args would run if you ran downloadFile description: Generates args, used for checking what args would run if you ran downloadFile
operationId: post-generateArgs operationId: post-generateArgs
requestBody: requestBody:

View File

@@ -803,7 +803,7 @@ app.post('/api/testConnectionString', optionalJwt, async (req, res) => {
app.post('/api/downloadFile', optionalJwt, async function(req, res) { app.post('/api/downloadFile', optionalJwt, async function(req, res) {
req.setTimeout(0); // remove timeout in case of long videos req.setTimeout(0); // remove timeout in case of long videos
const url = req.body.url; const url = req.body.url;
const type = req.body.type; const type = req.body.type ? req.body.type : 'video';
const user_uid = req.isAuthenticated() ? req.user.uid : null; const user_uid = req.isAuthenticated() ? req.user.uid : null;
const options = { const options = {
customArgs: req.body.customArgs, customArgs: req.body.customArgs,

View File

@@ -18,10 +18,19 @@ let JWT_EXPIRATION = null;
let opts = null; let opts = null;
let saltRounds = null; let saltRounds = null;
exports.initialize = function() { exports.initialize = function () {
/************************* /*************************
* Authentication module * Authentication module
************************/ ************************/
if (db_api.database_initialized) {
setupRoles();
} else {
db_api.database_initialized_bs.subscribe(init => {
if (init) setupRoles();
});
}
saltRounds = 10; saltRounds = 10;
JWT_EXPIRATION = config_api.getConfigItem('ytdl_jwt_expiration'); JWT_EXPIRATION = config_api.getConfigItem('ytdl_jwt_expiration');
@@ -49,6 +58,41 @@ exports.initialize = function() {
})); }));
} }
const setupRoles = async () => {
const required_roles = {
admin: {
permissions: [
'filemanager',
'settings',
'subscriptions',
'sharing',
'advanced_download',
'downloads_manager'
]
},
user: {
permissions: [
'filemanager',
'subscriptions',
'sharing'
]
}
}
const role_keys = Object.keys(required_roles);
for (let i = 0; i < role_keys.length; i++) {
const role_key = role_keys[i];
const role_in_db = await db_api.getRecord('roles', {key: role_key});
if (!role_in_db) {
// insert task metadata into table if missing
await db_api.insertRecordIntoTable('roles', {
key: role_key,
permissions: required_roles[role_key]['permissions']
});
}
}
}
exports.passport = require('passport'); exports.passport = require('passport');
exports.passport.serializeUser(function(user, done) { exports.passport.serializeUser(function(user, done) {

View File

@@ -85,6 +85,7 @@ exports.initialize = (input_db, input_users_db) => {
} }
exports.connectToDB = async (retries = 5, no_fallback = false, custom_connection_string = null) => { exports.connectToDB = async (retries = 5, no_fallback = false, custom_connection_string = null) => {
using_local_db = config_api.getConfigItem('ytdl_use_local_db'); // verify
if (using_local_db && !custom_connection_string) return; if (using_local_db && !custom_connection_string) return;
const success = await exports._connectToDB(custom_connection_string); const success = await exports._connectToDB(custom_connection_string);
if (success) return true; if (success) return true;

View File

@@ -3,7 +3,6 @@ const { uuid } = require('uuidv4');
const path = require('path'); const path = require('path');
const mergeFiles = require('merge-files'); const mergeFiles = require('merge-files');
const NodeID3 = require('node-id3') const NodeID3 = require('node-id3')
const glob = require('glob')
const Mutex = require('async-mutex').Mutex; const Mutex = require('async-mutex').Mutex;
const youtubedl = require('youtube-dl'); const youtubedl = require('youtube-dl');
@@ -583,20 +582,26 @@ async function checkDownloadPercent(download_uid) {
if (!resulting_file_size) return; if (!resulting_file_size) return;
let sum_size = 0; let sum_size = 0;
glob(`{${files_to_check_for_progress.join(',')}, }*`, async (err, files) => { for (let i = 0; i < files_to_check_for_progress.length; i++) {
files.forEach(async file => { const file_to_check_for_progress = files_to_check_for_progress[i];
try { const dir = path.dirname(file_to_check_for_progress);
const file_stats = fs.statSync(file); if (!fs.existsSync(dir)) continue;
if (file_stats && file_stats.size) { fs.readdir(dir, async (err, files) => {
sum_size += file_stats.size; for (let j = 0; j < files.length; j++) {
} const file = files[j];
} catch (e) { if (!file.includes(path.basename(file_to_check_for_progress))) continue;
try {
const file_stats = fs.statSync(path.join(dir, file));
if (file_stats && file_stats.size) {
sum_size += file_stats.size;
}
} catch (e) {}
} }
const percent_complete = (sum_size/resulting_file_size * 100).toFixed(2);
await db_api.updateRecord('download_queue', {uid: download_uid}, {percent_complete: percent_complete});
}); });
const percent_complete = (sum_size/resulting_file_size * 100).toFixed(2); }
await db_api.updateRecord('download_queue', {uid: download_uid}, {percent_complete: percent_complete});
});
} }
exports.generateNFOFile = (info, output_path) => { exports.generateNFOFile = (info, output_path) => {

View File

@@ -2567,9 +2567,9 @@
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
}, },
"passport": { "passport": {
"version": "0.5.2", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/passport/-/passport-0.5.2.tgz", "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz",
"integrity": "sha512-w9n/Ot5I7orGD4y+7V3EFJCQEznE5RxHamUxcqLT2QoJY0f2JdN8GyHonYFvN0Vz+L6lUJfVhrk2aZz2LbuREw==", "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==",
"requires": { "requires": {
"passport-strategy": "1.x.x", "passport-strategy": "1.x.x",
"pause": "0.0.1" "pause": "0.0.1"

View File

@@ -40,7 +40,6 @@
"express": "^4.17.3", "express": "^4.17.3",
"fluent-ffmpeg": "^2.1.2", "fluent-ffmpeg": "^2.1.2",
"fs-extra": "^9.0.0", "fs-extra": "^9.0.0",
"glob": "^7.1.6",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"lowdb": "^1.0.0", "lowdb": "^1.0.0",
"md5": "^2.2.1", "md5": "^2.2.1",
@@ -53,7 +52,7 @@
"node-id3": "^0.1.14", "node-id3": "^0.1.14",
"node-schedule": "^2.1.0", "node-schedule": "^2.1.0",
"nodemon": "^2.0.7", "nodemon": "^2.0.7",
"passport": "^0.5.2", "passport": "^0.4.1",
"passport-http": "^0.3.0", "passport-http": "^0.3.0",
"passport-jwt": "^4.0.0", "passport-jwt": "^4.0.0",
"passport-ldapauth": "^3.0.1", "passport-ldapauth": "^3.0.1",

View File

@@ -42,9 +42,9 @@ function scheduleJob(task_key, schedule) {
if (schedule['type'] === 'timestamp') { if (schedule['type'] === 'timestamp') {
converted_schedule = new Date(schedule['data']['timestamp']); converted_schedule = new Date(schedule['data']['timestamp']);
} else if (schedule['type'] === 'recurring') { } else if (schedule['type'] === 'recurring') {
const dayOfWeek = schedule['data']['dayOfWeek'] ? schedule['data']['dayOfWeek'] : null; const dayOfWeek = schedule['data']['dayOfWeek'] != null ? schedule['data']['dayOfWeek'] : null;
const hour = schedule['data']['hour'] ? schedule['data']['hour'] : null; const hour = schedule['data']['hour'] != null ? schedule['data']['hour'] : null;
const minute = schedule['data']['minute'] ? schedule['data']['minute'] : null; const minute = schedule['data']['minute'] != null ? schedule['data']['minute'] : null;
converted_schedule = new scheduler.RecurrenceRule(null, null, null, dayOfWeek, hour, minute); converted_schedule = new scheduler.RecurrenceRule(null, null, null, dayOfWeek, hour, minute);
} else { } else {
logger.error(`Failed to schedule job '${task_key}' as the type '${schedule['type']}' is invalid.`) logger.error(`Failed to schedule job '${task_key}' as the type '${schedule['type']}' is invalid.`)

View File

@@ -1,6 +1,6 @@
import { Component, Inject, OnInit } from '@angular/core'; import { Component, Inject, OnInit } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Schedule } from 'api-types'; import { Schedule, Task } from 'api-types';
import { PostsService } from 'app/posts.services'; import { PostsService } from 'app/posts.services';
@Component({ @Component({
@@ -18,7 +18,7 @@ export class UpdateTaskScheduleDialogComponent implements OnInit {
date = null; date = null;
today = new Date(); today = new Date();
constructor(@Inject(MAT_DIALOG_DATA) public data: any, private dialogRef: MatDialogRef<UpdateTaskScheduleDialogComponent>, private postsService: PostsService) { constructor(@Inject(MAT_DIALOG_DATA) public data: {task: Task}, private dialogRef: MatDialogRef<UpdateTaskScheduleDialogComponent>, private postsService: PostsService) {
this.processTask(this.data.task); this.processTask(this.data.task);
this.postsService.getTask(this.data.task.key).subscribe(res => { this.postsService.getTask(this.data.task.key).subscribe(res => {
this.processTask(res['task']); this.processTask(res['task']);
@@ -28,7 +28,7 @@ export class UpdateTaskScheduleDialogComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
} }
processTask(task) { processTask(task: Task): void {
if (!task['schedule']) { if (!task['schedule']) {
this.enabled = false; this.enabled = false;
return; return;
@@ -39,7 +39,11 @@ export class UpdateTaskScheduleDialogComponent implements OnInit {
this.recurring = schedule['type'] === Schedule.type.RECURRING; this.recurring = schedule['type'] === Schedule.type.RECURRING;
if (this.recurring) { if (this.recurring) {
this.time = `${schedule['data']['hour']}:${schedule['data']['minute']}`; const hour = schedule['data']['hour'];
const minute = schedule['data']['minute'];
// add padding 0s if necessary to hours and minutes
this.time = (hour < 10 ? '0' : '') + hour + ':' + (minute < 10 ? '0' : '') + minute;
if (schedule['data']['dayOfWeek']) { if (schedule['data']['dayOfWeek']) {
this.days_of_week = schedule['data']['dayOfWeek']; this.days_of_week = schedule['data']['dayOfWeek'];
@@ -75,7 +79,6 @@ export class UpdateTaskScheduleDialogComponent implements OnInit {
} }
} else { } else {
this.date.setHours(hours, minutes); this.date.setHours(hours, minutes);
console.log(this.date);
schedule['data'] = {timestamp: this.date.getTime()}; schedule['data'] = {timestamp: this.date.getTime()};
} }
this.dialogRef.close(schedule); this.dialogRef.close(schedule);