refactored code so node.js serves the angular app, and all the backend routes are prepended with /api/

nodejs now compressed requests
pull/12/head
Isaac Grynsztein 6 years ago
parent 37cc8f4fe1
commit 09bdae90e2

1
.gitignore vendored

@ -46,5 +46,6 @@ backend/node_modules/*
YoutubeDL-Material/node_modules/* YoutubeDL-Material/node_modules/*
backend/video/* backend/video/*
backend/audio/* backend/audio/*
backend/public/*
backend/db.json backend/db.json
src/assets/default.json src/assets/default.json

@ -2,6 +2,7 @@ var async = require('async');
var fs = require('fs'); var fs = require('fs');
var path = require('path'); var path = require('path');
var youtubedl = require('youtube-dl'); var youtubedl = require('youtube-dl');
var compression = require('compression');
var https = require('https'); var https = require('https');
var express = require("express"); var express = require("express");
var bodyParser = require("body-parser"); var bodyParser = require("body-parser");
@ -68,11 +69,6 @@ var descriptors = {};
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); app.use(bodyParser.json());
app.get('/using-encryption', function(req, res) {
res.send(usingEncryption);
res.end("yes");
});
// objects // objects
function File(id, title, thumbnailURL, isAudio, duration) { function File(id, title, thumbnailURL, isAudio, duration) {
@ -506,7 +502,21 @@ app.use(function(req, res, next) {
next(); next();
}); });
app.post('/tomp3', function(req, res) { app.use(compression());
app.get('/api/config', function(req, res) {
let config_file = config_api.getConfigFile();
res.send({
config_file: config_file,
success: !!config_file
});
});
app.get('/api/using-encryption', function(req, res) {
res.send(usingEncryption);
});
app.post('/api/tomp3', function(req, res) {
var url = req.body.url; var url = req.body.url;
var date = Date.now(); var date = Date.now();
var audiopath = '%(title)s'; var audiopath = '%(title)s';
@ -588,7 +598,7 @@ app.post('/tomp3', function(req, res) {
}); });
}); });
app.post('/tomp4', function(req, res) { app.post('/api/tomp4', function(req, res) {
var url = req.body.url; var url = req.body.url;
var date = Date.now(); var date = Date.now();
var path = videoFolderPath; var path = videoFolderPath;
@ -676,7 +686,7 @@ app.post('/tomp4', function(req, res) {
}); });
// gets the status of the mp3 file that's being downloaded // gets the status of the mp3 file that's being downloaded
app.post('/fileStatusMp3', function(req, res) { app.post('/api/fileStatusMp3', function(req, res) {
var name = decodeURI(req.body.name + ""); var name = decodeURI(req.body.name + "");
var exists = ""; var exists = "";
var fullpath = audioFolderPath + name + ".mp3"; var fullpath = audioFolderPath + name + ".mp3";
@ -698,7 +708,7 @@ app.post('/fileStatusMp3', function(req, res) {
}); });
// gets the status of the mp4 file that's being downloaded // gets the status of the mp4 file that's being downloaded
app.post('/fileStatusMp4', function(req, res) { app.post('/api/fileStatusMp4', function(req, res) {
var name = decodeURI(req.body.name); var name = decodeURI(req.body.name);
var exists = ""; var exists = "";
var fullpath = videoFolderPath + name + ".mp4"; var fullpath = videoFolderPath + name + ".mp4";
@ -718,7 +728,7 @@ app.post('/fileStatusMp4', function(req, res) {
}); });
// gets all download mp3s // gets all download mp3s
app.post('/getMp3s', function(req, res) { app.post('/api/getMp3s', function(req, res) {
var mp3s = []; var mp3s = [];
var playlists = db.get('playlists.audio').value(); var playlists = db.get('playlists.audio').value();
var files = recFindByExt(audioFolderPath, 'mp3'); // fs.readdirSync(audioFolderPath); var files = recFindByExt(audioFolderPath, 'mp3'); // fs.readdirSync(audioFolderPath);
@ -750,7 +760,7 @@ app.post('/getMp3s', function(req, res) {
}); });
// gets all download mp4s // gets all download mp4s
app.post('/getMp4s', function(req, res) { app.post('/api/getMp4s', function(req, res) {
var mp4s = []; var mp4s = [];
var playlists = db.get('playlists.video').value(); var playlists = db.get('playlists.video').value();
var fullpath = videoFolderPath; var fullpath = videoFolderPath;
@ -782,7 +792,7 @@ app.post('/getMp4s', function(req, res) {
res.end("yes"); res.end("yes");
}); });
app.post('/createPlaylist', async (req, res) => { app.post('/api/createPlaylist', async (req, res) => {
let playlistName = req.body.playlistName; let playlistName = req.body.playlistName;
let fileNames = req.body.fileNames; let fileNames = req.body.fileNames;
let type = req.body.type; let type = req.body.type;
@ -805,7 +815,7 @@ app.post('/createPlaylist', async (req, res) => {
}) })
}); });
app.post('/updatePlaylist', async (req, res) => { app.post('/api/updatePlaylist', async (req, res) => {
let playlistID = req.body.playlistID; let playlistID = req.body.playlistID;
let fileNames = req.body.fileNames; let fileNames = req.body.fileNames;
let type = req.body.type; let type = req.body.type;
@ -831,7 +841,7 @@ app.post('/updatePlaylist', async (req, res) => {
}) })
}); });
app.post('/deletePlaylist', async (req, res) => { app.post('/api/deletePlaylist', async (req, res) => {
let playlistID = req.body.playlistID; let playlistID = req.body.playlistID;
let type = req.body.type; let type = req.body.type;
@ -853,7 +863,7 @@ app.post('/deletePlaylist', async (req, res) => {
}); });
// deletes mp3 file // deletes mp3 file
app.post('/deleteMp3', async (req, res) => { app.post('/api/deleteMp3', async (req, res) => {
var name = req.body.name; var name = req.body.name;
var fullpath = audioFolderPath + name + ".mp3"; var fullpath = audioFolderPath + name + ".mp3";
var wasDeleted = false; var wasDeleted = false;
@ -873,7 +883,7 @@ app.post('/deleteMp3', async (req, res) => {
}); });
// deletes mp4 file // deletes mp4 file
app.post('/deleteMp4', async (req, res) => { app.post('/api/deleteMp4', async (req, res) => {
var name = req.body.name; var name = req.body.name;
var fullpath = videoFolderPath + name + ".mp4"; var fullpath = videoFolderPath + name + ".mp4";
var wasDeleted = false; var wasDeleted = false;
@ -892,7 +902,7 @@ app.post('/deleteMp4', async (req, res) => {
} }
}); });
app.post('/downloadFile', async (req, res) => { app.post('/api/downloadFile', async (req, res) => {
let fileNames = req.body.fileNames; let fileNames = req.body.fileNames;
let is_playlist = req.body.is_playlist; let is_playlist = req.body.is_playlist;
let type = req.body.type; let type = req.body.type;
@ -915,7 +925,7 @@ app.post('/downloadFile', async (req, res) => {
res.sendFile(file); res.sendFile(file);
}); });
app.post('/deleteFile', async (req, res) => { app.post('/api/deleteFile', async (req, res) => {
let fileName = req.body.fileName; let fileName = req.body.fileName;
let type = req.body.type; let type = req.body.type;
if (type === 'audio') { if (type === 'audio') {
@ -926,7 +936,7 @@ app.post('/deleteFile', async (req, res) => {
res.send() res.send()
}); });
app.get('/video/:id', function(req , res){ app.get('/api/video/:id', function(req , res){
var head; var head;
let id = decodeURI(req.params.id); let id = decodeURI(req.params.id);
const path = "video/" + id + '.mp4'; const path = "video/" + id + '.mp4';
@ -966,7 +976,7 @@ app.get('/video/:id', function(req , res){
} }
}); });
app.get('/audio/:id', function(req , res){ app.get('/api/audio/:id', function(req , res){
var head; var head;
let id = decodeURI(req.params.id); let id = decodeURI(req.params.id);
let path = "audio/" + id + '.mp3'; let path = "audio/" + id + '.mp3';
@ -1008,7 +1018,7 @@ app.get('/audio/:id', function(req , res){
}); });
app.post('/getVideoInfos', async (req, res) => { app.post('/api/getVideoInfos', async (req, res) => {
let fileNames = req.body.fileNames; let fileNames = req.body.fileNames;
let urlMode = !!req.body.urlMode; let urlMode = !!req.body.urlMode;
let type = req.body.type; let type = req.body.type;
@ -1027,3 +1037,22 @@ app.get('/audio/:id', function(req , res){
success: !!result success: !!result
}) })
}); });
app.use(function(req, res, next) {
//if the request is not html then move along
var accept = req.accepts('html', 'json', 'xml');
if (accept !== 'html') {
return next();
}
// if the request has a '.' assume that it's for a file, move along
var ext = path.extname(req.path);
if (ext !== '') {
return next();
}
fs.createReadStream('./public/index.html').pipe(res);
});
app.use(express.static('./public'));

@ -108,5 +108,6 @@ module.exports = {
getConfigItem: getConfigItem, getConfigItem: getConfigItem,
setConfigItem: setConfigItem, setConfigItem: setConfigItem,
setConfigItems: setConfigItems, setConfigItems: setConfigItems,
getConfigFile: getConfigFile,
CONFIG_ITEMS: CONFIG_ITEMS CONFIG_ITEMS: CONFIG_ITEMS
} }

@ -20,6 +20,7 @@
"dependencies": { "dependencies": {
"archiver": "^3.1.1", "archiver": "^3.1.1",
"async": "^3.1.0", "async": "^3.1.0",
"compression": "^1.7.4",
"config": "^3.2.3", "config": "^3.2.3",
"exe": "^1.0.2", "exe": "^1.0.2",
"express": "^4.17.1", "express": "^4.17.1",

@ -40,7 +40,8 @@ export class AppComponent implements OnInit {
public router: Router, public overlayContainer: OverlayContainer, private elementRef: ElementRef) { public router: Router, public overlayContainer: OverlayContainer, private elementRef: ElementRef) {
// loading config // loading config
this.postsService.loadNavItems().subscribe(result => { // loads settings this.postsService.loadNavItems().subscribe(res => { // loads settings
const result = !this.postsService.debugMode ? res['config_file'] : res;
this.topBarTitle = result['YoutubeDLMaterial']['Extra']['title_top']; this.topBarTitle = result['YoutubeDLMaterial']['Extra']['title_top'];
const themingExists = result['YoutubeDLMaterial']['Themes']; const themingExists = result['YoutubeDLMaterial']['Themes'];
this.defaultTheme = themingExists ? result['YoutubeDLMaterial']['Themes']['default_theme'] : 'default'; this.defaultTheme = themingExists ? result['YoutubeDLMaterial']['Themes']['default_theme'] : 'default';

@ -1,4 +1,4 @@
import { Component, OnInit, ElementRef, ViewChild, ViewChildren, QueryList } from '@angular/core'; import { Component, OnInit, ElementRef, ViewChild, ViewChildren, QueryList, isDevMode } from '@angular/core';
import {PostsService} from '../posts.services'; import {PostsService} from '../posts.services';
import {FileCardComponent} from '../file-card/file-card.component'; import {FileCardComponent} from '../file-card/file-card.component';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
@ -202,7 +202,8 @@ export class MainComponent implements OnInit {
this.audioOnly = false; this.audioOnly = false;
// loading config // loading config
this.postsService.loadNavItems().subscribe(result => { // loads settings this.postsService.loadNavItems().subscribe(res => { // loads settings
const result = !this.postsService.debugMode ? res['config_file'] : res;
const backendUrl = result['YoutubeDLMaterial']['Host']['backendurl']; const backendUrl = result['YoutubeDLMaterial']['Host']['backendurl'];
this.fileManagerEnabled = result['YoutubeDLMaterial']['Extra']['file_manager_enabled']; this.fileManagerEnabled = result['YoutubeDLMaterial']['Extra']['file_manager_enabled'];
this.downloadOnlyMode = result['YoutubeDLMaterial']['Extra']['download_only_mode']; this.downloadOnlyMode = result['YoutubeDLMaterial']['Extra']['download_only_mode'];
@ -216,7 +217,7 @@ export class MainComponent implements OnInit {
this.allowQualitySelect = result['YoutubeDLMaterial']['Extra']['allow_quality_select']; this.allowQualitySelect = result['YoutubeDLMaterial']['Extra']['allow_quality_select'];
this.allowAdvancedDownload = result['YoutubeDLMaterial']['Advanced']['allow_advanced_download']; this.allowAdvancedDownload = result['YoutubeDLMaterial']['Advanced']['allow_advanced_download'];
this.postsService.path = backendUrl; this.postsService.path = backendUrl + 'api/';
this.postsService.startPath = backendUrl; this.postsService.startPath = backendUrl;
this.postsService.startPathSSL = backendUrl; this.postsService.startPathSSL = backendUrl;

@ -53,13 +53,14 @@ export class PlayerComponent implements OnInit {
this.id = this.route.snapshot.paramMap.get('id'); this.id = this.route.snapshot.paramMap.get('id');
// loading config // loading config
this.postsService.loadNavItems().subscribe(result => { // loads settings this.postsService.loadNavItems().subscribe(res => { // loads settings
const result = !this.postsService.debugMode ? res['config_file'] : res;
this.baseStreamPath = result['YoutubeDLMaterial']['Downloader']['path-base']; this.baseStreamPath = result['YoutubeDLMaterial']['Downloader']['path-base'];
this.audioFolderPath = result['YoutubeDLMaterial']['Downloader']['path-audio']; this.audioFolderPath = result['YoutubeDLMaterial']['Downloader']['path-audio'];
this.videoFolderPath = result['YoutubeDLMaterial']['Downloader']['path-video']; this.videoFolderPath = result['YoutubeDLMaterial']['Downloader']['path-video'];
const backendUrl = result['YoutubeDLMaterial']['Host']['backendurl']; const backendUrl = result['YoutubeDLMaterial']['Host']['backendurl'];
this.postsService.path = backendUrl; this.postsService.path = backendUrl + 'api/';
this.postsService.startPath = backendUrl; this.postsService.startPath = backendUrl;
this.postsService.startPathSSL = backendUrl; this.postsService.startPathSSL = backendUrl;

@ -1,4 +1,4 @@
import {Injectable, isDevMode} from '@angular/core'; import {Injectable, isDevMode, Inject} from '@angular/core';
import { HttpClient, HttpHeaders, HttpRequest, HttpResponseBase } from '@angular/common/http'; import { HttpClient, HttpHeaders, HttpRequest, HttpResponseBase } from '@angular/common/http';
import config from '../assets/default.json'; import config from '../assets/default.json';
import 'rxjs/add/operator/map'; import 'rxjs/add/operator/map';
@ -7,20 +7,30 @@ import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw'; import 'rxjs/add/observable/throw';
import { THEMES_CONFIG } from '../themes'; import { THEMES_CONFIG } from '../themes';
import { Router } from '@angular/router';
import { DOCUMENT } from '@angular/common';
@Injectable() @Injectable()
export class PostsService { export class PostsService {
path = ''; path = '';
audioFolder = ''; audioFolder = '';
videoFolder = ''; videoFolder = '';
startPath = 'http://localhost:17442/'; startPath = null; // 'http://localhost:17442/';
startPathSSL = 'https://localhost:17442/' startPathSSL = null; // 'https://localhost:17442/'
handShakeComplete = false; handShakeComplete = false;
THEMES_CONFIG = THEMES_CONFIG; THEMES_CONFIG = THEMES_CONFIG;
theme; theme;
constructor(private http: HttpClient) { debugMode = false;
constructor(private http: HttpClient, private router: Router, @Inject(DOCUMENT) private document: Document) {
console.log('PostsService Initialized...'); console.log('PostsService Initialized...');
// this.startPath = window.location.href + '/api/';
// this.startPathSSL = window.location.href + '/api/';
this.path = this.document.location.origin + '/api/';
if (isDevMode()) {
this.debugMode = true;
}
} }
setTheme(theme) { setTheme(theme) {
@ -72,10 +82,9 @@ export class PostsService {
loadNavItems() { loadNavItems() {
if (isDevMode()) { if (isDevMode()) {
return this.http.get('./assets/default.json'); return this.http.get('./assets/default.json');
} else {
return this.http.get(this.path + 'config');
} }
const locations = window.location.href.split('#');
const current_location = locations[0];
return this.http.get(current_location + 'backend/config/default.json');
} }
deleteFile(name: string, isAudio: boolean) { deleteFile(name: string, isAudio: boolean) {

Loading…
Cancel
Save