wip ze ipc

This commit is contained in:
Manav Rathi 2024-04-30 09:39:38 +05:30
parent 93991c3a7f
commit 77fe4f9f03
No known key found for this signature in database
5 changed files with 53 additions and 29 deletions

View file

@ -54,9 +54,9 @@ import {
import {
clearPendingUploads,
listZipEntries,
pathOrZipEntrySize,
markUploadedFiles,
markUploadedZipEntries,
pathOrZipEntrySize,
pendingUploads,
setPendingUploads,
} from "./services/upload";
@ -152,10 +152,11 @@ export const attachIPCHandlers = () => {
"generateImageThumbnail",
(
_,
dataOrPath: Uint8Array | string,
dataOrPathOrZipEntry: Uint8Array | string | ZipEntry,
maxDimension: number,
maxSize: number,
) => generateImageThumbnail(dataOrPath, maxDimension, maxSize),
) =>
generateImageThumbnail(dataOrPathOrZipEntry, maxDimension, maxSize),
);
ipcMain.handle(
@ -163,10 +164,16 @@ export const attachIPCHandlers = () => {
(
_,
command: string[],
dataOrPath: Uint8Array | string,
dataOrPathOrZipEntry: Uint8Array | string | ZipEntry,
outputFileExtension: string,
timeoutMS: number,
) => ffmpegExec(command, dataOrPath, outputFileExtension, timeoutMS),
) =>
ffmpegExec(
command,
dataOrPathOrZipEntry,
outputFileExtension,
timeoutMS,
),
);
// - ML

View file

@ -1,8 +1,9 @@
/** @file Image format conversions and thumbnail generation */
import StreamZip from "node-stream-zip";
import fs from "node:fs/promises";
import path from "path";
import { CustomErrorMessage } from "../../types/ipc";
import { CustomErrorMessage, type ZipEntry } from "../../types/ipc";
import log from "../log";
import { execAsync, isDev } from "../utils-electron";
import { deleteTempFile, makeTempFilePath } from "../utils-temp";
@ -63,18 +64,31 @@ const imageMagickPath = () =>
path.join(isDev ? "build" : process.resourcesPath, "image-magick");
export const generateImageThumbnail = async (
dataOrPath: Uint8Array | string,
dataOrPathOrZipEntry: Uint8Array | string | ZipEntry,
maxDimension: number,
maxSize: number,
): Promise<Uint8Array> => {
let inputFilePath: string;
let isInputFileTemporary: boolean;
if (dataOrPath instanceof Uint8Array) {
let writeToTemporaryInputFile = async () => {};
if (typeof dataOrPathOrZipEntry == "string") {
inputFilePath = dataOrPathOrZipEntry;
isInputFileTemporary = false;
} else {
inputFilePath = await makeTempFilePath();
isInputFileTemporary = true;
} else {
inputFilePath = dataOrPath;
isInputFileTemporary = false;
if (dataOrPathOrZipEntry instanceof Uint8Array) {
writeToTemporaryInputFile = async () => {
await fs.writeFile(inputFilePath, dataOrPathOrZipEntry);
};
} else {
writeToTemporaryInputFile = async () => {
const [zipPath, entryName] = dataOrPathOrZipEntry;
const zip = new StreamZip.async({ file: zipPath });
await zip.extract(entryName, inputFilePath);
zip.close();
};
}
}
const outputFilePath = await makeTempFilePath("jpeg");
@ -89,8 +103,7 @@ export const generateImageThumbnail = async (
);
try {
if (dataOrPath instanceof Uint8Array)
await fs.writeFile(inputFilePath, dataOrPath);
writeToTemporaryInputFile();
let thumbnail: Uint8Array;
do {

View file

@ -97,9 +97,7 @@ const handleRead = async (path: string) => {
const handleReadZip = async (zipPath: string, zipEntryPath: string) => {
try {
const zip = new StreamZip.async({
file: zipPath,
});
const zip = new StreamZip.async({ file: zipPath });
const entry = await zip.entry(zipEntryPath);
const stream = await zip.stream(entry);

View file

@ -129,27 +129,27 @@ const convertToJPEG = (imageData: Uint8Array): Promise<Uint8Array> =>
ipcRenderer.invoke("convertToJPEG", imageData);
const generateImageThumbnail = (
dataOrPath: Uint8Array | string,
dataOrPathOrZipEntry: Uint8Array | string | ZipEntry,
maxDimension: number,
maxSize: number,
): Promise<Uint8Array> =>
ipcRenderer.invoke(
"generateImageThumbnail",
dataOrPath,
dataOrPathOrZipEntry,
maxDimension,
maxSize,
);
const ffmpegExec = (
command: string[],
dataOrPath: Uint8Array | string,
dataOrPathOrZipEntry: Uint8Array | string | ZipEntry,
outputFileExtension: string,
timeoutMS: number,
): Promise<Uint8Array> =>
ipcRenderer.invoke(
"ffmpegExec",
command,
dataOrPath,
dataOrPathOrZipEntry,
outputFileExtension,
timeoutMS,
);

View file

@ -221,22 +221,27 @@ export interface Electron {
* not yet possible, this function will throw an error with the
* {@link CustomErrorMessage.NotAvailable} message.
*
* @param dataOrPath The raw image data (the contents of the image file), or
* the path to the image file, whose thumbnail we want to generate.
* @param dataOrPathOrZipEntry The file whose thumbnail we want to generate.
* It can be provided as raw image data (the contents of the image file), or
* the path to the image file, or a tuple containing the path of the zip
* file along with the name of an entry in it.
*
* @param maxDimension The maximum width or height of the generated
* thumbnail.
*
* @param maxSize Maximum size (in bytes) of the generated thumbnail.
*
* @returns JPEG data of the generated thumbnail.
*/
generateImageThumbnail: (
dataOrPath: Uint8Array | string,
dataOrPathOrZipEntry: Uint8Array | string | ZipEntry,
maxDimension: number,
maxSize: number,
) => Promise<Uint8Array>;
/**
* Execute a FFmpeg {@link command} on the given {@link dataOrPath}.
* Execute a FFmpeg {@link command} on the given
* {@link dataOrPathOrZipEntry}.
*
* This executes the command using a FFmpeg executable we bundle with our
* desktop app. We also have a wasm FFmpeg wasm implementation that we use
@ -249,10 +254,11 @@ export interface Electron {
* (respectively {@link inputPathPlaceholder},
* {@link outputPathPlaceholder}, {@link ffmpegPathPlaceholder}).
*
* @param dataOrPath The bytes of the input file, or the path to the input
* file on the user's local disk. In both cases, the data gets serialized to
* a temporary file, and then that path gets substituted in the FFmpeg
* {@link command} in lieu of {@link inputPathPlaceholder}.
* @param dataOrPathOrZipEntry The bytes of the input file, or the path to
* the input file on the user's local disk, or the path to a zip file on the
* user's disk and the name of an entry in it. In all three cases, the data
* gets serialized to a temporary file, and then that path gets substituted
* in the FFmpeg {@link command} in lieu of {@link inputPathPlaceholder}.
*
* @param outputFileExtension The extension (without the dot, e.g. "jpeg")
* to use for the output file that we ask FFmpeg to create in
@ -268,7 +274,7 @@ export interface Electron {
*/
ffmpegExec: (
command: string[],
dataOrPath: Uint8Array | string,
dataOrPathOrZipEntry: Uint8Array | string | ZipEntry,
outputFileExtension: string,
timeoutMS: number,
) => Promise<Uint8Array>;