1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | var tslib_1 = require("tslib");
|
4 | var fs = require("fs");
|
5 | var path = require("path");
|
6 | var StreamZip = require("node-stream-zip");
|
7 | var yauzl = require("yauzl");
|
8 | var unzipper = require("unzipper");
|
9 | console.log("process.cwd():");
|
10 | console.log(process.cwd());
|
11 | console.log("__dirname:");
|
12 | console.log(__dirname);
|
13 | var args = process.argv.slice(2);
|
14 | console.log("args:");
|
15 | console.log(args);
|
16 | if (!args[0]) {
|
17 | console.log("FILEPATH ARGUMENT IS MISSING.");
|
18 | process.exit(1);
|
19 | }
|
20 | var argPath = args[0].trim();
|
21 | var filePath = argPath;
|
22 | console.log(filePath);
|
23 | if (!fs.existsSync(filePath)) {
|
24 | filePath = path.join(__dirname, argPath);
|
25 | console.log(filePath);
|
26 | if (!fs.existsSync(filePath)) {
|
27 | filePath = path.join(process.cwd(), argPath);
|
28 | console.log(filePath);
|
29 | if (!fs.existsSync(filePath)) {
|
30 | console.log("FILEPATH DOES NOT EXIST.");
|
31 | process.exit(1);
|
32 | }
|
33 | }
|
34 | }
|
35 | var stats = fs.lstatSync(filePath);
|
36 | if (!stats.isFile() && !stats.isDirectory()) {
|
37 | console.log("FILEPATH MUST BE FILE OR DIRECTORY.");
|
38 | process.exit(1);
|
39 | }
|
40 | var fileName = path.basename(filePath);
|
41 | var ext = path.extname(fileName);
|
42 | var argExtra = args[1] ? args[1].trim() : undefined;
|
43 | var READ_ZIP_STREAMS = argExtra === "1";
|
44 | var UNVERBOSE = false;
|
45 | var VERBOSE = process.env.DEBUG || false;
|
46 | var N_ITERATIONS = (READ_ZIP_STREAMS && VERBOSE) ? 1 : (READ_ZIP_STREAMS ? 5 : 10);
|
47 | function streamReadAll(readStream) {
|
48 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
49 | return tslib_1.__generator(this, function (_a) {
|
50 | return [2, new Promise(function (resolve, reject) {
|
51 | var totalBytes = 0;
|
52 | var cleanup = function () {
|
53 | readStream.removeListener("data", handleData);
|
54 | readStream.removeListener("error", handleError);
|
55 | readStream.removeListener("end", handleEnd);
|
56 | };
|
57 | var handleError = function (err) {
|
58 | cleanup();
|
59 | reject(err);
|
60 | };
|
61 | readStream.on("error", handleError);
|
62 | var handleData = function (data) {
|
63 | totalBytes += data.length;
|
64 | };
|
65 | readStream.on("data", handleData);
|
66 | var handleEnd = function () {
|
67 | cleanup();
|
68 | resolve(totalBytes);
|
69 | };
|
70 | readStream.on("end", handleEnd);
|
71 | })];
|
72 | });
|
73 | });
|
74 | }
|
75 | var zip1 = function (file) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
76 | return tslib_1.__generator(this, function (_a) {
|
77 | return [2, new Promise(function (resolve, reject) {
|
78 | var zip = new StreamZip({
|
79 | file: file,
|
80 | storeEntries: true,
|
81 | });
|
82 | zip.on("error", function (err) {
|
83 | console.log("--ZIP error: " + filePath);
|
84 | console.log(err);
|
85 | reject(err);
|
86 | });
|
87 | zip.on("entry", function (_entry) {
|
88 | });
|
89 | zip.on("extract", function (entry, f) {
|
90 | console.log("--ZIP extract:");
|
91 | console.log(entry.name);
|
92 | console.log(f);
|
93 | });
|
94 | zip.on("ready", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
95 | var zipEntries, crcs, _loop_1, _i, zipEntries_1, zipEntry;
|
96 | return tslib_1.__generator(this, function (_a) {
|
97 | switch (_a.label) {
|
98 | case 0:
|
99 | zipEntries = Object.values(zip.entries());
|
100 | crcs = zipEntries.map(function (zipEntry) {
|
101 | if (zipEntry.isDirectory) {
|
102 | return 0;
|
103 | }
|
104 | else {
|
105 | if (!zipEntry.crc && zipEntry.size) {
|
106 | console.log("1 CRC zero? ".concat(zipEntry.name, " (").concat(zipEntry.size, " bytes) => ").concat(zipEntry.crc));
|
107 | }
|
108 | return zipEntry.crc;
|
109 | }
|
110 | }).filter(function (val) {
|
111 | return val;
|
112 | });
|
113 | if (!READ_ZIP_STREAMS) return [3, 5];
|
114 | if (VERBOSE) {
|
115 | process.stdout.write("## 1 ##\n");
|
116 | }
|
117 | _loop_1 = function (zipEntry) {
|
118 | var promize, size;
|
119 | return tslib_1.__generator(this, function (_b) {
|
120 | switch (_b.label) {
|
121 | case 0:
|
122 | if (zipEntry.isDirectory) {
|
123 | return [2, "continue"];
|
124 | }
|
125 | promize = new Promise(function (res, rej) {
|
126 | zip.stream(zipEntry.name, function (err, stream) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
127 | var totalBytes;
|
128 | return tslib_1.__generator(this, function (_a) {
|
129 | if (err) {
|
130 | console.log(err);
|
131 | rej(err);
|
132 | return [2];
|
133 | }
|
134 | totalBytes = streamReadAll(stream);
|
135 | process.nextTick(function () {
|
136 | res(totalBytes);
|
137 | });
|
138 | return [2];
|
139 | });
|
140 | }); });
|
141 | });
|
142 | return [4, promize];
|
143 | case 1:
|
144 | size = _b.sent();
|
145 | if (zipEntry.size !== size) {
|
146 | console.log("1 SIZE MISMATCH? ".concat(zipEntry.name, " ").concat(zipEntry.size, " != ").concat(size));
|
147 | }
|
148 | if (VERBOSE) {
|
149 | process.stdout.write(" ".concat(zipEntry.name, " "));
|
150 | }
|
151 | else if (!UNVERBOSE) {
|
152 | process.stdout.write(".");
|
153 | }
|
154 | return [2];
|
155 | }
|
156 | });
|
157 | };
|
158 | _i = 0, zipEntries_1 = zipEntries;
|
159 | _a.label = 1;
|
160 | case 1:
|
161 | if (!(_i < zipEntries_1.length)) return [3, 4];
|
162 | zipEntry = zipEntries_1[_i];
|
163 | return [5, _loop_1(zipEntry)];
|
164 | case 2:
|
165 | _a.sent();
|
166 | _a.label = 3;
|
167 | case 3:
|
168 | _i++;
|
169 | return [3, 1];
|
170 | case 4:
|
171 | if (!UNVERBOSE) {
|
172 | process.stdout.write("\n");
|
173 | }
|
174 | _a.label = 5;
|
175 | case 5:
|
176 | process.nextTick(function () {
|
177 | zip.close();
|
178 | process.nextTick(function () {
|
179 | resolve(crcs);
|
180 | });
|
181 | });
|
182 | return [2];
|
183 | }
|
184 | });
|
185 | }); });
|
186 | })];
|
187 | });
|
188 | }); };
|
189 | zip1.zipName = "node-stream-zip";
|
190 | var zip2 = function (file) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
191 | return tslib_1.__generator(this, function (_a) {
|
192 | return [2, new Promise(function (resolve, reject) {
|
193 | var crcs;
|
194 | yauzl.open(file, { lazyEntries: true, autoClose: false }, function (error, zip) {
|
195 | if (error || !zip) {
|
196 | console.log("yauzl init ERROR");
|
197 | console.log(error);
|
198 | reject(error);
|
199 | return;
|
200 | }
|
201 | zip.on("error", function (erro) {
|
202 | console.log("yauzl ERROR");
|
203 | console.log(erro);
|
204 | reject(erro);
|
205 | });
|
206 | if (READ_ZIP_STREAMS && VERBOSE) {
|
207 | process.stdout.write("## 2 ##\n");
|
208 | }
|
209 | zip.readEntry();
|
210 | zip.on("entry", function (zipEntry) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
211 | var promize, size;
|
212 | return tslib_1.__generator(this, function (_a) {
|
213 | switch (_a.label) {
|
214 | case 0:
|
215 | if (!(zipEntry.fileName[zipEntry.fileName.length - 1] === "/")) return [3, 1];
|
216 | return [3, 3];
|
217 | case 1:
|
218 | if (!zipEntry.crc32 && zipEntry.uncompressedSize) {
|
219 | console.log("2 CRC zero? ".concat(zipEntry.fileName, " (").concat(zipEntry.uncompressedSize, " bytes) => ").concat(zipEntry.crc32));
|
220 | }
|
221 | if (!crcs) {
|
222 | crcs = [];
|
223 | }
|
224 | crcs.push(zipEntry.crc32);
|
225 | if (!READ_ZIP_STREAMS) return [3, 3];
|
226 | promize = new Promise(function (res, rej) {
|
227 | zip.openReadStream(zipEntry, function (err, stream) {
|
228 | if (err || !stream) {
|
229 | console.log(err);
|
230 | rej(err);
|
231 | return;
|
232 | }
|
233 | var totalBytes = streamReadAll(stream);
|
234 | process.nextTick(function () {
|
235 | res(totalBytes);
|
236 | });
|
237 | });
|
238 | });
|
239 | return [4, promize];
|
240 | case 2:
|
241 | size = _a.sent();
|
242 | if (zipEntry.uncompressedSize !== size) {
|
243 | console.log("2 SIZE MISMATCH? ".concat(zipEntry.fileName, " ").concat(zipEntry.uncompressedSize, " != ").concat(size));
|
244 | }
|
245 | if (VERBOSE) {
|
246 | process.stdout.write(" ".concat(zipEntry.fileName, " "));
|
247 | }
|
248 | else if (!UNVERBOSE) {
|
249 | process.stdout.write(".");
|
250 | }
|
251 | _a.label = 3;
|
252 | case 3:
|
253 | zip.readEntry();
|
254 | return [2];
|
255 | }
|
256 | });
|
257 | }); });
|
258 | zip.on("end", function () {
|
259 | if (READ_ZIP_STREAMS && !UNVERBOSE) {
|
260 | process.stdout.write("\n");
|
261 | }
|
262 | process.nextTick(function () {
|
263 | zip.close();
|
264 | process.nextTick(function () {
|
265 | if (!crcs) {
|
266 | reject(crcs);
|
267 | return;
|
268 | }
|
269 | resolve(crcs.filter(function (val) {
|
270 | return val;
|
271 | }));
|
272 | });
|
273 | });
|
274 | });
|
275 | zip.on("close", function () {
|
276 | });
|
277 | });
|
278 | })];
|
279 | });
|
280 | }); };
|
281 | zip2.zipName = "yauzl";
|
282 | var streams = {};
|
283 | var zip3 = function (file) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
284 | return tslib_1.__generator(this, function (_a) {
|
285 | return [2, new Promise(function (resolve, reject) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
286 | var zip, err_1, crcs, _loop_2, _i, _a, zipEntry, state_1;
|
287 | return tslib_1.__generator(this, function (_b) {
|
288 | switch (_b.label) {
|
289 | case 0:
|
290 | _b.trys.push([0, 2, , 3]);
|
291 | return [4, unzipper.Open.file(file)];
|
292 | case 1:
|
293 | zip = _b.sent();
|
294 | return [3, 3];
|
295 | case 2:
|
296 | err_1 = _b.sent();
|
297 | console.log(err_1);
|
298 | reject(err_1);
|
299 | return [2];
|
300 | case 3:
|
301 | crcs = zip.files.map(function (zipEntry) {
|
302 | if (zipEntry.type === "Directory") {
|
303 | return 0;
|
304 | }
|
305 | else {
|
306 | if (!zipEntry.crc32 && zipEntry.uncompressedSize) {
|
307 | console.log("3 CRC zero? ".concat(zipEntry.path, " (").concat(zipEntry.uncompressedSize, " bytes) => ").concat(zipEntry.crc32));
|
308 | }
|
309 | return zipEntry.crc32;
|
310 | }
|
311 | }).filter(function (val) {
|
312 | return val;
|
313 | });
|
314 | if (!READ_ZIP_STREAMS) return [3, 8];
|
315 | if (VERBOSE) {
|
316 | process.stdout.write("## 3 ##\n");
|
317 | }
|
318 | _loop_2 = function (zipEntry) {
|
319 | var stream, promize, size, err_2;
|
320 | return tslib_1.__generator(this, function (_c) {
|
321 | switch (_c.label) {
|
322 | case 0:
|
323 | if (zipEntry.type === "Directory") {
|
324 | return [2, "continue"];
|
325 | }
|
326 | stream = zipEntry.stream();
|
327 | stream.on("error", function (err) {
|
328 | console.log("err1");
|
329 | console.log(err);
|
330 | });
|
331 | stream.__ZIP_FILE_PATH = file;
|
332 | stream.__ZIP_RESOURCE_PATH = zipEntry.path;
|
333 | if (!streams[file]) {
|
334 | streams[file] = {};
|
335 | }
|
336 | streams[file][zipEntry.path] = stream;
|
337 | stream.on("end", function () {
|
338 | process.nextTick(function () {
|
339 | delete streams[stream.__ZIP_FILE_PATH][stream.__ZIP_RESOURCE_PATH];
|
340 | });
|
341 | });
|
342 | promize = streamReadAll(stream);
|
343 | size = void 0;
|
344 | _c.label = 1;
|
345 | case 1:
|
346 | _c.trys.push([1, 3, , 4]);
|
347 | return [4, promize];
|
348 | case 2:
|
349 | size = _c.sent();
|
350 | return [3, 4];
|
351 | case 3:
|
352 | err_2 = _c.sent();
|
353 | console.log("err2");
|
354 | console.log(err_2);
|
355 | reject(err_2);
|
356 | return [2, { value: void 0 }];
|
357 | case 4:
|
358 | if (zipEntry.uncompressedSize !== size) {
|
359 | console.log("3 SIZE MISMATCH? ".concat(zipEntry.path, " ").concat(zipEntry.uncompressedSize, " != ").concat(size));
|
360 | }
|
361 | if (VERBOSE) {
|
362 | process.stdout.write(" ".concat(zipEntry.path, " "));
|
363 | }
|
364 | else if (!UNVERBOSE) {
|
365 | process.stdout.write(".");
|
366 | }
|
367 | return [2];
|
368 | }
|
369 | });
|
370 | };
|
371 | _i = 0, _a = zip.files;
|
372 | _b.label = 4;
|
373 | case 4:
|
374 | if (!(_i < _a.length)) return [3, 7];
|
375 | zipEntry = _a[_i];
|
376 | return [5, _loop_2(zipEntry)];
|
377 | case 5:
|
378 | state_1 = _b.sent();
|
379 | if (typeof state_1 === "object")
|
380 | return [2, state_1.value];
|
381 | _b.label = 6;
|
382 | case 6:
|
383 | _i++;
|
384 | return [3, 4];
|
385 | case 7:
|
386 | if (!UNVERBOSE) {
|
387 | process.stdout.write("\n");
|
388 | }
|
389 | process.nextTick(function () {
|
390 | delete streams[file];
|
391 | });
|
392 | _b.label = 8;
|
393 | case 8:
|
394 | resolve(crcs);
|
395 | return [2];
|
396 | }
|
397 | });
|
398 | }); })];
|
399 | });
|
400 | }); };
|
401 | zip3.zipName = "unzipper";
|
402 | var zips = READ_ZIP_STREAMS ? [zip1, zip2] :
|
403 | [zip1, zip2, zip3];
|
404 | function processFile(file) {
|
405 | return tslib_1.__awaiter(this, void 0, void 0, function () {
|
406 | var winner, minNanoOverall, iZip, _i, zips_1, zip, crcsPreviousIteration, i, time, crcs, diffTime, nanos, crcsPreviousZip, isDiff, _a, zips_2, zip, _b, zips_3, zip, j, zip, nDiffs, k, zip_, _c, zips_4, zip, won;
|
407 | return tslib_1.__generator(this, function (_d) {
|
408 | switch (_d.label) {
|
409 | case 0:
|
410 | console.log("=====================================");
|
411 | if (!UNVERBOSE) {
|
412 | console.log("".concat(file));
|
413 | console.log("=====================================");
|
414 | }
|
415 | winner = 0;
|
416 | minNanoOverall = Number.MAX_SAFE_INTEGER;
|
417 | iZip = 0;
|
418 | _i = 0, zips_1 = zips;
|
419 | _d.label = 1;
|
420 | case 1:
|
421 | if (!(_i < zips_1.length)) return [3, 7];
|
422 | zip = zips_1[_i];
|
423 | iZip++;
|
424 | zip.minNano = Number.MAX_SAFE_INTEGER;
|
425 | if (VERBOSE) {
|
426 | console.log("-------------------------------");
|
427 | }
|
428 | crcsPreviousIteration = void 0;
|
429 | i = 0;
|
430 | _d.label = 2;
|
431 | case 2:
|
432 | if (!(i < N_ITERATIONS)) return [3, 5];
|
433 | process.stdout.write("".concat(i + 1, "/").concat(N_ITERATIONS, " "));
|
434 | time = process.hrtime();
|
435 | return [4, zip(file)];
|
436 | case 3:
|
437 | crcs = _d.sent();
|
438 | diffTime = process.hrtime(time);
|
439 | nanos = diffTime[0] * 1e9 + diffTime[1];
|
440 | if (nanos < zip.minNano) {
|
441 | zip.minNano = nanos;
|
442 | }
|
443 | if (nanos < minNanoOverall) {
|
444 | minNanoOverall = nanos;
|
445 | winner = iZip;
|
446 | }
|
447 | if (VERBOSE) {
|
448 | console.log("Zip ".concat(iZip, " (").concat(crcs.length, "): ").concat(diffTime[0], " seconds + ").concat(diffTime[1], " nanoseconds"));
|
449 | }
|
450 | if (crcsPreviousIteration) {
|
451 | if (!sameArrays(crcsPreviousIteration, crcs)) {
|
452 | console.log("++++ Zip ".concat(iZip, " (ITERATION ").concat(i, ") CRC DIFF!?"));
|
453 | console.log("-- ".concat(crcsPreviousIteration.length, ":"));
|
454 | console.log(JSON.stringify(crcsPreviousIteration, null, 2));
|
455 | console.log("-- ".concat(crcs.length, ":"));
|
456 | console.log(JSON.stringify(crcs, null, 2));
|
457 | process.exit(1);
|
458 | }
|
459 | }
|
460 | crcsPreviousIteration = crcs;
|
461 | _d.label = 4;
|
462 | case 4:
|
463 | i++;
|
464 | return [3, 2];
|
465 | case 5:
|
466 | zip.CRCs = crcsPreviousIteration;
|
467 | if (!VERBOSE) {
|
468 | console.log("\n");
|
469 | }
|
470 | _d.label = 6;
|
471 | case 6:
|
472 | _i++;
|
473 | return [3, 1];
|
474 | case 7:
|
475 | isDiff = false;
|
476 | for (_a = 0, zips_2 = zips; _a < zips_2.length; _a++) {
|
477 | zip = zips_2[_a];
|
478 | if (crcsPreviousZip && zip.CRCs) {
|
479 | isDiff = !sameArrays(crcsPreviousZip, zip.CRCs);
|
480 | if (isDiff) {
|
481 | break;
|
482 | }
|
483 | }
|
484 | crcsPreviousZip = zip.CRCs;
|
485 | }
|
486 | if (isDiff) {
|
487 | console.log("CRC DIFF! ##############################################");
|
488 | iZip = 0;
|
489 | for (_b = 0, zips_3 = zips; _b < zips_3.length; _b++) {
|
490 | zip = zips_3[_b];
|
491 | iZip++;
|
492 | console.log("==========================");
|
493 | console.log("++++ Zip ".concat(iZip, " CRC:"));
|
494 | console.log("-- ".concat(zip.CRCs.length, ":"));
|
495 | console.log(JSON.stringify(zip.CRCs));
|
496 | }
|
497 | for (j = 0; j < zips.length; j++) {
|
498 | zip = zips[j];
|
499 | nDiffs = 0;
|
500 | for (k = 0; k < zips.length; k++) {
|
501 | if (j === k) {
|
502 | continue;
|
503 | }
|
504 | zip_ = zips[k];
|
505 | if (!sameArrays(zip.CRCs, zip_.CRCs)) {
|
506 | nDiffs++;
|
507 | }
|
508 | }
|
509 | if (nDiffs === (zips.length - 1)) {
|
510 | console.log("####################################");
|
511 | console.log("####################################");
|
512 | console.log("SUSPECT ====> Zip ".concat(j + 1, " (").concat(zip.zipName, ")"));
|
513 | console.log("####################################");
|
514 | console.log("####################################");
|
515 | }
|
516 | }
|
517 | process.exit(1);
|
518 | }
|
519 | if (VERBOSE) {
|
520 | console.log("=====================================");
|
521 | }
|
522 | iZip = 0;
|
523 | for (_c = 0, zips_4 = zips; _c < zips_4.length; _c++) {
|
524 | zip = zips_4[_c];
|
525 | iZip++;
|
526 | won = iZip === winner;
|
527 | console.log("".concat(won ? ">>" : "--", " Zip ").concat(iZip, " (").concat(zip.zipName, ") => ").concat(zip.minNano.toLocaleString(), " nanoseconds ").concat(won ? " [ WINNER ]" : "[ +".concat((zip.minNano - minNanoOverall).toLocaleString(), " ]")));
|
528 | }
|
529 | return [2];
|
530 | }
|
531 | });
|
532 | });
|
533 | }
|
534 | if (stats.isDirectory()) {
|
535 | (function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
536 | var files, _i, files_1, file;
|
537 | return tslib_1.__generator(this, function (_a) {
|
538 | switch (_a.label) {
|
539 | case 0:
|
540 | files = fs.readdirSync(filePath, { withFileTypes: true }).
|
541 | filter(function (f) { return f.isFile() &&
|
542 | /((\.epub3?)|(\.zip)|(\.cbz))$/i.test(f.name); }).
|
543 | map(function (f) { return path.join(filePath, f.name); });
|
544 | _i = 0, files_1 = files;
|
545 | _a.label = 1;
|
546 | case 1:
|
547 | if (!(_i < files_1.length)) return [3, 4];
|
548 | file = files_1[_i];
|
549 | return [4, processFile(file)];
|
550 | case 2:
|
551 | _a.sent();
|
552 | _a.label = 3;
|
553 | case 3:
|
554 | _i++;
|
555 | return [3, 1];
|
556 | case 4: return [2];
|
557 | }
|
558 | });
|
559 | }); })();
|
560 | }
|
561 | else if (/((\.epub3?)|(\.cbz)|(\.zip))$/i.test(ext)) {
|
562 | (function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
563 | return tslib_1.__generator(this, function (_a) {
|
564 | switch (_a.label) {
|
565 | case 0: return [4, processFile(filePath)];
|
566 | case 1:
|
567 | _a.sent();
|
568 | return [2];
|
569 | }
|
570 | });
|
571 | }); })();
|
572 | }
|
573 | function sameArrays(arr1, arr2) {
|
574 | if (arr1.length !== arr2.length) {
|
575 | return false;
|
576 | }
|
577 | for (var j = 0; j < arr1.length; j++) {
|
578 | if (arr1[j] !== arr2[j]) {
|
579 | return false;
|
580 | }
|
581 | }
|
582 | return true;
|
583 | }
|
584 |
|
\ | No newline at end of file |