mirror of
https://github.com/KevinMidboe/immich.git
synced 2025-10-29 17:40:28 +00:00
fix(server): regenerate missing person thumbnails (#3970)
* Regenerate missing person thumbnails * Check for empty string instead of zero length * Remember asset used as person face * Define entity relation between person and asset via faceAssetId * Typo * Fix entity relation * Tests * Tests * Fix code formatting * Fix import path * Fix migration * format * Fix entity and migration * Linting * Remove unneeded cast * Conventions * Simplify queries * Simplify queries * Remove unneeded typings from entity * Remove unneeded cast --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
import { AssetFaceEntity } from './asset-face.entity';
|
||||
import { AssetEntity } from './asset.entity';
|
||||
import { UserEntity } from './user.entity';
|
||||
|
||||
@Entity('person')
|
||||
@@ -36,6 +37,12 @@ export class PersonEntity {
|
||||
@Column({ default: '' })
|
||||
thumbnailPath!: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
faceAssetId!: string | null;
|
||||
|
||||
@ManyToOne(() => AssetEntity, { onDelete: 'SET NULL', nullable: true })
|
||||
faceAsset!: AssetEntity | null;
|
||||
|
||||
@OneToMany(() => AssetFaceEntity, (assetFace) => assetFace.person)
|
||||
faces!: AssetFaceEntity[];
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { MigrationInterface, QueryRunner } from "typeorm"
|
||||
|
||||
export class AddPersonFaceAssetId1693833336881 implements MigrationInterface {
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "person" ADD "faceAssetId" uuid`);
|
||||
await queryRunner.query(`ALTER TABLE "person" ADD CONSTRAINT "FK_2bbabe31656b6778c6b87b61023" FOREIGN KEY ("faceAssetId") REFERENCES "assets"("id") ON DELETE SET NULL ON UPDATE NO ACTION`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`ALTER TABLE "person" DROP CONSTRAINT "FK_2bbabe31656b6778c6b87b61023"`);
|
||||
await queryRunner.query(`ALTER TABLE "person" DROP COLUMN "faceAssetId"`);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,7 +50,15 @@ export class PersonRepository implements IPersonRepository {
|
||||
return people.length;
|
||||
}
|
||||
|
||||
getAll(userId: string, options?: PersonSearchOptions): Promise<PersonEntity[]> {
|
||||
getAll(): Promise<PersonEntity[]> {
|
||||
return this.personRepository.find();
|
||||
}
|
||||
|
||||
getAllWithoutThumbnail(): Promise<PersonEntity[]> {
|
||||
return this.personRepository.findBy({ thumbnailPath: '' });
|
||||
}
|
||||
|
||||
getAllForUser(userId: string, options?: PersonSearchOptions): Promise<PersonEntity[]> {
|
||||
const queryBuilder = this.personRepository
|
||||
.createQueryBuilder('person')
|
||||
.leftJoin('person.faces', 'face')
|
||||
@@ -118,4 +126,8 @@ export class PersonRepository implements IPersonRepository {
|
||||
async getFaceById({ personId, assetId }: AssetFaceId): Promise<AssetFaceEntity | null> {
|
||||
return this.assetFaceRepository.findOneBy({ assetId, personId });
|
||||
}
|
||||
|
||||
async getRandomFace(personId: string): Promise<AssetFaceEntity | null> {
|
||||
return this.assetFaceRepository.findOneBy({ personId });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user