Merge pull request #4175 from albertgasset/MOBILE-4642
MOBILE-4642 h5p: Prevent partially saved packagesmain
commit
7271ee3c24
|
@ -449,4 +449,43 @@ export class CoreH5PFileStorage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that library is fully saved to the file system.
|
||||||
|
*
|
||||||
|
* @param libraryData Library data.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @returns Promise resolved with true if all library files are present.
|
||||||
|
*/
|
||||||
|
async checkLibrary(libraryData: CoreH5PLibraryBeingSaved, siteId?: string): Promise<boolean> {
|
||||||
|
const getFileNames = async (baseDir: string, dirName = ''): Promise<string[]> => {
|
||||||
|
const entries = await CoreFile.getDirectoryContents( baseDir + dirName);
|
||||||
|
const fileNames: string[] = [];
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
const name = dirName + '/' + entry.name;
|
||||||
|
if (entry.isDirectory) {
|
||||||
|
fileNames.push(...(await getFileNames(baseDir, name)));
|
||||||
|
} else {
|
||||||
|
fileNames.push(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileNames;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!libraryData.uploadDirectory) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
siteId = siteId || CoreSites.getCurrentSiteId();
|
||||||
|
const folderPath = this.getLibraryFolderPath(libraryData, siteId);
|
||||||
|
|
||||||
|
const [sourceFiles, destFiles] = await Promise.all([
|
||||||
|
getFileNames(libraryData.uploadDirectory),
|
||||||
|
getFileNames(folderPath).catch(() => ([])).then(files => new Set(files)),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return sourceFiles.every(name => destFiles.has(name));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,9 @@ export class CoreH5PStorage {
|
||||||
|
|
||||||
const newerPatchVersion = existingLibrary.patchversion < libraryData.patchVersion;
|
const newerPatchVersion = existingLibrary.patchversion < libraryData.patchVersion;
|
||||||
|
|
||||||
if (!newerPatchVersion) {
|
// Make sure the library is fully saved to the file system if it is present in the DB.
|
||||||
|
// Some files might be missing if a previous library update was interrupted.
|
||||||
|
if (!newerPatchVersion && await this.h5pCore.h5pFS.checkLibrary(libraryData, siteId)) {
|
||||||
// Same or older version, no need to save.
|
// Same or older version, no need to save.
|
||||||
libraryData.saveDependencies = false;
|
libraryData.saveDependencies = false;
|
||||||
|
|
||||||
|
@ -79,21 +81,12 @@ export class CoreH5PStorage {
|
||||||
libraryData.metadataSettings = libraryData.metadataSettings ?
|
libraryData.metadataSettings = libraryData.metadataSettings ?
|
||||||
CoreH5PMetadata.boolifyAndEncodeSettings(libraryData.metadataSettings) : undefined;
|
CoreH5PMetadata.boolifyAndEncodeSettings(libraryData.metadataSettings) : undefined;
|
||||||
|
|
||||||
|
// Save the library files before saving to DB, in case the app is closed while copying the files.
|
||||||
|
await this.h5pCore.h5pFS.saveLibrary(libraryData, siteId);
|
||||||
|
|
||||||
// Save the library data in DB.
|
// Save the library data in DB.
|
||||||
await this.h5pFramework.saveLibraryData(libraryData, siteId);
|
await this.h5pFramework.saveLibraryData(libraryData, siteId);
|
||||||
|
|
||||||
// Now save it in FS.
|
|
||||||
try {
|
|
||||||
await this.h5pCore.h5pFS.saveLibrary(libraryData, siteId);
|
|
||||||
} catch (error) {
|
|
||||||
if (libraryData.libraryId) {
|
|
||||||
// An error occurred, delete the DB data because the lib FS data has been deleted.
|
|
||||||
await this.h5pFramework.deleteLibrary(libraryData.libraryId, siteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (libraryData.libraryId !== undefined) {
|
if (libraryData.libraryId !== undefined) {
|
||||||
const promises: Promise<void>[] = [];
|
const promises: Promise<void>[] = [];
|
||||||
|
|
||||||
|
@ -196,21 +189,15 @@ export class CoreH5PStorage {
|
||||||
|
|
||||||
content.params = JSON.stringify(data.contentJsonData);
|
content.params = JSON.stringify(data.contentJsonData);
|
||||||
|
|
||||||
// Save the content data in DB.
|
|
||||||
await this.h5pCore.saveContent(content, folderName, fileUrl, siteId);
|
|
||||||
|
|
||||||
// Save the content files in their right place in FS.
|
// Save the content files in their right place in FS.
|
||||||
const destFolder = CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName);
|
const destFolder = CorePath.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName);
|
||||||
const contentPath = CorePath.concatenatePaths(destFolder, 'content');
|
const contentPath = CorePath.concatenatePaths(destFolder, 'content');
|
||||||
|
|
||||||
try {
|
// Save the content files before saving to DB, in case the app is closed while copying the files.
|
||||||
await this.h5pCore.h5pFS.saveContent(contentPath, folderName, siteId);
|
await this.h5pCore.h5pFS.saveContent(contentPath, folderName, siteId);
|
||||||
} catch (error) {
|
|
||||||
// An error occurred, delete the DB data because the content files have been deleted.
|
|
||||||
await this.h5pFramework.deleteContentData(content.id!, siteId);
|
|
||||||
|
|
||||||
throw error;
|
// Save the content data in DB.
|
||||||
}
|
await this.h5pCore.saveContent(content, folderName, fileUrl, siteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
|
|
Loading…
Reference in New Issue