New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

images-to-pdf-book

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

images-to-pdf-book - npm Package Compare versions

Comparing version 0.1.6 to 0.1.7

dist/src/fancy-console/ora.js

2

dist/bin/images-to-pdf-book.js

@@ -24,2 +24,2 @@ #!/usr/bin/env node

.demandOption(['images-directory', 'w', 'h', 'o']).argv;
src_1.default(argv);
src_1.main(argv).run();

@@ -1,120 +0,73 @@

'use strict';
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const chalk_1 = require("chalk");
const fs = require("fs-extra");
const Apply_1 = require("fp-ts/lib/Apply");
const Array_1 = require("fp-ts/lib/Array");
const Either_1 = require("fp-ts/lib/Either");
const function_1 = require("fp-ts/lib/function");
const IO_1 = require("fp-ts/lib/IO");
const Ord_1 = require("fp-ts/lib/Ord");
const TaskEither_1 = require("fp-ts/lib/TaskEither");
const isImage = require("is-image");
const ora = require("ora");
const os = require("os");
const pMap = require("p-map");
const Path = require("path");
const PDFDocument = require("pdfkit");
const ProgressBar = require("progress");
const recursive = require("recursive-readdir");
const sharp = require("sharp");
const cpuCount = os.cpus().length;
const error = chalk_1.default.bold.red;
function start({ imagesDirectory, width, height, output, }) {
return __awaiter(this, void 0, void 0, function* () {
const doc = new PDFDocument({
autoFirstPage: false,
});
const imagesDir = Path.resolve(imagesDirectory);
const outputStream = fs.createWriteStream(Path.resolve(output));
doc.pipe(outputStream);
const docSpinner = ora('Creating document...');
outputStream.on('close', () => {
docSpinner.succeed();
process.exit();
});
const images = yield getImages(imagesDir);
const resizingImagesProgressBar = new ProgressBar('Processing images [:bar] :current/:total', {
total: images.length,
width: 17,
});
const resizingImagesPromises = pMap(images, (imagePath) => __awaiter(this, void 0, void 0, function* () {
const parentDirName = getParentDirName(imagePath);
const imageBuffer = yield fs.readFile(imagePath);
return new Promise((resolve, reject) => sharp(imageBuffer)
.trim()
.toBuffer((err, trimmedImageBuffer, info) => {
if (err)
return reject(err);
const name = parentDirName + Path.parse(imagePath).name;
const newSize = calculateOutputImageSize(info, { width, height });
const resizeAndArchive = sharp(trimmedImageBuffer)
.resize(...newSize)
.png()
.toBuffer()
.then((buffer) => {
resizingImagesProgressBar.tick();
return {
buffer,
name,
size: newSize,
};
});
resolve(resizeAndArchive);
}));
}), { concurrency: cpuCount });
yield resizingImagesPromises.then((res) => {
docSpinner.start();
res
.sort(sortImagesByName) // tslint:disable-line no-misleading-array-reverse
.forEach((resizedImage) => addImageToDoc(resizedImage, doc));
});
doc.end();
const ora = require("./fancyConsole/ora");
const progressBar = require("./fancyConsole/progress");
const fs = require("./fs");
const img = require("./imageProcessing");
const d = require("./pdfDocument");
const recursiveReaddir_1 = require("./recursiveReaddir");
const ioParallel = Array_1.array.sequence(IO_1.io);
const tEParallel = Array_1.array.sequence(TaskEither_1.taskEither);
const tESeries = Array_1.array.sequence(TaskEither_1.taskEitherSeq);
const sequenceTIo = Apply_1.sequenceT(IO_1.io);
const cpuCountIO = new IO_1.IO(() => os.cpus()).map((_) => _.length);
const exit = new IO_1.IO(() => process.exit());
const createProgressBar = (total) => progressBar.create('Processing images [:bar] :current/:total', {
total,
width: 17,
});
const getImagePaths = (imagesDir) => recursiveReaddir_1.recursiveTE(imagesDir).map((files) => Array_1.filter(files, isImage));
const getParentDirName = (imagePath) => Array_1.last(Path.dirname(imagePath).split('/'));
const ordImagesByName = Ord_1.contramap((image) => image.name.toLowerCase(), Ord_1.ordString);
const initOutputAndCreateSpinner = (outputFile, doc) => TaskEither_1.fromIO(sequenceTIo(fs.createWriteStream(Path.resolve(outputFile)).chain(d.pipeDoc(doc)), ora.create('Creating document...')));
const processImage = (progressBarInstance) => (imagePath, { width, height }) => {
const fileName = Path.parse(imagePath).name;
const fullName = getParentDirName(imagePath).fold(fileName, (dirName) => dirName + fileName);
return fs
.readFile(imagePath)
.chain(img.trimImage)
.chain(({ fst: buffer, snd: info }) => {
const outputSize = img.calculateOutputImageSize(info, { width, height });
return img
.resizeImage(outputSize, buffer)
.chain(() => TaskEither_1.fromIO(progressBar.tick(progressBarInstance)).chain(() => TaskEither_1.taskEither.of({ buffer, name: fullName, size: outputSize })));
});
}
exports.default = start;
function getImages(imagesDir) {
return __awaiter(this, void 0, void 0, function* () {
const files = yield recursive(imagesDir);
return files.filter(isImage);
};
const prepareImages = (imagePaths, outputSize, cpuCount, progressBarInstance) => {
const processImageWithProgressBar = processImage(progressBarInstance);
// Let's take advantage on multithreading by running the tasks asynchronously.
// The tasks are being chunked, each chunk runs in series, in order to bail out
// as soon as a task fails.
return tESeries(Array_1.chunksOf(imagePaths, cpuCount).map((chunk) => tEParallel(chunk.map((imagePath) => processImageWithProgressBar(imagePath, outputSize))))).map(function_1.compose(Array_1.sort(ordImagesByName), Array_1.flatten));
};
const writeImagesToDocument = (doc, docSpinner) => (images) => TaskEither_1.fromIO(ora
.start(docSpinner)
.chain(() => ioParallel(images.map(d.addImageToDoc(doc))))
.chain(() => d.closeDoc(doc)));
const getCpuCountAndCreateProgressBar = (progressBarLength) => TaskEither_1.fromIO(sequenceTIo(cpuCountIO, createProgressBar(progressBarLength)));
function main({ imagesDirectory, width, height, output, }) {
const doc = new PDFDocument({ autoFirstPage: false });
const imagesDir = Path.resolve(imagesDirectory);
const outputSize = { width, height };
return initOutputAndCreateSpinner(output, doc).chain(([outputStream, docSpinner]) => {
outputStream.on('close', () => (docSpinner.isSpinning
? sequenceTIo(ora.succeed(docSpinner, 'Done!'), exit)
: exit).run());
return getImagePaths(imagesDir).chain((imagePaths) => getCpuCountAndCreateProgressBar(imagePaths.length)
.chain(([cpuCount, progressBarInstance]) => prepareImages(imagePaths, outputSize, cpuCount, progressBarInstance))
.chain(writeImagesToDocument(doc, docSpinner))
.foldTaskEither((err) => TaskEither_1.fromIO(ora.fail(docSpinner, err.message).chain(() => IO_1.io.of(undefined))).chain(() => TaskEither_1.fromEither(Either_1.left(err))), () => TaskEither_1.taskEither.of(undefined)));
});
}
function getParentDirName(imagePath) {
return Path.dirname(imagePath)
.split('/')
.pop();
}
function calculateOutputImageSize(imageSize, viewportSize) {
const outputRatio = viewportSize.width / viewportSize.height;
const imageRatio = imageSize.width / imageSize.height;
// determs if the image orientation will be portrait or landscape
// if landscape, fit the image by viewport's height
const outputImageRatio = imageRatio < outputRatio
? viewportSize.width / viewportSize.height
: (viewportSize.width * 2) / viewportSize.height;
return imageRatio > outputImageRatio
? [viewportSize.width, Math.round(viewportSize.width / imageRatio)]
: [Math.round(viewportSize.height * imageRatio), viewportSize.height];
}
function sortImagesByName(prev, next) {
const prevName = prev.name.toLowerCase();
const nextName = next.name.toLowerCase();
if (prevName < nextName)
return -1;
if (prevName > nextName)
return 1;
return 0;
}
function addImageToDoc({ buffer, size }, doc) {
doc.addPage({ size });
doc.image(buffer, 0, 0, { fit: size });
}
process.on('unhandledRejection', (err) => {
throw err;
});
process.on('uncaughtException', ({ message, stack }) => {
console.error(error(message));
console.error(stack);
process.exit(1);
});
exports.main = main;
{
"name": "images-to-pdf-book",
"version": "0.1.6",
"version": "0.1.7",
"description": "Create a PDF document from a bunch of images.",

@@ -24,32 +24,31 @@ "keywords": [

"dependencies": {
"chalk": "^2.4.1",
"fs-extra": "^7.0.0",
"fp-ts": "^1.15.1",
"io-ts": "^1.8.5",
"io-ts-types": "^0.4.6",
"is-image": "^2.0.0",
"ora": "^3.0.0",
"p-map": "^1.2.0",
"pdfkit": "^0.8.3",
"progress": "^2.0.0",
"ora": "^3.4.0",
"pdfkit": "^0.9.0",
"progress": "^2.0.3",
"recursive-readdir": "^2.2.2",
"rm": "^0.1.8",
"sharp": "^0.20.5",
"yargs": "^12.0.1"
"sharp": "^0.22.0",
"yargs": "^13.2.2"
},
"devDependencies": {
"@types/fs-extra": "^5.0.4",
"@types/node": "^10.5.4",
"@types/ora": "^1.3.4",
"@types/p-map": "^1.1.0",
"@types/is-image": "^2.0.0",
"@types/node": "^11.13.0",
"@types/ora": "^3.2.0",
"@types/pdfkit": "^0.7.36",
"@types/progress": "^2.0.1",
"@types/progress": "^2.0.3",
"@types/recursive-readdir": "^2.2.0",
"@types/sharp": "^0.17.9",
"@types/yargs": "^11.1.1",
"husky": "^0.14.3",
"prettier": "^1.13.7",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.14.0",
"tslint-immutable": "^4.6.0",
"tslint-plugin-prettier": "^1.3.0",
"tslint-sonarts": "^1.7.0",
"typescript": "^2.9.2"
"@types/sharp": "^0.22.1",
"@types/yargs": "^11.1.2",
"husky": "^1.3.1",
"prettier": "^1.16.4",
"tslint": "^5.15.0",
"tslint-config-prettier": "^1.18.0",
"tslint-config-standard": "^8.0.1",
"tslint-plugin-prettier": "^2.0.1",
"typescript": "^3.4.2",
"typestrict": "^1.0.2"
},

@@ -56,0 +55,0 @@ "author": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc