This commit is contained in:
Manav Rathi
2024-09-25 13:41:54 +05:30
parent b763cab1ba
commit 7f132b1827
2 changed files with 29 additions and 52 deletions

View File

@@ -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<Person, "name"> & {
@@ -180,9 +180,9 @@ export const namedPeopleFromCGroups = async (): Promise<NamedPerson[]> => {
}
// 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<NamedPerson[]> => {
displayFaceFile = highestScoringFace.file;
}
const id = cgroup.id;
return { id, name, fileIDs, displayFaceID, displayFaceFile };
})
.filter((c) => !!c)

View File

@@ -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<typeof RemoteLocationTag>;
/**
@@ -61,54 +65,17 @@ export type LocationTag = z.infer<typeof RemoteLocationTag>;
*/
export const savedLocationTags = (): Promise<LocationTag[]> =>
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<CGroup> => ({
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<typeof RemoteCGroup>;
export type CGroupUserEntity = Omit<LocalUserEntity, "data"> & {
data: RemoteCGroup;
};
/**
* Return the list of locally available cgroup user entities.
*/
export const savedCGroups = (): Promise<CGroupUserEntity[]> =>
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.