🪛 Data transferring over sockets!
This commit is contained in:
94
package-lock.json
generated
94
package-lock.json
generated
@@ -1099,15 +1099,6 @@
|
||||
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/oboe": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/oboe/-/oboe-2.1.0.tgz",
|
||||
"integrity": "sha512-2F95dk3QRgauL9gTUrydXkmnHA1tSCMzqwlSwXlfuBW8Y8F4IfgHecdTf7x4UX9sn3dpNKpfk297r+f/YHJXtA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/pino": {
|
||||
"version": "6.3.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/pino/-/pino-6.3.8.tgz",
|
||||
@@ -1507,14 +1498,6 @@
|
||||
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
|
||||
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"babel-jest": {
|
||||
"version": "25.5.1",
|
||||
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz",
|
||||
@@ -3504,11 +3487,6 @@
|
||||
"resolved": "https://registry.npmjs.org/fn-args/-/fn-args-5.0.0.tgz",
|
||||
"integrity": "sha512-CtbfI3oFFc3nbdIoHycrfbrxiGgxXBXXuyOl49h47JawM1mYrqpiRqnH5CB2mBatdXvHHOUO6a+RiAuuvKt0lw=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
|
||||
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg=="
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
@@ -3840,19 +3818,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"highland": {
|
||||
"version": "2.13.5",
|
||||
"resolved": "https://registry.npmjs.org/highland/-/highland-2.13.5.tgz",
|
||||
"integrity": "sha512-dn2flPapIIAa4BtkB2ahjshg8iSJtrJtdhEb9/oiOrS5HMQTR/GuhFpqJ+11YBdtnl3AwWKvbZd1Uxr8uAmA7A==",
|
||||
"requires": {
|
||||
"util-deprecate": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"highland-json": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/highland-json/-/highland-json-1.4.1.tgz",
|
||||
"integrity": "sha512-rZDAxg5gfSQVnuQ6LHnrBzouxt9WNM4uNiFAp8X+LDuz1TiO63rnf5wPnDWkJLzEnbSsrN7ks3lIIibmbNuKmg=="
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||
@@ -3893,11 +3858,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-https": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz",
|
||||
"integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs="
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
@@ -5702,19 +5662,6 @@
|
||||
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
|
||||
"dev": true
|
||||
},
|
||||
"json-stream-stringify": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/json-stream-stringify/-/json-stream-stringify-2.0.3.tgz",
|
||||
"integrity": "sha512-Ry+1rZE1YVKlCMG1emCiReP/OfZrFrEGZn6TC7NPpIGO9NXf0KEqqBL0flgt2J59EiRPv+CKi7S7v31RAHrdXw=="
|
||||
},
|
||||
"json-streamify": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/json-streamify/-/json-streamify-0.1.4.tgz",
|
||||
"integrity": "sha1-HBgHSnAJv3vS0hRDzEJbmGTNCJ0=",
|
||||
"requires": {
|
||||
"traverse": ">=0.2.6"
|
||||
}
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
@@ -6725,14 +6672,6 @@
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"oboe": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.5.tgz",
|
||||
"integrity": "sha1-VVQoTFQ6ImbXo48X4HOCH73jk80=",
|
||||
"requires": {
|
||||
"http-https": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
@@ -8542,19 +8481,6 @@
|
||||
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
|
||||
"dev": true
|
||||
},
|
||||
"stream-chain": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.4.tgz",
|
||||
"integrity": "sha512-9lsl3YM53V5N/I1C2uJtc3Kavyi3kNYN83VkKb/bMWRk7D9imiFyUPYa0PoZbLohSVOX1mYE9YsmwObZUsth6Q=="
|
||||
},
|
||||
"stream-json": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.7.1.tgz",
|
||||
"integrity": "sha512-I7g0IDqvdJXbJ279/D3ZoTx0VMhmKnEF7u38CffeWdF8bfpMPsLo+5fWnkNjO2GU/JjWaRjdH+zmH03q+XGXFw==",
|
||||
"requires": {
|
||||
"stream-chain": "^2.2.3"
|
||||
}
|
||||
},
|
||||
"streamsearch": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
|
||||
@@ -8821,26 +8747,6 @@
|
||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||
},
|
||||
"through2": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
|
||||
"integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
|
||||
"requires": {
|
||||
"readable-stream": "3"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"timers-ext": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
|
||||
|
||||
10
package.json
10
package.json
@@ -18,7 +18,6 @@
|
||||
"author": "",
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/oboe": "^2.1.0",
|
||||
"@types/unzipper": "^0.10.3",
|
||||
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
||||
"@typescript-eslint/parser": "^2.26.0",
|
||||
@@ -38,12 +37,7 @@
|
||||
"@types/node": "^13.9.8",
|
||||
"@types/pino": "^6.3.8",
|
||||
"JSONStream": "^1.3.5",
|
||||
"axios": "^0.21.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"highland": "^2.13.5",
|
||||
"highland-json": "^1.4.1",
|
||||
"json-stream-stringify": "^2.0.3",
|
||||
"json-streamify": "^0.1.4",
|
||||
"lodash": "^4.17.21",
|
||||
"moleculer": "^0.14.0",
|
||||
"moleculer-db": "^0.8.4",
|
||||
@@ -54,15 +48,11 @@
|
||||
"mongoose-paginate": "^5.0.3",
|
||||
"nats": "^1.3.2",
|
||||
"node-unrar-js": "^1.0.2",
|
||||
"oboe": "^2.1.5",
|
||||
"pino": "^6.11.3",
|
||||
"pino-pretty": "^4.7.1",
|
||||
"sharp": "^0.28.1",
|
||||
"socket.io": "^4.1.1",
|
||||
"socket.io-stream": "^0.9.1",
|
||||
"stream-chain": "^2.2.4",
|
||||
"stream-json": "^1.7.1",
|
||||
"through2": "^4.0.2",
|
||||
"typescript": "^3.8.3",
|
||||
"unzipper": "^0.10.11"
|
||||
},
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
import { IncomingMessage } from "http";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { Service, ServiceBroker, Context } from "moleculer";
|
||||
import ApiGateway from "moleculer-web";
|
||||
import { getCovers, extractArchive } from "../utils/uncompression.utils";
|
||||
import { map, flatten } from "lodash";
|
||||
import JSONStream from "JSONStream";
|
||||
import { extractArchive } from "../utils/uncompression.utils";
|
||||
import { map } from "lodash";
|
||||
const IO = require("socket.io")();
|
||||
const ss = require("socket.io-stream");
|
||||
const JsonStreamStringify = require("json-stream-stringify");
|
||||
import axios from "axios";
|
||||
const { Writable, Readable } = require("stream");
|
||||
|
||||
export default class ApiService extends Service {
|
||||
public constructor(broker: ServiceBroker) {
|
||||
@@ -34,12 +26,7 @@ export default class ApiService extends Service {
|
||||
mergeParams: true,
|
||||
autoAliases: true,
|
||||
|
||||
aliases: {
|
||||
async "POST getComicCovers"(req, res) {
|
||||
const { extractionOptions, walkedFolders } =
|
||||
req.body;
|
||||
},
|
||||
},
|
||||
aliases: {},
|
||||
|
||||
// Calling options. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Calling-options
|
||||
callingOptions: {},
|
||||
@@ -105,25 +92,20 @@ export default class ApiService extends Service {
|
||||
params
|
||||
);
|
||||
const { extractionOptions, walkedFolders } = params;
|
||||
const stream = ss.createStream();
|
||||
switch (extractionOptions.extractionMode) {
|
||||
case "bulk":
|
||||
map(walkedFolders, async (folder, idx) => {
|
||||
let foo = await extractArchive(
|
||||
extractionOptions,
|
||||
folder
|
||||
);
|
||||
|
||||
let fo = new JsonStreamStringify({
|
||||
foo,
|
||||
});
|
||||
let comicBookCoverMetadata =
|
||||
await extractArchive(
|
||||
extractionOptions,
|
||||
folder
|
||||
);
|
||||
|
||||
client.emit("comicBookCoverMetadata", {
|
||||
data: foo,
|
||||
data: comicBookCoverMetadata,
|
||||
status: "Done!",
|
||||
});
|
||||
});
|
||||
// res.end();
|
||||
|
||||
case "single":
|
||||
return await extractArchive(
|
||||
@@ -141,13 +123,6 @@ export default class ApiService extends Service {
|
||||
data: `${extractionOptions}`,
|
||||
};
|
||||
}
|
||||
|
||||
// this.broker
|
||||
// .call("import." + action, params, opts)
|
||||
// .then((resp) => {
|
||||
// // client.emit("comicBookCoverMetadata", resp);
|
||||
// })
|
||||
// .catch((err) => this.logger.error(err));
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,33 +1,8 @@
|
||||
"use strict";
|
||||
import { Context, Service, ServiceBroker, ServiceSchema } from "moleculer";
|
||||
import fs from "fs";
|
||||
import { DbMixin } from "../mixins/db.mixin";
|
||||
import Comic from "../models/comic.model";
|
||||
import { map, flatten, isUndefined } from "lodash";
|
||||
import {
|
||||
extractArchive,
|
||||
getCovers,
|
||||
walkFolder,
|
||||
} from "../utils/uncompression.utils";
|
||||
import {
|
||||
IExtractionOptions,
|
||||
IExtractedComicBookCoverFile,
|
||||
IFolderData,
|
||||
} from "../interfaces/folder.interface";
|
||||
import axios from "axios";
|
||||
import { Readable } from "stream";
|
||||
import through2 from "through2";
|
||||
import oboe from "oboe";
|
||||
import H from "highland";
|
||||
import { stringify } from "highland-json";
|
||||
const JsonStreamStringify = require("json-stream-stringify");
|
||||
const IO = require("socket.io")();
|
||||
const { chain } = require("stream-chain");
|
||||
const { parser } = require("stream-json");
|
||||
const { pick } = require("stream-json/filters/Pick");
|
||||
const { ignore } = require("stream-json/filters/Ignore");
|
||||
const { streamValues } = require("stream-json/streamers/StreamValues");
|
||||
const StreamArray = require("stream-json/streamers/StreamArray");
|
||||
import { walkFolder } from "../utils/uncompression.utils";
|
||||
|
||||
export default class ProductsService extends Service {
|
||||
// @ts-ignore
|
||||
@@ -66,57 +41,6 @@ export default class ProductsService extends Service {
|
||||
);
|
||||
},
|
||||
},
|
||||
// getComicCovers: {
|
||||
// rest: "POST /getComicCovers",
|
||||
// params: {
|
||||
// extractionOptions: "object",
|
||||
// walkedFolders: "array",
|
||||
// },
|
||||
// async handler(
|
||||
// ctx: Context<{
|
||||
// extractionOptions: IExtractionOptions;
|
||||
// walkedFolders: IFolderData[];
|
||||
// }>
|
||||
// ) {
|
||||
// switch (
|
||||
// ctx.params.extractionOptions.extractionMode
|
||||
// ) {
|
||||
// case "bulk":
|
||||
// map(
|
||||
// ctx.params.walkedFolders,
|
||||
// async (folder, idx) => {
|
||||
// let foo = await extractArchive(
|
||||
// ctx.params
|
||||
// .extractionOptions,
|
||||
// folder
|
||||
// );
|
||||
// // console.log("levar", foo);
|
||||
// let jsonStream =
|
||||
// new JsonStreamStringify({
|
||||
// foo,
|
||||
// });
|
||||
// return jsonStream;
|
||||
// }
|
||||
// );
|
||||
//
|
||||
// case "single":
|
||||
// return await extractArchive(
|
||||
// ctx.params.extractionOptions,
|
||||
// ctx.params.walkedFolders[0]
|
||||
// );
|
||||
// default:
|
||||
// console.log(
|
||||
// "Unknown extraction mode selected."
|
||||
// );
|
||||
// return {
|
||||
// message:
|
||||
// "Unknown extraction mode selected.",
|
||||
// errorCode: "90",
|
||||
// data: `${ctx.params.extractionOptions}`,
|
||||
// };
|
||||
// }
|
||||
// },
|
||||
// },
|
||||
},
|
||||
methods: {},
|
||||
},
|
||||
|
||||
@@ -37,11 +37,11 @@ import { default as unzipper } from "unzipper";
|
||||
import _ from "lodash";
|
||||
import { each, isEmpty, map, remove, indexOf } from "lodash";
|
||||
import {
|
||||
IExplodedPathResponse,
|
||||
IExtractComicBookCoverErrorResponse,
|
||||
IExtractedComicBookCoverFile,
|
||||
IExtractionOptions,
|
||||
IFolderData,
|
||||
IExplodedPathResponse,
|
||||
IExtractComicBookCoverErrorResponse,
|
||||
IExtractedComicBookCoverFile,
|
||||
IExtractionOptions,
|
||||
IFolderData,
|
||||
} from "../interfaces/folder.interface";
|
||||
import { logger } from "./logger.utils";
|
||||
const { writeFile, readFile } = require("fs").promises;
|
||||
@@ -50,274 +50,299 @@ const unrarer = require("node-unrar-js");
|
||||
const Walk = require("@root/walk");
|
||||
const fse = require("fs-extra");
|
||||
|
||||
|
||||
export const unrar = async (
|
||||
extractionOptions: IExtractionOptions,
|
||||
walkedFolder: IFolderData,
|
||||
extractionOptions: IExtractionOptions,
|
||||
walkedFolder: IFolderData
|
||||
): Promise<
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractedComicBookCoverFile[]
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractedComicBookCoverFile[]
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
> => {
|
||||
const paths = constructPaths(extractionOptions, walkedFolder);
|
||||
const directoryOptions = {
|
||||
mode: 0o2775,
|
||||
};
|
||||
const fileBuffer = await readFile(paths.inputFilePath).catch(err =>
|
||||
console.error("Failed to read file", err),
|
||||
);
|
||||
try {
|
||||
await fse.ensureDir(paths.targetPath, directoryOptions);
|
||||
logger.info(`${paths.targetPath} was created.`);
|
||||
} catch (error) {
|
||||
logger.error(`${error}: Couldn't create directory.`);
|
||||
}
|
||||
const paths = constructPaths(extractionOptions, walkedFolder);
|
||||
const directoryOptions = {
|
||||
mode: 0o2775,
|
||||
};
|
||||
const fileBuffer = await readFile(paths.inputFilePath).catch((err) =>
|
||||
console.error("Failed to read file", err)
|
||||
);
|
||||
try {
|
||||
await fse.ensureDir(paths.targetPath, directoryOptions);
|
||||
logger.info(`${paths.targetPath} was created.`);
|
||||
} catch (error) {
|
||||
logger.error(`${error}: Couldn't create directory.`);
|
||||
}
|
||||
|
||||
const extractor = await unrarer.createExtractorFromData({ data: fileBuffer });
|
||||
const extractor = await unrarer.createExtractorFromData({
|
||||
data: fileBuffer,
|
||||
});
|
||||
|
||||
switch (extractionOptions.extractTarget) {
|
||||
case "cover":
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let fileNameToExtract = "";
|
||||
const list = extractor.getFileList();
|
||||
const fileHeaders = [...list.fileHeaders];
|
||||
each(fileHeaders, async fileHeader => {
|
||||
const fileName = explodePath(fileHeader.name).fileName;
|
||||
if (
|
||||
fileName !== "" &&
|
||||
fileHeader.flags.directory === false &&
|
||||
isEmpty(fileNameToExtract)
|
||||
) {
|
||||
logger.info(`Attempting to write ${fileHeader.name}`);
|
||||
fileNameToExtract = fileHeader.name;
|
||||
const file = extractor.extract({ files: [fileHeader.name] });
|
||||
const extractedFile = [...file.files][0];
|
||||
const fileArrayBuffer = extractedFile.extraction;
|
||||
await writeFile(
|
||||
paths.targetPath + "/" + fileName,
|
||||
fileArrayBuffer,
|
||||
);
|
||||
resolve({
|
||||
name: `${fileName}`,
|
||||
path: paths.targetPath,
|
||||
fileSize: fileHeader.packSize,
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(`${error}: Couldn't write file.`);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
switch (extractionOptions.extractTarget) {
|
||||
case "cover":
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
let fileNameToExtract = "";
|
||||
const list = extractor.getFileList();
|
||||
const fileHeaders = [...list.fileHeaders];
|
||||
each(fileHeaders, async (fileHeader) => {
|
||||
const fileName = explodePath(fileHeader.name).fileName;
|
||||
if (
|
||||
fileName !== "" &&
|
||||
fileHeader.flags.directory === false &&
|
||||
isEmpty(fileNameToExtract)
|
||||
) {
|
||||
logger.info(
|
||||
`Attempting to write ${fileHeader.name}`
|
||||
);
|
||||
fileNameToExtract = fileHeader.name;
|
||||
const file = extractor.extract({
|
||||
files: [fileHeader.name],
|
||||
});
|
||||
const extractedFile = [...file.files][0];
|
||||
const fileArrayBuffer = extractedFile.extraction;
|
||||
await writeFile(
|
||||
paths.targetPath + "/" + fileName,
|
||||
fileArrayBuffer
|
||||
);
|
||||
resolve({
|
||||
name: `${fileName}`,
|
||||
path: paths.targetPath,
|
||||
fileSize: fileHeader.packSize,
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(`${error}: Couldn't write file.`);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
|
||||
case "all":
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const files = extractor.extract({});
|
||||
const extractedFiles = [...files.files];
|
||||
const comicBookCoverFiles: IExtractedComicBookCoverFile[] = [];
|
||||
for (const file of extractedFiles) {
|
||||
logger.info(`Attempting to write ${file.fileHeader.name}`);
|
||||
const fileBuffer = file.extraction;
|
||||
const fileName = explodePath(file.fileHeader.name).fileName;
|
||||
case "all":
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const files = extractor.extract({});
|
||||
const extractedFiles = [...files.files];
|
||||
const comicBookCoverFiles: IExtractedComicBookCoverFile[] =
|
||||
[];
|
||||
for (const file of extractedFiles) {
|
||||
logger.info(
|
||||
`Attempting to write ${file.fileHeader.name}`
|
||||
);
|
||||
const fileBuffer = file.extraction;
|
||||
const fileName = explodePath(
|
||||
file.fileHeader.name
|
||||
).fileName;
|
||||
|
||||
if (fileName !== "" && file.fileHeader.flags.directory === false) {
|
||||
await writeFile(paths.targetPath + "/" + fileName, fileBuffer);
|
||||
}
|
||||
comicBookCoverFiles.push({
|
||||
name: `${file.fileHeader.name}`,
|
||||
path: paths.targetPath,
|
||||
fileSize: file.fileHeader.packSize,
|
||||
});
|
||||
}
|
||||
resolve(_.flatten(comicBookCoverFiles));
|
||||
} catch (error) {
|
||||
resolve({
|
||||
message: `${error}`,
|
||||
errorCode: "500",
|
||||
data: walkedFolder.name,
|
||||
});
|
||||
}
|
||||
});
|
||||
if (
|
||||
fileName !== "" &&
|
||||
file.fileHeader.flags.directory === false
|
||||
) {
|
||||
await writeFile(
|
||||
paths.targetPath + "/" + fileName,
|
||||
fileBuffer
|
||||
);
|
||||
}
|
||||
comicBookCoverFiles.push({
|
||||
name: `${file.fileHeader.name}`,
|
||||
path: paths.targetPath,
|
||||
fileSize: file.fileHeader.packSize,
|
||||
});
|
||||
}
|
||||
resolve(_.flatten(comicBookCoverFiles));
|
||||
} catch (error) {
|
||||
resolve({
|
||||
message: `${error}`,
|
||||
errorCode: "500",
|
||||
data: walkedFolder.name,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
default:
|
||||
return {
|
||||
message: "File format not supported, yet.",
|
||||
errorCode: "90",
|
||||
data: "asda",
|
||||
};
|
||||
}
|
||||
default:
|
||||
return {
|
||||
message: "File format not supported, yet.",
|
||||
errorCode: "90",
|
||||
data: "asda",
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const unzip = async (
|
||||
extractionOptions: IExtractionOptions,
|
||||
walkedFolder: IFolderData,
|
||||
extractionOptions: IExtractionOptions,
|
||||
walkedFolder: IFolderData
|
||||
): Promise<
|
||||
| IExtractedComicBookCoverFile[]
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
| IExtractedComicBookCoverFile[]
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
> => {
|
||||
const directoryOptions = {
|
||||
mode: 0o2775,
|
||||
};
|
||||
const paths = constructPaths(extractionOptions, walkedFolder);
|
||||
const directoryOptions = {
|
||||
mode: 0o2775,
|
||||
};
|
||||
const paths = constructPaths(extractionOptions, walkedFolder);
|
||||
|
||||
try {
|
||||
await fse.ensureDir(paths.targetPath, directoryOptions);
|
||||
logger.info(`${paths.targetPath} was created or already exists.`);
|
||||
} catch (error) {
|
||||
logger.error(`${error} Couldn't create directory.`);
|
||||
}
|
||||
try {
|
||||
await fse.ensureDir(paths.targetPath, directoryOptions);
|
||||
logger.info(`${paths.targetPath} was created or already exists.`);
|
||||
} catch (error) {
|
||||
logger.error(`${error} Couldn't create directory.`);
|
||||
}
|
||||
|
||||
const extractedFiles: IExtractedComicBookCoverFile[] = [];
|
||||
const zip = createReadStream(paths.inputFilePath).pipe(
|
||||
unzipper.Parse({ forceStream: true }),
|
||||
);
|
||||
for await (const entry of zip) {
|
||||
const fileName = explodePath(entry.path).fileName;
|
||||
const size = entry.vars.uncompressedSize;
|
||||
if (
|
||||
extractedFiles.length === 1 &&
|
||||
extractionOptions.extractTarget === "cover"
|
||||
) {
|
||||
break;
|
||||
}
|
||||
if (fileName !== "" && entry.type !== "Directory") {
|
||||
logger.info(`Attempting to write ${fileName}`);
|
||||
entry.pipe(createWriteStream(paths.targetPath + "/" + fileName));
|
||||
extractedFiles.push({
|
||||
name: fileName,
|
||||
fileSize: size,
|
||||
path: paths.targetPath,
|
||||
});
|
||||
}
|
||||
entry.autodrain();
|
||||
}
|
||||
const extractedFiles: IExtractedComicBookCoverFile[] = [];
|
||||
const zip = createReadStream(paths.inputFilePath).pipe(
|
||||
unzipper.Parse({ forceStream: true })
|
||||
);
|
||||
for await (const entry of zip) {
|
||||
const fileName = explodePath(entry.path).fileName;
|
||||
const size = entry.vars.uncompressedSize;
|
||||
if (
|
||||
extractedFiles.length === 1 &&
|
||||
extractionOptions.extractTarget === "cover"
|
||||
) {
|
||||
break;
|
||||
}
|
||||
if (fileName !== "" && entry.type !== "Directory") {
|
||||
logger.info(`Attempting to write ${fileName}`);
|
||||
entry.pipe(createWriteStream(paths.targetPath + "/" + fileName));
|
||||
extractedFiles.push({
|
||||
name: fileName,
|
||||
fileSize: size,
|
||||
path: paths.targetPath,
|
||||
});
|
||||
}
|
||||
entry.autodrain();
|
||||
}
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
logger.info("");
|
||||
resolve(_.flatten(extractedFiles));
|
||||
});
|
||||
return new Promise(async (resolve, reject) => {
|
||||
logger.info("");
|
||||
resolve(_.flatten(extractedFiles));
|
||||
});
|
||||
};
|
||||
|
||||
export const extractArchive = async (
|
||||
extractionOptions: IExtractionOptions,
|
||||
walkedFolder: IFolderData,
|
||||
extractionOptions: IExtractionOptions,
|
||||
walkedFolder: IFolderData
|
||||
): Promise<
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractedComicBookCoverFile[]
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractedComicBookCoverFile[]
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
> => {
|
||||
switch (walkedFolder.extension) {
|
||||
case ".cbz":
|
||||
return await unzip(extractionOptions, walkedFolder);
|
||||
case ".cbr":
|
||||
return await unrar(extractionOptions, walkedFolder);
|
||||
default:
|
||||
return {
|
||||
message: "File format not supported, yet.",
|
||||
errorCode: "90",
|
||||
data: `${extractionOptions}`,
|
||||
};
|
||||
}
|
||||
switch (walkedFolder.extension) {
|
||||
case ".cbz":
|
||||
return await unzip(extractionOptions, walkedFolder);
|
||||
case ".cbr":
|
||||
return await unrar(extractionOptions, walkedFolder);
|
||||
default:
|
||||
return {
|
||||
message: "File format not supported, yet.",
|
||||
errorCode: "90",
|
||||
data: `${extractionOptions}`,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const getCovers = async (
|
||||
options: IExtractionOptions,
|
||||
walkedFolders: IFolderData[],
|
||||
options: IExtractionOptions,
|
||||
walkedFolders: IFolderData[]
|
||||
): Promise<
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
| IExtractedComicBookCoverFile[]
|
||||
| (
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
| IExtractedComicBookCoverFile[]
|
||||
)[]
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
| IExtractedComicBookCoverFile[]
|
||||
| (
|
||||
| IExtractedComicBookCoverFile
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
| IExtractedComicBookCoverFile[]
|
||||
)[]
|
||||
| IExtractComicBookCoverErrorResponse
|
||||
> => {
|
||||
switch (options.extractionMode) {
|
||||
case "bulk":
|
||||
const extractedDataPromises = map(walkedFolders, async folder => await extractArchive(options, folder));
|
||||
return Promise.all(extractedDataPromises).then(data => _.flatten(data));
|
||||
case "single":
|
||||
return await extractArchive(options, walkedFolders[0]);
|
||||
default:
|
||||
logger.error("Unknown extraction mode selected.");
|
||||
return {
|
||||
message: "Unknown extraction mode selected.",
|
||||
errorCode: "90",
|
||||
data: `${options}`,
|
||||
};
|
||||
}
|
||||
switch (options.extractionMode) {
|
||||
case "bulk":
|
||||
const extractedDataPromises = map(
|
||||
walkedFolders,
|
||||
async (folder) => await extractArchive(options, folder)
|
||||
);
|
||||
return Promise.all(extractedDataPromises).then((data) =>
|
||||
_.flatten(data)
|
||||
);
|
||||
case "single":
|
||||
return await extractArchive(options, walkedFolders[0]);
|
||||
default:
|
||||
logger.error("Unknown extraction mode selected.");
|
||||
return {
|
||||
message: "Unknown extraction mode selected.",
|
||||
errorCode: "90",
|
||||
data: `${options}`,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const walkFolder = async (folder: string): Promise<IFolderData[]> => {
|
||||
const result: IFolderData[] = [];
|
||||
let walkResult: IFolderData = {
|
||||
name: "",
|
||||
extension: "",
|
||||
containedIn: "",
|
||||
isFile: false,
|
||||
isLink: true,
|
||||
};
|
||||
const result: IFolderData[] = [];
|
||||
let walkResult: IFolderData = {
|
||||
name: "",
|
||||
extension: "",
|
||||
containedIn: "",
|
||||
isFile: false,
|
||||
isLink: true,
|
||||
};
|
||||
|
||||
const walk = Walk.create({ sort: filterOutDotFiles });
|
||||
await walk(folder, async (err, pathname, dirent) => {
|
||||
if (err) {
|
||||
logger.error("Failed to lstat directory", { error: err });
|
||||
return false;
|
||||
}
|
||||
if ([".cbz", ".cbr"].includes(path.extname(dirent.name))) {
|
||||
walkResult = {
|
||||
name: path.basename(dirent.name, path.extname(dirent.name)),
|
||||
extension: path.extname(dirent.name),
|
||||
containedIn: path.dirname(pathname),
|
||||
isFile: dirent.isFile(),
|
||||
isLink: dirent.isSymbolicLink(),
|
||||
};
|
||||
logger.info(
|
||||
`Scanned ${dirent.name} contained in ${path.dirname(pathname)}`,
|
||||
);
|
||||
result.push(walkResult);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
const walk = Walk.create({ sort: filterOutDotFiles });
|
||||
await walk(folder, async (err, pathname, dirent) => {
|
||||
if (err) {
|
||||
logger.error("Failed to lstat directory", { error: err });
|
||||
return false;
|
||||
}
|
||||
if ([".cbz", ".cbr"].includes(path.extname(dirent.name))) {
|
||||
walkResult = {
|
||||
name: path.basename(dirent.name, path.extname(dirent.name)),
|
||||
extension: path.extname(dirent.name),
|
||||
containedIn: path.dirname(pathname),
|
||||
isFile: dirent.isFile(),
|
||||
isLink: dirent.isSymbolicLink(),
|
||||
};
|
||||
logger.info(
|
||||
`Scanned ${dirent.name} contained in ${path.dirname(pathname)}`
|
||||
);
|
||||
result.push(walkResult);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
export const explodePath = (filePath: string): IExplodedPathResponse => {
|
||||
const exploded = filePath.split("/");
|
||||
const fileName = remove(exploded, item => indexOf(exploded, item) === exploded.length - 1).join("");
|
||||
const exploded = filePath.split("/");
|
||||
const fileName = remove(
|
||||
exploded,
|
||||
(item) => indexOf(exploded, item) === exploded.length - 1
|
||||
).join("");
|
||||
|
||||
return {
|
||||
exploded,
|
||||
fileName,
|
||||
};
|
||||
return {
|
||||
exploded,
|
||||
fileName,
|
||||
};
|
||||
};
|
||||
|
||||
const constructPaths = (
|
||||
extractionOptions: IExtractionOptions,
|
||||
walkedFolder: IFolderData,
|
||||
extractionOptions: IExtractionOptions,
|
||||
walkedFolder: IFolderData
|
||||
) => ({
|
||||
targetPath:
|
||||
extractionOptions.targetExtractionFolder + "/" + walkedFolder.name,
|
||||
inputFilePath:
|
||||
walkedFolder.containedIn +
|
||||
"/" +
|
||||
walkedFolder.name +
|
||||
walkedFolder.extension,
|
||||
});
|
||||
targetPath:
|
||||
extractionOptions.targetExtractionFolder + "/" + walkedFolder.name,
|
||||
inputFilePath:
|
||||
walkedFolder.containedIn +
|
||||
"/" +
|
||||
walkedFolder.name +
|
||||
walkedFolder.extension,
|
||||
});
|
||||
|
||||
export const extractMetadataFromImage = async (
|
||||
imageFilePath: string,
|
||||
imageFilePath: string
|
||||
): Promise<unknown> => {
|
||||
const image = await sharp(imageFilePath)
|
||||
.metadata()
|
||||
.then(function(metadata) {
|
||||
return metadata;
|
||||
});
|
||||
return image;
|
||||
const image = await sharp(imageFilePath)
|
||||
.metadata()
|
||||
.then(function (metadata) {
|
||||
return metadata;
|
||||
});
|
||||
return image;
|
||||
};
|
||||
|
||||
const filterOutDotFiles = entities => entities.filter(ent => !ent.name.startsWith("."));
|
||||
const filterOutDotFiles = (entities) =>
|
||||
entities.filter((ent) => !ent.name.startsWith("."));
|
||||
|
||||
Reference in New Issue
Block a user