From 7f132b1827becfd0454dbf85629939290007cfa3 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Wed, 25 Sep 2024 13:41:54 +0530 Subject: [PATCH] cgroups --- web/packages/new/photos/services/ml/people.ts | 12 ++-- .../new/photos/services/user-entity/index.ts | 69 +++++++------------ 2 files changed, 29 insertions(+), 52 deletions(-) diff --git a/web/packages/new/photos/services/ml/people.ts b/web/packages/new/photos/services/ml/people.ts index f33e27e53c..5eba77a5b0 100644 --- a/web/packages/new/photos/services/ml/people.ts +++ b/web/packages/new/photos/services/ml/people.ts @@ -2,9 +2,9 @@ import { masterKeyFromSession } from "@/base/session-store"; import { wipClusterEnable } from "."; import type { EnteFile } from "../../types/file"; import { getLocalFiles } from "../files"; -import { pullCGroups } from "../user-entity"; +import { pullUserEntities, savedCGroups } from "../user-entity"; import type { FaceCluster } from "./cluster"; -import { getClusterGroups, getFaceIndexes } from "./db"; +import { getFaceIndexes } from "./db"; import { fileIDFromFaceID } from "./face"; /** @@ -131,7 +131,7 @@ export const syncCGroups = async () => { if (!(await wipClusterEnable())) return; const masterKey = await masterKeyFromSession(); - await pullCGroups(masterKey); + await pullUserEntities("cgroup", masterKey); }; export type NamedPerson = Omit & { @@ -180,9 +180,9 @@ export const namedPeopleFromCGroups = async (): Promise => { } // Convert cgroups to people. - const cgroups = await getClusterGroups(); + const cgroups = await savedCGroups(); return cgroups - .map((cgroup) => { + .map(({ id, data: cgroup }) => { // Hidden cgroups are clusters specifically marked so as to not be shown // in the UI. if (cgroup.isHidden) return undefined; @@ -229,8 +229,6 @@ export const namedPeopleFromCGroups = async (): Promise => { displayFaceFile = highestScoringFace.file; } - const id = cgroup.id; - return { id, name, fileIDs, displayFaceID, displayFaceFile }; }) .filter((c) => !!c) diff --git a/web/packages/new/photos/services/user-entity/index.ts b/web/packages/new/photos/services/user-entity/index.ts index c53a5cec1b..35e3709288 100644 --- a/web/packages/new/photos/services/user-entity/index.ts +++ b/web/packages/new/photos/services/user-entity/index.ts @@ -6,8 +6,6 @@ import { import { nullToUndefined } from "@/utils/transform"; import { z } from "zod"; import { gunzip } from "../../utils/gzip"; -import { applyCGroupDiff } from "../ml/db"; -import type { CGroup } from "../ml/people"; import { savedEntities, savedLatestUpdatedAt, @@ -15,13 +13,13 @@ import { saveEntities, saveLatestUpdatedAt, saveRemoteUserEntityKey, + type LocalUserEntity, } from "./db"; import { getUserEntityKey, postUserEntityKey, RemoteUserEntityKey, userEntityDiff, - type UserEntityChange, } from "./remote"; /** @@ -44,7 +42,10 @@ export type EntityType = */ | "cgroup"; -/** Zod schema for the fields of interest in the location tag that we get from remote. */ +/** + * Zod schema for the fields of interest in the location tag that we get from + * remote. + */ const RemoteLocationTag = z.object({ name: z.string(), radius: z.number(), @@ -54,6 +55,9 @@ const RemoteLocationTag = z.object({ }), }); +/** + * A view of the location tag data suitable for use by the rest of the app. + */ export type LocationTag = z.infer; /** @@ -61,54 +65,17 @@ export type LocationTag = z.infer; */ export const savedLocationTags = (): Promise => savedEntities("location").then((es) => - es.map((e) => RemoteLocationTag.parse(e)), + es.map((e) => RemoteLocationTag.parse(e.data)), ); -/** - * Update our local cgroups with changes from remote. - * - * This fetches all the user entities corresponding to the "cgroup" entity type - * from remote that have been created, updated or deleted since the last time we - * checked. - * - * This diff is then applied to the data we have persisted locally. - * - * * This function fetches all the location tag user entities from remote and - * updates our local database. It uses local state to remember the latest entry - * the last time it did a pull, so each subsequent pull is a lightweight diff. - * - * @param masterKey The user's master key. This is used to encrypt and decrypt - * the cgroup specific entity key. - */ -export const pullCGroups = (masterKey: Uint8Array) => { - // See: [Note: strict mode migration] - // - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const parse = async (id: string, data: Uint8Array): Promise => ({ - id, - name: undefined, - avatarFaceID: undefined, - ...RemoteCGroup.parse(JSON.parse(await gunzip(data))), - }); - - const processBatch = async (entities: UserEntityChange[]) => - await applyCGroupDiff( - await Promise.all( - entities.map(async ({ id, data }) => - data ? await parse(id, data) : id, - ), - ), - ); - - return pullUserEntities("cgroup", masterKey); -}; - const RemoteFaceCluster = z.object({ id: z.string(), faces: z.string().array(), }); +/** + * Zod schema for the fields of interest in the cgroup that we get from remote. + */ const RemoteCGroup = z.object({ name: z.string().nullish().transform(nullToUndefined), assigned: z.array(RemoteFaceCluster), @@ -120,6 +87,18 @@ const RemoteCGroup = z.object({ export type RemoteCGroup = z.infer; +export type CGroupUserEntity = Omit & { + data: RemoteCGroup; +}; + +/** + * Return the list of locally available cgroup user entities. + */ +export const savedCGroups = (): Promise => + savedEntities("cgroup").then((es) => + es.map((e) => ({ ...e, data: RemoteCGroup.parse(e.data) })), + ); + /** * Update our local entities of the given {@link type} by pulling the latest * changes from remote.