import downloadUtils = require ( './utils' ) ; import drive = require ( '../fs-walk' ) ; const Aria2 = require ( 'aria2' ) ; import constants = require ( '../.constants' ) ; import tar = require ( '../drive/tar' ) ; const diskspace = require ( 'diskspace' ) ; import filenameUtils = require ( './filename-utils' ) ; import { DlVars } from '../dl_model/detail' ; const ariaOptions = { host : 'localhost' , port : constants . ARIA_PORT ? constants . ARIA_PORT : 8210 , secure : false , secret : constants . ARIA_SECRET , path : '/jsonrpc' } ; const aria2 = new Aria2 ( ariaOptions ) ; export function openWebsocket ( callback ) { aria2 . open ( ) . then ( ( ) => { callback ( null ) ; } ) . catch ( ( err ) => { callback ( err ) ; } ) ; } export function setOnDownloadStart ( callback ) { aria2 . onDownloadStart = ( keys ) => { callback ( keys . gid , 1 ) ; } ; } export function setOnDownloadStop ( callback ) { aria2 . onDownloadStop = ( keys ) => { callback ( keys . gid , 1 ) ; } ; } export function setOnDownloadComplete ( callback ) { aria2 . onDownloadComplete = ( keys ) => { callback ( keys . gid , 1 ) ; } ; } export function setOnDownloadError ( callback ) { aria2 . onDownloadError = ( keys ) => { callback ( keys . gid , 1 ) ; } ; } export function getAriaFilePath ( gid , callback ) { aria2 . getFiles ( gid , ( err , files ) => { if ( err ) { callback ( err . message , null ) ; } else { var filePath = filenameUtils . findAriaFilePath ( files ) ; if ( filePath ) { callback ( null , filePath . path ) ; } else { callback ( null , null ) ; } } } ) ; } param { string } gid param { function } callback export function getStatus ( dlDetails , callback ) { aria2 . tellStatus ( dlDetails . gid , [ 'status' , 'totalLength' , 'completedLength' , 'downloadSpeed' , 'files' ] , ( err , res ) => { if ( err ) { callback ( err . message , null , null , null ) ; } else if ( res . status === 'active' ) { var statusMessage = downloadUtils . generateStatusMessage ( parseFloat ( res . totalLength ) , parseFloat ( res . completedLength ) , parseFloat ( res . downloadSpeed ) , res . files , false ) ; callback ( null , statusMessage . message , statusMessage . filename , statusMessage . filesize ) ; } else if ( dlDetails . isUploading ) { var downloadSpeed ; var time = new Date ( ) . getTime ( ) ; if ( ! dlDetails . lastUploadCheckTimestamp ) { downloadSpeed = 0 ; } else { downloadSpeed = ( dlDetails . uploadedBytes - dlDetails . uploadedBytesLast ) / ( ( time - dlDetails . lastUploadCheckTimestamp ) / 1000 ) ; } dlDetails . uploadedBytesLast = dlDetails . uploadedBytes ; dlDetails . lastUploadCheckTimestamp = time ; var statusMessage = downloadUtils . generateStatusMessage ( parseFloat ( res . totalLength ) , dlDetails . uploadedBytes , downloadSpeed , res . files , true ) ; callback ( null , statusMessage . message , statusMessage . filename , statusMessage . filesize ) ; } else { var filePath = filenameUtils . findAriaFilePath ( res [ 'files' ] ) ; var filename = filenameUtils . getFileNameFromPath ( filePath . path , filePath . inputPath , filePath . downloadUri ) ; var message ; if ( res . status === 'waiting' ) { message = `<i>${ filename }</i> - Queued` ; } else { message = `<i>${ filename }</i> - ${ res . status }` ; } callback ( null , message , filename , '0B' ) ; } } ) ; } export function getError ( gid , callback ) { aria2 . tellStatus ( gid , [ 'errorMessage' ] , ( err , res ) => { if ( err ) { callback ( err . message , null ) ; } else { callback ( null , res . errorMessage ) ; } } ) ; } export function isDownloadMetadata ( gid , callback ) { aria2 . tellStatus ( gid , [ 'followedBy' ] , ( err , res ) => { if ( err ) { callback ( err . message , null , null ) ; } else { if ( res . followedBy ) { callback ( null , true , res . followedBy [ 0 ] ) ; } else { callback ( null , false , null ) ; } } } ) ; } export function getFileSize ( gid , callback ) { aria2 . tellStatus ( gid , [ 'totalLength' ] , ( err , res ) => { if ( err ) { callback ( err . message , res ) ; } else { callback ( null , res [ 'totalLength' ] ) ; } } ) ; } interface DriveUploadCompleteCallback { ( err , gid , url , filePath , fileName , fileSize , isFolder ) : void ; } param { dlVars . DlVars } dlDetails param { string } filePath param { number } fileSize param { function } callback export function uploadFile ( dlDetails , filePath , fileSize , callback ) { dlDetails . isUploading = true ; var fileName = filenameUtils . getFileNameFromPath ( filePath , null ) ; var realFilePath = filenameUtils . getActualDownloadPath ( filePath ) ; if ( dlDetails . isTar ) { if ( filePath === realFilePath ) { driveUploadFile ( dlDetails , realFilePath , fileName , fileSize , callback ) ; } else { diskspace . check ( constants . ARIA_DOWNLOAD_LOCATION_ROOT , ( err , res ) => { if ( err ) { console . log ( 'uploadFile: diskspace: ' + err ) ; driveUploadFile ( dlDetails , realFilePath , fileName , fileSize , callback ) ; return ; } if ( res [ 'free' ] > fileSize ) { console . log ( 'Starting archival' ) ; var destName = fileName + '.tar' ; tar . archive ( realFilePath , destName , ( err , size ) => { if ( err ) { callback ( err , dlDetails . gid , null , null , null , null , false ) ; } else { console . log ( 'Archive complete' ) ; driveUploadFile ( dlDetails , realFilePath + '.tar' , destName , size , callback ) ; } } ) ; } else { console . log ( 'uploadFile: Not enough space, uploading without archiving' ) ; driveUploadFile ( dlDetails , realFilePath , fileName , fileSize , callback ) ; } } ) ; } } else { driveUploadFile ( dlDetails , realFilePath , fileName , fileSize , callback ) ; } } function driveUploadFile ( dlDetails , filePath , fileName , fileSize , callback ) { drive . uploadRecursive ( dlDetails , filePath , constants . GDRIVE_PARENT_DIR_ID , ( err , url , isFolder ) => { callback ( err , dlDetails . gid , url , filePath , fileName , fileSize , isFolder ) ; } ) ; } export function stopDownload ( gid , callback ) { aria2 . remove ( gid , callback ) ; } export function addUri ( uri , dlDir , callback ) { aria2 . addUri ( [ uri ] , { dir : `${ constants . ARIA_DOWNLOAD_LOCATION }/${ dlDir }` } ) . then ( ( gid ) => { callback ( null , gid ) ; } ) . catch ( ( err ) => { callback ( err , null ) ; } ) ; }