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 113 114 115 116 117 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | // tslint:disable-next-line:no-var-requires
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;
/**
* the function to determine the target file name having the sourece file name.
* If the file should not be downloaded, return an empty string
* @param {SourceTargetFileNames} fileNames source and target file names
*/
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 the client
* @param {DownloadFolderCommandOptions} options constructor options
*/
constructor(client: Client, options: DownloadFolderCommandOptions) {
super(client);
this.sourceFolder = options.sourceFolder;
this.getTargetFileNameBeforeDownload = options.getTargetFileNameBeforeDownload;
this.filterFile = options.filterFile;
this.bytesDownloaded = 0;
}
/**
* execute the command
* @async
* @returns {Promise<void>}
*/
protected async onExecute(): Promise<void> {
this.status = CommandStatus.running;
const writeFile = util.promisify(fs.writeFile);
const mkdir = util.promisify(fs.mkdir);
try {
// determine all files to download
// it is assumed that this command will use 20% of the time
const command: GetFilesRecursivelyCommand =
new GetFilesRecursivelyCommand(this.client,
{ sourceFolder: this.sourceFolder, filterFile: this.filterFile });
command.execute();
// check the processing status as long as the command is running
while (command.isFinished() !== true) {
// wait a bit
this.percentCompleted = command.getPercentCompleted() / 5; // 20%
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: File[] = command.getFiles();
let bytesToDownload: number = 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: Buffer = await file.getContent();
const path: string = 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;
Iif (this.resultMetaData.errors.length > 0) {
this.status = CommandStatus.failed;
} else {
this.status = CommandStatus.success;
}
return;
};
public getBytesDownloaded(): number {
return this.bytesDownloaded;
}
}
|