All files / src/command uploadFolderCommand.ts

97.83% Statements 45/46
100% Branches 4/4
85.71% Functions 6/7
97.62% Lines 41/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112  1x   1x                 1x                                           1x                       6x 6x 6x 6x 4x   14x   6x                 6x 6x 6x 6x 6x   1x 1x 1x 1x 1x 1x     5x 5x 70x   70x 56x       5x 5x 5x     5x 65x 65x 65x 65x   65x     5x 5x 5x 5x 5x              
// tslint:disable-next-line:no-var-requires
const debug = require("debug").debug("UploadFolderCommand");
 
import Client,
{
    File,
    FileSystemFolder,
    IFileNameFormats,
    UploadFilesCommand,
    UploadFilesCommandOptions,
    SourceTargetFileNames,
} from "../client";
import Command, { CommandStatus } from "./command";
 
/**
 * options to create a upload folder command
 */
export interface UploadFolderCommandOptions {
    /**
     * The name of the source folder with the file structure to be uploaded
     */
    folderName: string;
    /**
     * the function to determine the target file name having the sourece file name.
     * If the file should not be uploaded, return an empty string
     * @param {SourceTargetFileNames} fileNames
     */
    getTargetFileNameBeforeUpload?: (fileNames: SourceTargetFileNames) => string;
    processFileAfterUpload?: (file: File) => Promise<void>;
}
 
/**
 * Command to upload the contents of a folder from local file system to nextcloud recursively
 */
export default class UploadFolderCommand extends Command {
    private folderName: string;
    private processFileAfterUpload?: (file: File) => Promise<void>;
    private getTargetFileNameBeforeUpload: (fileNames: SourceTargetFileNames) => string;
    private bytesUploaded: number;
 
    /**
     * @param {Client} client the client
     * @param {ISourceTargetFileNames[]} files the files to be uploaded
     * @param {(file: File) => void} processAfterUpload callback function to process the uploaded file
     */
    constructor(client: Client, options: UploadFolderCommandOptions) {
        super(client);
        this.folderName = options.folderName;
        this.processFileAfterUpload = options.processFileAfterUpload;
        if (options.getTargetFileNameBeforeUpload) {
            this.getTargetFileNameBeforeUpload = options.getTargetFileNameBeforeUpload;
        } else {
            this.getTargetFileNameBeforeUpload = (fileNames: SourceTargetFileNames): string => { return fileNames.targetFileName };
        }
        this.bytesUploaded = 0;
    }
 
    /**
     * execute the command
     * @async
     * @returns {Promise<void>}
     */
    protected async onExecute(): Promise<void> {
        this.status = CommandStatus.running;
        let fileNames: IFileNameFormats[] = [];
        const fsf: FileSystemFolder = new FileSystemFolder(this.folderName);
        try {
            fileNames = await fsf.getFileNames();
        } catch (e) {
            this.resultMetaData.errors.push(e);
            this.status = CommandStatus.failed;
            this.percentCompleted = 100;
            this.bytesUploaded = 0;
            this.resultMetaData.timeElapsed = 0;
            return;
        }
 
        const files: SourceTargetFileNames[] = [];
        for (const fileNameFormat of fileNames) {
            const targetFileName = this.getTargetFileNameBeforeUpload({ sourceFileName: fileNameFormat.absolute, targetFileName: fileNameFormat.relative });
            // add only files with a target name
            if (targetFileName !== "") {
                files.push({ sourceFileName: fileNameFormat.absolute, targetFileName });
            }
        }
 
        const options: UploadFilesCommandOptions = { files, processFileAfterUpload: this.processFileAfterUpload };
        const uc: UploadFilesCommand = new UploadFilesCommand(this.client, options);
        uc.execute();
 
        // check the processing status
        while (uc.isFinished() !== true) {
            this.status = uc.getStatus();
            this.percentCompleted = uc.getPercentCompleted();
            this.resultMetaData = uc.getResultMetaData();
            this.bytesUploaded = uc.getBytesUploaded();
            // wait one second
            await (async () => { return new Promise(resolve => setTimeout(resolve, 1000)) })();
        }
 
        this.status = uc.getStatus();
        this.percentCompleted = uc.getPercentCompleted();
        this.resultMetaData = uc.getResultMetaData();
        this.bytesUploaded = uc.getBytesUploaded();
        return;
    };
    public getBytesUploaded(): number {
        return this.bytesUploaded;
    }
 
}