From 36d18d484602ade0f9e1668904bca6a1323702ab Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Fri, 25 Feb 2022 22:27:19 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Adding=20methods=20for=20comicin?= =?UTF-8?q?fo.xml=20detection/extraction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + test/unit/mixins/db.mixin.spec.ts | 85 --------------------- test/unit/services/greeter.spec.ts | 40 ---------- utils/uncompression.utils.ts | 114 +++++++++++++++++++++++------ utils/xml.utils.ts | 4 +- 5 files changed, 94 insertions(+), 150 deletions(-) delete mode 100644 test/unit/mixins/db.mixin.spec.ts delete mode 100644 test/unit/services/greeter.spec.ts diff --git a/.gitignore b/.gitignore index 29f3b9f..c6334bf 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,4 @@ userdata/ .DS_Store erl_crash.dump temp +test diff --git a/test/unit/mixins/db.mixin.spec.ts b/test/unit/mixins/db.mixin.spec.ts deleted file mode 100644 index e9c28a9..0000000 --- a/test/unit/mixins/db.mixin.spec.ts +++ /dev/null @@ -1,85 +0,0 @@ -"use strict"; - -import { ServiceBroker } from "moleculer"; -import DbService from "moleculer-db"; -import {DbMixin} from "../../../mixins/db.mixin"; - -describe("Test DB mixin", () => { - - describe("Test schema generator", () => { - const broker = new ServiceBroker({ logger: false, cacher: "Memory" }); - - beforeAll(() => broker.start()); - afterAll(() => broker.stop()); - - it("check schema properties", async () => { - const schema = new DbMixin("my-collection").start(); - - expect(schema.mixins).toEqual([DbService]); - // @ts-ignore - expect(schema.adapter).toBeInstanceOf(DbService.MemoryAdapter); - expect(schema.started).toBeDefined(); - expect(schema.events["cache.clean.my-collection"]).toBeInstanceOf(Function); - }); - - it("check cache event handler", async () => { - jest.spyOn(broker.cacher, "clean"); - - const schema = new DbMixin("my-collection").start(); - - // @ts-ignore - await schema.events["cache.clean.my-collection"].call({ broker, fullName: "my-service" }); - - expect(broker.cacher.clean).toBeCalledTimes(1); - expect(broker.cacher.clean).toBeCalledWith("my-service.*"); - }); - - describe("Check service started handler", () => { - - it("should not call seedDB method", async () => { - const schema = new DbMixin("my-collection").start(); - - schema.adapter.count = jest.fn(async () => 10); - const seedDBFn = jest.fn(); - - // @ts-ignore - await schema.started.call({ broker, logger: broker.logger, adapter: schema.adapter, seedDB: seedDBFn }); - - expect(schema.adapter.count).toBeCalledTimes(1); - expect(schema.adapter.count).toBeCalledWith(); - - expect(seedDBFn).toBeCalledTimes(0); - }); - - it("should call seedDB method", async () => { - const schema = new DbMixin("my-collection").start(); - - schema.adapter.count = jest.fn(async () => 0); - const seedDBFn = jest.fn(); - - // @ts-ignore - await schema.started.call({ broker, logger: broker.logger, adapter: schema.adapter, seedDB: seedDBFn }); - - expect(schema.adapter.count).toBeCalledTimes(2); - expect(schema.adapter.count).toBeCalledWith(); - - expect(seedDBFn).toBeCalledTimes(1); - expect(seedDBFn).toBeCalledWith(); - }); - }); - - it("should broadcast a cache clear event", async () => { - const schema = new DbMixin("my-collection").start(); - - const ctx = { - broadcast: jest.fn(), - }; - - await schema.methods.entityChanged(null, null, ctx); - - expect(ctx.broadcast).toBeCalledTimes(1); - expect(ctx.broadcast).toBeCalledWith("cache.clean.my-collection"); - }); - }); - -}); diff --git a/test/unit/services/greeter.spec.ts b/test/unit/services/greeter.spec.ts deleted file mode 100644 index b0529fd..0000000 --- a/test/unit/services/greeter.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -import { Errors, ServiceBroker} from "moleculer"; -import TestService from "../../../services/greeter.service"; - -describe("Test 'greeter' service", () => { - const broker = new ServiceBroker({ logger: false }); - broker.createService(TestService); - - beforeAll(() => broker.start()); - afterAll(() => broker.stop()); - - describe("Test 'greeter.hello' action", () => { - - it("should return with 'Hello Moleculer'", async () => { - const res = await broker.call("greeter.hello"); - expect(res).toBe("Hello Moleculer"); - }); - - }); - - describe("Test 'greeter.welcome' action", () => { - - it("should return with 'Welcome'", async () => { - const res = await broker.call("greeter.welcome", { name: "Adam" }); - expect(res).toBe("Welcome, Adam"); - }); - - it("should reject an ValidationError", async () => { - expect.assertions(1); - try { - await broker.call("greeter.welcome"); - } catch (err) { - expect(err).toBeInstanceOf(Errors.ValidationError); - } - }); - - }); - -}); diff --git a/utils/uncompression.utils.ts b/utils/uncompression.utils.ts index 3c306da..7eeeed8 100644 --- a/utils/uncompression.utils.ts +++ b/utils/uncompression.utils.ts @@ -44,63 +44,65 @@ import { import { constructPaths, explodePath, walkFolder } from "../utils/file.utils"; import { resizeImage } from "./imagetransformation.utils"; -import { isNil } from "lodash"; +import { isNil, isUndefined } from "lodash"; +import { convertXMLToJSON } from "./xml.utils"; const sevenZip = require("7zip-min"); const unrar = require("node-unrar-js"); const { Calibre } = require("node-calibre"); import { USERDATA_DIRECTORY, COMICS_DIRECTORY } from "../constants/directories"; - export const extractCoverFromFile2 = async ( fileObject: any ): Promise => { try { const { filePath, fileSize } = fileObject; - + const calibre = new Calibre(); console.info(`Initiating extraction process for path ${filePath}`); // 1. Check for process.env.COMICS_DIRECTORY and process.env.USERDATA_DIRECTORY if (!isNil(USERDATA_DIRECTORY)) { // 2. Create the directory to which the cover image will be extracted - console.info("Attempting to create target directory for cover extraction..."); + console.info( + "Attempting to create target directory for cover extraction..." + ); const directoryOptions = { mode: 0o2775, }; + const extension = path.extname(filePath); const fileNameWithExtension = path.basename(filePath); - const fileNameWithoutExtension = path.basename(filePath, path.extname(filePath)); + const fileNameWithoutExtension = path.basename( + filePath, + path.extname(filePath) + ); const targetDirectory = `${USERDATA_DIRECTORY}/covers/${fileNameWithoutExtension}`; - + await fse.ensureDir(targetDirectory, directoryOptions); console.info(`%s was created.`, targetDirectory); + // 2.1 look for comicinfo.xml + extractFileFromArchive(filePath, targetDirectory, extension); + // 3. extract the cover console.info(`Starting cover extraction...`); let result: string; const targetCoverImageFilePath = path.resolve( - targetDirectory + - "/" + - fileNameWithoutExtension + - "_cover.jpg" + targetDirectory + "/" + fileNameWithoutExtension + "_cover.jpg" ); const ebookMetaPath = process.env.CALIBRE_EBOOK_META_PATH ? `${process.env.CALIBRE_EBOOK_META_PATH}` : `ebook-meta`; - result = await calibre.run( - ebookMetaPath, - [filePath], - { - getCover: targetCoverImageFilePath, - } + result = await calibre.run(ebookMetaPath, [filePath], { + getCover: targetCoverImageFilePath, + }); + console.info( + `ebook-meta ran with the following result: %o`, + result ); - console.info(`ebook-meta ran with the following result: %o`, result) // 4. create rendition path const renditionPath = - targetDirectory+ - "/" + - fileNameWithoutExtension + - "_275px.jpg"; + targetDirectory + "/" + fileNameWithoutExtension + "_275px.jpg"; // 5. resize image await resizeImage( @@ -112,9 +114,9 @@ export const extractCoverFromFile2 = async ( name: fileNameWithoutExtension, filePath, fileSize, - extension: path.extname(filePath), + extension, cover: { - filePath: path.relative(process.cwd(),renditionPath), + filePath: path.relative(process.cwd(), renditionPath), }, containedIn: path.resolve(fileNameWithExtension), calibreMetadata: { @@ -170,3 +172,69 @@ export const unrarArchive = async ( console.info(`${error}`); } }; + +export const extractFileFromRar = async ( + filePath: string, + fileToExtract: string +) => { + try { + // Read the archive file into a typedArray + const fileBuffer = await fse + .readFile(filePath) + .catch((err) => console.error("Failed to read file", err)); + const extractor = await unrar.createExtractorFromData({ + data: fileBuffer, + }); + + const list = extractor.getFileList(); + const listArcHeader = list.arcHeader; // archive header + const fileHeaders = [...list.fileHeaders]; // load the file headers + + const extracted = extractor.extract({ files: ["ComicInfo.xml"] }); + const files = [...extracted.files]; //load the files + console.log("asdas", files[0]); + if(!isUndefined(files[0])) { + const trin = String.fromCharCode.apply(null, files[0].extraction) + const foo = await convertXMLToJSON(trin); + console.log(foo); + } + } catch (error) { + throw new Error(error); + } +}; + +export const extractFileFromZip = async ( + filePath: string, + outputDirectory: string +) => { + const foo = sevenZip.cmd( + ["e", path.resolve(filePath), outputDirectory, "*.xml"], + (err) => { + console.log(err); + } + ); + return foo; +}; + +export const extractFileFromArchive = async ( + filePath: string, + outputDirectory: string, + extension: string +) => { + console.log(extension); + switch (extension) { + case ".cbz": + console.log("cbz"); + extractFileFromZip(filePath, outputDirectory); + break; + + case ".cbr": + console.log("cbr"); + extractFileFromRar(filePath, outputDirectory); + break; + + default: + console.log("error na rao"); + break; + } +}; diff --git a/utils/xml.utils.ts b/utils/xml.utils.ts index ddcbd4d..5826aca 100644 --- a/utils/xml.utils.ts +++ b/utils/xml.utils.ts @@ -35,9 +35,9 @@ export const convertXMLToJSON = (xmlPayload) => { trim: true, normalizeTags: true, }); - const xml = fs.readFileSync(__dirname + "/comicinfo.xml", "utf8"); + return parser - .parseStringPromise(xml) + .parseStringPromise(xmlPayload) .then((result) => { return result; })