refactor(server): move files to separate table (#11861)

This commit is contained in:
Jason Rasmussen
2024-08-19 20:03:33 -04:00
committed by GitHub
parent af3a793fe8
commit 7af6733665
32 changed files with 403 additions and 210 deletions

View File

@@ -15,7 +15,7 @@ import { SystemConfigCore } from 'src/cores/system-config.core';
import { SystemConfigFFmpegDto } from 'src/dtos/system-config.dto';
import { AssetEntity } from 'src/entities/asset.entity';
import { AssetPathType } from 'src/entities/move.entity';
import { AssetType } from 'src/enum';
import { AssetFileType, AssetType } from 'src/enum';
import { IAssetRepository, WithoutProperty } from 'src/interfaces/asset.interface';
import { ICryptoRepository } from 'src/interfaces/crypto.interface';
import {
@@ -34,6 +34,7 @@ import { IMoveRepository } from 'src/interfaces/move.interface';
import { IPersonRepository } from 'src/interfaces/person.interface';
import { IStorageRepository } from 'src/interfaces/storage.interface';
import { ISystemMetadataRepository } from 'src/interfaces/system-metadata.interface';
import { getAssetFiles } from 'src/utils/asset.util';
import { BaseConfig, ThumbnailConfig } from 'src/utils/media';
import { mimeTypes } from 'src/utils/mime-types';
import { usePagination } from 'src/utils/pagination';
@@ -72,7 +73,11 @@ export class MediaService {
async handleQueueGenerateThumbnails({ force }: IBaseJob): Promise<JobStatus> {
const assetPagination = usePagination(JOBS_ASSET_PAGINATION_SIZE, (pagination) => {
return force
? this.assetRepository.getAll(pagination, { isVisible: true, withDeleted: true, withArchived: true })
? this.assetRepository.getAll(pagination, {
isVisible: true,
withDeleted: true,
withArchived: true,
})
: this.assetRepository.getWithout(pagination, WithoutProperty.THUMBNAIL);
});
@@ -80,13 +85,17 @@ export class MediaService {
const jobs: JobItem[] = [];
for (const asset of assets) {
if (!asset.previewPath || force) {
const { previewFile, thumbnailFile } = getAssetFiles(asset.files);
if (!previewFile || force) {
jobs.push({ name: JobName.GENERATE_PREVIEW, data: { id: asset.id } });
continue;
}
if (!asset.thumbnailPath) {
if (!thumbnailFile) {
jobs.push({ name: JobName.GENERATE_THUMBNAIL, data: { id: asset.id } });
}
if (!asset.thumbhash) {
jobs.push({ name: JobName.GENERATE_THUMBHASH, data: { id: asset.id } });
}
@@ -152,7 +161,7 @@ export class MediaService {
async handleAssetMigration({ id }: IEntityJob): Promise<JobStatus> {
const { image } = await this.configCore.getConfig({ withCache: true });
const [asset] = await this.assetRepository.getByIds([id]);
const [asset] = await this.assetRepository.getByIds([id], { files: true });
if (!asset) {
return JobStatus.FAILED;
}
@@ -182,12 +191,14 @@ export class MediaService {
return JobStatus.SKIPPED;
}
if (asset.previewPath && asset.previewPath !== previewPath) {
const { previewFile } = getAssetFiles(asset.files);
if (previewFile && previewFile.path !== previewPath) {
this.logger.debug(`Deleting old preview for asset ${asset.id}`);
await this.storageRepository.unlink(asset.previewPath);
await this.storageRepository.unlink(previewFile.path);
}
await this.assetRepository.update({ id: asset.id, previewPath });
await this.assetRepository.upsertFile({ assetId: asset.id, type: AssetFileType.PREVIEW, path: previewPath });
await this.assetRepository.update({ id: asset.id, updatedAt: new Date() });
await this.assetRepository.upsertJobStatus({ assetId: asset.id, previewAt: new Date() });
return JobStatus.SUCCESS;
@@ -253,7 +264,7 @@ export class MediaService {
async handleGenerateThumbnail({ id }: IEntityJob): Promise<JobStatus> {
const [{ image }, [asset]] = await Promise.all([
this.configCore.getConfig({ withCache: true }),
this.assetRepository.getByIds([id], { exifInfo: true }),
this.assetRepository.getByIds([id], { exifInfo: true, files: true }),
]);
if (!asset) {
return JobStatus.FAILED;
@@ -268,19 +279,21 @@ export class MediaService {
return JobStatus.SKIPPED;
}
if (asset.thumbnailPath && asset.thumbnailPath !== thumbnailPath) {
const { thumbnailFile } = getAssetFiles(asset.files);
if (thumbnailFile && thumbnailFile.path !== thumbnailPath) {
this.logger.debug(`Deleting old thumbnail for asset ${asset.id}`);
await this.storageRepository.unlink(asset.thumbnailPath);
await this.storageRepository.unlink(thumbnailFile.path);
}
await this.assetRepository.update({ id: asset.id, thumbnailPath });
await this.assetRepository.upsertFile({ assetId: asset.id, type: AssetFileType.THUMBNAIL, path: thumbnailPath });
await this.assetRepository.update({ id: asset.id, updatedAt: new Date() });
await this.assetRepository.upsertJobStatus({ assetId: asset.id, thumbnailAt: new Date() });
return JobStatus.SUCCESS;
}
async handleGenerateThumbhash({ id }: IEntityJob): Promise<JobStatus> {
const [asset] = await this.assetRepository.getByIds([id]);
const [asset] = await this.assetRepository.getByIds([id], { files: true });
if (!asset) {
return JobStatus.FAILED;
}
@@ -289,11 +302,12 @@ export class MediaService {
return JobStatus.SKIPPED;
}
if (!asset.previewPath) {
const { previewFile } = getAssetFiles(asset.files);
if (!previewFile) {
return JobStatus.FAILED;
}
const thumbhash = await this.mediaRepository.generateThumbhash(asset.previewPath);
const thumbhash = await this.mediaRepository.generateThumbhash(previewFile.path);
await this.assetRepository.update({ id: asset.id, thumbhash });
return JobStatus.SUCCESS;