mirror of
https://github.com/immich-app/immich.git
synced 2024-11-28 09:33:27 +02:00
refactor(server): track thumbnail jobs in job status table (#11908)
refactor: track thumbnail jobs in job status table
This commit is contained in:
parent
8338657eaa
commit
d9698884bd
@ -18,4 +18,10 @@ export class AssetJobStatusEntity {
|
|||||||
|
|
||||||
@Column({ type: 'timestamptz', nullable: true })
|
@Column({ type: 'timestamptz', nullable: true })
|
||||||
duplicatesDetectedAt!: Date | null;
|
duplicatesDetectedAt!: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamptz', nullable: true })
|
||||||
|
previewAt!: Date | null;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamptz', nullable: true })
|
||||||
|
thumbnailAt!: Date | null;
|
||||||
}
|
}
|
||||||
|
17
server/src/migrations/1724080823160-AddThumbnailJobStatus.ts
Normal file
17
server/src/migrations/1724080823160-AddThumbnailJobStatus.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class AddThumbnailJobStatus1724080823160 implements MigrationInterface {
|
||||||
|
name = 'AddThumbnailJobStatus1724080823160';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "asset_job_status" ADD "previewAt" TIMESTAMP WITH TIME ZONE`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "asset_job_status" ADD "thumbnailAt" TIMESTAMP WITH TIME ZONE`);
|
||||||
|
await queryRunner.query(`UPDATE "asset_job_status" SET "previewAt" = NOW() FROM "assets" WHERE "assetId" = "assets"."id" AND "assets"."previewPath" IS NOT NULL`);
|
||||||
|
await queryRunner.query(`UPDATE "asset_job_status" SET "thumbnailAt" = NOW() FROM "assets" WHERE "assetId" = "assets"."id" AND "assets"."thumbnailPath" IS NOT NULL`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "asset_job_status" DROP COLUMN "thumbnailAt"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "asset_job_status" DROP COLUMN "previewAt"`);
|
||||||
|
}
|
||||||
|
}
|
@ -391,11 +391,10 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
|
|
||||||
switch (property) {
|
switch (property) {
|
||||||
case WithoutProperty.THUMBNAIL: {
|
case WithoutProperty.THUMBNAIL: {
|
||||||
|
relations = { jobStatus: true };
|
||||||
where = [
|
where = [
|
||||||
{ previewPath: IsNull(), isVisible: true },
|
{ jobStatus: { previewAt: IsNull() }, isVisible: true },
|
||||||
{ previewPath: '', isVisible: true },
|
{ jobStatus: { thumbnailAt: IsNull() }, isVisible: true },
|
||||||
{ thumbnailPath: IsNull(), isVisible: true },
|
|
||||||
{ thumbnailPath: '', isVisible: true },
|
|
||||||
{ thumbhash: IsNull(), isVisible: true },
|
{ thumbhash: IsNull(), isVisible: true },
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
@ -429,7 +428,7 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
};
|
};
|
||||||
where = {
|
where = {
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
previewPath: Not(IsNull()),
|
jobStatus: { previewAt: Not(IsNull()) },
|
||||||
smartSearch: {
|
smartSearch: {
|
||||||
embedding: IsNull(),
|
embedding: IsNull(),
|
||||||
},
|
},
|
||||||
@ -439,10 +438,10 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
|
|
||||||
case WithoutProperty.DUPLICATE: {
|
case WithoutProperty.DUPLICATE: {
|
||||||
where = {
|
where = {
|
||||||
previewPath: Not(IsNull()),
|
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
smartSearch: true,
|
smartSearch: true,
|
||||||
jobStatus: {
|
jobStatus: {
|
||||||
|
previewAt: Not(IsNull()),
|
||||||
duplicatesDetectedAt: IsNull(),
|
duplicatesDetectedAt: IsNull(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -454,7 +453,9 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
smartInfo: true,
|
smartInfo: true,
|
||||||
};
|
};
|
||||||
where = {
|
where = {
|
||||||
previewPath: Not(IsNull()),
|
jobStatus: {
|
||||||
|
previewAt: Not(IsNull()),
|
||||||
|
},
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
smartInfo: {
|
smartInfo: {
|
||||||
tags: IsNull(),
|
tags: IsNull(),
|
||||||
@ -469,13 +470,13 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
jobStatus: true,
|
jobStatus: true,
|
||||||
};
|
};
|
||||||
where = {
|
where = {
|
||||||
previewPath: Not(IsNull()),
|
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
faces: {
|
faces: {
|
||||||
assetId: IsNull(),
|
assetId: IsNull(),
|
||||||
personId: IsNull(),
|
personId: IsNull(),
|
||||||
},
|
},
|
||||||
jobStatus: {
|
jobStatus: {
|
||||||
|
previewAt: Not(IsNull()),
|
||||||
facesRecognizedAt: IsNull(),
|
facesRecognizedAt: IsNull(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -487,7 +488,9 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
faces: true,
|
faces: true,
|
||||||
};
|
};
|
||||||
where = {
|
where = {
|
||||||
previewPath: Not(IsNull()),
|
jobStatus: {
|
||||||
|
previewAt: Not(IsNull()),
|
||||||
|
},
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
faces: {
|
faces: {
|
||||||
assetId: Not(IsNull()),
|
assetId: Not(IsNull()),
|
||||||
|
@ -178,11 +178,18 @@ export class MediaService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const previewPath = await this.generateThumbnail(asset, AssetPathType.PREVIEW, image.previewFormat);
|
const previewPath = await this.generateThumbnail(asset, AssetPathType.PREVIEW, image.previewFormat);
|
||||||
|
if (!previewPath) {
|
||||||
|
return JobStatus.SKIPPED;
|
||||||
|
}
|
||||||
|
|
||||||
if (asset.previewPath && asset.previewPath !== previewPath) {
|
if (asset.previewPath && asset.previewPath !== previewPath) {
|
||||||
this.logger.debug(`Deleting old preview for asset ${asset.id}`);
|
this.logger.debug(`Deleting old preview for asset ${asset.id}`);
|
||||||
await this.storageRepository.unlink(asset.previewPath);
|
await this.storageRepository.unlink(asset.previewPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.assetRepository.update({ id: asset.id, previewPath });
|
await this.assetRepository.update({ id: asset.id, previewPath });
|
||||||
|
await this.assetRepository.upsertJobStatus({ assetId: asset.id, previewAt: new Date() });
|
||||||
|
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,11 +264,18 @@ export class MediaService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const thumbnailPath = await this.generateThumbnail(asset, AssetPathType.THUMBNAIL, image.thumbnailFormat);
|
const thumbnailPath = await this.generateThumbnail(asset, AssetPathType.THUMBNAIL, image.thumbnailFormat);
|
||||||
|
if (!thumbnailPath) {
|
||||||
|
return JobStatus.SKIPPED;
|
||||||
|
}
|
||||||
|
|
||||||
if (asset.thumbnailPath && asset.thumbnailPath !== thumbnailPath) {
|
if (asset.thumbnailPath && asset.thumbnailPath !== thumbnailPath) {
|
||||||
this.logger.debug(`Deleting old thumbnail for asset ${asset.id}`);
|
this.logger.debug(`Deleting old thumbnail for asset ${asset.id}`);
|
||||||
await this.storageRepository.unlink(asset.thumbnailPath);
|
await this.storageRepository.unlink(asset.thumbnailPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.assetRepository.update({ id: asset.id, thumbnailPath });
|
await this.assetRepository.update({ id: asset.id, thumbnailPath });
|
||||||
|
await this.assetRepository.upsertJobStatus({ assetId: asset.id, thumbnailAt: new Date() });
|
||||||
|
|
||||||
return JobStatus.SUCCESS;
|
return JobStatus.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user