storage-migration.processor.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { APP_UPLOAD_LOCATION } from '@app/common';
  2. import { AssetEntity } from '@app/infra';
  3. import { ImmichConfigService } from '@app/immich-config';
  4. import { QueueName, JobName } from '@app/job';
  5. import { StorageService } from '@app/storage';
  6. import { Process, Processor } from '@nestjs/bull';
  7. import { Logger } from '@nestjs/common';
  8. import { InjectRepository } from '@nestjs/typeorm';
  9. import { Repository } from 'typeorm';
  10. @Processor(QueueName.CONFIG)
  11. export class StorageMigrationProcessor {
  12. readonly logger: Logger = new Logger(StorageMigrationProcessor.name);
  13. constructor(
  14. private storageService: StorageService,
  15. private immichConfigService: ImmichConfigService,
  16. @InjectRepository(AssetEntity)
  17. private assetRepository: Repository<AssetEntity>,
  18. ) {}
  19. /**
  20. * Migration process when a new user set a new storage template.
  21. * @param job
  22. */
  23. @Process({ name: JobName.TEMPLATE_MIGRATION, concurrency: 100 })
  24. async templateMigration() {
  25. console.time('migrating-time');
  26. const assets = await this.assetRepository.find({
  27. relations: ['exifInfo'],
  28. });
  29. const livePhotoMap: Record<string, AssetEntity> = {};
  30. for (const asset of assets) {
  31. if (asset.livePhotoVideoId) {
  32. livePhotoMap[asset.livePhotoVideoId] = asset;
  33. }
  34. }
  35. for (const asset of assets) {
  36. const livePhotoParentAsset = livePhotoMap[asset.id];
  37. const filename = asset.exifInfo?.imageName || livePhotoParentAsset?.exifInfo?.imageName || asset.id;
  38. await this.storageService.moveAsset(asset, filename);
  39. }
  40. await this.storageService.removeEmptyDirectories(APP_UPLOAD_LOCATION);
  41. console.timeEnd('migrating-time');
  42. }
  43. /**
  44. * Update config when a new storage template is set.
  45. * This is to ensure the synchronization between processes.
  46. * @param job
  47. */
  48. @Process({ name: JobName.CONFIG_CHANGE, concurrency: 1 })
  49. async updateTemplate() {
  50. await this.immichConfigService.refreshConfig();
  51. }
  52. }