MOBILE-3213 files: Refactor files size calculation to avoid network requests

main
Noel De Martin 2019-12-16 12:40:47 +01:00
parent fb1096381e
commit 826c9a0f30
3 changed files with 79 additions and 87 deletions

View File

@ -14,11 +14,8 @@
// limitations under the License. // limitations under the License.
import { Injectable, Injector } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { CoreFileProvider } from '@providers/file';
import { CoreFileSessionProvider } from '@providers/file-session'; import { CoreFileSessionProvider } from '@providers/file-session';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFileHelperProvider } from '@providers/file-helper';
import { CoreSitesProvider } from '@providers/sites';
import { CoreWSProvider } from '@providers/ws';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
import { import {
@ -39,11 +36,10 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis
name = 'AddonModAssignSubmissionFileHandler'; name = 'AddonModAssignSubmissionFileHandler';
type = 'file'; type = 'file';
constructor(private sitesProvider: CoreSitesProvider, private wsProvider: CoreWSProvider, constructor(private assignProvider: AddonModAssignProvider, private assignOfflineProvider: AddonModAssignOfflineProvider,
private assignProvider: AddonModAssignProvider, private assignOfflineProvider: AddonModAssignOfflineProvider,
private assignHelper: AddonModAssignHelperProvider, private fileSessionProvider: CoreFileSessionProvider, private assignHelper: AddonModAssignHelperProvider, private fileSessionProvider: CoreFileSessionProvider,
private fileUploaderProvider: CoreFileUploaderProvider, private filepoolProvider: CoreFilepoolProvider, private fileUploaderProvider: CoreFileUploaderProvider, private fileHelper: CoreFileHelperProvider,
private fileProvider: CoreFileProvider, private utils: CoreUtilsProvider) { } private utils: CoreUtilsProvider) { }
/** /**
* Whether the plugin can be edited in offline for existing submissions. In general, this should return false if the * Whether the plugin can be edited in offline for existing submissions. In general, this should return false if the
@ -157,24 +153,9 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis
* @return The size (or promise resolved with size). * @return The size (or promise resolved with size).
*/ */
getSizeForCopy(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin): number | Promise<number> { getSizeForCopy(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin): number | Promise<number> {
const files = this.assignProvider.getSubmissionPluginAttachments(plugin), const files = this.assignProvider.getSubmissionPluginAttachments(plugin);
promises = [];
let totalSize = 0;
files.forEach((file) => { return this.fileHelper.getTotalFilesSize(files);
promises.push(this.wsProvider.getRemoteFileSize(file.fileurl).then((size) => {
if (size == -1) {
// Couldn't determine the size, reject.
return Promise.reject(null);
}
totalSize += size;
}));
});
return Promise.all(promises).then(() => {
return totalSize;
});
} }
/** /**
@ -188,45 +169,11 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis
*/ */
getSizeForEdit(assign: AddonModAssignAssign, submission: AddonModAssignSubmission, getSizeForEdit(assign: AddonModAssignAssign, submission: AddonModAssignSubmission,
plugin: AddonModAssignPlugin, inputData: any): number | Promise<number> { plugin: AddonModAssignPlugin, inputData: any): number | Promise<number> {
const siteId = this.sitesProvider.getCurrentSiteId();
// Check if there's any change. // Check if there's any change.
if (this.hasDataChanged(assign, submission, plugin, inputData)) { if (this.hasDataChanged(assign, submission, plugin, inputData)) {
const files = this.fileSessionProvider.getFiles(AddonModAssignProvider.COMPONENT, assign.id), const files = this.fileSessionProvider.getFiles(AddonModAssignProvider.COMPONENT, assign.id);
promises = [];
let totalSize = 0;
files.forEach((file) => { return this.fileHelper.getTotalFilesSize(files);
if (file.filename && !file.name) {
// It's a remote file. First check if we have the file downloaded since it's more reliable.
promises.push(this.filepoolProvider.getFilePathByUrl(siteId, file.fileurl).then((path) => {
return this.fileProvider.getFile(path).then((fileEntry) => {
return this.fileProvider.getFileObjectFromFileEntry(fileEntry);
}).then((file) => {
totalSize += file.size;
});
}).catch(() => {
// Error getting the file, maybe it's not downloaded. Get remote size.
return this.wsProvider.getRemoteFileSize(file.fileurl).then((size) => {
if (size == -1) {
// Couldn't determine the size, reject.
return Promise.reject(null);
}
totalSize += size;
});
}));
} else if (file.name) {
// It's a local file, get its size.
promises.push(this.fileProvider.getFileObjectFromFileEntry(file).then((file) => {
totalSize += file.size;
}));
}
});
return Promise.all(promises).then(() => {
return totalSize;
});
} else { } else {
// Nothing has changed, we won't upload any file. // Nothing has changed, we won't upload any file.
return 0; return 0;

View File

@ -16,7 +16,7 @@
import { Injectable, Injector } from '@angular/core'; import { Injectable, Injector } from '@angular/core';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
import { CoreWSProvider } from '@providers/ws'; import { CoreFileHelperProvider } from '@providers/file-helper';
import { CoreTextUtilsProvider } from '@providers/utils/text'; import { CoreTextUtilsProvider } from '@providers/utils/text';
import { import {
AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin AddonModAssignProvider, AddonModAssignAssign, AddonModAssignSubmission, AddonModAssignPlugin
@ -34,9 +34,10 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign
name = 'AddonModAssignSubmissionOnlineTextHandler'; name = 'AddonModAssignSubmissionOnlineTextHandler';
type = 'onlinetext'; type = 'onlinetext';
constructor(private translate: TranslateService, private sitesProvider: CoreSitesProvider, private wsProvider: CoreWSProvider, constructor(private translate: TranslateService, private sitesProvider: CoreSitesProvider,
private textUtils: CoreTextUtilsProvider, private assignProvider: AddonModAssignProvider, private fileHelper: CoreFileHelperProvider, private textUtils: CoreTextUtilsProvider,
private assignOfflineProvider: AddonModAssignOfflineProvider, private assignHelper: AddonModAssignHelperProvider) { } private assignProvider: AddonModAssignProvider, private assignOfflineProvider: AddonModAssignOfflineProvider,
private assignHelper: AddonModAssignHelperProvider) { }
/** /**
* Whether the plugin can be edited in offline for existing submissions. In general, this should return false if the * Whether the plugin can be edited in offline for existing submissions. In general, this should return false if the
@ -124,30 +125,13 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign
* @param plugin The plugin object. * @param plugin The plugin object.
* @return The size (or promise resolved with size). * @return The size (or promise resolved with size).
*/ */
getSizeForCopy(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin): number | Promise<number> { async getSizeForCopy(assign: AddonModAssignAssign, plugin: AddonModAssignPlugin): Promise<number> {
const text = this.assignProvider.getSubmissionPluginText(plugin, true), const text = this.assignProvider.getSubmissionPluginText(plugin, true),
files = this.assignProvider.getSubmissionPluginAttachments(plugin), files = this.assignProvider.getSubmissionPluginAttachments(plugin);
promises = [];
let totalSize = text.length;
if (!files.length) { const filesSize = await this.fileHelper.getTotalFilesSize(files);
return totalSize;
}
files.forEach((file) => { return text.length + filesSize;
promises.push(this.wsProvider.getRemoteFileSize(file.fileurl).then((size) => {
if (size == -1) {
// Couldn't determine the size, reject.
return Promise.reject(null);
}
totalSize += size;
}));
});
return Promise.all(promises).then(() => {
return totalSize;
});
} }
/** /**

View File

@ -18,6 +18,7 @@ import { CoreAppProvider } from './app';
import { CoreFileProvider } from './file'; import { CoreFileProvider } from './file';
import { CoreFilepoolProvider } from './filepool'; import { CoreFilepoolProvider } from './filepool';
import { CoreSitesProvider } from './sites'; import { CoreSitesProvider } from './sites';
import { CoreWSProvider } from './ws';
import { CoreUtilsProvider } from './utils/utils'; import { CoreUtilsProvider } from './utils/utils';
import { CoreConstants } from '@core/constants'; import { CoreConstants } from '@core/constants';
@ -29,7 +30,7 @@ export class CoreFileHelperProvider {
constructor(private fileProvider: CoreFileProvider, private filepoolProvider: CoreFilepoolProvider, constructor(private fileProvider: CoreFileProvider, private filepoolProvider: CoreFilepoolProvider,
private sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider, private translate: TranslateService, private sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider, private translate: TranslateService,
private utils: CoreUtilsProvider) { } private utils: CoreUtilsProvider, private wsProvider: CoreWSProvider) { }
/** /**
* Convenience function to open a file, downloading it if needed. * Convenience function to open a file, downloading it if needed.
@ -273,4 +274,64 @@ export class CoreFileHelperProvider {
return false; return false;
} }
/**
* Calculate the total size of the given files.
*
* @param files The files to check.
* @return Total files size.
*/
async getTotalFilesSize(files: any[]): Promise<number> {
let totalSize = 0;
for (const file of files) {
totalSize += await this.getFileSize(file);
}
return totalSize;
}
/**
* Calculate the file size.
*
* @param file The file to check.
* @return File size.
*/
async getFileSize(file: any): Promise<number> {
if (file.filesize) {
return file.filesize;
}
// If it's a remote file. First check if we have the file downloaded since it's more reliable.
if (file.filename && !file.name) {
try {
const siteId = this.sitesProvider.getCurrentSiteId();
const path = await this.filepoolProvider.getFilePathByUrl(siteId, file.fileurl);
const fileEntry = await this.fileProvider.getFile(path);
const fileObject = await this.fileProvider.getFileObjectFromFileEntry(fileEntry);
return fileObject.size;
} catch (error) {
// Error getting the file, maybe it's not downloaded. Get remote size.
const size = await this.wsProvider.getRemoteFileSize(file.fileurl);
if (size === -1) {
throw new Error('Couldn\'t determine file size: ' + file.fileurl);
}
return size;
}
}
// If it's a local file, get its size.
if (file.name) {
const fileObject = await this.fileProvider.getFileObjectFromFileEntry(file);
return fileObject.size;
}
throw new Error('Couldn\'t determine file size: ' + file.fileurl);
}
} }