Convert the other conversion functions

This commit is contained in:
Manav Rathi 2024-03-25 12:44:54 +05:30
parent 2522da2b5e
commit e8acbd8c9f
No known key found for this signature in database
6 changed files with 111 additions and 118 deletions

View file

@ -1,64 +0,0 @@
import { ipcRenderer } from "electron/renderer";
import { existsSync } from "fs";
import { CustomErrors } from "../constants/errors";
import { writeStream } from "../services/fs";
import { logError } from "../main/log";
import { ElectronFile } from "../types";
import { isPlatform } from "../utils/common/platform";
export async function convertToJPEG(
fileData: Uint8Array,
filename: string,
): Promise<Uint8Array> {
if (isPlatform("windows")) {
throw Error(CustomErrors.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED);
}
const convertedFileData = await ipcRenderer.invoke(
"convert-to-jpeg",
fileData,
filename,
);
return convertedFileData;
}
export async function generateImageThumbnail(
inputFile: File | ElectronFile,
maxDimension: number,
maxSize: number,
): Promise<Uint8Array> {
let inputFilePath = null;
let createdTempInputFile = null;
try {
if (isPlatform("windows")) {
throw Error(
CustomErrors.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED,
);
}
if (!existsSync(inputFile.path)) {
const tempFilePath = await ipcRenderer.invoke(
"get-temp-file-path",
inputFile.name,
);
await writeStream(tempFilePath, await inputFile.stream());
inputFilePath = tempFilePath;
createdTempInputFile = true;
} else {
inputFilePath = inputFile.path;
}
const thumbnail = await ipcRenderer.invoke(
"generate-image-thumbnail",
inputFilePath,
maxDimension,
maxSize,
);
return thumbnail;
} finally {
if (createdTempInputFile) {
try {
await ipcRenderer.invoke("remove-temp-file", inputFilePath);
} catch (e) {
logError(e, "failed to deleteTempFile");
}
}
}
}

View file

