MOBILE-4653 utils: Move file related utils functions

main
Pau Ferrer Ocaña 2024-11-15 13:49:21 +01:00
parent 94b0266794
commit 5e3d233272
9 changed files with 109 additions and 43 deletions

View File

@ -25,7 +25,7 @@ import { Injectable, Type } from '@angular/core';
import { CoreFileUploader, CoreFileUploaderStoreFilesResult } from '@features/fileuploader/services/fileuploader';
import { CoreFileEntry, CoreFileHelper } from '@services/file-helper';
import { CoreFileSession } from '@services/file-session';
import { CoreUtils } from '@services/utils/utils';
import { CoreFileUtils } from '@singletons/file-utils';
import { CoreWSFile } from '@services/ws';
import { makeSingleton } from '@singletons';
import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
@ -242,7 +242,7 @@ export class AddonModAssignSubmissionFileHandlerService implements AddonModAssig
// Data has changed, we need to upload new files and re-upload all the existing files.
const currentFiles = CoreFileSession.getFiles(ADDON_MOD_ASSIGN_COMPONENT, assign.id);
const error = CoreUtils.hasRepeatedFilenames(currentFiles);
const error = CoreFileUtils.hasRepeatedFilenames(currentFiles);
if (error) {
throw error;

View File

@ -45,7 +45,7 @@ import { CoreSync } from '@services/sync';
import { CoreText } from '@singletons/text';
import { AddonModForumHelper } from '../../services/forum-helper';
import { AddonModForumOffline } from '../../services/forum-offline';
import { CoreUtils } from '@services/utils/utils';
import { CoreFileUtils } from '@singletons/file-utils';
import { CoreRatingInfo } from '@features/rating/services/rating';
import { CoreForms } from '@singletons/form';
import { CoreFileEntry, CoreFileHelper } from '@services/file-helper';
@ -506,7 +506,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
}
// Use prepare post for edition to avoid re-uploading all files.
let filesToKeep = files.filter((file): file is CoreWSFile => !CoreUtils.isFileEntry(file));
let filesToKeep = files.filter((file): file is CoreWSFile => !CoreFileUtils.isFileEntry(file));
let removedFiles: { filepath: string; filename: string }[] | undefined;
if (previousAttachments.length && !filesToKeep.length) {

View File

@ -19,6 +19,7 @@ import { MediaFile, CaptureError, CaptureVideoOptions } from '@awesome-cordova-p
import { Subject } from 'rxjs';
import { CoreFile, CoreFileProvider } from '@services/file';
import { CoreFileUtils } from '@singletons/file-utils';
import { CoreFilepool } from '@services/filepool';
import { CoreSites } from '@services/sites';
import { CoreMimetypeUtils } from '@services/utils/mimetype';
@ -557,7 +558,7 @@ export class CoreFileUploaderProvider {
await CoreFile.removeUnusedFiles(folderPath, files);
await Promise.all(files.map(async (file) => {
if (!CoreUtils.isFileEntry(file)) {
if (!CoreFileUtils.isFileEntry(file)) {
// It's an online file, add it to the result and ignore it.
result.online.push({
filename: file.filename,
@ -632,7 +633,7 @@ export class CoreFileUploaderProvider {
const usedNames: {[name: string]: CoreFileEntry} = {};
const filesToUpload: FileEntry[] = [];
files.forEach((file) => {
if (CoreUtils.isFileEntry(file)) {
if (CoreFileUtils.isFileEntry(file)) {
filesToUpload.push(<FileEntry> file);
} else {
// It's an online file.
@ -679,9 +680,9 @@ export class CoreFileUploaderProvider {
let fileName = '';
let fileEntry: FileEntry | undefined;
const isOnline = !CoreUtils.isFileEntry(file);
const isOnline = !CoreFileUtils.isFileEntry(file);
if (CoreUtils.isFileEntry(file)) {
if (CoreFileUtils.isFileEntry(file)) {
// Local file, we already have the file entry.
fileName = file.name;
fileEntry = file;

View File

@ -17,6 +17,7 @@ import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
import { CoreNetwork } from '@services/network';
import { CoreFile } from '@services/file';
import { CoreFileUtils } from '@singletons/file-utils';
import { CoreFilepool } from '@services/filepool';
import { CoreSites } from '@services/sites';
import { CoreWS, CoreWSFile } from '@services/ws';
@ -489,7 +490,7 @@ export class CoreFileHelperProvider {
* @returns The file name.
*/
getFilenameFromPath(file: CoreFileEntry): string | undefined {
const path = CoreUtils.isFileEntry(file) ? file.fullPath : file.filepath;
const path = CoreFileUtils.isFileEntry(file) ? file.fullPath : file.filepath;
if (path === undefined || path.length == 0) {
return;

View File

@ -17,7 +17,7 @@ import { Injectable } from '@angular/core';
import { FileEntry, DirectoryEntry, Entry, Metadata, IFile } from '@awesome-cordova-plugins/file/ngx';
import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { CoreUtils } from '@services/utils/utils';
import { CoreFileUtils } from '@singletons/file-utils';
import { CoreConstants } from '@/core/constants';
import { CoreError } from '@classes/errors/error';
@ -1304,7 +1304,7 @@ export class CoreFileProvider {
* @returns The file name.
*/
getFileName(file: CoreFileEntry): string | undefined {
return CoreUtils.isFileEntry(file) ? file.name : file.filename;
return CoreFileUtils.isFileEntry(file) ? file.name : file.filename;
}
}

View File

@ -16,11 +16,11 @@ import { Injectable } from '@angular/core';
import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
import { CoreFile } from '@services/file';
import { CoreFileUtils } from '@singletons/file-utils';
import { CoreText } from '@singletons/text';
import { makeSingleton, Translate } from '@singletons';
import { CoreLogger } from '@singletons/logger';
import { CoreWSFile } from '@services/ws';
import { CoreUtils } from '@services/utils/utils';
import extToMime from '@/assets/exttomime.json';
import mimeToExt from '@/assets/mimetoext.json';
@ -168,11 +168,11 @@ export class CoreMimetypeUtilsProvider {
* @returns The embedded HTML string.
*/
getEmbeddedHtml(file: CoreFileEntry, path?: string): string {
const filename = CoreUtils.isFileEntry(file) ? (file as FileEntry).name : file.filename;
const extension = !CoreUtils.isFileEntry(file) && file.mimetype
const filename = CoreFileUtils.isFileEntry(file) ? (file as FileEntry).name : file.filename;
const extension = !CoreFileUtils.isFileEntry(file) && file.mimetype
? this.getExtension(file.mimetype)
: (filename && this.getFileExtension(filename));
const mimeType = !CoreUtils.isFileEntry(file) && file.mimetype
const mimeType = !CoreFileUtils.isFileEntry(file) && file.mimetype
? file.mimetype
: (extension && this.getMimeType(extension));
@ -185,7 +185,7 @@ export class CoreMimetypeUtilsProvider {
// @todo linting: See if this can be removed
(file as { embedType?: string }).embedType = embedType;
path = path ?? (CoreUtils.isFileEntry(file) ? CoreFile.getFileEntryURL(file) : CoreFileHelper.getFileUrl(file));
path = path ?? (CoreFileUtils.isFileEntry(file) ? CoreFile.getFileEntryURL(file) : CoreFileHelper.getFileUrl(file));
path = path && CoreFile.convertFileSrc(path);
switch (embedType) {
@ -424,7 +424,7 @@ export class CoreMimetypeUtilsProvider {
let mimetype: string | undefined = '';
let extension: string | undefined = '';
if (typeof obj == 'object' && CoreUtils.isFileEntry(obj)) {
if (typeof obj == 'object' && CoreFileUtils.isFileEntry(obj)) {
// It's a FileEntry. Don't use the file function because it's asynchronous and the type isn't reliable.
filename = obj.name;
} else if (typeof obj == 'object') {

View File

@ -16,6 +16,7 @@ import { Injectable } from '@angular/core';
import { InAppBrowserObject } from '@awesome-cordova-plugins/in-app-browser';
import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
import { CoreFile } from '@services/file';
import { CoreFileUtils } from '@singletons/file-utils';
import { CoreLang, CoreLangFormat } from '@services/lang';
import { CoreWS } from '@services/ws';
import { CoreMimetypeUtils } from '@services/utils/mimetype';
@ -288,7 +289,7 @@ export class CoreUtilsProvider {
return source;
}
if (this.valueIsFileEntry(source)) {
if (CoreFileUtils.valueIsFileEntry(source)) {
// Don't clone FileEntry. It has a lot of depth and they shouldn't be modified.
return source;
} else if (Array.isArray(source)) {
@ -717,9 +718,10 @@ export class CoreUtilsProvider {
*
* @param file File.
* @returns Type guard indicating if the file is a FileEntry.
* @deprecated since 5.0. Use CoreFile.isFileEntry singleton instead.
*/
isFileEntry(file: CoreFileEntry): file is FileEntry {
return 'isFile' in file;
return CoreFileUtils.isFileEntry(file);
}
/**
@ -727,11 +729,10 @@ export class CoreUtilsProvider {
*
* @param file Object to check.
* @returns Type guard indicating if the file is a FileEntry.
* @deprecated since 5.0. Use CoreFile.valueIsFileEntry singleton instead.
*/
valueIsFileEntry(file: unknown): file is FileEntry {
// We cannot use instanceof because FileEntry is a type. Check some of the properties.
return !!(file && typeof file == 'object' && 'isFile' in file && 'filesystem' in file &&
'toInternalURL' in file && 'copyTo' in file);
return CoreFileUtils.valueIsFileEntry(file);
}
/**
@ -749,27 +750,10 @@ export class CoreUtilsProvider {
*
* @param files List of files.
* @returns String with error message if repeated, false if no repeated.
* @deprecated since 5.0. Use CoreFileUtils.hasRepeatedFilenames instead.
*/
hasRepeatedFilenames(files: CoreFileEntry[]): string | false {
if (!files || !files.length) {
return false;
}
const names: string[] = [];
// Check if there are 2 files with the same name.
for (let i = 0; i < files.length; i++) {
const file = files[i];
const name = (this.isFileEntry(file) ? file.name : file.filename) || '';
if (names.indexOf(name) > -1) {
return Translate.instant('core.filenameexist', { $a: name });
}
names.push(name);
}
return false;
return CoreFileUtils.hasRepeatedFilenames(files);
}
/**
@ -956,7 +940,7 @@ export class CoreUtilsProvider {
// Path needs to be decoded, the file won't be opened if the path has %20 instead of spaces and so.
try {
path = decodeURIComponent(path);
} catch (ex) {
} catch {
// Error, use the original path.
}

View File

@ -0,0 +1,79 @@
// (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 { CoreFileEntry } from '@services/file-helper';
import { FileEntry } from '@awesome-cordova-plugins/file/ngx';
import { Translate } from '@singletons';
/**
* Helpers to interact with the file system.
*/
export class CoreFileUtils {
// Avoid creating singleton instances.
private constructor() {
// Nothing to do.
}
/**
* Check if a file is a FileEntry
*
* @param file File.
* @returns Type guard indicating if the file is a FileEntry.
*/
static isFileEntry(file: CoreFileEntry): file is FileEntry {
return 'isFile' in file;
}
/**
* Check if an unknown value is a FileEntry.
*
* @param file Object to check.
* @returns Type guard indicating if the file is a FileEntry.
*/
static valueIsFileEntry(file: unknown): file is FileEntry {
// We cannot use instanceof because FileEntry is a type. Check some of the properties.
return !!(file && typeof file == 'object' && 'isFile' in file && 'filesystem' in file &&
'toInternalURL' in file && 'copyTo' in file);
}
/**
* Given a list of files, check if there are repeated names.
*
* @param files List of files.
* @returns String with error message if repeated, false if no repeated.
*/
static hasRepeatedFilenames(files: CoreFileEntry[]): string | false {
if (!files || !files.length) {
return false;
}
const names: string[] = [];
// Check if there are 2 files with the same name.
for (let i = 0; i < files.length; i++) {
const file = files[i];
const name = (this.isFileEntry(file) ? file.name : file.filename) || '';
if (names.indexOf(name) > -1) {
return Translate.instant('core.filenameexist', { $a: name });
}
names.push(name);
}
return false;
}
}

View File

@ -83,7 +83,8 @@ export class CoreWindow {
try {
await CoreFileHelper.showConfirmOpenUnsupportedFile(false, { filename });
} catch {
return; // Cancelled, stop.
// Cancelled, stop.
return;
}
}