Stremlined dependencies | built ad'Hoc http server
This commit is contained in:
86
server/src/core/HTTPServer.ts
Normal file
86
server/src/core/HTTPServer.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import http from 'http';
|
||||
import url from 'url';
|
||||
import fs, { open, close } from 'fs';
|
||||
import { parse, join } from 'path';
|
||||
|
||||
namespace server {
|
||||
export const mimes = {
|
||||
'.html': 'text/html',
|
||||
'.ico': 'image/x-icon',
|
||||
'.js': 'text/javascript',
|
||||
'.json': 'application/json',
|
||||
'.css': 'text/css',
|
||||
'.png': 'image/png',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.webp': 'image/webp',
|
||||
};
|
||||
}
|
||||
|
||||
class Jean {
|
||||
private workingDir: string;
|
||||
|
||||
/**
|
||||
* Jean static file server its only purpose is serving SPA and images
|
||||
* with the lowest impact possible.
|
||||
* @param workingDir sets the root directory automatically trying index.html
|
||||
* If specified the file in addition to the directory it will serve the
|
||||
* file directly.
|
||||
* *e.g* new Jean(path.join(__dirname, 'dist')) will try
|
||||
* index.html from the dist directory;
|
||||
* @author me :D
|
||||
*/
|
||||
|
||||
constructor(workingDir: string) {
|
||||
this.workingDir = workingDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a static file server
|
||||
* @returns an instance of a standard NodeJS http.Server
|
||||
*/
|
||||
public createServer(): http.Server {
|
||||
return http.createServer((req, res) => {
|
||||
// parse the current given url
|
||||
const parsedUrl = url.parse(req.url, false)
|
||||
// extract the pathname and guard it with the working dir
|
||||
let pathname = join(this.workingDir, `.${parsedUrl.pathname}`);
|
||||
// extract the file extension
|
||||
const ext = parse(pathname).ext;
|
||||
|
||||
// open the file or directory and fetch its descriptor
|
||||
open(pathname, 'r', (err, fd) => {
|
||||
// whoops, not found, send a 404
|
||||
if (err) {
|
||||
res.statusCode = 404;
|
||||
res.end(`File ${pathname} not found!`);
|
||||
return;
|
||||
}
|
||||
// something's gone wrong it's not a file or a directory
|
||||
fs.fstat(fd, (err, stat) => {
|
||||
if (err) {
|
||||
res.statusCode = 500;
|
||||
res.end(err);
|
||||
}
|
||||
// try file index.html
|
||||
if (stat.isDirectory()) {
|
||||
pathname = join(pathname, 'index.html')
|
||||
}
|
||||
// read the file
|
||||
fs.readFile(pathname, (err, data) => {
|
||||
if (err) {
|
||||
res.statusCode = 500;
|
||||
res.end(`Error reading the file: ${err}`);
|
||||
} else {
|
||||
// infer it's extension otherwise it's the index.html
|
||||
res.setHeader('Content-type', server.mimes[ext] || 'text/html');
|
||||
res.end(data);
|
||||
close(fd);
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Jean;
|
||||
@@ -2,6 +2,7 @@ import { spawn } from 'child_process';
|
||||
import { join } from 'path';
|
||||
import { Readable } from 'stream';
|
||||
import { deleteDownloadByPID, insertDownload } from '../db/db';
|
||||
import { ISettings } from '../interfaces/ISettings';
|
||||
import Logger from '../utils/BetterLogger';
|
||||
|
||||
const log = new Logger();
|
||||
@@ -9,15 +10,15 @@ const log = new Logger();
|
||||
/**
|
||||
* Represents a download process that spawns yt-dlp.
|
||||
* @constructor
|
||||
* @param {string} url - The downlaod url.
|
||||
* @param {Array<String>} params - The cli arguments passed by the frontend.
|
||||
* @param {*} settings - The download settings passed by the frontend.
|
||||
* @param url - The downlaod url.
|
||||
* @param params - The cli arguments passed by the frontend.
|
||||
* @param settings - The download settings passed by the frontend.
|
||||
*/
|
||||
|
||||
class Process {
|
||||
private url: string;
|
||||
private params: Array<string>;
|
||||
private settings: any;
|
||||
private settings: ISettings;
|
||||
private stdout: Readable;
|
||||
private pid: number;
|
||||
private info: any;
|
||||
@@ -35,11 +36,11 @@ class Process {
|
||||
|
||||
/**
|
||||
* function that launch the download process, sets the stdout property and the pid
|
||||
* @param {Function} callback not yet implemented
|
||||
* @returns {Promise<this>} the process instance
|
||||
* @param callback not yet implemented
|
||||
* @returns the process instance
|
||||
*/
|
||||
async start(callback?: Function): Promise<this> {
|
||||
await this.#__internalGetInfo();
|
||||
await this.internalGetInfo();
|
||||
|
||||
const ytldp = spawn(this.exePath,
|
||||
['-o', `${this.settings?.download_path || 'downloads/'}%(title)s.%(ext)s`]
|
||||
@@ -69,8 +70,8 @@ class Process {
|
||||
* function used internally by the download process to fetch information, usually thumbnail and title
|
||||
* @returns Promise to the lock
|
||||
*/
|
||||
async #__internalGetInfo() {
|
||||
let lock = true;
|
||||
private async internalGetInfo() {
|
||||
this.lock = true;
|
||||
let stdoutChunks = [];
|
||||
const ytdlpInfo = spawn(this.exePath, ['-s', '-j', this.url]);
|
||||
|
||||
@@ -93,7 +94,7 @@ class Process {
|
||||
}
|
||||
});
|
||||
|
||||
if (!lock) {
|
||||
if (!this.lock) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,15 @@ import { from, interval } from 'rxjs';
|
||||
import { throttle } from 'rxjs/operators';
|
||||
import { pruneDownloads } from '../db/db';
|
||||
import { killProcess } from '../utils/procUtils';
|
||||
import { Socket } from 'socket.io';
|
||||
import { IPayload } from '../interfaces/IPayload';
|
||||
import { ISettings } from '../interfaces/ISettings';
|
||||
import Logger from '../utils/BetterLogger';
|
||||
import Process from './Process';
|
||||
import ProcessPool from './ProcessPool';
|
||||
import { Socket } from 'socket.io';
|
||||
import { IPayload } from '../interfaces/IPayload';
|
||||
|
||||
// settings read from settings.json
|
||||
let settings;
|
||||
let settings: ISettings;
|
||||
let coldRestart = true;
|
||||
const log = new Logger();
|
||||
|
||||
@@ -20,7 +21,7 @@ try {
|
||||
settings = require('../settings.json');
|
||||
}
|
||||
catch (e) {
|
||||
console.warn("settings.json not found");
|
||||
log.warn('dl', 'settings.json not found');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +96,6 @@ export async function retriveDownload(socket: Socket) {
|
||||
if (coldRestart) {
|
||||
coldRestart = false;
|
||||
let downloads = await pruneDownloads();
|
||||
console.log(downloads)
|
||||
// sanitize
|
||||
downloads = [... new Set(downloads.filter(el => el !== undefined))];
|
||||
log.info('dl', `Cold restart, retrieving ${downloads.length} jobs`)
|
||||
|
||||
Reference in New Issue
Block a user