MOBILE-2235 h5p: Delete index files when updating libs

main
Dani Palou 2019-11-25 15:05:49 +01:00
parent ea2aa48d77
commit d5e12fb136
4 changed files with 92 additions and 16 deletions

View File

@ -15,6 +15,7 @@
import { Component, Input, ElementRef, OnInit, OnDestroy, OnChanges, SimpleChange } from '@angular/core'; import { Component, Input, ElementRef, OnInit, OnDestroy, OnChanges, SimpleChange } from '@angular/core';
import { CoreAppProvider } from '@providers/app'; import { CoreAppProvider } from '@providers/app';
import { CoreEventsProvider } from '@providers/events'; import { CoreEventsProvider } from '@providers/events';
import { CoreFileProvider } from '@providers/file';
import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreLoggerProvider } from '@providers/logger'; import { CoreLoggerProvider } from '@providers/logger';
import { CoreSitesProvider } from '@providers/sites'; import { CoreSitesProvider } from '@providers/sites';
@ -62,7 +63,8 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
protected eventsProvider: CoreEventsProvider, protected eventsProvider: CoreEventsProvider,
protected appProvider: CoreAppProvider, protected appProvider: CoreAppProvider,
protected domUtils: CoreDomUtilsProvider, protected domUtils: CoreDomUtilsProvider,
protected pluginFileDelegate: CorePluginFileDelegate) { protected pluginFileDelegate: CorePluginFileDelegate,
protected fileProvider: CoreFileProvider) {
this.logger = loggerProvider.getInstance('CoreH5PPlayerComponent'); this.logger = loggerProvider.getInstance('CoreH5PPlayerComponent');
this.siteId = sitesProvider.getCurrentSiteId(); this.siteId = sitesProvider.getCurrentSiteId();
@ -103,8 +105,19 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
if (this.canDownload && (this.state == CoreConstants.DOWNLOADED || this.state == CoreConstants.OUTDATED)) { if (this.canDownload && (this.state == CoreConstants.DOWNLOADED || this.state == CoreConstants.OUTDATED)) {
// Package is downloaded, use the local URL. // Package is downloaded, use the local URL.
promise = this.h5pProvider.getContentIndexFileUrl(this.urlParams.url).catch((error) => { promise = this.h5pProvider.getContentIndexFileUrl(this.urlParams.url, this.siteId).catch(() => {
// It seems there was something wrong when creating the index file. Delete the package?
// Index file doesn't exist, probably deleted because a lib was updated. Try to create it again.
return this.filepoolProvider.getInternalUrlByUrl(this.siteId, this.urlParams.url).then((path) => {
return this.fileProvider.getFile(path);
}).then((file) => {
return this.h5pProvider.extractH5PFile(this.urlParams.url, file, this.siteId);
}).then(() => {
// File treated. Try to get the index file URL again.
return this.h5pProvider.getContentIndexFileUrl(this.urlParams.url, this.siteId);
});
}).catch((error) => {
// Still failing. Delete the H5P package?
this.logger.error('Error loading downloaded index:', error, this.src); this.logger.error('Error loading downloaded index:', error, this.src);
}); });
} else { } else {

View File

@ -25,6 +25,7 @@ import { CoreMimetypeUtilsProvider } from '@providers/utils/mimetype';
import { CoreUrlUtilsProvider } from '@providers/utils/url'; import { CoreUrlUtilsProvider } from '@providers/utils/url';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreH5PUtilsProvider } from './utils'; import { CoreH5PUtilsProvider } from './utils';
import { FileEntry } from '@ionic-native/file';
/** /**
* Service to provide H5P functionalities. * Service to provide H5P functionalities.
@ -279,6 +280,11 @@ export class CoreH5PProvider {
name: 'hash', name: 'hash',
type: 'TEXT', type: 'TEXT',
notNull: true notNull: true
},
{
name: 'foldername',
type: 'TEXT',
notNull: true
} }
] ]
} }
@ -566,7 +572,8 @@ export class CoreH5PProvider {
db.deleteRecords(this.CONTENT_TABLE), db.deleteRecords(this.CONTENT_TABLE),
db.deleteRecords(this.LIBRARIES_TABLE), db.deleteRecords(this.LIBRARIES_TABLE),
db.deleteRecords(this.LIBRARY_DEPENDENCIES_TABLE), db.deleteRecords(this.LIBRARY_DEPENDENCIES_TABLE),
db.deleteRecords(this.CONTENTS_LIBRARIES_TABLE) db.deleteRecords(this.CONTENTS_LIBRARIES_TABLE),
db.deleteRecords(this.LIBRARIES_CACHEDASSETS_TABLE)
]); ]);
}); });
} }
@ -575,15 +582,13 @@ export class CoreH5PProvider {
* Delete cached assets from DB and filesystem. * Delete cached assets from DB and filesystem.
* *
* @param libraryId Library identifier. * @param libraryId Library identifier.
* @param folderName Name of the folder of the H5P package.
* @param siteId Site ID. If not defined, current site. * @param siteId Site ID. If not defined, current site.
* @return Promise resolved when done. * @return Promise resolved when done.
*/ */
protected deleteCachedAssets(libraryId: number, folderName: string, siteId?: string): Promise<any> { protected deleteCachedAssets(libraryId: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => { return this.sitesProvider.getSite(siteId).then((site) => {
const db = site.getDb(), const db = site.getDb();
cachedAssetsFolder = this.getCachedAssetsFolderPath(folderName, site.getId());
// Get all the hashes that use this library. // Get all the hashes that use this library.
return db.getRecords(this.LIBRARIES_CACHEDASSETS_TABLE, {libraryid: libraryId}).then((entries) => { return db.getRecords(this.LIBRARIES_CACHEDASSETS_TABLE, {libraryid: libraryId}).then((entries) => {
@ -594,6 +599,8 @@ export class CoreH5PProvider {
entries.forEach((entry) => { entries.forEach((entry) => {
hashes.push(entry.hash); hashes.push(entry.hash);
const cachedAssetsFolder = this.getCachedAssetsFolderPath(entry.foldername, site.getId());
['js', 'css'].forEach((type) => { ['js', 'css'].forEach((type) => {
const path = this.textUtils.concatenatePaths(cachedAssetsFolder, entry.hash + '.' + type); const path = this.textUtils.concatenatePaths(cachedAssetsFolder, entry.hash + '.' + type);
@ -603,11 +610,6 @@ export class CoreH5PProvider {
}); });
}); });
// Also, delete the index.html file.
promises.push(this.fileProvider.removeFile(this.getContentIndexPath(folderName, site.getId())).catch(() => {
// Ignore errors.
}));
return Promise.all(promises).then(() => { return Promise.all(promises).then(() => {
return db.deleteRecordsList(this.LIBRARIES_CACHEDASSETS_TABLE, 'hash', hashes); return db.deleteRecordsList(this.LIBRARIES_CACHEDASSETS_TABLE, 'hash', hashes);
}); });
@ -636,6 +638,45 @@ export class CoreH5PProvider {
return Promise.all(promises); return Promise.all(promises);
} }
/**
* Delete content indexes from filesystem.
*
* @param libraryId Library identifier.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved when done.
*/
protected deleteContentIndexesForLibrary(libraryId: number, siteId?: string): Promise<any> {
return this.sitesProvider.getSite(siteId).then((site) => {
const db = site.getDb();
// Get the folder names of all the packages that use this library.
const query = 'SELECT DISTINCT hc.foldername ' +
'FROM ' + this.CONTENTS_LIBRARIES_TABLE + ' hcl ' +
'JOIN ' + this.CONTENT_TABLE + ' hc ON hcl.h5pid = hc.id ' +
'WHERE hcl.libraryid = ?',
queryArgs = [];
queryArgs.push(libraryId);
return db.execute(query, queryArgs).then((result) => {
const promises = [];
for (let i = 0; i < result.rows.length; i++) {
const entry = result.rows.item(i);
// Delete the index.html file.
promises.push(this.fileProvider.removeFile(this.getContentIndexPath(entry.foldername, site.getId()))
.catch(() => {
// Ignore errors.
}));
}
return Promise.all(promises);
});
});
}
/** /**
* Delete library data from DB. * Delete library data from DB.
* *
@ -1796,6 +1837,27 @@ export class CoreH5PProvider {
}); });
} }
/**
* Performs actions required when a library has been installed.
*
* @param libraryId ID of library that was installed.
* @param siteId Site ID.
* @return Promise resolved when done.
*/
protected libraryInstalled(libraryId: number, siteId: string): Promise<any> {
const promises = [];
// Remove all indexes of contents that use this library.
promises.push(this.deleteContentIndexesForLibrary(libraryId, siteId));
if (this.aggregateAssets) {
// Remove cached assets that use this library.
promises.push(this.deleteCachedAssets(libraryId, siteId));
}
return this.utils.allPromises(promises);
}
/** /**
* Writes library data as string on the form {machineName} {majorVersion}.{minorVersion}. * Writes library data as string on the form {machineName} {majorVersion}.{minorVersion}.
* *
@ -2198,9 +2260,8 @@ export class CoreH5PProvider {
}); });
}); });
}).then(() => { }).then(() => {
// Remove cached assets that use this library. if (typeof libraryData.libraryId != 'undefined') {
if (this.aggregateAssets && typeof libraryData.libraryId != 'undefined') { return this.libraryInstalled(libraryData.libraryId, siteId);
return this.deleteCachedAssets(libraryData.libraryId, folderName, siteId);
} }
}); });
})); }));

View File

@ -21,6 +21,7 @@ import { CoreUrlUtilsProvider } from '@providers/utils/url';
import { CoreUtilsProvider } from '@providers/utils/utils'; import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreH5PProvider } from './h5p'; import { CoreH5PProvider } from './h5p';
import { CoreWSExternalFile } from '@providers/ws'; import { CoreWSExternalFile } from '@providers/ws';
import { FileEntry } from '@ionic-native/file';
/** /**
* Handler to treat H5P files. * Handler to treat H5P files.

View File

@ -15,6 +15,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreLoggerProvider } from './logger'; import { CoreLoggerProvider } from './logger';
import { CoreWSExternalFile } from '@providers/ws'; import { CoreWSExternalFile } from '@providers/ws';
import { FileEntry } from '@ionic-native/file';
/** /**
* Interface that all plugin file handlers must implement. * Interface that all plugin file handlers must implement.