@ -13,7 +13,7 @@ var express = require("express");
var bodyParser = require ( "body-parser" ) ;
var archiver = require ( 'archiver' ) ;
var unzipper = require ( 'unzipper' ) ;
var db _api = require ( './db' )
var db _api = require ( './db' ) ;
var utils = require ( './utils' )
var mergeFiles = require ( 'merge-files' ) ;
const low = require ( 'lowdb' )
@ -87,14 +87,8 @@ categories_api.initialize(db, users_db, logger, db_api);
// Set some defaults
db . defaults (
{
playlists : {
audio : [ ] ,
video : [ ]
} ,
files : {
audio : [ ] ,
video : [ ]
} ,
playlists : [ ] ,
files : [ ] ,
configWriteFlag : false ,
downloads : { } ,
subscriptions : [ ] ,
@ -218,10 +212,12 @@ async function checkMigrations() {
// 4.1->4.2 migration
const add _description _migration _complete = false ; // db.get('add_description_migration_complete').value();
const add _description _migration _complete = db . get ( 'add_description_migration_complete' ) . value ( ) ;
if ( ! add _description _migration _complete ) {
logger . info ( 'Beginning migration: 4.1->4.2+' )
const success = await addMetadataPropertyToDB ( 'description' ) ;
let success = await simplifyDBFileStructure ( ) ;
success = success && await addMetadataPropertyToDB ( 'view_count' ) ;
success = success && await addMetadataPropertyToDB ( 'description' ) ;
if ( success ) { logger . info ( '4.1->4.2+ migration complete!' ) ; }
else { logger . error ( 'Migration failed: 4.1->4.2+' ) ; }
}
@ -229,6 +225,7 @@ async function checkMigrations() {
return true ;
}
/ *
async function runFilesToDBMigration ( ) {
try {
let mp3s = await getMp3s ( ) ;
@ -260,6 +257,37 @@ async function runFilesToDBMigration() {
return false ;
}
}
* /
async function simplifyDBFileStructure ( ) {
let users = users _db . get ( 'users' ) . value ( ) ;
for ( let i = 0 ; i < users . length ; i ++ ) {
const user = users [ i ] ;
if ( user [ 'files' ] [ 'video' ] !== undefined && user [ 'files' ] [ 'audio' ] !== undefined ) {
const user _files = user [ 'files' ] [ 'video' ] . concat ( user [ 'files' ] [ 'audio' ] ) ;
const user _db _path = users _db . get ( 'users' ) . find ( { uid : user [ 'uid' ] } ) ;
user _db _path . assign ( { files : user _files } ) . write ( ) ;
}
if ( user [ 'playlists' ] [ 'video' ] !== undefined && user [ 'playlists' ] [ 'audio' ] !== undefined ) {
const user _playlists = user [ 'playlists' ] [ 'video' ] . concat ( user [ 'playlists' ] [ 'audio' ] ) ;
const user _db _path = users _db . get ( 'users' ) . find ( { uid : user [ 'uid' ] } ) ;
user _db _path . assign ( { playlists : user _playlists } ) . write ( ) ;
}
}
if ( db . get ( 'files.video' ) . value ( ) !== undefined && db . get ( 'files.audio' ) . value ( ) !== undefined ) {
const files = db . get ( 'files.video' ) . value ( ) . concat ( db . get ( 'files.audio' ) ) ;
db . assign ( { files : files } ) . write ( ) ;
}
if ( db . get ( 'playlists.video' ) . value ( ) !== undefined && db . get ( 'playlists.audio' ) . value ( ) !== undefined ) {
const playlists = db . get ( 'playlists.video' ) . value ( ) . concat ( db . get ( 'playlists.audio' ) ) ;
db . assign ( { playlists : playlists } ) . write ( ) ;
}
return true ;
}
async function addMetadataPropertyToDB ( property _key ) {
try {
@ -592,6 +620,9 @@ async function loadConfig() {
// creates archive path if missing
await fs . ensureDir ( archivePath ) ;
// check migrations
await checkMigrations ( ) ;
// now this is done here due to youtube-dl's repo takedown
await startYoutubeDL ( ) ;
@ -606,9 +637,6 @@ async function loadConfig() {
db _api . importUnregisteredFiles ( ) ;
// check migrations
await checkMigrations ( ) ;
// load in previous downloads
downloads = db . get ( 'downloads' ) . value ( ) ;
@ -1994,7 +2022,7 @@ async function addThumbnails(files) {
// gets all download mp3s
app . get ( '/api/getMp3s' , optionalJwt , async function ( req , res ) {
var mp3s = db . get ( 'files .audio' ) . value ( ) ; // getMp3s();
var mp3s = db . get ( 'files ') . chain ( ) . find ( { isAudio : true } ) . value ( ) ; // getMp3s();
var playlists = db . get ( 'playlists.audio' ) . value ( ) ;
const is _authenticated = req . isAuthenticated ( ) ;
if ( is _authenticated ) {
@ -2020,8 +2048,8 @@ app.get('/api/getMp3s', optionalJwt, async function(req, res) {
// gets all download mp4s
app . get ( '/api/getMp4s' , optionalJwt , async function ( req , res ) {
var mp4s = db . get ( 'files .video' ) . value ( ) ; // getMp4s();
var playlists = db . get ( 'playlists .video ') . value ( ) ;
var mp4s = db . get ( 'files ') . chain ( ) . find ( { isAudio : false } ) . value ( ) ; // getMp4s();
var playlists = db . get ( 'playlists ') . value ( ) ;
const is _authenticated = req . isAuthenticated ( ) ;
if ( is _authenticated ) {
@ -2052,21 +2080,11 @@ app.post('/api/getFile', optionalJwt, function (req, res) {
var file = null ;
if ( req . isAuthenticated ( ) ) {
file = auth _api . getUserVideo ( req . user . uid , uid , type );
file = auth _api . getUserVideo ( req . user . uid , uid );
} else if ( uuid ) {
file = auth _api . getUserVideo ( uuid , uid , type , true ) ;
file = auth _api . getUserVideo ( uuid , uid , true ) ;
} else {
if ( ! type ) {
file = db . get ( 'files.audio' ) . find ( { uid : uid } ) . value ( ) ;
if ( ! file ) {
file = db . get ( 'files.video' ) . find ( { uid : uid } ) . value ( ) ;
if ( file ) type = 'video' ;
} else {
type = 'audio' ;
}
}
if ( ! file && type ) file = db . get ( ` files. ${ type } ` ) . find ( { uid : uid } ) . value ( ) ;
file = db . get ( 'files' ) . find ( { uid : uid } ) . value ( ) ;
}
// check if chat exists for twitch videos
@ -2086,32 +2104,20 @@ app.post('/api/getFile', optionalJwt, function (req, res) {
app . post ( '/api/getAllFiles' , optionalJwt , async function ( req , res ) {
// these are returned
let files = [ ] ;
let playlists = [ ] ;
let subscription _files = [ ] ;
let videos = null ;
let audios = null ;
let audio _playlists = null ;
let video _playlists = null ;
let files = null ;
let playlists = null ;
let subscriptions = config _api . getConfigItem ( 'ytdl_allow_subscriptions' ) ? ( subscriptions _api . getAllSubscriptions ( req . isAuthenticated ( ) ? req . user . uid : null ) ) : [ ] ;
// get basic info depending on multi-user mode being enabled
if ( req . isAuthenticated ( ) ) {
videos = auth _api . getUserVideos ( req . user . uid , 'video' ) ;
audios = auth _api . getUserVideos ( req . user . uid , 'audio' ) ;
audio _playlists = auth _api . getUserPlaylists ( req . user . uid , 'audio' ) ;
video _playlists = auth _api . getUserPlaylists ( req . user . uid , 'video' ) ;
files = auth _api . getUserVideos ( req . user . uid ) ;
playlists = auth _api . getUserPlaylists ( req . user . uid ) ;
} else {
videos = db . get ( 'files.audio' ) . value ( ) ;
audios = db . get ( 'files.video' ) . value ( ) ;
audio _playlists = db . get ( 'playlists.audio' ) . value ( ) ;
video _playlists = db . get ( 'playlists.video' ) . value ( ) ;
files = db . get ( 'files' ) . value ( ) ;
playlists = db . get ( 'playlists' ) . value ( ) ;
}
files = videos . concat ( audios ) ;
playlists = video _playlists . concat ( audio _playlists ) ;
// loop through subscriptions and add videos
for ( let i = 0 ; i < subscriptions . length ; i ++ ) {
sub = subscriptions [ i ] ;
@ -2187,14 +2193,13 @@ app.post('/api/downloadTwitchChatByVODID', optionalJwt, async (req, res) => {
// video sharing
app . post ( '/api/enableSharing' , optionalJwt , function ( req , res ) {
var type = req . body . type ;
var uid = req . body . uid ;
var is _playlist = req . body . is _playlist ;
let success = false ;
// multi-user mode
if ( req . isAuthenticated ( ) ) {
// if multi user mode, use this method instead
success = auth _api . changeSharingMode ( req . user . uid , uid , type, is_playlist , true ) ;
success = auth _api . changeSharingMode ( req . user . uid , uid , is_playlist , true ) ;
res . send ( { success : success } ) ;
return ;
}
@ -2203,12 +2208,12 @@ app.post('/api/enableSharing', optionalJwt, function(req, res) {
try {
success = true ;
if ( ! is _playlist && type !== 'subscription' ) {
db . get ( ` files .${ type } ` )
db . get ( ` files ` )
. find ( { uid : uid } )
. assign ( { sharingEnabled : true } )
. write ( ) ;
} else if ( is _playlist ) {
db . get ( ` playlists .${ type } ` )
db . get ( ` playlists ` )
. find ( { id : uid } )
. assign ( { sharingEnabled : true } )
. write ( ) ;
@ -2237,7 +2242,7 @@ app.post('/api/disableSharing', optionalJwt, function(req, res) {
// multi-user mode
if ( req . isAuthenticated ( ) ) {
// if multi user mode, use this method instead
success = auth _api . changeSharingMode ( req . user . uid , uid , type, is_playlist , false ) ;
success = auth _api . changeSharingMode ( req . user . uid , uid , is_playlist , false ) ;
res . send ( { success : success } ) ;
return ;
}
@ -2246,12 +2251,12 @@ app.post('/api/disableSharing', optionalJwt, function(req, res) {
try {
success = true ;
if ( ! is _playlist && type !== 'subscription' ) {
db . get ( ` files .${ type } ` )
db . get ( ` files ` )
. find ( { uid : uid } )
. assign ( { sharingEnabled : false } )
. write ( ) ;
} else if ( is _playlist ) {
db . get ( ` playlists .${ type } ` )
db . get ( ` playlists ` )
. find ( { id : uid } )
. assign ( { sharingEnabled : false } )
. write ( ) ;
@ -2544,7 +2549,7 @@ app.post('/api/createPlaylist', optionalJwt, async (req, res) => {
if ( req . isAuthenticated ( ) ) {
auth _api . addPlaylist ( req . user . uid , new _playlist , type ) ;
} else {
db . get ( ` playlists .${ type } ` )
db . get ( ` playlists ` )
. push ( new _playlist )
. write ( ) ;
}
@ -2558,26 +2563,15 @@ app.post('/api/createPlaylist', optionalJwt, async (req, res) => {
app . post ( '/api/getPlaylist' , optionalJwt , async ( req , res ) => {
let playlistID = req . body . playlistID ;
let type = req . body . type ;
let uuid = req . body . uuid ;
let playlist = null ;
if ( req . isAuthenticated ( ) ) {
playlist = auth _api . getUserPlaylist ( uuid ? uuid : req . user . uid , playlistID , type );
playlist = auth _api . getUserPlaylist ( uuid ? uuid : req . user . uid , playlistID );
type = playlist . type ;
} else {
if ( ! type ) {
playlist = db . get ( 'playlists.audio' ) . find ( { id : playlistID } ) . value ( ) ;
if ( ! playlist ) {
playlist = db . get ( 'playlists.video' ) . find ( { id : playlistID } ) . value ( ) ;
if ( playlist ) type = 'video' ;
} else {
type = 'audio' ;
}
}
if ( ! playlist ) playlist = db . get ( ` playlists. ${ type } ` ) . find ( { id : playlistID } ) . value ( ) ;
playlist = db . get ( ` playlists ` ) . find ( { id : playlistID } ) . value ( ) ;
}
res . send ( {
@ -2590,14 +2584,13 @@ app.post('/api/getPlaylist', optionalJwt, async (req, res) => {
app . post ( '/api/updatePlaylistFiles' , optionalJwt , async ( req , res ) => {
let playlistID = req . body . playlistID ;
let fileNames = req . body . fileNames ;
let type = req . body . type ;
let success = false ;
try {
if ( req . isAuthenticated ( ) ) {
auth _api . updatePlaylistFiles ( req . user . uid , playlistID , fileNames , type );
auth _api . updatePlaylistFiles ( req . user . uid , playlistID , fileNames );
} else {
db . get ( ` playlists .${ type } ` )
db . get ( ` playlists ` )
. find ( { id : playlistID } )
. assign ( { fileNames : fileNames } )
. write ( ) ;
@ -2623,15 +2616,14 @@ app.post('/api/updatePlaylist', optionalJwt, async (req, res) => {
app . post ( '/api/deletePlaylist' , optionalJwt , async ( req , res ) => {
let playlistID = req . body . playlistID ;
let type = req . body . type ;
let success = null ;
try {
if ( req . isAuthenticated ( ) ) {
auth _api . removePlaylist ( req . user . uid , playlistID , type );
auth _api . removePlaylist ( req . user . uid , playlistID );
} else {
// removes playlist from playlists
db . get ( ` playlists .${ type } ` )
db . get ( ` playlists ` )
. remove ( { id : playlistID } )
. write ( ) ;
}
@ -2653,23 +2645,23 @@ app.post('/api/deleteFile', optionalJwt, async (req, res) => {
var blacklistMode = req . body . blacklistMode ;
if ( req . isAuthenticated ( ) ) {
let success = auth _api . deleteUserFile ( req . user . uid , uid , type, blacklistMode) ;
let success = auth _api . deleteUserFile ( req . user . uid , uid , blacklistMode) ;
res . send ( success ) ;
return ;
}
var file _obj = db . get ( ` files .${ type } ` ) . find ( { uid : uid } ) . value ( ) ;
var file _obj = db . get ( ` files ` ) . find ( { uid : uid } ) . value ( ) ;
var name = file _obj . id ;
var fullpath = file _obj ? file _obj . path : null ;
var wasDeleted = false ;
if ( await fs . pathExists ( fullpath ) )
{
wasDeleted = type === 'audio' ? await deleteAudioFile ( name , path . basename ( fullpath ) , blacklistMode ) : await deleteVideoFile ( name , path . basename ( fullpath ) , blacklistMode ) ;
db . get ( 'files .video ') . remove ( { uid : uid } ) . write ( ) ;
db . get ( 'files ') . remove ( { uid : uid } ) . write ( ) ;
// wasDeleted = true;
res . send ( wasDeleted ) ;
} else if ( video _obj ) {
db . get ( 'files .video ') . remove ( { uid : uid } ) . write ( ) ;
db . get ( 'files ') . remove ( { uid : uid } ) . write ( ) ;
wasDeleted = true ;
res . send ( wasDeleted ) ;
} else {