MOBILE-2261 core: Support progress in download/upload/unzip

main
Dani Palou 2017-11-17 14:20:19 +01:00
parent 8e32938a1e
commit 39a1623f8d
3 changed files with 36 additions and 21 deletions

View File

@ -694,14 +694,15 @@ export class CoreFileProvider {
* @param {string} path Path to the ZIP file. * @param {string} path Path to the ZIP file.
* @param {string} [destFolder] Path to the destination folder. If not defined, a new folder will be created with the * @param {string} [destFolder] Path to the destination folder. If not defined, a new folder will be created with the
* same location and name as the ZIP file (without extension). * same location and name as the ZIP file (without extension).
* @param {Function} [onProgress] Function to call on progress.
* @return {Promise<any>} Promise resolved when the file is unzipped. * @return {Promise<any>} Promise resolved when the file is unzipped.
*/ */
unzipFile(path: string, destFolder?: string) : Promise<any> { unzipFile(path: string, destFolder?: string, onProgress?: Function) : Promise<any> {
// Get the source file. // Get the source file.
return this.getFile(path).then((fileEntry) => { return this.getFile(path).then((fileEntry) => {
// If destFolder is not set, use same location as ZIP file. We need to use absolute paths (including basePath). // If destFolder is not set, use same location as ZIP file. We need to use absolute paths (including basePath).
destFolder = this.addBasePathIfNeeded(destFolder || this.mimeUtils.removeExtension(path)); destFolder = this.addBasePathIfNeeded(destFolder || this.mimeUtils.removeExtension(path));
return this.zip.unzip(fileEntry.toURL(), destFolder); return this.zip.unzip(fileEntry.toURL(), destFolder, onProgress);
}); });
} }

View File

@ -23,6 +23,12 @@ import { CoreLoggerProvider } from '../logger';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreLangProvider } from '../lang'; import { CoreLangProvider } from '../lang';
export interface PromiseDefer {
promise?: Promise<any>; // Promise created.
resolve?: (value?: any) => any; // Function to resolve the promise.
reject?: (reason?: any) => any; // Function to reject the promise.
}
/* /*
* "Utils" service with helper functions. * "Utils" service with helper functions.
*/ */
@ -966,12 +972,12 @@ export class CoreUtilsProvider {
} }
/** /**
* Similar to AngularJS $q.defer(). It will return an object containing the promise, and the resolve and reject functions. * Similar to AngularJS $q.defer().
* *
* @return {any} Object containing the promise, and the resolve and reject functions. * @return {PromiseDefer} The deferred promise.
*/ */
promiseDefer() : any { promiseDefer() : PromiseDefer {
let deferred: any = {}; let deferred: PromiseDefer = {};
deferred.promise = new Promise((resolve, reject) => { deferred.promise = new Promise((resolve, reject) => {
deferred.resolve = resolve; deferred.resolve = resolve;
deferred.reject = reject; deferred.reject = reject;

View File

@ -85,9 +85,9 @@ export class CoreWSProvider {
* @param {string} siteUrl Complete site url to perform the call. * @param {string} siteUrl Complete site url to perform the call.
* @param {any} ajaxData Arguments to pass to the method. * @param {any} ajaxData Arguments to pass to the method.
* @param {CoreWSPreSets} preSets Extra settings and information. * @param {CoreWSPreSets} preSets Extra settings and information.
* @return {Promise} Deferrend promise resolved with the response data in success and rejected with the error message if it fails. * @return {Promise<any>} Deferred promise resolved with the response data in success and rejected with the error message if it fails.
*/ */
protected addToRetryQueue(method: string, siteUrl: string, ajaxData: any, preSets: CoreWSPreSets) { protected addToRetryQueue(method: string, siteUrl: string, ajaxData: any, preSets: CoreWSPreSets) : Promise<any> {
let call = { let call = {
method: method, method: method,
siteUrl: siteUrl, siteUrl: siteUrl,
@ -106,9 +106,9 @@ export class CoreWSProvider {
* @param {string} method The WebService method to be called. * @param {string} method The WebService method to be called.
* @param {any} data Arguments to pass to the method. It's recommended to call convertValuesToString before passing the data. * @param {any} data Arguments to pass to the method. It's recommended to call convertValuesToString before passing the data.
* @param {CoreWSPreSets} preSets Extra settings and information. * @param {CoreWSPreSets} preSets Extra settings and information.
* @return {Promise} Promise resolved with the response data in success and rejected with the error message if it fails. * @return {Promise<any>} Promise resolved with the response data in success and rejected if it fails.
*/ */
call(method: string, data: any, preSets: CoreWSPreSets) { call(method: string, data: any, preSets: CoreWSPreSets) : Promise<any> {
let siteUrl; let siteUrl;
@ -148,12 +148,12 @@ export class CoreWSProvider {
* @param {string} method The WebService method to be called. * @param {string} method The WebService method to be called.
* @param {any} data Arguments to pass to the method. * @param {any} data Arguments to pass to the method.
* @param {CoreWSAjaxPreSets} preSets Extra settings and information. Only some * @param {CoreWSAjaxPreSets} preSets Extra settings and information. Only some
* @return {Promise} Promise resolved with the response data in success and rejected with an object containing: * @return {Promise<any>} Promise resolved with the response data in success and rejected with an object containing:
* - error: Error message. * - error: Error message.
* - errorcode: Error code returned by the site (if any). * - errorcode: Error code returned by the site (if any).
* - available: 0 if unknown, 1 if available, -1 if not available. * - available: 0 if unknown, 1 if available, -1 if not available.
*/ */
callAjax(method: string, data: any, preSets: CoreWSAjaxPreSets) { callAjax(method: string, data: any, preSets: CoreWSAjaxPreSets) : Promise<any> {
let siteUrl, let siteUrl,
ajaxData; ajaxData;
@ -275,10 +275,11 @@ export class CoreWSProvider {
* *
* @param {string} url Download url. * @param {string} url Download url.
* @param {string} path Local path to store the file. * @param {string} path Local path to store the file.
* @param {boolean} addExtension True if extension need to be added to the final path. * @param {boolean} [addExtension] True if extension need to be added to the final path.
* @return {Promise<FileEntry>} Promise resolved with the downloaded file. * @param {Function} [onProgress] Function to call on progress.
* @return {Promise<any>} Promise resolved with the downloaded file.
*/ */
downloadFile(url: string, path: string, addExtension?: boolean) : Promise<FileEntry> { downloadFile(url: string, path: string, addExtension?: boolean, onProgress?: (event: ProgressEvent) => any) : Promise<any> {
this.logger.debug('Downloading file', url, path, addExtension); this.logger.debug('Downloading file', url, path, addExtension);
if (!this.appProvider.isOnline()) { if (!this.appProvider.isOnline()) {
@ -292,6 +293,8 @@ export class CoreWSProvider {
// Create the tmp file as an empty file. // Create the tmp file as an empty file.
return this.fileProvider.createFile(tmpPath).then((fileEntry) => { return this.fileProvider.createFile(tmpPath).then((fileEntry) => {
let transfer = this.fileTransfer.create(); let transfer = this.fileTransfer.create();
transfer.onProgress(onProgress);
return transfer.download(url, fileEntry.toURL(), true).then(() => { return transfer.download(url, fileEntry.toURL(), true).then(() => {
let promise; let promise;
@ -335,7 +338,7 @@ export class CoreWSProvider {
}); });
}); });
}).catch((err) => { }).catch((err) => {
this.logger.error(`Error downloading ${url} to ${path}`, JSON.stringify(err)); this.logger.error(`Error downloading ${url} to ${path}`, err);
return Promise.reject(err); return Promise.reject(err);
}); });
} }
@ -387,7 +390,7 @@ export class CoreWSProvider {
* Perform a HEAD request to get the size of a remote file. * Perform a HEAD request to get the size of a remote file.
* *
* @param {string} url File URL. * @param {string} url File URL.
* @return {Promise} Promise resolved with the size or -1 if failure. * @return {Promise<number>} Promise resolved with the size or -1 if failure.
*/ */
getRemoteFileSize(url: string) : Promise<number> { getRemoteFileSize(url: string) : Promise<number> {
return this.performHead(url).then((data) => { return this.performHead(url).then((data) => {
@ -409,8 +412,9 @@ export class CoreWSProvider {
* @param {string} method Method of the HTTP request. * @param {string} method Method of the HTTP request.
* @param {string} url Base URL of the HTTP request. * @param {string} url Base URL of the HTTP request.
* @param {object} [params] Params of the HTTP request. * @param {object} [params] Params of the HTTP request.
* @return {string} Queue item ID.
*/ */
protected getQueueItemId(method: string, url: string, params?: any) { protected getQueueItemId(method: string, url: string, params?: any) : string {
if (params) { if (params) {
url += '###' + this.utils.serialize(params); url += '###' + this.utils.serialize(params);
} }
@ -646,9 +650,11 @@ export class CoreWSProvider {
* @param {string} filePath File path. * @param {string} filePath File path.
* @param {CoreWSFileUploadOptions} options File upload options. * @param {CoreWSFileUploadOptions} options File upload options.
* @param {CoreWSPreSets} preSets Must contain siteUrl and wsToken. * @param {CoreWSPreSets} preSets Must contain siteUrl and wsToken.
* @param {Function} [onProgress] Function to call on progress.
* @return {Promise<any>} Promise resolved when uploaded. * @return {Promise<any>} Promise resolved when uploaded.
*/ */
uploadFile(filePath: string, options: CoreWSFileUploadOptions, preSets: CoreWSPreSets) : Promise<any> { uploadFile(filePath: string, options: CoreWSFileUploadOptions, preSets: CoreWSPreSets,
onProgress?: (event: ProgressEvent) => any) : Promise<any> {
this.logger.debug(`Trying to upload file: ${filePath}`); this.logger.debug(`Trying to upload file: ${filePath}`);
if (!filePath || !options || !preSets) { if (!filePath || !options || !preSets) {
@ -662,6 +668,8 @@ export class CoreWSProvider {
let uploadUrl = preSets.siteUrl + '/webservice/upload.php', let uploadUrl = preSets.siteUrl + '/webservice/upload.php',
transfer = this.fileTransfer.create(); transfer = this.fileTransfer.create();
transfer.onProgress(onProgress);
options.httpMethod = 'POST'; options.httpMethod = 'POST';
options.params = { options.params = {
token: preSets.wsToken, token: preSets.wsToken,
@ -700,8 +708,8 @@ export class CoreWSProvider {
// We uploaded only 1 file, so we only return the first file returned. // We uploaded only 1 file, so we only return the first file returned.
this.logger.debug('Successfully uploaded file', filePath); this.logger.debug('Successfully uploaded file', filePath);
return data[0]; return data[0];
}, (error) => { }).catch((error) => {
this.logger.error('Error while uploading file', filePath, error.exception); this.logger.error('Error while uploading file', filePath, error);
return Promise.reject(this.translate.instant('mm.core.errorinvalidresponse')); return Promise.reject(this.translate.instant('mm.core.errorinvalidresponse'));
}); });
} }