1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-01-10 05:46:46 +01:00
immich/server/libs/domain/src/storage-template/storage-template.service.ts
Jason Rasmussen 6c7679714b
refactor(server): jobs and processors (#1787)
* refactor: jobs and processors

* refactor: storage migration processor

* fix: tests

* fix: code warning

* chore: ignore coverage from infra

* fix: sync move asset logic between job core and asset core

* refactor: move error handling inside of catch

* refactor(server): job core into dedicated service calls

* refactor: smart info

* fix: tests

* chore: smart info tests

* refactor: use asset repository

* refactor: thumbnail processor

* chore: coverage reqs
2023-02-25 08:12:03 -06:00

73 lines
2.8 KiB
TypeScript

import { APP_UPLOAD_LOCATION } from '@app/common';
import { AssetEntity, SystemConfig } from '@app/infra/db/entities';
import { Inject, Injectable, Logger } from '@nestjs/common';
import { IAssetRepository } from '../asset/asset.repository';
import { IStorageRepository } from '../storage/storage.repository';
import { INITIAL_SYSTEM_CONFIG, ISystemConfigRepository } from '../system-config';
import { StorageTemplateCore } from './storage-template.core';
@Injectable()
export class StorageTemplateService {
private logger = new Logger(StorageTemplateService.name);
private core: StorageTemplateCore;
constructor(
@Inject(IAssetRepository) private assetRepository: IAssetRepository,
@Inject(ISystemConfigRepository) configRepository: ISystemConfigRepository,
@Inject(INITIAL_SYSTEM_CONFIG) config: SystemConfig,
@Inject(IStorageRepository) private storageRepository: IStorageRepository,
) {
this.core = new StorageTemplateCore(configRepository, config, storageRepository);
}
async handleTemplateMigration() {
try {
console.time('migrating-time');
const assets = await this.assetRepository.getAll();
const livePhotoMap: Record<string, AssetEntity> = {};
for (const asset of assets) {
if (asset.livePhotoVideoId) {
livePhotoMap[asset.livePhotoVideoId] = asset;
}
}
for (const asset of assets) {
const livePhotoParentAsset = livePhotoMap[asset.id];
// TODO: remove livePhoto specific stuff once upload is fixed
const filename = asset.exifInfo?.imageName || livePhotoParentAsset?.exifInfo?.imageName || asset.id;
await this.moveAsset(asset, filename);
}
this.logger.debug('Cleaning up empty directories...');
await this.storageRepository.removeEmptyDirs(APP_UPLOAD_LOCATION);
} catch (error: any) {
this.logger.error('Error running template migration', error);
} finally {
console.timeEnd('migrating-time');
}
}
// TODO: use asset core (once in domain)
async moveAsset(asset: AssetEntity, originalName: string) {
const destination = await this.core.getTemplatePath(asset, originalName);
if (asset.originalPath !== destination) {
const source = asset.originalPath;
try {
await this.storageRepository.moveFile(asset.originalPath, destination);
try {
await this.assetRepository.save({ id: asset.id, originalPath: destination });
asset.originalPath = destination;
} catch (error: any) {
this.logger.warn('Unable to save new originalPath to database, undoing move', error?.stack);
await this.storageRepository.moveFile(destination, source);
}
} catch (error: any) {
this.logger.error(`Problem applying storage template`, error?.stack, { id: asset.id, source, destination });
}
}
return asset;
}
}