[bugfix] fixed logic with folder extraction events

This commit is contained in:
silentrald
2024-11-10 15:34:50 +08:00
parent d0831f2e44
commit 0fd4d51898
4 changed files with 88 additions and 36 deletions
+12 -16
View File
@@ -5,7 +5,6 @@ import { extractZip, getFilesFromZip } from "main/helpers/zip.helpers";
const TEST_FOLDER = path.resolve(__dirname, "../../..", "assets", "tests");
const STANDARD_ZIP = path.join(TEST_FOLDER, "standard.zip");
const WINDOWS_LEGACY_MAP_ZIP = path.join(TEST_FOLDER, "windows_legacy.zip");
const SPECIAL_ZIP = path.join(TEST_FOLDER, "special.zip");
const MANIFEST_ZIP = path.join(TEST_FOLDER, "manifest.zip");
const DESTINATION_FOLDER = path.join(TEST_FOLDER, "out");
@@ -41,7 +40,12 @@ describe("Zip Server Service Test", () => {
// Uses '\\'
it("Extract map zips using forward slashes", async () => {
await extractZip(WINDOWS_LEGACY_MAP_ZIP, DESTINATION_FOLDER);
const beforeExtractedFolders: string[] = [];
const afterExtractedFolders: string[] = [];
await extractZip(WINDOWS_LEGACY_MAP_ZIP, DESTINATION_FOLDER, {
beforeFolderExtracted: (folder) => beforeExtractedFolders.push(folder),
afterFolderExtracted: (folder) => afterExtractedFolders.push(folder),
});
// Expect all the files to exists
for (const file of [
@@ -67,22 +71,14 @@ describe("Zip Server Service Test", () => {
expect(pathExistsSync(path.join(SUBFOLDER_PATH, file)))
.toBe(true);
}
});
it("Extract special zip file", async () => {
const beforeExtracted: string[] = [];
const afterExtracted: string[] = [];
await extractZip(SPECIAL_ZIP, DESTINATION_FOLDER, {
beforeFolderExtracted: (folder) => beforeExtracted.push(folder),
afterFolderExtracted: (folder) => afterExtracted.push(folder),
});
expect(beforeExtractedFolders).toContain(".");
expect(beforeExtractedFolders).toContain("pfp");
expect(beforeExtractedFolders.length).toBe(2);
const expected = [
"1/a", "1/aa", "1/aaa",
"2/a", "2/aa", "2/aaa",
]
expect(beforeExtracted).toEqual(expected);
expect(afterExtracted).toEqual(expected);
expect(afterExtractedFolders).toContain(".");
expect(afterExtractedFolders).toContain("pfp");
expect(afterExtractedFolders.length).toBe(2);
});
it("Extract manifest.json from zip file", async () => {
+74 -17
View File
@@ -67,7 +67,37 @@ function handleExtractZip(
name: "",
directory: false,
};
let currentDirname = "";
let indexes: number[] = [];
let dirname = "";
options?.beforeFolderExtracted?.(".");
const folderExtractEvents = options?.beforeFolderExtracted
|| options?.afterFolderExtracted
? (filename: string) => {
let newDirname = path.dirname(filename);
if (newDirname === ".") newDirname = "";
const comparison = compareStringIndex(dirname, newDirname);
if (comparison === -1) { return; }
// Push after extraction
if (options?.afterFolderExtracted) {
for (let i = indexes.length - 1; i > -1 && indexes[i] > comparison; --i) {
options.afterFolderExtracted(dirname.substring(0, indexes[i]));
}
}
// Push before extraction
indexes = getSlashIndexes(newDirname);
if (options?.beforeFolderExtracted) {
for (let i = 0; i < indexes.length; ++i) {
if (indexes[i] <= comparison) { continue; }
options.beforeFolderExtracted(newDirname.substring(0, indexes[i]));
}
}
dirname = newDirname;
} : () => {};
zip.readEntry();
@@ -86,21 +116,7 @@ function handleExtractZip(
zip.openReadStream(entry, (readError, readStream) => {
if (readError) return reject(readError);
const dirname = path.dirname(entry.fileName);
if (dirname !== currentDirname) {
if (path.dirname(dirname) === path.dirname(currentDirname)) {
options?.afterFolderExtracted?.(currentDirname);
options?.beforeFolderExtracted?.(dirname);
} else if (currentDirname.startsWith(dirname)) {
options?.afterFolderExtracted?.(currentDirname);
} else if (dirname.startsWith(currentDirname)) {
options?.beforeFolderExtracted?.(dirname);
} else {
options?.afterFolderExtracted?.(currentDirname);
options?.beforeFolderExtracted?.(dirname);
}
currentDirname = dirname;
}
folderExtractEvents(entry.fileName);
zipEntry.name = entry.fileName;
zipEntry.directory = false;
@@ -134,7 +150,14 @@ function handleExtractZip(
});
zip.once("end", () => {
options?.afterFolderExtracted?.(currentDirname);
if (options?.afterFolderExtracted) {
// Push after extraction
for (let i = indexes.length - 1; i > -1; --i) {
options.afterFolderExtracted(dirname.substring(0, indexes[i]));
}
options.afterFolderExtracted(".");
}
zip.close();
resolve(files);
});
@@ -272,3 +295,37 @@ function handleProcessZip<T>(
});
}
/**
* @returns(number)
* -1 = string are the same
* > 0 = index where they don't equal the same
*/
function compareStringIndex(str1: string, str2: string) {
const N = Math.min(str1.length, str2.length);
let i = 0;
for (; i < N; ++i) {
if (str1[i] !== str2[i]) { break; }
}
return i === str1.length && i === str2.length
? -1 : i;
}
/**
* @returns(number[]) - int array of the positions of the slashes
*/
function getSlashIndexes(str: string) {
if (str === "") {
return [];
}
const indexes: number[] = [];
for (let i = 0; i < str.length; ++i) {
if (str[i] === "/") {
indexes.push(i);
}
}
indexes.push(str.length);
return indexes;
}
@@ -329,7 +329,6 @@ export class LocalMapsManagerService {
let nbImportedMaps = 0;
(async () => {
// BUG: UI bug where the map is not showing even if it was extracted properly
const terminate = () => unsubscribed;
let completeNewFolder: () => void;
const newFolderTap = tap((folder: string) => {
@@ -402,11 +401,11 @@ export class LocalMapsManagerService {
condition: !isRoot && ((entry) => mapsFolders.has(path.dirname(entry.name))),
beforeFolderExtracted: (folder) => {
if (!mapsFolders.has(folder)) return;
log.info("*", `"${folder}"`);
log.info("*", `"${folder}"`, "before");
},
afterFolderExtracted: (folder) => {
if (!mapsFolders.has(folder)) return;
newFolder.next(path.join(destination, folder));
newFolder.next(path.resolve(destination, folder));
}
});