MOBILE-3437 files: Ignore downloaded files on prefetch calculations
parent
4f9adba63e
commit
2052080673
|
@ -28,6 +28,7 @@ import { CoreGroupsProvider } from '@providers/groups';
|
|||
import { AddonModFeedbackSyncProvider } from './sync';
|
||||
import { CoreFilterHelperProvider } from '@core/filter/providers/helper';
|
||||
import { CorePluginFileDelegate } from '@providers/plugin-file-delegate';
|
||||
import { CoreWSExternalFile } from '@providers/ws';
|
||||
|
||||
/**
|
||||
* Handler to prefetch feedbacks.
|
||||
|
@ -68,26 +69,31 @@ export class AddonModFeedbackPrefetchHandler extends CoreCourseActivityPrefetchH
|
|||
* @param single True if we're downloading a single module, false if we're downloading a whole section.
|
||||
* @return Promise resolved with the list of files.
|
||||
*/
|
||||
getFiles(module: any, courseId: number, single?: boolean): Promise<any[]> {
|
||||
async getFiles(module: any, courseId: number, single?: boolean): Promise<CoreWSExternalFile[]> {
|
||||
let files = [];
|
||||
|
||||
return this.feedbackProvider.getFeedback(courseId, module.id).then((feedback) => {
|
||||
const feedback = await this.feedbackProvider.getFeedback(courseId, module.id);
|
||||
|
||||
// Get intro files and page after submit files.
|
||||
files = feedback.pageaftersubmitfiles || [];
|
||||
files = files.concat(this.getIntroFilesFromInstance(module, feedback));
|
||||
|
||||
return this.feedbackProvider.getItems(feedback.id);
|
||||
}).then((response) => {
|
||||
try {
|
||||
const response = await this.feedbackProvider.getItems(feedback.id);
|
||||
|
||||
response.items.forEach((item) => {
|
||||
files = files.concat(item.itemfiles);
|
||||
files = files.concat(item.itemfiles.map((file) => {
|
||||
file.fileurl = file.fileurl || file.url;
|
||||
|
||||
return file;
|
||||
}));
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
||||
return files;
|
||||
}).catch(() => {
|
||||
// Any error, return the list we have.
|
||||
return files;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,7 +103,7 @@ export class AddonModFeedbackPrefetchHandler extends CoreCourseActivityPrefetchH
|
|||
* @param courseId Course ID.
|
||||
* @return Promise resolved with list of intro files.
|
||||
*/
|
||||
getIntroFiles(module: any, courseId: number): Promise<any[]> {
|
||||
getIntroFiles(module: any, courseId: number): Promise<CoreWSExternalFile[]> {
|
||||
return this.feedbackProvider.getFeedback(courseId, module.id).catch(() => {
|
||||
// Not found, return undefined so module description is used.
|
||||
}).then((feedback) => {
|
||||
|
|
|
@ -111,7 +111,7 @@ export class AddonModLessonPrefetchHandler extends CoreCourseActivityPrefetchHan
|
|||
let files = lesson.mediafiles || [];
|
||||
files = files.concat(this.getIntroFilesFromInstance(module, lesson));
|
||||
|
||||
return this.pluginFileDelegate.getFilesSize(files);
|
||||
return this.pluginFileDelegate.getFilesDownloadSize(files);
|
||||
}).then((res) => {
|
||||
result = res;
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ export class AddonModWikiPrefetchHandler extends CoreCourseActivityPrefetchHandl
|
|||
siteId = this.sitesProvider.getCurrentSiteId();
|
||||
|
||||
promises.push(this.getFiles(module, courseId, single, siteId).then((files) => {
|
||||
return this.pluginFileDelegate.getFilesSize(files);
|
||||
return this.pluginFileDelegate.getFilesDownloadSize(files);
|
||||
}));
|
||||
|
||||
promises.push(this.getAllPages(module, courseId, false, true, siteId).then((pages) => {
|
||||
|
|
|
@ -19,6 +19,7 @@ import { CoreSitesProvider } from '@providers/sites';
|
|||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||
import { CoreUtilsProvider } from '@providers/utils/utils';
|
||||
import { CoreCourseProvider } from '../providers/course';
|
||||
import { CoreWSExternalFile } from '@providers/ws';
|
||||
import { CoreCourseModulePrefetchHandler } from '../providers/module-prefetch-delegate';
|
||||
import { CoreFilterHelperProvider } from '@core/filter/providers/helper';
|
||||
import { CorePluginFileDelegate } from '@providers/plugin-file-delegate';
|
||||
|
@ -114,7 +115,7 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
|
|||
* @param module The module object returned by WS.
|
||||
* @return List of files.
|
||||
*/
|
||||
getContentDownloadableFiles(module: any): any[] {
|
||||
getContentDownloadableFiles(module: any): CoreWSExternalFile[] {
|
||||
const files = [];
|
||||
|
||||
if (module.contents && module.contents.length) {
|
||||
|
@ -139,7 +140,7 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
|
|||
*/
|
||||
getDownloadSize(module: any, courseId: number, single?: boolean): Promise<{ size: number, total: boolean }> {
|
||||
return this.getFiles(module, courseId).then((files) => {
|
||||
return this.pluginFileDelegate.getFilesSize(files);
|
||||
return this.pluginFileDelegate.getFilesDownloadSize(files);
|
||||
}).catch(() => {
|
||||
return { size: -1, total: false };
|
||||
});
|
||||
|
@ -166,7 +167,7 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
|
|||
* @param single True if we're downloading a single module, false if we're downloading a whole section.
|
||||
* @return Promise resolved with the list of files.
|
||||
*/
|
||||
getFiles(module: any, courseId: number, single?: boolean): Promise<any[]> {
|
||||
getFiles(module: any, courseId: number, single?: boolean): Promise<CoreWSExternalFile[]> {
|
||||
// To be overridden.
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
@ -179,7 +180,7 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
|
|||
* @param ignoreCache True if it should ignore cached data (it will always fail in offline or server down).
|
||||
* @return Promise resolved with list of intro files.
|
||||
*/
|
||||
getIntroFiles(module: any, courseId: number, ignoreCache?: boolean): Promise<any[]> {
|
||||
getIntroFiles(module: any, courseId: number, ignoreCache?: boolean): Promise<CoreWSExternalFile[]> {
|
||||
return Promise.resolve(this.getIntroFilesFromInstance(module));
|
||||
}
|
||||
|
||||
|
@ -190,7 +191,7 @@ export class CoreCourseModulePrefetchHandlerBase implements CoreCourseModulePref
|
|||
* @param instance The instance to get the intro files (book, assign, ...). If not defined, module will be used.
|
||||
* @return List of intro files.
|
||||
*/
|
||||
getIntroFilesFromInstance(module: any, instance?: any): any[] {
|
||||
getIntroFilesFromInstance(module: any, instance?: any): CoreWSExternalFile[] {
|
||||
if (instance) {
|
||||
if (typeof instance.introfiles != 'undefined') {
|
||||
return instance.introfiles;
|
||||
|
|
|
@ -1397,7 +1397,7 @@ export class CoreFilepoolProvider {
|
|||
* @param html HTML code.
|
||||
* @return List of fake file objects with file URLs.
|
||||
*/
|
||||
extractDownloadableFilesFromHtmlAsFakeFileObjects(html: string): any[] {
|
||||
extractDownloadableFilesFromHtmlAsFakeFileObjects(html: string): CoreWSExternalFile[] {
|
||||
const urls = this.extractDownloadableFilesFromHtml(html);
|
||||
|
||||
// Convert them to fake file objects.
|
||||
|
@ -1768,46 +1768,50 @@ export class CoreFilepoolProvider {
|
|||
* @param revision File revision. If not defined, it will be calculated using the URL.
|
||||
* @return Promise resolved with the file state.
|
||||
*/
|
||||
getFileStateByUrl(siteId: string, fileUrl: string, timemodified: number = 0, filePath?: string, revision?: number)
|
||||
async getFileStateByUrl(siteId: string, fileUrl: string, timemodified: number = 0, filePath?: string, revision?: number)
|
||||
: Promise<string> {
|
||||
let fileId;
|
||||
let file;
|
||||
|
||||
return this.fixPluginfileURL(siteId, fileUrl, timemodified).then((file) => {
|
||||
try {
|
||||
file = await this.fixPluginfileURL(siteId, fileUrl, timemodified);
|
||||
} catch (e) {
|
||||
return CoreConstants.NOT_DOWNLOADABLE;
|
||||
}
|
||||
|
||||
fileUrl = file.fileurl;
|
||||
timemodified = file.timemodified || timemodified;
|
||||
revision = revision || this.getRevisionFromUrl(fileUrl);
|
||||
fileId = this.getFileIdByUrl(fileUrl);
|
||||
const fileId = this.getFileIdByUrl(fileUrl);
|
||||
|
||||
try {
|
||||
// Check if the file is in queue (waiting to be downloaded).
|
||||
return this.hasFileInQueue(siteId, fileId).then(() => {
|
||||
return CoreConstants.DOWNLOADING;
|
||||
}).catch(() => {
|
||||
// Check if the file is being downloaded right now.
|
||||
const extension = this.mimeUtils.guessExtensionFromUrl(fileUrl),
|
||||
path = filePath ? filePath : this.getFilePath(siteId, fileId, extension);
|
||||
await this.hasFileInQueue(siteId, fileId);
|
||||
|
||||
return CoreConstants.DOWNLOADING;
|
||||
} catch (e) {
|
||||
// Check if the file is being downloaded right now.
|
||||
const extension = this.mimeUtils.guessExtensionFromUrl(fileUrl);
|
||||
filePath = filePath || (await this.getFilePath(siteId, fileId, extension));
|
||||
|
||||
return Promise.resolve(path).then((filePath) => {
|
||||
const downloadId = this.getFileDownloadId(fileUrl, filePath);
|
||||
|
||||
if (this.filePromises[siteId] && this.filePromises[siteId][downloadId]) {
|
||||
return CoreConstants.DOWNLOADING;
|
||||
}
|
||||
|
||||
try {
|
||||
// File is not being downloaded. Check if it's downloaded and if it's outdated.
|
||||
return this.hasFileInPool(siteId, fileId).then((entry) => {
|
||||
const entry = await this.hasFileInPool(siteId, fileId);
|
||||
|
||||
if (this.isFileOutdated(entry, revision, timemodified)) {
|
||||
return CoreConstants.OUTDATED;
|
||||
} else {
|
||||
return CoreConstants.DOWNLOADED;
|
||||
}
|
||||
}).catch(() => {
|
||||
|
||||
return CoreConstants.DOWNLOADED;
|
||||
} catch (e) {
|
||||
return CoreConstants.NOT_DOWNLOADED;
|
||||
});
|
||||
});
|
||||
});
|
||||
}, () => {
|
||||
return CoreConstants.NOT_DOWNLOADABLE;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,8 @@ import { CoreLoggerProvider } from './logger';
|
|||
import { CoreSitesProvider } from './sites';
|
||||
import { CoreWSExternalFile } from '@providers/ws';
|
||||
import { FileEntry } from '@ionic-native/file';
|
||||
import { CoreFilepool } from './filepool';
|
||||
import { CoreConstants } from '@core/constants';
|
||||
import { CoreDelegate, CoreDelegateHandler } from '@classes/delegate';
|
||||
import { makeSingleton } from '@singletons/core.singletons';
|
||||
|
||||
|
@ -234,6 +236,27 @@ export class CorePluginFileDelegate extends CoreDelegate {
|
|||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sum the filesizes from a list if they are not downloaded.
|
||||
*
|
||||
* @param files List of files to sum its filesize.
|
||||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved with file size and a boolean to indicate if it is the total size or only partial.
|
||||
*/
|
||||
async getFilesDownloadSize(files: CoreWSExternalFile[], siteId?: string): Promise<{ size: number, total: boolean }> {
|
||||
const filteredFiles = [];
|
||||
|
||||
await Promise.all(files.map(async (file) => {
|
||||
const state = await CoreFilepool.instance.getFileStateByUrl(siteId, file.fileurl, file.timemodified);
|
||||
|
||||
if (state != CoreConstants.DOWNLOADED && state != CoreConstants.NOT_DOWNLOADABLE) {
|
||||
filteredFiles.push(file);
|
||||
}
|
||||
}));
|
||||
|
||||
return this.getFilesSize(filteredFiles, siteId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sum the filesizes from a list of files checking if the size will be partial or totally calculated.
|
||||
*
|
||||
|
@ -241,15 +264,15 @@ export class CorePluginFileDelegate extends CoreDelegate {
|
|||
* @param siteId Site ID. If not defined, current site.
|
||||
* @return Promise resolved with file size and a boolean to indicate if it is the total size or only partial.
|
||||
*/
|
||||
getFilesSize(files: CoreWSExternalFile[], siteId?: string): Promise<{ size: number, total: boolean }> {
|
||||
const promises = [],
|
||||
result = {
|
||||
async getFilesSize(files: CoreWSExternalFile[], siteId?: string): Promise<{ size: number, total: boolean }> {
|
||||
const result = {
|
||||
size: 0,
|
||||
total: true
|
||||
};
|
||||
|
||||
files.forEach((file) => {
|
||||
promises.push(this.getFileSize(file, siteId).then((size) => {
|
||||
await Promise.all(files.map(async (file) => {
|
||||
const size = await this.getFileSize(file, siteId);
|
||||
|
||||
if (typeof size == 'undefined') {
|
||||
// We don't have the file size, cannot calculate its total size.
|
||||
result.total = false;
|
||||
|
@ -257,11 +280,8 @@ export class CorePluginFileDelegate extends CoreDelegate {
|
|||
result.size += size;
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
return Promise.all(promises).then(() => {
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue