blob: ac2b688a7f6e00e87878756a7c15d6738e4b6d35 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* 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 JSZip from 'jszip';
import {FunctionUtils, OnProgressUpdateType} from './function_utils';
export type OnFile = (file: File, parentArchive: File | undefined) => void;
class FileUtils {
static getFileExtension(file: File) {
const split = file.name.split('.');
if (split.length > 1) {
return split.pop();
}
return undefined;
}
static removeDirFromFileName(name: string) {
if (name.includes('/')) {
const startIndex = name.lastIndexOf('/') + 1;
return name.slice(startIndex);
} else {
return name;
}
}
static async createZipArchive(files: File[]): Promise<Blob> {
const zip = new JSZip();
for (let i = 0; i < files.length; i++) {
const file = files[i];
const blob = await file.arrayBuffer();
zip.file(file.name, blob);
}
return await zip.generateAsync({type: 'blob'});
}
static async unzipFile(
file: File,
onProgressUpdate: OnProgressUpdateType = FunctionUtils.DO_NOTHING
): Promise<File[]> {
const unzippedFiles: File[] = [];
const zip = new JSZip();
const content = await zip.loadAsync(file);
const filenames = Object.keys(content.files);
for (const [index, filename] of filenames.entries()) {
const file = content.files[filename];
if (file.dir) {
// Ignore directories
continue;
} else {
const fileBlob = await file.async('blob');
const unzippedFile = new File([fileBlob], filename);
unzippedFiles.push(unzippedFile);
}
onProgressUpdate((100 * (index + 1)) / filenames.length);
}
return unzippedFiles;
}
static async unzipFilesIfNeeded(
files: File[],
onFile: OnFile,
onProgressUpdate: OnProgressUpdateType = FunctionUtils.DO_NOTHING
) {
for (let i = 0; i < files.length; i++) {
const file = files[i];
const onSubprogressUpdate = (subPercentage: number) => {
const percentage = (100 * i) / files.length + subPercentage / files.length;
onProgressUpdate(percentage);
};
if (FileUtils.isZipFile(file)) {
const unzippedFile = await FileUtils.unzipFile(file, onSubprogressUpdate);
unzippedFile.forEach((unzippedFile) => onFile(unzippedFile, file));
} else {
onFile(file, undefined);
}
}
}
static isZipFile(file: File) {
return FileUtils.getFileExtension(file) === 'zip';
}
}
export {FileUtils};