aboutsummaryrefslogtreecommitdiff
path: root/src/server/DashUploadUtils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/DashUploadUtils.ts')
-rw-r--r--src/server/DashUploadUtils.ts94
1 files changed, 53 insertions, 41 deletions
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 8f012f783..5cf86b2ae 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -1,5 +1,5 @@
import axios from 'axios';
-import { spawn, exec } from 'child_process';
+import { exec, spawn } from 'child_process';
import { green, red } from 'colors';
import { ExifData, ExifImage } from 'exif';
import * as exifr from 'exifr';
@@ -7,9 +7,8 @@ import * as ffmpeg from 'fluent-ffmpeg';
import * as formidable from 'formidable';
import { File } from 'formidable';
import * as fs from 'fs';
-import { createReadStream, createWriteStream, existsSync, readFileSync, rename, unlinkSync, writeFile } from 'fs';
-import Jimp from 'jimp';
-import * as autorotate from 'jpeg-autorotate';
+import { createReadStream, createWriteStream, existsSync, readFileSync, rename, unlinkSync, writeFile } from 'fs'; // import { Jimp } from "@jimp/core";
+import { Jimp } from 'jimp';
import * as md5File from 'md5-file';
import * as path from 'path';
import { basename } from 'path';
@@ -23,6 +22,38 @@ import { AcceptableMedia, Upload } from './SharedMediaTypes';
import { Directory, clientPathToFile, filesDirectory, pathToDirectory, publicDirectory, serverPathToFile } from './SocketData';
import { resolvedServerUrl } from './server_Initialization';
+import { Worker, isMainThread, parentPort } from 'worker_threads';
+
+// Create an array to store worker threads
+const workerThreads: Worker[] = [];
+if (isMainThread) {
+ // Main thread code
+ // Create worker threads -- just one right to do image resampling
+ workerThreads.push(new Worker(__filename));
+} else {
+ // Worker thread code - Listens for messages from the main thread
+ parentPort?.on('message', message => workerResampleImage(message.task));
+ async function workerResampleImage(task: string) {
+ const [sourcePath, outputFileName, outputDirectory, unlinkSource] = task.split('::');
+ const sizes = DashUploadUtils.imageResampleSizes(path.extname(sourcePath));
+ const imgBuffer = await fs.readFileSync(sourcePath);
+ const outputPath = (suffix: SizeSuffix) => {
+ const writtenFile = InjectSize(outputFileName, suffix);
+ return path.resolve(outputDirectory, writtenFile);
+ };
+ await Jimp.fromBuffer(imgBuffer)
+ .then(img => sizes.filter(({ width }) => width).map(({ width, suffix }) => img.resize({ w: width }).write(outputPath(suffix) as `${string}.${string}`)))
+ .catch(e => {
+ console.log('ERROR' + e);
+ });
+ if (unlinkSource === 'true') {
+ unlinkSync(sourcePath);
+ }
+
+ // … operations to be performed to execute the task
+ }
+}
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
const requestImageSize = require('../client/util/request-image-size');
@@ -277,15 +308,6 @@ export namespace DashUploadUtils {
}
};
- async function correctRotation(imgSourcePath: string) {
- const buffer = fs.readFileSync(imgSourcePath);
- try {
- return (await autorotate.rotate(buffer, { quality: 30 })).buffer;
- } catch (e) {
- return buffer;
- }
- }
-
/**
* define the resizers to use
* @param ext the extension
@@ -310,38 +332,29 @@ export namespace DashUploadUtils {
* @param outputDirectory the directory to output to, usually Directory.Images
* @returns a map with suffixes as keys and resized filenames as values.
*/
- export async function outputResizedImages(imgSourcePath: string, outputFileName: string, outputDirectory: string) {
+ export async function outputResizedImages(imgSourcePath: string, outputFileName: string, outputDirectory: string, unlinkSource: boolean) {
const writtenFiles: { [suffix: string]: string } = {};
- const sizes = imageResampleSizes(path.extname(outputFileName));
- const imgBuffer = await correctRotation(imgSourcePath);
- const imgReadStream = new Duplex();
- imgReadStream.push(imgBuffer);
- imgReadStream.push(null);
const outputPath = (suffix: SizeSuffix) => {
writtenFiles[suffix] = InjectSize(outputFileName, suffix);
return path.resolve(outputDirectory, writtenFiles[suffix]);
};
+
+ const sizes = imageResampleSizes(path.extname(outputFileName));
+ const imgBuffer = fs.readFileSync(imgSourcePath);
+ const imgReadStream = new Duplex();
+ imgReadStream.push(imgBuffer);
+ imgReadStream.push(null);
await Promise.all(
- sizes.filter(({ width }) => !width).map(({ suffix }) =>
- new Promise<void>(res => {
- imgReadStream.pipe(createWriteStream(outputPath(suffix))).on('close', res);
- })
+ sizes.map(({ suffix }) =>
+ new Promise<unknown>(res =>
+ imgReadStream.pipe(createWriteStream(outputPath(suffix))).on('close', res)
+ )
)); // prettier-ignore
- return Jimp.read(imgBuffer)
- .then(async imgIn => {
- let img = imgIn;
- await Promise.all( sizes.filter(({ width }) => width).map(({ width, suffix }) => {
- img = img.resize(width, Jimp.AUTO).write(outputPath(suffix));
- return img;
- } )); // prettier-ignore
- return writtenFiles;
- })
- .catch(e => {
- console.log('ERROR' + e);
- return writtenFiles;
- });
+ // Send a message to worker thread to resample image
+ workerThreads[0].postMessage({ task: imgSourcePath + '::' + outputFileName + '::' + outputDirectory + '::' + unlinkSource });
+ return writtenFiles;
}
/**
@@ -387,8 +400,9 @@ export namespace DashUploadUtils {
writtenFiles = {};
}
} else {
+ const unlinkSrcWhenFinished = isLocal().test(source) && cleanUp;
try {
- writtenFiles = await outputResizedImages(metadata.source, resolved, pathToDirectory(Directory.images));
+ writtenFiles = await outputResizedImages(metadata.source, resolved, pathToDirectory(Directory.images), unlinkSrcWhenFinished);
} catch (e) {
// input is a blob or other, try reading it to create a metadata source file.
const reqSource = request(metadata.source);
@@ -400,16 +414,14 @@ export namespace DashUploadUtils {
.on('close', () => res())
.on('error', () => rej());
});
- writtenFiles = await outputResizedImages(readSource, resolved, pathToDirectory(Directory.images));
+ writtenFiles = await outputResizedImages(readSource, resolved, pathToDirectory(Directory.images), unlinkSrcWhenFinished);
fs.unlink(readSource, err => console.log("Couldn't unlink temporary image file:" + readSource, err));
}
}
Array.from(Object.keys(writtenFiles)).forEach(suffix => {
information.accessPaths[suffix] = getAccessPaths(images, writtenFiles[suffix]);
});
- if (isLocal().test(source) && cleanUp) {
- unlinkSync(source);
- }
+
return information;
};