@ -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' )
@ -79,7 +79,7 @@ const logger = winston.createLogger({
} ) ;
config _api . initialize ( logger ) ;
auth _api . initialize ( users_db , logger ) ;
auth _api . initialize ( db, users_db , logger ) ;
db _api . initialize ( db , users _db , logger ) ;
subscriptions _api . initialize ( db , users _db , logger , db _api ) ;
categories _api . initialize ( db , users _db , logger , db _api ) ;
@ -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 : [ ] ,
@ -216,6 +210,20 @@ async function checkMigrations() {
else { logger . error ( 'Migration failed: 3.5->3.6+' ) ; }
}
// 4.1->4.2 migration
const simplified _db _migration _complete = db . get ( 'simplified_db_migration_complete' ) . value ( ) ;
if ( ! simplified _db _migration _complete ) {
logger . info ( 'Beginning migration: 4.1->4.2+' )
let success = await simplifyDBFileStructure ( ) ;
success = success && await addMetadataPropertyToDB ( 'view_count' ) ;
success = success && await addMetadataPropertyToDB ( 'description' ) ;
success = success && await addMetadataPropertyToDB ( 'height' ) ;
success = success && await addMetadataPropertyToDB ( 'abr' ) ;
if ( success ) { logger . info ( '4.1->4.2+ migration complete!' ) ; }
else { logger . error ( 'Migration failed: 4.1->4.2+' ) ; }
}
return true ;
}
@ -251,6 +259,65 @@ async function runFilesToDBMigration() {
}
}
async function simplifyDBFileStructure ( ) {
// back up db files
const old _db _file = fs . readJSONSync ( './appdata/db.json' ) ;
const old _users _db _file = fs . readJSONSync ( './appdata/users.json' ) ;
fs . writeJSONSync ( 'appdata/db.old.json' , old _db _file ) ;
fs . writeJSONSync ( 'appdata/users.old.json' , old _users _db _file ) ;
// simplify
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' ) . value ( ) ) ;
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' ) . value ( ) ) ;
db . assign ( { playlists : playlists } ) . write ( ) ;
}
return true ;
}
async function addMetadataPropertyToDB ( property _key ) {
try {
const dirs _to _check = db _api . getFileDirectoriesAndDBs ( ) ;
for ( const dir _to _check of dirs _to _check ) {
// recursively get all files in dir's path
const files = await utils . getDownloadedFilesByType ( dir _to _check . basePath , dir _to _check . type , true ) ;
for ( const file of files ) {
if ( file [ property _key ] ) {
dir _to _check . dbPath . find ( { id : file . id } ) . assign ( { [ property _key ] : file [ property _key ] } ) . write ( ) ;
}
}
}
// sets migration to complete
db . set ( 'simplified_db_migration_complete' , true ) . write ( ) ;
return true ;
} catch ( err ) {
logger . error ( err ) ;
return false ;
}
}
async function startServer ( ) {
if ( process . env . USING _HEROKU && process . env . PORT ) {
// default to heroku port if using heroku
@ -560,11 +627,17 @@ 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 ( ) ;
// get subscriptions
if ( allowSubscriptions ) {
// set downloading to false
let subscriptions = subscriptions _api . getAllSubscriptions ( ) ;
subscriptions _api . updateSubscriptionPropertyMultiple ( subscriptions , { downloading : false } ) ;
// runs initially, then runs every ${subscriptionCheckInterval} seconds
watchSubscriptions ( ) ;
setInterval ( ( ) => {
@ -574,9 +647,6 @@ async function loadConfig() {
db _api . importUnregisteredFiles ( ) ;
// check migrations
await checkMigrations ( ) ;
// load in previous downloads
downloads = db . get ( 'downloads' ) . value ( ) ;
@ -626,27 +696,20 @@ function calculateSubcriptionRetrievalDelay(subscriptions_amount) {
}
async function watchSubscriptions ( ) {
let subscriptions = null ;
const multiUserMode = config _api . getConfigItem ( 'ytdl_multi_user_mode' ) ;
if ( multiUserMode ) {
subscriptions = [ ] ;
let users = users _db . get ( 'users' ) . value ( ) ;
for ( let i = 0 ; i < users . length ; i ++ ) {
if ( users [ i ] [ 'subscriptions' ] ) subscriptions = subscriptions . concat ( users [ i ] [ 'subscriptions' ] ) ;
}
} else {
subscriptions = subscriptions _api . getAllSubscriptions ( ) ;
}
let subscriptions = subscriptions _api . getAllSubscriptions ( ) ;
if ( ! subscriptions ) return ;
let subscriptions _amount = subscriptions . length ;
const valid _subscriptions = subscriptions . filter ( sub => ! sub . paused ) ;
let subscriptions _amount = valid _subscriptions . length ;
let delay _interval = calculateSubcriptionRetrievalDelay ( subscriptions _amount ) ;
let current _delay = 0 ;
for ( let i = 0 ; i < subscriptions . length ; i ++ ) {
let sub = subscriptions [ i ] ;
const multiUserMode = config _api . getConfigItem ( 'ytdl_multi_user_mode' ) ;
for ( let i = 0 ; i < valid _subscriptions . length ; i ++ ) {
let sub = valid _subscriptions [ i ] ;
// don't check the sub if the last check for the same subscription has not completed
if ( subscription _timeouts [ sub . id ] ) {
@ -700,64 +763,6 @@ function generateEnvVarConfigItem(key) {
return { key : key , value : process [ 'env' ] [ key ] } ;
}
async function getMp3s ( ) {
let mp3s = [ ] ;
var files = await utils . recFindByExt ( audioFolderPath , 'mp3' ) ; // fs.readdirSync(audioFolderPath);
for ( let i = 0 ; i < files . length ; i ++ ) {
let file = files [ i ] ;
var file _path = file . substring ( audioFolderPath . length , file . length ) ;
var stats = await fs . stat ( file ) ;
var id = file _path . substring ( 0 , file _path . length - 4 ) ;
var jsonobj = await utils . getJSONMp3 ( id , audioFolderPath ) ;
if ( ! jsonobj ) continue ;
var title = jsonobj . title ;
var url = jsonobj . webpage _url ;
var uploader = jsonobj . uploader ;
var upload _date = jsonobj . upload _date ;
upload _date = upload _date ? ` ${ upload _date . substring ( 0 , 4 ) } - ${ upload _date . substring ( 4 , 6 ) } - ${ upload _date . substring ( 6 , 8 ) } ` : null ;
var size = stats . size ;
var thumbnail = jsonobj . thumbnail ;
var duration = jsonobj . duration ;
var isaudio = true ;
var file _obj = new utils . File ( id , title , thumbnail , isaudio , duration , url , uploader , size , file , upload _date ) ;
mp3s . push ( file _obj ) ;
}
return mp3s ;
}
async function getMp4s ( relative _path = true ) {
let mp4s = [ ] ;
var files = await utils . recFindByExt ( videoFolderPath , 'mp4' ) ;
for ( let i = 0 ; i < files . length ; i ++ ) {
let file = files [ i ] ;
var file _path = file . substring ( videoFolderPath . length , file . length ) ;
var stats = fs . statSync ( file ) ;
var id = file _path . substring ( 0 , file _path . length - 4 ) ;
var jsonobj = await utils . getJSONMp4 ( id , videoFolderPath ) ;
if ( ! jsonobj ) continue ;
var title = jsonobj . title ;
var url = jsonobj . webpage _url ;
var uploader = jsonobj . uploader ;
var upload _date = jsonobj . upload _date ;
upload _date = upload _date ? ` ${ upload _date . substring ( 0 , 4 ) } - ${ upload _date . substring ( 4 , 6 ) } - ${ upload _date . substring ( 6 , 8 ) } ` : null ;
var thumbnail = jsonobj . thumbnail ;
var duration = jsonobj . duration ;
var size = stats . size ;
var isaudio = false ;
var file _obj = new utils . File ( id , title , thumbnail , isaudio , duration , url , uploader , size , file , upload _date ) ;
mp4s . push ( file _obj ) ;
}
return mp4s ;
}
function getThumbnailMp3 ( name )
{
var obj = utils . getJSONMp3 ( name , audioFolderPath ) ;
@ -1121,10 +1126,10 @@ async function downloadFileByURL_exec(url, type, options, sessionID = null) {
// get video info prior to download
let info = await getVideoInfoByURL ( url , downloadConfig , download ) ;
if ( ! info ) {
if ( ! info && url . includes ( 'youtu' ) ) {
resolve ( false ) ;
return ;
} else {
} else if ( info ) {
// check if it fits into a category. If so, then get info again using new downloadConfig
category = await categories _api . categorize ( info ) ;
@ -1217,7 +1222,7 @@ async function downloadFileByURL_exec(url, type, options, sessionID = null) {
const customPath = options . noRelativePath ? path . dirname ( full _file _path ) . split ( path . sep ) . pop ( ) : null ;
// registers file in DB
file _uid = db _api . registerFileDB ( file _path , type , multiUserMode , null , customPath );
file _uid = db _api . registerFileDB ( file _path , type , multiUserMode , null , customPath , category );
if ( file _name ) file _names . push ( file _name ) ;
}
@ -1937,8 +1942,8 @@ 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 playlists = db . get ( 'playlists .audio ') . value ( ) ;
var mp3s = db . get ( 'files ') . value ( ) .filter ( file => file . isAudio === true ) ;
var playlists = db . get ( 'playlists ') . value ( ) ;
const is _authenticated = req . isAuthenticated ( ) ;
if ( is _authenticated ) {
// get user audio files/playlists
@ -1949,12 +1954,6 @@ app.get('/api/getMp3s', optionalJwt, async function(req, res) {
mp3s = JSON . parse ( JSON . stringify ( mp3s ) ) ;
if ( config _api . getConfigItem ( 'ytdl_include_thumbnail' ) ) {
// add thumbnails if present
// await addThumbnails(mp3s);
}
res . send ( {
mp3s : mp3s ,
playlists : playlists
@ -1963,8 +1962,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 ') . value ( ) .filter ( file => file . isAudio === false ) ;
var playlists = db . get ( 'playlists ') . value ( ) ;
const is _authenticated = req . isAuthenticated ( ) ;
if ( is _authenticated ) {
@ -1976,11 +1975,6 @@ app.get('/api/getMp4s', optionalJwt, async function(req, res) {
mp4s = JSON . parse ( JSON . stringify ( mp4s ) ) ;
if ( config _api . getConfigItem ( 'ytdl_include_thumbnail' ) ) {
// add thumbnails if present
// await addThumbnails(mp4s);
}
res . send ( {
mp4s : mp4s ,
playlists : playlists
@ -1995,21 +1989,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
@ -2029,32 +2013,47 @@ 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 files = null ;
let playlists = null ;
let videos = null ;
let audios = null ;
let audio _playlists = null ;
let video _playlists = null ;
let subscriptions = config _api . getConfigItem ( 'ytdl_allow_subscriptions' ) ? ( subscriptions _api . getAllSubscriptions ( req . isAuthenticated ( ) ? req . user . uid : null ) ) : [ ] ;
let subscriptions = config _api . getConfigItem ( 'ytdl_allow_subscriptions' ) ? ( subscriptions _api . getSubscriptions ( 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 , files ) ;
} 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 = JSON . parse ( JSON . stringify ( db . get ( 'playlists' ) . value ( ) ) ) ;
const categories = db . get ( 'categories' ) . value ( ) ;
if ( categories ) {
categories . forEach ( category => {
const audio _files = files && files . filter ( file => file . category && file . category . uid === category . uid && file . isAudio ) ;
const video _files = files && files . filter ( file => file . category && file . category . uid === category . uid && ! file . isAudio ) ;
if ( audio _files && audio _files . length > 0 ) {
playlists . push ( {
name : category [ 'name' ] ,
thumbnailURL : audio _files [ 0 ] . thumbnailURL ,
thumbnailPath : audio _files [ 0 ] . thumbnailPath ,
fileNames : audio _files . map ( file => file . id ) ,
type : 'audio' ,
auto : true
} ) ;
}
if ( video _files && video _files . length > 0 ) {
playlists . push ( {
name : category [ 'name' ] ,
thumbnailURL : video _files [ 0 ] . thumbnailURL ,
thumbnailPath : video _files [ 0 ] . thumbnailPath ,
fileNames : video _files . map ( file => file . id ) ,
type : 'video' ,
auto : true
} ) ;
}
} ) ;
}
}
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 ] ;
@ -2122,14 +2121,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 ;
}
@ -2138,12 +2136,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 ( ) ;
@ -2172,7 +2170,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 ;
}
@ -2181,12 +2179,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 ( ) ;
@ -2207,6 +2205,27 @@ app.post('/api/disableSharing', optionalJwt, function(req, res) {
} ) ;
} ) ;
app . post ( '/api/incrementViewCount' , optionalJwt , async ( req , res ) => {
let file _uid = req . body . file _uid ;
let sub _id = req . body . sub _id ;
let uuid = req . body . uuid ;
if ( ! uuid && req . isAuthenticated ( ) ) {
uuid = req . user . uid ;
}
const file _obj = await db _api . getVideo ( file _uid , uuid , sub _id ) ;
const current _view _count = file _obj && file _obj [ 'local_view_count' ] ? file _obj [ 'local_view_count' ] : 0 ;
const new _view _count = current _view _count + 1 ;
await db _api . setVideoProperty ( file _uid , { local _view _count : new _view _count } , uuid , sub _id ) ;
res . send ( {
success : true
} ) ;
} ) ;
// categories
app . post ( '/api/getAllCategories' , optionalJwt , async ( req , res ) => {
@ -2399,7 +2418,7 @@ app.post('/api/getSubscription', optionalJwt, async (req, res) => {
var size = stats . size ;
var isaudio = false ;
var file _obj = new utils . File ( id , title , thumbnail , isaudio , duration , url , uploader , size , file , upload _date );
var file _obj = new utils . File ( id , title , thumbnail , isaudio , duration , url , uploader , size , file , upload _date , jsonobj . description , jsonobj . view _count , jsonobj . height , jsonobj . abr );
parsed _files . push ( file _obj ) ;
}
} else {
@ -2421,7 +2440,7 @@ app.post('/api/getSubscription', optionalJwt, async (req, res) => {
if ( subscription . videos ) {
for ( let i = 0 ; i < subscription . videos . length ; i ++ ) {
const video = subscription . videos [ i ] ;
parsed _files . push ( new utils . File ( video . title , video . title , video . thumbnail , false , video . duration , video . url , video . uploader , video . size , null , null , video . upload _date )) ;
parsed _files . push ( new utils . File ( video . title , video . title , video . thumbnail , false , video . duration , video . url , video . uploader , video . size , null , null , video . upload _date , video . view _count , video . height , video . abr )) ;
}
}
res . send ( {
@ -2454,11 +2473,11 @@ app.post('/api/updateSubscription', optionalJwt, async (req, res) => {
} ) ;
} ) ;
app . post ( '/api/get All Subscriptions', optionalJwt , async ( req , res ) => {
app . post ( '/api/get Subscriptions', optionalJwt , async ( req , res ) => {
let user _uid = req . isAuthenticated ( ) ? req . user . uid : null ;
// get subs from api
let subscriptions = subscriptions _api . get All Subscriptions( user _uid ) ;
let subscriptions = subscriptions _api . get Subscriptions( user _uid ) ;
res . send ( {
subscriptions : subscriptions
@ -2485,7 +2504,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 ( ) ;
}
@ -2499,31 +2518,19 @@ 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 ) ;
type = playlist . type ;
playlist = auth _api . getUserPlaylist ( uuid ? uuid : req . user . uid , playlistID ) ;
} 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 ( {
playlist : playlist ,
type : type,
type : playlist && playlist . type ,
success : ! ! playlist
} ) ;
} ) ;
@ -2531,14 +2538,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 ( ) ;
@ -2564,15 +2570,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 ( ) ;
}
@ -2594,23 +2599,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 = await 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 ( ) ;
// wasDeleted = true;
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 {
@ -2746,7 +2751,7 @@ app.get('/api/stream/:id', optionalJwt, (req, res) => {
var head ;
let optionalParams = url _api . parse ( req . url , true ) . query ;
let id = decodeURIComponent ( req . params . id ) ;
let file _path = req . query . file _path ? decodeURIComponent ( req . query . file _path ) : null ;
let file _path = req . query . file _path ? decodeURIComponent ( req . query . file _path .split ( '?' ) [ 0 ] ) : null ;
if ( ! file _path && ( req . isAuthenticated ( ) || req . can _watch ) ) {
let usersFileFolder = config _api . getConfigItem ( 'ytdl_users_base_path' ) ;
if ( optionalParams [ 'subName' ] ) {
@ -2763,7 +2768,7 @@ app.get('/api/stream/:id', optionalJwt, (req, res) => {
}
if ( ! file _path ) {
file _path = path . join ( videoFolderPath, id + ext ) ;
file _path = path . join ( type === 'audio' ? audioFolderPath : videoFolderPath, id + ext ) ;
}
const stat = fs . statSync ( file _path )