🪛 Data transferring over sockets!

This commit is contained in:
2021-05-27 15:50:10 -07:00
parent ef4e1f75b0
commit 0aea022208
5 changed files with 268 additions and 448 deletions

View File

@@ -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("."));