@ -8,7 +8,6 @@
import { ipcMain } from "electron/main";
import { clearElectronStore } from "../api/electronStore";
import { runFFmpegCmd } from "../api/ffmpeg";
import { getEncryptionKey, setEncryptionKey } from "../api/safeStorage";
import {
appVersion,
@ -20,7 +19,12 @@ import {
computeImageEmbedding,
computeTextEmbedding,
} from "../services/clipService";
import type { Model } from "../types";
import { runFFmpegCmd } from "../services/ffmpeg";
import {
convertToJPEG,
generateImageThumbnail,
} from "../services/imageProcessor";
import type { ElectronFile, Model } from "../types";
import { checkExistsAndCreateDir, fsExists } from "./fs";
import { openDirectory, openLogDirectory } from "./general";
import { logToDisk } from "./log";
@ -71,6 +75,16 @@ export const attachIPCHandlers = () => {
muteUpdateNotification(version),
);
ipcMain.handle("convertToJPEG", (_, fileData, filename) =>
convertToJPEG(fileData, filename),
);
ipcMain.handle(
"generateImageThumbnail",
(_, inputFile, maxDimension, maxSize) =>
generateImageThumbnail(inputFile, maxDimension, maxSize),
);
ipcMain.handle(
"runFFmpegCmd",
(

View file

@ -32,7 +32,6 @@ import * as fs from "node:fs/promises";
import { Readable } from "node:stream";
import path from "path";
import { getDirFiles } from "./api/fs";
import { convertToJPEG, generateImageThumbnail } from "./api/imageProcessor";
import {
getElectronFilesFromGoogleZip,
getPendingUploads,
@ -51,6 +50,7 @@ import {
updateWatchMappingSyncedFiles,
} from "./api/watch";
import { logErrorSentry, setupLogging } from "./main/log";
import type { ElectronFile } from "types";
setupLogging();
@ -142,6 +142,24 @@ const muteUpdateNotification = (version: string) => {
// - Conversion
const convertToJPEG = (
fileData: Uint8Array,
filename: string,
): Promise<Uint8Array> =>
ipcRenderer.invoke("convertToJPEG", fileData, filename);
const generateImageThumbnail = (
inputFile: File | ElectronFile,
maxDimension: number,
maxSize: number,
): Promise<Uint8Array> =>
ipcRenderer.invoke(
"generateImageThumbnail",
inputFile,
maxDimension,
maxSize,
);
const runFFmpegCmd = (
cmd: string[],
inputFile: File | ElectronFile,
@ -398,6 +416,8 @@ contextBridge.exposeInMainWorld("ElectronAPIs", {
registerUpdateEventListener,
// - Conversion
convertToJPEG,
generateImageThumbnail,
runFFmpegCmd,
// - ML
@ -434,9 +454,6 @@ contextBridge.exposeInMainWorld("ElectronAPIs", {
isFolder,
updateWatchMappingSyncedFiles,
updateWatchMappingIgnoredFiles,
convertToJPEG,
generateImageThumbnail,
moveFile,
deleteFolder,
rename,

View file

@ -1,14 +1,18 @@
import { exec } from "child_process";
import util from "util";
import log from "electron-log";
import { existsSync } from "fs";
import * as fs from "node:fs/promises";
import path from "path";
import util from "util";
import { CustomErrors } from "../constants/errors";
import { isDev } from "../main/general";
import { logError, logErrorSentry } from "../main/log";
import { writeStream } from "../services/fs";
import { ElectronFile } from "../types";
import { isPlatform } from "../utils/common/platform";
import { generateTempFilePath } from "../utils/temp";
import { logErrorSentry } from "../main/log";
import { deleteTempFile } from "./ffmpeg";
const shellescape = require("any-shell-escape");
const asyncExec = util.promisify(exec);
@ -80,6 +84,17 @@ function getImageMagickStaticPath() {
export async function convertToJPEG(
fileData: Uint8Array,
filename: string,
): Promise<Uint8Array> {
if (isPlatform("windows")) {
throw Error(CustomErrors.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED);
}
const convertedFileData = await convertToJPEG_(fileData, filename);
return convertedFileData;
}
async function convertToJPEG_(
fileData: Uint8Array,
filename: string,
): Promise<Uint8Array> {
let tempInputFilePath: string;
let tempOutputFilePath: string;
@ -159,6 +174,44 @@ function constructConvertCommand(
}
export async function generateImageThumbnail(
inputFile: File | ElectronFile,
maxDimension: number,
maxSize: number,
): Promise<Uint8Array> {
let inputFilePath = null;
let createdTempInputFile = null;
try {
if (isPlatform("windows")) {
throw Error(
CustomErrors.WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED,
);
}
if (!existsSync(inputFile.path)) {
const tempFilePath = await generateTempFilePath(inputFile.name);
await writeStream(tempFilePath, await inputFile.stream());
inputFilePath = tempFilePath;
createdTempInputFile = true;
} else {
inputFilePath = inputFile.path;
}
const thumbnail = await generateImageThumbnail_(
inputFilePath,
maxDimension,
maxSize,
);
return thumbnail;
} finally {
if (createdTempInputFile) {
try {
await deleteTempFile(inputFilePath);
} catch (e) {
logError(e, "failed to deleteTempFile");
}
}
}
}
async function generateImageThumbnail_(
inputFilePath: string,
width: number,
maxSize: number,

View file

@ -2,17 +2,7 @@ import chokidar from "chokidar";
import { BrowserWindow, dialog, ipcMain, Tray } from "electron";
import path from "path";
import { attachIPCHandlers } from "../main/ipc";
import {
computeImageEmbedding,
computeTextEmbedding,
} from "../services/clipService";
import { deleteTempFile } from "../services/ffmpeg";
import { getDirFilePaths } from "../services/fs";
import {
convertToJPEG,
generateImageThumbnail,
} from "../services/imageProcessor";
import { generateTempFilePath } from "./temp";
export default function setupIpcComs(
tray: Tray,
@ -65,29 +55,4 @@ export default function setupIpcComs(
ipcMain.handle("remove-watcher", async (_, args: { dir: string }) => {
watcher.unwatch(args.dir);
});
ipcMain.handle("convert-to-jpeg", (_, fileData, filename) => {
return convertToJPEG(fileData, filename);
});
ipcMain.handle("get-temp-file-path", (_, formatSuffix) => {
return generateTempFilePath(formatSuffix);
});
ipcMain.handle("remove-temp-file", (_, tempFilePath: string) => {
return deleteTempFile(tempFilePath);
});
ipcMain.handle(
"generate-image-thumbnail",
(_, fileData, maxDimension, maxSize) => {
return generateImageThumbnail(fileData, maxDimension, maxSize);
},
);
ipcMain.handle("compute-image-embedding", (_, model, inputFilePath) => {
return computeImageEmbedding(model, inputFilePath);
});
ipcMain.handle("compute-text-embedding", (_, model, text) => {
return computeTextEmbedding(model, text);
});
}

View file

@ -79,16 +79,23 @@ export interface ElectronAPIsType {
};
/** TODO: AUDIT below this */
// - General
registerForegroundEventListener: (onForeground: () => void) => void;
clearElectronStore: () => void;
setEncryptionKey: (encryptionKey: string) => Promise<void>;
getEncryptionKey: () => Promise<string>;
// - App update
updateAndRestart: () => void;
skipAppUpdate: (version: string) => void;
muteUpdateNotification: (version: string) => void;
registerUpdateEventListener: (
@ -97,6 +104,17 @@ export interface ElectronAPIsType {
// - Conversion
convertToJPEG: (
fileData: Uint8Array,
filename: string,
) => Promise<Uint8Array>;
generateImageThumbnail: (
inputFile: File | ElectronFile,
maxDimension: number,
maxSize: number,
) => Promise<Uint8Array>;
runFFmpegCmd: (
cmd: string[],
inputFile: File | ElectronFile,
@ -160,16 +178,6 @@ export interface ElectronAPIsType {
removeFolder: (folderPath: string) => Promise<void>,
) => void;
isFolder: (dirPath: string) => Promise<boolean>;
convertToJPEG: (
fileData: Uint8Array,
filename: string,
) => Promise<Uint8Array>;
generateImageThumbnail: (
inputFile: File | ElectronFile,
maxDimension: number,
maxSize: number,
) => Promise<Uint8Array>;
moveFile: (oldPath: string, newPath: string) => Promise<void>;
deleteFolder: (path: string) => Promise<void>;
deleteFile: (path: string) => Promise<void>;