MOBILE-3666 h5p: Implement pluginfile handler

main
Dani Palou 2020-12-16 14:46:06 +01:00
parent f1ac735abf
commit 0ead40c72e
2 changed files with 176 additions and 1 deletions

View File

@ -14,6 +14,7 @@
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { CorePluginFileDelegate } from '@services/plugin-file-delegate';
import { CORE_SITE_SCHEMAS } from '@services/sites';
import {
CONTENT_TABLE_NAME,
@ -22,6 +23,7 @@ import {
CONTENTS_LIBRARIES_TABLE_NAME,
LIBRARIES_CACHEDASSETS_TABLE_NAME,
} from './services/database/h5p';
import { CoreH5PPluginFileHandler } from './services/handlers/pluginfile';
@NgModule({
imports: [
@ -43,7 +45,7 @@ import {
multi: true,
deps: [],
useFactory: () => () => {
// @todo
CorePluginFileDelegate.instance.registerHandler(CoreH5PPluginFileHandler.instance);
},
},
],

View File

@ -0,0 +1,173 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Injectable } from '@angular/core';
import { FileEntry } from '@ionic-native/file';
import { CoreFilepoolOnProgressCallback } from '@services/filepool';
import { CorePluginFileDownloadableResult, CorePluginFileHandler } from '@services/plugin-file-delegate';
import { CoreSites } from '@services/sites';
import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { CoreUrlUtils } from '@services/utils/url';
import { CoreUtils } from '@services/utils/utils';
import { CoreWSExternalFile } from '@services/ws';
import { CoreH5P } from '../h5p';
import { Translate, makeSingleton } from '@singletons';
import { CoreH5PHelper } from '../../classes/helper';
/**
* Handler to treat H5P files.
*/
@Injectable({ providedIn: 'root' })
export class CoreH5PPluginFileHandlerService implements CorePluginFileHandler {
name = 'CoreH5PPluginFileHandler';
/**
* React to a file being deleted.
*
* @param fileUrl The file URL used to download the file.
* @param path The path of the deleted file.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved when done.
*/
async fileDeleted(fileUrl: string, path: string, siteId?: string): Promise<void> {
// If an h5p file is deleted, remove the contents folder.
await CoreH5P.instance.h5pPlayer.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.
*/
async getDownloadableFile(file: CoreWSExternalFile, siteId?: string): Promise<CoreWSExternalFile> {
const site = await CoreSites.instance.getSite(siteId);
if (site.containsUrl(file.fileurl) && file.fileurl.match(/pluginfile\.php\/[^/]+\/core_h5p\/export\//i)) {
// It's already a deployed file, use it.
return file;
}
return CoreH5P.instance.getTrustedH5PFile(file.fileurl, {}, false, siteId);
}
/**
* Given an HTML element, get the URLs of the files that should be downloaded and weren't treated by
* CoreFilepoolProvider.extractDownloadableFilesFromHtml.
*
* @param container Container where to get the URLs from.
* @return List of URLs.
*/
getDownloadableFilesFromHTML(container: HTMLElement): string[] {
const iframes = <HTMLIFrameElement[]> Array.from(container.querySelectorAll('iframe.h5p-iframe'));
const urls: string[] = [];
for (let i = 0; i < iframes.length; i++) {
const params = CoreUrlUtils.instance.extractUrlParams(iframes[i].src);
if (params.url) {
urls.push(params.url);
}
}
return urls;
}
/**
* Get a file size.
*
* @param file The file data.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with the size.
*/
async getFileSize(file: CoreWSExternalFile, siteId?: string): Promise<number> {
try {
const trustedFile = await this.getDownloadableFile(file, siteId);
return trustedFile.filesize || 0;
} catch (error) {
if (CoreUtils.instance.isWebServiceError(error)) {
// WS returned an error, it means it cannot be downloaded.
return 0;
}
throw error;
}
}
/**
* Whether or not the handler is enabled on a site level.
*
* @return Whether or not the handler is enabled on a site level.
*/
async isEnabled(): Promise<boolean> {
return CoreH5P.instance.canGetTrustedH5PFileInSite();
}
/**
* Check if a file is downloadable.
*
* @param file The file data.
* @param siteId Site ID. If not defined, current site.
* @return Promise resolved with a boolean and a reason why it isn't downloadable if needed.
*/
async isFileDownloadable(file: CoreWSExternalFile, siteId?: string): Promise<CorePluginFileDownloadableResult> {
const offlineDisabled = await CoreH5P.instance.isOfflineDisabled(siteId);
if (offlineDisabled) {
return {
downloadable: false,
reason: Translate.instance.instant('core.h5p.offlinedisabled'),
};
} else {
return {
downloadable: true,
};
}
}
/**
* Check whether the file should be treated by this handler. It is used in functions where the component isn't used.
*
* @param file The file data.
* @return Whether the file should be treated by this handler.
*/
shouldHandleFile(file: CoreWSExternalFile): boolean {
return CoreMimetypeUtils.instance.guessExtensionFromUrl(file.fileurl) == 'h5p';
}
/**
* Treat a downloaded file.
*
* @param fileUrl The file URL used to download the file.
* @param file The file entry of the downloaded file.
* @param siteId Site ID. If not defined, current site.
* @param onProgress Function to call on progress.
* @return Promise resolved when done.
*/
treatDownloadedFile(
fileUrl: string,
file: FileEntry,
siteId?: string,
onProgress?: CoreFilepoolOnProgressCallback,
): Promise<void> {
return CoreH5PHelper.saveH5P(fileUrl, file, siteId, onProgress);
}
}
export class CoreH5PPluginFileHandler extends makeSingleton(CoreH5PPluginFileHandlerService) {}