Serve legacy face crops
This commit is contained in:
parent
0af7d2c13e
commit
333f364d38
6 changed files with 76 additions and 13 deletions
|
@ -287,13 +287,27 @@ const setupTrayItem = (mainWindow: BrowserWindow) => {
|
|||
|
||||
/**
|
||||
* Older versions of our app used to maintain a cache dir using the main
|
||||
* process. This has been deprecated in favor of using a normal web cache.
|
||||
* process. This has been removed in favor of cache on the web layer.
|
||||
*
|
||||
* Delete the old cache dir if it exists. This code was added March 2024, and
|
||||
* can be removed after some time once most people have upgraded to newer
|
||||
* versions.
|
||||
* Delete the old cache dir if it exists.
|
||||
*
|
||||
* This will happen in two phases. The cache had three subdirectories:
|
||||
*
|
||||
* - Two of them, "thumbs" and "files", will be removed now (v1.7.0, May 2024).
|
||||
*
|
||||
* - The third one, "face-crops" will be removed once we finish the face search
|
||||
* changes. See: [Note: Legacy face crops].
|
||||
*
|
||||
* This migration code can be removed after some time once most people have
|
||||
* upgraded to newer versions.
|
||||
*/
|
||||
const deleteLegacyDiskCacheDirIfExists = async () => {
|
||||
const removeIfExists = async (dirPath: string) => {
|
||||
log.info(`Removing legacy disk cache from ${dirPath}`);
|
||||
await fs.rm(dirPath, { recursive: true });
|
||||
};
|
||||
// [Note: Getting the cache path]
|
||||
//
|
||||
// The existing code was passing "cache" as a parameter to getPath.
|
||||
//
|
||||
// However, "cache" is not a valid parameter to getPath. It works! (for
|
||||
|
@ -309,8 +323,8 @@ const deleteLegacyDiskCacheDirIfExists = async () => {
|
|||
// @ts-expect-error "cache" works but is not part of the public API.
|
||||
const cacheDir = path.join(app.getPath("cache"), "ente");
|
||||
if (existsSync(cacheDir)) {
|
||||
log.info(`Removing legacy disk cache from ${cacheDir}`);
|
||||
await fs.rm(cacheDir, { recursive: true });
|
||||
await removeIfExists(path.join(cacheDir, "thumbs"));
|
||||
await removeIfExists(path.join(cacheDir, "files"));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
updateOnNextRestart,
|
||||
} from "./services/app-update";
|
||||
import {
|
||||
legacyFaceCrop,
|
||||
openDirectory,
|
||||
openLogDirectory,
|
||||
selectDirectory,
|
||||
|
@ -198,6 +199,10 @@ export const attachIPCHandlers = () => {
|
|||
faceEmbedding(input),
|
||||
);
|
||||
|
||||
ipcMain.handle("legacyFaceCrop", (_, faceID: string) =>
|
||||
legacyFaceCrop(faceID),
|
||||
);
|
||||
|
||||
// - Upload
|
||||
|
||||
ipcMain.handle("listZipItems", (_, zipPath: string) =>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { shell } from "electron/common";
|
||||
import { app, dialog } from "electron/main";
|
||||
import { existsSync } from "fs";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { posixPath } from "../utils/electron";
|
||||
|
||||
|
@ -49,3 +51,16 @@ export const openLogDirectory = () => openDirectory(logDirectoryPath());
|
|||
*
|
||||
*/
|
||||
const logDirectoryPath = () => app.getPath("logs");
|
||||
|
||||
/**
|
||||
* See: [Note: Legacy face crops]
|
||||
*/
|
||||
export const legacyFaceCrop = async (
|
||||
faceID: string,
|
||||
): Promise<Uint8Array | undefined> => {
|
||||
// See: [Note: Getting the cache path]
|
||||
// @ts-expect-error "cache" works but is not part of the public API.
|
||||
const cacheDir = path.join(app.getPath("cache"), "ente");
|
||||
const filePath = path.join(cacheDir, "face-crops", faceID);
|
||||
return existsSync(filePath) ? await fs.readFile(filePath) : undefined;
|
||||
};
|
||||
|
|
|
@ -164,6 +164,9 @@ const detectFaces = (input: Float32Array) =>
|
|||
const faceEmbedding = (input: Float32Array) =>
|
||||
ipcRenderer.invoke("faceEmbedding", input);
|
||||
|
||||
const legacyFaceCrop = (faceID: string) =>
|
||||
ipcRenderer.invoke("legacyFaceCrop", faceID);
|
||||
|
||||
// - Watch
|
||||
|
||||
const watchGet = () => ipcRenderer.invoke("watchGet");
|
||||
|
@ -341,6 +344,7 @@ contextBridge.exposeInMainWorld("electron", {
|
|||
clipTextEmbeddingIfAvailable,
|
||||
detectFaces,
|
||||
faceEmbedding,
|
||||
legacyFaceCrop,
|
||||
|
||||
// - Watch
|
||||
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
import { cachedOrNew } from "@/next/blob-cache";
|
||||
import { ensureLocalUser } from "@/next/local-user";
|
||||
import log from "@/next/log";
|
||||
import { Skeleton, styled } from "@mui/material";
|
||||
import { Legend } from "components/PhotoViewer/styledComponents/Legend";
|
||||
import { t } from "i18next";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import machineLearningService from "services/machineLearning/machineLearningService";
|
||||
import { EnteFile } from "types/file";
|
||||
import { Face, Person } from "types/machineLearning";
|
||||
import { getPeopleList, getUnidentifiedFaces } from "utils/machineLearning";
|
||||
|
@ -163,8 +160,12 @@ const FaceCropImageView: React.FC<FaceCropImageViewProps> = ({
|
|||
|
||||
useEffect(() => {
|
||||
let didCancel = false;
|
||||
const electron = globalThis.electron;
|
||||
|
||||
if (cacheKey) {
|
||||
if (cacheKey && electron) {
|
||||
electron
|
||||
.legacyFaceCrop(cacheKey)
|
||||
/*
|
||||
cachedOrNew("face-crops", cacheKey, async () => {
|
||||
const user = await ensureLocalUser();
|
||||
return machineLearningService.regenerateFaceCrop(
|
||||
|
@ -172,9 +173,11 @@ const FaceCropImageView: React.FC<FaceCropImageViewProps> = ({
|
|||
user.id,
|
||||
faceId,
|
||||
);
|
||||
}).then((blob) => {
|
||||
if (!didCancel) setObjectURL(URL.createObjectURL(blob));
|
||||
});
|
||||
})*/
|
||||
.then((data) => {
|
||||
const blob = new Blob([data]);
|
||||
if (!didCancel) setObjectURL(URL.createObjectURL(blob));
|
||||
});
|
||||
} else setObjectURL(undefined);
|
||||
|
||||
return () => {
|
||||
|
|
|
@ -346,6 +346,28 @@ export interface Electron {
|
|||
*/
|
||||
faceEmbedding: (input: Float32Array) => Promise<Float32Array>;
|
||||
|
||||
/**
|
||||
* Return a face crop stored by a previous version of ML.
|
||||
*
|
||||
* [Note: Legacy face crops]
|
||||
*
|
||||
* Older versions of ML generated and stored face crops in a "face-crops"
|
||||
* cache directory on the Electron side. For the time being, we have
|
||||
* disabled the face search whilst we put finishing touches to it. However,
|
||||
* it'll be nice to still show the existing faces that have been clustered
|
||||
* for people who opted in to the older beta.
|
||||
*
|
||||
* So we retain the older "face-crops" disk cache, and use this method to
|
||||
* serve faces from it when needed.
|
||||
*
|
||||
* @param faceID An identifier corresponding to which the face crop had been
|
||||
* stored by the older version of our app.
|
||||
*
|
||||
* @returns the JPEG data of the face crop if a file is found for the given
|
||||
* {@link faceID}, otherwise undefined.
|
||||
*/
|
||||
legacyFaceCrop: (faceID: string) => Promise<Uint8Array | undefined>;
|
||||
|
||||
// - Watch
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue