const debug = require ( "debug" ) . debug ( "DownloadFilesCommand" ) ; import Client , { File , Folder , SourceTargetFileNames , CommandStatus , GetFilesRecursivelyCommand , } from "../client" ; import util from "util" ; import fs from "fs" ; import Command from "./command" ; /**
 * options to create a download folder command
 */ export interface DownloadFolderCommandOptions { /**
     * The source folder with the file structure to be downloaded
     */ sourceFolder : Folder ; /**
     * function to filter files
     */ filterFile ? : ( file : File ) => File | null ; param { SourceTargetFileNames } fileNames getTargetFileNameBeforeDownload : ( fileNames : SourceTargetFileNames ) => string ; } /**
 * Command to download the contents of a folder from nextcloud to local file system recursively
 */ export default class DownloadFolderCommand extends Command { private sourceFolder : Folder ; private getTargetFileNameBeforeDownload : ( fileNames : SourceTargetFileNames ) => string ; private bytesDownloaded : number ; private filterFile ? : ( file : File ) => File | null ; param { Client } client param { DownloadFolderCommandOptions } options constructor ( client , options ) { super ( client ) ; this . sourceFolder = options . sourceFolder ; this . getTargetFileNameBeforeDownload = options . getTargetFileNameBeforeDownload ; this . filterFile = options . filterFile ; this . bytesDownloaded = 0 ; } async returns { Promise < void > } protected async onExecute ( ) { this . status = CommandStatus . running ; const writeFile = util . promisify ( fs . writeFile ) ; const mkdir = util . promisify ( fs . mkdir ) ; try { const command = new GetFilesRecursivelyCommand ( this . client , { sourceFolder : this . sourceFolder , filterFile : this . filterFile } ) ; command . execute ( ) ; while ( command . isFinished ( ) !== true ) { this . percentCompleted = command . getPercentCompleted ( ) / 5 ; await ( async ( ) => { return new Promise ( resolve => setTimeout ( resolve , 100 ) ) ; } ) ( ) ; } this . resultMetaData . messages . concat ( command . getResultMetaData ( ) . messages ) ; this . resultMetaData . errors . concat ( command . getResultMetaData ( ) . errors ) ; const files = command . getFiles ( ) ; let bytesToDownload = 0 ; for ( const file of files ) { bytesToDownload += file . size ; } for ( const file of files ) { const targetFileName = this . getTargetFileNameBeforeDownload ( { sourceFileName : file . name , targetFileName : "." + file . name } ) ; const content = await file . getContent ( ) ; const path = targetFileName . substring ( 0 , targetFileName . lastIndexOf ( "/" ) ) ; await mkdir ( path , { recursive : true } ) ; await writeFile ( targetFileName , content ) ; this . bytesDownloaded += file . size ; this . percentCompleted = ( this . bytesDownloaded / bytesToDownload * 80 ) + 20 ; } this . resultMetaData . messages . push ( files . length + " files downloaded" ) ; } catch ( e ) { debug ( e . message ) ; this . resultMetaData . errors . push ( e . message ) ; } this . percentCompleted = 100 ; if ( this . resultMetaData . errors . length > 0 ) { this . status = CommandStatus . failed ; } else { this . status = CommandStatus . success ; } return ; } ; public getBytesDownloaded ( ) { return this . bytesDownloaded ; } }