MOBILE-2235 h5p: Fix issues identified during PeerReview
parent
1a2ea9485f
commit
5dae06ff81
|
@ -1620,6 +1620,7 @@
|
||||||
"core.h5p.originator": "h5p",
|
"core.h5p.originator": "h5p",
|
||||||
"core.h5p.pd": "h5p",
|
"core.h5p.pd": "h5p",
|
||||||
"core.h5p.pddl": "h5p",
|
"core.h5p.pddl": "h5p",
|
||||||
|
"core.h5p.play": "local_moodlemobileapp",
|
||||||
"core.h5p.pdm": "h5p",
|
"core.h5p.pdm": "h5p",
|
||||||
"core.h5p.resizescript": "h5p",
|
"core.h5p.resizescript": "h5p",
|
||||||
"core.h5p.resubmitScores": "h5p",
|
"core.h5p.resubmitScores": "h5p",
|
||||||
|
|
|
@ -172,11 +172,6 @@ export class AddonModScormPrefetchHandler extends CoreCourseActivityPrefetchHand
|
||||||
return this.filepoolProvider.downloadUrl(siteId, packageUrl, true, this.component, scorm.coursemodule,
|
return this.filepoolProvider.downloadUrl(siteId, packageUrl, true, this.component, scorm.coursemodule,
|
||||||
undefined, this.downloadProgress.bind(this, true, onProgress));
|
undefined, this.downloadProgress.bind(this, true, onProgress));
|
||||||
}
|
}
|
||||||
}).then(() => {
|
|
||||||
// Remove the destination folder to prevent having old unused files.
|
|
||||||
return this.fileProvider.removeDir(dirPath).catch(() => {
|
|
||||||
// Ignore errors, it might have failed because the folder doesn't exist.
|
|
||||||
});
|
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
// Get the ZIP file path.
|
// Get the ZIP file path.
|
||||||
return this.filepoolProvider.getFilePathByUrl(siteId, packageUrl);
|
return this.filepoolProvider.getFilePathByUrl(siteId, packageUrl);
|
||||||
|
|
|
@ -148,7 +148,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
if (this.canDownload && (this.state == CoreConstants.OUTDATED || this.state == CoreConstants.NOT_DOWNLOADED)) {
|
if (this.canDownload && (this.state == CoreConstants.OUTDATED || this.state == CoreConstants.NOT_DOWNLOADED)) {
|
||||||
// Download the package in background if the size is low.
|
// Download the package in background if the size is low.
|
||||||
this.downloadInBg().catch((error) => {
|
this.attemptDownloadInBg().catch((error) => {
|
||||||
this.logger.error('Error downloading H5P in background', error);
|
this.logger.error('Error downloading H5P in background', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
*
|
*
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected downloadInBg(): Promise<any> {
|
protected attemptDownloadInBg(): Promise<any> {
|
||||||
if (this.urlParams && this.src && this.siteCanDownload && this.h5pProvider.canGetTrustedH5PFileInSite() &&
|
if (this.urlParams && this.src && this.siteCanDownload && this.h5pProvider.canGetTrustedH5PFileInSite() &&
|
||||||
this.appProvider.isOnline()) {
|
this.appProvider.isOnline()) {
|
||||||
|
|
||||||
|
@ -225,8 +225,6 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
|
|
||||||
if (this.src && this.siteCanDownload && this.h5pProvider.canGetTrustedH5PFileInSite() && this.site.containsUrl(this.src)) {
|
if (this.src && this.siteCanDownload && this.h5pProvider.canGetTrustedH5PFileInSite() && this.site.containsUrl(this.src)) {
|
||||||
|
|
||||||
this.calculating = true;
|
|
||||||
|
|
||||||
this.calculateState();
|
this.calculateState();
|
||||||
|
|
||||||
// Listen for changes in the state.
|
// Listen for changes in the state.
|
||||||
|
@ -238,19 +236,21 @@ export class CoreH5PPlayerComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
// An error probably means the file cannot be downloaded or we cannot check it (offline).
|
// An error probably means the file cannot be downloaded or we cannot check it (offline).
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
} else {
|
||||||
|
this.calculating = false;
|
||||||
|
this.canDownload = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.calculating = false;
|
|
||||||
this.canDownload = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calcuñate state of the file.
|
* Calculate state of the file.
|
||||||
*
|
*
|
||||||
* @param fileUrl The H5P file URL.
|
* @param fileUrl The H5P file URL.
|
||||||
*/
|
*/
|
||||||
protected calculateState(): void {
|
protected calculateState(): void {
|
||||||
|
this.calculating = true;
|
||||||
|
|
||||||
// Get the status of the file.
|
// Get the status of the file.
|
||||||
this.filepoolProvider.getFileStateByUrl(this.siteId, this.urlParams.url).then((state) => {
|
this.filepoolProvider.getFileStateByUrl(this.siteId, this.urlParams.url).then((state) => {
|
||||||
this.canDownload = true;
|
this.canDownload = true;
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CoreEventsProvider } from '@providers/events';
|
|
||||||
import { CoreFileProvider } from '@providers/file';
|
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';
|
||||||
|
@ -81,6 +80,10 @@ export class CoreH5PProvider {
|
||||||
protected siteSchema: CoreSiteSchema = {
|
protected siteSchema: CoreSiteSchema = {
|
||||||
name: 'CoreH5PProvider',
|
name: 'CoreH5PProvider',
|
||||||
version: 1,
|
version: 1,
|
||||||
|
canBeCleared: [
|
||||||
|
this.CONTENT_TABLE, this.LIBRARIES_TABLE, this.LIBRARY_DEPENDENCIES_TABLE, this.CONTENTS_LIBRARIES_TABLE,
|
||||||
|
this.LIBRARIES_CACHEDASSETS_TABLE
|
||||||
|
],
|
||||||
tables: [
|
tables: [
|
||||||
{
|
{
|
||||||
name: this.CONTENT_TABLE,
|
name: this.CONTENT_TABLE,
|
||||||
|
@ -101,10 +104,6 @@ export class CoreH5PProvider {
|
||||||
type: 'INTEGER',
|
type: 'INTEGER',
|
||||||
notNull: true
|
notNull: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: 'displayoptions', // Not used right now, but we keep the field to be consistent with Moodle web.
|
|
||||||
type: 'INTEGER'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'foldername',
|
name: 'foldername',
|
||||||
type: 'TEXT',
|
type: 'TEXT',
|
||||||
|
@ -293,12 +292,11 @@ export class CoreH5PProvider {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
protected ROOT_CACHE_KEY = 'mmH5P:';
|
protected ROOT_CACHE_KEY = 'CoreH5P:';
|
||||||
|
|
||||||
protected logger;
|
protected logger;
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider,
|
constructor(logger: CoreLoggerProvider,
|
||||||
eventsProvider: CoreEventsProvider,
|
|
||||||
private sitesProvider: CoreSitesProvider,
|
private sitesProvider: CoreSitesProvider,
|
||||||
private textUtils: CoreTextUtilsProvider,
|
private textUtils: CoreTextUtilsProvider,
|
||||||
private fileProvider: CoreFileProvider,
|
private fileProvider: CoreFileProvider,
|
||||||
|
@ -312,12 +310,6 @@ export class CoreH5PProvider {
|
||||||
this.logger = logger.getInstance('CoreH5PProvider');
|
this.logger = logger.getInstance('CoreH5PProvider');
|
||||||
|
|
||||||
this.sitesProvider.registerSiteSchema(this.siteSchema);
|
this.sitesProvider.registerSiteSchema(this.siteSchema);
|
||||||
|
|
||||||
eventsProvider.on(CoreEventsProvider.SITE_STORAGE_DELETED, (data) => {
|
|
||||||
this.deleteAllData(data.siteId).catch((error) => {
|
|
||||||
this.logger.error('Error deleting all H5P data from site.', error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -568,24 +560,6 @@ export class CoreH5PProvider {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all the H5P data from the DB of a certain site.
|
|
||||||
*
|
|
||||||
* @param siteId Site ID.
|
|
||||||
* @return Promise resolved when done.
|
|
||||||
*/
|
|
||||||
protected deleteAllData(siteId: string): Promise<any> {
|
|
||||||
return this.sitesProvider.getSiteDb(siteId).then((db) => {
|
|
||||||
return Promise.all([
|
|
||||||
db.deleteRecords(this.CONTENT_TABLE),
|
|
||||||
db.deleteRecords(this.LIBRARIES_TABLE),
|
|
||||||
db.deleteRecords(this.LIBRARY_DEPENDENCIES_TABLE),
|
|
||||||
db.deleteRecords(this.CONTENTS_LIBRARIES_TABLE),
|
|
||||||
db.deleteRecords(this.LIBRARIES_CACHEDASSETS_TABLE)
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete cached assets from DB and filesystem.
|
* Delete cached assets from DB and filesystem.
|
||||||
*
|
*
|
||||||
|
@ -784,14 +758,8 @@ export class CoreH5PProvider {
|
||||||
const folderName = this.mimeUtils.removeExtension(file.name),
|
const folderName = this.mimeUtils.removeExtension(file.name),
|
||||||
destFolder = this.textUtils.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName);
|
destFolder = this.textUtils.concatenatePaths(CoreFileProvider.TMPFOLDER, 'h5p/' + folderName);
|
||||||
|
|
||||||
// Make sure the dest dir doesn't exist already.
|
// Unzip the file.
|
||||||
return this.fileProvider.removeDir(destFolder).catch(() => {
|
return this.fileProvider.unzipFile(file.toURL(), destFolder).then(() => {
|
||||||
// Ignore errors.
|
|
||||||
}).then(() => {
|
|
||||||
return this.fileProvider.createDir(destFolder);
|
|
||||||
}).then(() => {
|
|
||||||
return this.fileProvider.unzipFile(file.toURL(), destFolder);
|
|
||||||
}).then(() => {
|
|
||||||
// Read the contents of the unzipped dir.
|
// Read the contents of the unzipped dir.
|
||||||
return this.fileProvider.getDirectoryContents(destFolder);
|
return this.fileProvider.getDirectoryContents(destFolder);
|
||||||
}).then((contents) => {
|
}).then((contents) => {
|
||||||
|
@ -830,11 +798,6 @@ export class CoreH5PProvider {
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).then(() => {
|
|
||||||
// Remove tmp folder.
|
|
||||||
return this.fileProvider.removeDir(destFolder).catch(() => {
|
|
||||||
// Ignore errors, it will be deleted eventually.
|
|
||||||
});
|
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
// Create the content player.
|
// Create the content player.
|
||||||
|
|
||||||
|
@ -843,6 +806,11 @@ export class CoreH5PProvider {
|
||||||
|
|
||||||
return this.createContentIndex(content.id, fileUrl, contentData, embedType, siteId);
|
return this.createContentIndex(content.id, fileUrl, contentData, embedType, siteId);
|
||||||
});
|
});
|
||||||
|
}).finally(() => {
|
||||||
|
// Remove tmp folder.
|
||||||
|
return this.fileProvider.removeDir(destFolder).catch(() => {
|
||||||
|
// Ignore errors, it will be deleted eventually.
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1002,6 +970,40 @@ export class CoreH5PProvider {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate and fix display options, updating them if needed.
|
||||||
|
*
|
||||||
|
* @param displayOptions The display options to validate.
|
||||||
|
* @param id Package ID.
|
||||||
|
*/
|
||||||
|
fixDisplayOptions(displayOptions: CoreH5PDisplayOptions, id: number): CoreH5PDisplayOptions {
|
||||||
|
|
||||||
|
// Never allow downloading in the app.
|
||||||
|
displayOptions[CoreH5PProvider.DISPLAY_OPTION_DOWNLOAD] = false;
|
||||||
|
|
||||||
|
// Embed - force setting it if always on or always off. In web, this is done when storing in DB.
|
||||||
|
const embed = this.getOption(CoreH5PProvider.DISPLAY_OPTION_EMBED, CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW);
|
||||||
|
if (embed == CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW || embed == CoreH5PDisplayOptionBehaviour.NEVER_SHOW) {
|
||||||
|
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED] = (embed == CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.getOption(CoreH5PProvider.DISPLAY_OPTION_FRAME, true)) {
|
||||||
|
displayOptions[CoreH5PProvider.DISPLAY_OPTION_FRAME] = false;
|
||||||
|
} else {
|
||||||
|
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED] = this.setDisplayOptionOverrides(
|
||||||
|
CoreH5PProvider.DISPLAY_OPTION_EMBED, CoreH5PPermission.EMBED_H5P, id,
|
||||||
|
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED]);
|
||||||
|
|
||||||
|
if (this.getOption(CoreH5PProvider.DISPLAY_OPTION_COPYRIGHT, true) == false) {
|
||||||
|
displayOptions[CoreH5PProvider.DISPLAY_OPTION_COPYRIGHT] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
displayOptions[CoreH5PProvider.DISPLAY_OPTION_COPY] = this.hasPermission(CoreH5PPermission.COPY_H5P, id);
|
||||||
|
|
||||||
|
return displayOptions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the assets of a package.
|
* Get the assets of a package.
|
||||||
*
|
*
|
||||||
|
@ -1215,7 +1217,7 @@ export class CoreH5PProvider {
|
||||||
}).then((url) => {
|
}).then((url) => {
|
||||||
// Add display options to the URL.
|
// Add display options to the URL.
|
||||||
return this.getContentDataByUrl(fileUrl, siteId).then((data) => {
|
return this.getContentDataByUrl(fileUrl, siteId).then((data) => {
|
||||||
const options = this.validateDisplayOptions(this.getDisplayOptionsFromUrlParams(urlParams), data.id);
|
const options = this.fixDisplayOptions(this.getDisplayOptionsFromUrlParams(urlParams), data.id);
|
||||||
|
|
||||||
return this.urlUtils.addParamsToUrl(url, options, undefined, true);
|
return this.urlUtils.addParamsToUrl(url, options, undefined, true);
|
||||||
});
|
});
|
||||||
|
@ -1478,7 +1480,7 @@ export class CoreH5PProvider {
|
||||||
* @return Display options as object.
|
* @return Display options as object.
|
||||||
*/
|
*/
|
||||||
getDisplayOptionsForView(disable: number, id: number): CoreH5PDisplayOptions {
|
getDisplayOptionsForView(disable: number, id: number): CoreH5PDisplayOptions {
|
||||||
return this.validateDisplayOptions(this.getDisplayOptionsAsObject(disable), id);
|
return this.fixDisplayOptions(this.getDisplayOptionsAsObject(disable), id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1733,8 +1735,8 @@ export class CoreH5PProvider {
|
||||||
* @return Return the value for this display option.
|
* @return Return the value for this display option.
|
||||||
*/
|
*/
|
||||||
getOption(name: string, defaultValue: any = false): any {
|
getOption(name: string, defaultValue: any = false): any {
|
||||||
// For now, all them are disabled by default, so only will be rendered when defined in the displayoptions DB field.
|
// For now, all them are disabled by default, so only will be rendered when defined in the display options.
|
||||||
return CoreH5PDisplayOptionBehaviour.CONTROLLED_BY_AUTHOR_DEFAULT_OFF; // CONTROLLED_BY_AUTHOR_DEFAULT_OFF.
|
return CoreH5PDisplayOptionBehaviour.CONTROLLED_BY_AUTHOR_DEFAULT_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1776,7 +1778,7 @@ export class CoreH5PProvider {
|
||||||
*
|
*
|
||||||
* @param url The file URL.
|
* @param url The file URL.
|
||||||
* @param options Options.
|
* @param options Options.
|
||||||
* @param ignoreCache Whether to ignore cache..
|
* @param ignoreCache Whether to ignore cache.
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Promise resolved with the file data.
|
* @return Promise resolved with the file data.
|
||||||
*/
|
*/
|
||||||
|
@ -2135,7 +2137,6 @@ export class CoreH5PProvider {
|
||||||
*
|
*
|
||||||
* @param fileUrl The file URL used to download the file.
|
* @param fileUrl The file URL used to download the file.
|
||||||
* @param file The file entry of the downloaded file.
|
* @param file The file entry of the downloaded file.
|
||||||
* @param siteId Site ID. If not defined, current site.
|
|
||||||
* @return Promise resolved when done.
|
* @return Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected processH5PFiles(destFolder: string, entries: (DirectoryEntry | FileEntry)[])
|
protected processH5PFiles(destFolder: string, entries: (DirectoryEntry | FileEntry)[])
|
||||||
|
@ -2227,7 +2228,6 @@ export class CoreH5PProvider {
|
||||||
|
|
||||||
const data: any = {
|
const data: any = {
|
||||||
jsoncontent: content.params,
|
jsoncontent: content.params,
|
||||||
displayoptions: null,
|
|
||||||
mainlibraryid: content.library.libraryId,
|
mainlibraryid: content.library.libraryId,
|
||||||
timemodified: Date.now(),
|
timemodified: Date.now(),
|
||||||
filtered: null,
|
filtered: null,
|
||||||
|
@ -2597,40 +2597,6 @@ export class CoreH5PProvider {
|
||||||
return db.updateRecords(this.CONTENT_TABLE, data, {id: id});
|
return db.updateRecords(this.CONTENT_TABLE, data, {id: id});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate display options, updating them if needed.
|
|
||||||
*
|
|
||||||
* @param displayOptions The display options to validate.
|
|
||||||
* @param id Package ID.
|
|
||||||
*/
|
|
||||||
validateDisplayOptions(displayOptions: CoreH5PDisplayOptions, id: number): CoreH5PDisplayOptions {
|
|
||||||
|
|
||||||
// Never allow downloading in the app.
|
|
||||||
displayOptions[CoreH5PProvider.DISPLAY_OPTION_DOWNLOAD] = false;
|
|
||||||
|
|
||||||
// Embed - force setting it if always on or always off. In web, this is done when storing in DB.
|
|
||||||
const embed = this.getOption(CoreH5PProvider.DISPLAY_OPTION_EMBED, CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW);
|
|
||||||
if (embed == CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW || embed == CoreH5PDisplayOptionBehaviour.NEVER_SHOW) {
|
|
||||||
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED] = (embed == CoreH5PDisplayOptionBehaviour.ALWAYS_SHOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getOption(CoreH5PProvider.DISPLAY_OPTION_FRAME, true) == false) {
|
|
||||||
displayOptions[CoreH5PProvider.DISPLAY_OPTION_FRAME] = false;
|
|
||||||
} else {
|
|
||||||
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED] = this.setDisplayOptionOverrides(
|
|
||||||
CoreH5PProvider.DISPLAY_OPTION_EMBED, CoreH5PPermission.EMBED_H5P, id,
|
|
||||||
displayOptions[CoreH5PProvider.DISPLAY_OPTION_EMBED]);
|
|
||||||
|
|
||||||
if (this.getOption(CoreH5PProvider.DISPLAY_OPTION_COPYRIGHT, true) == false) {
|
|
||||||
displayOptions[CoreH5PProvider.DISPLAY_OPTION_COPYRIGHT] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
displayOptions[CoreH5PProvider.DISPLAY_OPTION_COPY] = this.hasPermission(CoreH5PPermission.COPY_H5P, id);
|
|
||||||
|
|
||||||
return displayOptions;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2701,7 +2667,6 @@ export type CoreH5PContentDBData = {
|
||||||
id: number; // The id of the content.
|
id: number; // The id of the content.
|
||||||
jsoncontent: string; // The content in json format.
|
jsoncontent: string; // The content in json format.
|
||||||
mainlibraryid: number; // The library we first instantiate for this node.
|
mainlibraryid: number; // The library we first instantiate for this node.
|
||||||
displayoptions: number; // H5P Button display options. Not used right now.
|
|
||||||
foldername: string; // Name of the folder that contains the contents.
|
foldername: string; // Name of the folder that contains the contents.
|
||||||
fileurl: string; // The online URL of the H5P package.
|
fileurl: string; // The online URL of the H5P package.
|
||||||
filtered: string; // Filtered version of json_content.
|
filtered: string; // Filtered version of json_content.
|
||||||
|
|
|
@ -37,17 +37,6 @@ export class CoreH5PPluginFileHandler implements CorePluginFileHandler {
|
||||||
protected fileProvider: CoreFileProvider,
|
protected fileProvider: CoreFileProvider,
|
||||||
protected h5pProvider: CoreH5PProvider) { }
|
protected h5pProvider: CoreH5PProvider) { }
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether a file can be downloaded. If so, return the file to download.
|
|
||||||
*
|
|
||||||
* @param file The file data.
|
|
||||||
* @param siteId Site ID. If not defined, current site.
|
|
||||||
* @return Promise resolved with the file to use. Rejected if cannot download.
|
|
||||||
*/
|
|
||||||
canDownloadFile(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile> {
|
|
||||||
return this.h5pProvider.getTrustedH5PFile(file.fileurl, {}, false, siteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* React to a file being deleted.
|
* React to a file being deleted.
|
||||||
*
|
*
|
||||||
|
@ -61,6 +50,17 @@ export class CoreH5PPluginFileHandler implements CorePluginFileHandler {
|
||||||
return this.h5pProvider.deleteContentByUrl(fileUrl, siteId);
|
return this.h5pProvider.deleteContentByUrl(fileUrl, siteId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a file can be downloaded. If so, return the file to download.
|
||||||
|
*
|
||||||
|
* @param file The file data.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with the file to use. Rejected if cannot download.
|
||||||
|
*/
|
||||||
|
getDownloadableFile(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile> {
|
||||||
|
return this.h5pProvider.getTrustedH5PFile(file.fileurl, {}, false, siteId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an HTML element, get the URLs of the files that should be downloaded and weren't treated by
|
* Given an HTML element, get the URLs of the files that should be downloaded and weren't treated by
|
||||||
* CoreDomUtilsProvider.extractDownloadableFilesFromHtml.
|
* CoreDomUtilsProvider.extractDownloadableFilesFromHtml.
|
||||||
|
@ -68,7 +68,7 @@ export class CoreH5PPluginFileHandler implements CorePluginFileHandler {
|
||||||
* @param container Container where to get the URLs from.
|
* @param container Container where to get the URLs from.
|
||||||
* @return {string[]} List of URLs.
|
* @return {string[]} List of URLs.
|
||||||
*/
|
*/
|
||||||
getDownloadableFiles(container: HTMLElement): string[] {
|
getDownloadableFilesFromHTML(container: HTMLElement): string[] {
|
||||||
const iframes = <HTMLIFrameElement[]> Array.from(container.querySelectorAll('iframe.h5p-iframe'));
|
const iframes = <HTMLIFrameElement[]> Array.from(container.querySelectorAll('iframe.h5p-iframe'));
|
||||||
const urls = [];
|
const urls = [];
|
||||||
|
|
||||||
|
|
|
@ -762,7 +762,7 @@ export class CoreFileProvider {
|
||||||
* @return Promise resolved when the entry is moved.
|
* @return Promise resolved when the entry is moved.
|
||||||
*/
|
*/
|
||||||
moveDir(originalPath: string, newPath: string, destDirExists?: boolean): Promise<any> {
|
moveDir(originalPath: string, newPath: string, destDirExists?: boolean): Promise<any> {
|
||||||
return this.moveFileOrDir(originalPath, newPath, true);
|
return this.moveFileOrDir(originalPath, newPath, true, destDirExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -775,7 +775,7 @@ export class CoreFileProvider {
|
||||||
* @return Promise resolved when the entry is moved.
|
* @return Promise resolved when the entry is moved.
|
||||||
*/
|
*/
|
||||||
moveFile(originalPath: string, newPath: string, destDirExists?: boolean): Promise<any> {
|
moveFile(originalPath: string, newPath: string, destDirExists?: boolean): Promise<any> {
|
||||||
return this.moveFileOrDir(originalPath, newPath, false);
|
return this.moveFileOrDir(originalPath, newPath, false, destDirExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -991,11 +991,26 @@ export class CoreFileProvider {
|
||||||
* @param destFolder Path to the destination folder. If not defined, a new folder will be created with the
|
* @param 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 onProgress Function to call on progress.
|
* @param onProgress Function to call on progress.
|
||||||
|
* @param recreateDir Delete the dest directory before unzipping. Defaults to true.
|
||||||
* @return Promise resolved when the file is unzipped.
|
* @return Promise resolved when the file is unzipped.
|
||||||
*/
|
*/
|
||||||
unzipFile(path: string, destFolder?: string, onProgress?: Function): Promise<any> {
|
unzipFile(path: string, destFolder?: string, onProgress?: Function, recreateDir: boolean = true): Promise<any> {
|
||||||
// Get the source file.
|
// Get the source file.
|
||||||
return this.getFile(path).then((fileEntry) => {
|
let fileEntry: FileEntry;
|
||||||
|
|
||||||
|
return this.getFile(path).then((fe) => {
|
||||||
|
fileEntry = fe;
|
||||||
|
|
||||||
|
if (destFolder && recreateDir) {
|
||||||
|
// Make sure the dest dir doesn't exist already.
|
||||||
|
return this.removeDir(destFolder).catch(() => {
|
||||||
|
// Ignore errors.
|
||||||
|
}).then(() => {
|
||||||
|
// Now create the dir, otherwise if any of the ancestor dirs doesn't exist the unzip would fail.
|
||||||
|
return this.createDir(destFolder);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).then(() => {
|
||||||
// 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));
|
||||||
|
|
||||||
|
|
|
@ -1339,7 +1339,7 @@ export class CoreFilepoolProvider {
|
||||||
*/
|
*/
|
||||||
protected fixPluginfileURL(siteId: string, fileUrl: string, timemodified: number = 0): Promise<CoreWSExternalFile> {
|
protected fixPluginfileURL(siteId: string, fileUrl: string, timemodified: number = 0): Promise<CoreWSExternalFile> {
|
||||||
|
|
||||||
return this.pluginFileDelegate.canDownloadFile({fileurl: fileUrl, timemodified: timemodified}).then((file) => {
|
return this.pluginFileDelegate.getDownloadableFile({fileurl: fileUrl, timemodified: timemodified}).then((file) => {
|
||||||
|
|
||||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
return site.checkAndFixPluginfileURL(file.fileurl);
|
return site.checkAndFixPluginfileURL(file.fileurl);
|
||||||
|
|
|
@ -48,15 +48,6 @@ export interface CorePluginFileHandler {
|
||||||
*/
|
*/
|
||||||
getComponentRevisionReplace?(args: string[]): string;
|
getComponentRevisionReplace?(args: string[]): string;
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether a file can be downloaded. If so, return the file to download.
|
|
||||||
*
|
|
||||||
* @param file The file data.
|
|
||||||
* @param siteId Site ID. If not defined, current site.
|
|
||||||
* @return Promise resolved with the file to use. Rejected if cannot download.
|
|
||||||
*/
|
|
||||||
canDownloadFile?(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* React to a file being deleted.
|
* React to a file being deleted.
|
||||||
*
|
*
|
||||||
|
@ -67,6 +58,15 @@ export interface CorePluginFileHandler {
|
||||||
*/
|
*/
|
||||||
fileDeleted?(fileUrl: string, path: string, siteId?: string): Promise<any>;
|
fileDeleted?(fileUrl: string, path: string, siteId?: string): Promise<any>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a file can be downloaded. If so, return the file to download.
|
||||||
|
*
|
||||||
|
* @param file The file data.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with the file to use. Rejected if cannot download.
|
||||||
|
*/
|
||||||
|
getDownloadableFile?(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an HTML element, get the URLs of the files that should be downloaded and weren't treated by
|
* Given an HTML element, get the URLs of the files that should be downloaded and weren't treated by
|
||||||
* CoreDomUtilsProvider.extractDownloadableFilesFromHtml.
|
* CoreDomUtilsProvider.extractDownloadableFilesFromHtml.
|
||||||
|
@ -74,7 +74,7 @@ export interface CorePluginFileHandler {
|
||||||
* @param container Container where to get the URLs from.
|
* @param container Container where to get the URLs from.
|
||||||
* @return {string[]} List of URLs.
|
* @return {string[]} List of URLs.
|
||||||
*/
|
*/
|
||||||
getDownloadableFiles?(container: HTMLElement): string[];
|
getDownloadableFilesFromHTML?(container: HTMLElement): string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a file size.
|
* Get a file size.
|
||||||
|
@ -116,39 +116,6 @@ export class CorePluginFileDelegate {
|
||||||
this.logger = logger.getInstance('CorePluginFileDelegate');
|
this.logger = logger.getInstance('CorePluginFileDelegate');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether a file can be downloaded. If so, return the file to download.
|
|
||||||
*
|
|
||||||
* @param file The file data.
|
|
||||||
* @param siteId Site ID. If not defined, current site.
|
|
||||||
* @return Promise resolved with the file to use. Rejected if cannot download.
|
|
||||||
*/
|
|
||||||
canDownloadFile(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile> {
|
|
||||||
const handler = this.getHandlerForFile(file);
|
|
||||||
|
|
||||||
return this.canHandlerDownloadFile(file, handler, siteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check whether a file can be downloaded. If so, return the file to download.
|
|
||||||
*
|
|
||||||
* @param file The file data.
|
|
||||||
* @param handler The handler to use.
|
|
||||||
* @param siteId Site ID. If not defined, current site.
|
|
||||||
* @return Promise resolved with the file to use. Rejected if cannot download.
|
|
||||||
*/
|
|
||||||
protected canHandlerDownloadFile(file: CoreWSExternalFile, handler: CorePluginFileHandler, siteId?: string)
|
|
||||||
: Promise<CoreWSExternalFile> {
|
|
||||||
|
|
||||||
if (handler && handler.canDownloadFile) {
|
|
||||||
return handler.canDownloadFile(file, siteId).then((newFile) => {
|
|
||||||
return newFile || file;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.resolve(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* React to a file being deleted.
|
* React to a file being deleted.
|
||||||
*
|
*
|
||||||
|
@ -167,6 +134,39 @@ export class CorePluginFileDelegate {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a file can be downloaded. If so, return the file to download.
|
||||||
|
*
|
||||||
|
* @param file The file data.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with the file to use. Rejected if cannot download.
|
||||||
|
*/
|
||||||
|
getDownloadableFile(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile> {
|
||||||
|
const handler = this.getHandlerForFile(file);
|
||||||
|
|
||||||
|
return this.getHandlerDownloadableFile(file, handler, siteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether a file can be downloaded. If so, return the file to download.
|
||||||
|
*
|
||||||
|
* @param file The file data.
|
||||||
|
* @param handler The handler to use.
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with the file to use. Rejected if cannot download.
|
||||||
|
*/
|
||||||
|
protected getHandlerDownloadableFile(file: CoreWSExternalFile, handler: CorePluginFileHandler, siteId?: string)
|
||||||
|
: Promise<CoreWSExternalFile> {
|
||||||
|
|
||||||
|
if (handler && handler.getDownloadableFile) {
|
||||||
|
return handler.getDownloadableFile(file, siteId).then((newFile) => {
|
||||||
|
return newFile || file;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve(file);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the handler for a certain pluginfile url.
|
* Get the handler for a certain pluginfile url.
|
||||||
*
|
*
|
||||||
|
@ -201,14 +201,14 @@ export class CorePluginFileDelegate {
|
||||||
* @param container Container where to get the URLs from.
|
* @param container Container where to get the URLs from.
|
||||||
* @return List of URLs.
|
* @return List of URLs.
|
||||||
*/
|
*/
|
||||||
getDownloadableFiles(container: HTMLElement): string[] {
|
getDownloadableFilesFromHTML(container: HTMLElement): string[] {
|
||||||
let files = [];
|
let files = [];
|
||||||
|
|
||||||
for (const component in this.handlers) {
|
for (const component in this.handlers) {
|
||||||
const handler = this.handlers[component];
|
const handler = this.handlers[component];
|
||||||
|
|
||||||
if (handler && handler.getDownloadableFiles) {
|
if (handler && handler.getDownloadableFilesFromHTML) {
|
||||||
files = files.concat(handler.getDownloadableFiles(container));
|
files = files.concat(handler.getDownloadableFilesFromHTML(container));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,8 +256,8 @@ export class CorePluginFileDelegate {
|
||||||
const handler = this.getHandlerForFile(file);
|
const handler = this.getHandlerForFile(file);
|
||||||
|
|
||||||
// First of all check if file can be downloaded.
|
// First of all check if file can be downloaded.
|
||||||
return this.canHandlerDownloadFile(file, handler, siteId).then((canDownload) => {
|
return this.getHandlerDownloadableFile(file, handler, siteId).then((file) => {
|
||||||
if (!canDownload) {
|
if (!file) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -286,7 +286,7 @@ export class CoreDomUtilsProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now get other files from plugin file handlers.
|
// Now get other files from plugin file handlers.
|
||||||
urls = urls.concat(this.pluginFileDelegate.getDownloadableFiles(element));
|
urls = urls.concat(this.pluginFileDelegate.getDownloadableFilesFromHTML(element));
|
||||||
|
|
||||||
return urls;
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue