mirror of
https://github.com/KevinMidboe/immich.git
synced 2026-01-08 02:05:48 +00:00
refactor(server): Move metadata extraction to domain (#4243)
* use storageRepository in metadata extraction * move metadata extraction processor to domain * cleanup infra/domain --------- Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
||||
} from '@app/domain';
|
||||
import archiver from 'archiver';
|
||||
import { constants, createReadStream, existsSync, mkdirSync } from 'fs';
|
||||
import fs, { readdir } from 'fs/promises';
|
||||
import fs, { readdir, writeFile } from 'fs/promises';
|
||||
import { glob } from 'glob';
|
||||
import mv from 'mv';
|
||||
import { promisify } from 'node:util';
|
||||
@@ -39,6 +39,18 @@ export class FilesystemProvider implements IStorageRepository {
|
||||
};
|
||||
}
|
||||
|
||||
async readFile(filepath: string, options?: fs.FileReadOptions<Buffer>): Promise<Buffer> {
|
||||
const file = await fs.open(filepath);
|
||||
try {
|
||||
const { buffer } = await file.read(options);
|
||||
return buffer;
|
||||
} finally {
|
||||
await file.close();
|
||||
}
|
||||
}
|
||||
|
||||
writeFile = writeFile;
|
||||
|
||||
async moveFile(source: string, destination: string): Promise<void> {
|
||||
if (await this.checkFileExists(destination)) {
|
||||
throw new Error(`Destination file already exists: ${destination}`);
|
||||
|
||||
@@ -7,11 +7,11 @@ export * from './communication.repository';
|
||||
export * from './crypto.repository';
|
||||
export * from './face.repository';
|
||||
export * from './filesystem.provider';
|
||||
export * from './geocoding.repository';
|
||||
export * from './job.repository';
|
||||
export * from './library.repository';
|
||||
export * from './machine-learning.repository';
|
||||
export * from './media.repository';
|
||||
export * from './metadata.repository';
|
||||
export * from './partner.repository';
|
||||
export * from './person.repository';
|
||||
export * from './shared-link.repository';
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { GeoPoint, IGeocodingRepository, ReverseGeocodeResult } from '@app/domain';
|
||||
import { GeoPoint, IMetadataRepository, ImmichTags, ReverseGeocodeResult } from '@app/domain';
|
||||
import { REVERSE_GEOCODING_DUMP_DIRECTORY } from '@app/infra';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { DefaultReadTaskOptions, exiftool } from 'exiftool-vendored';
|
||||
import { readdir, rm } from 'fs/promises';
|
||||
import * as geotz from 'geo-tz';
|
||||
import { getName } from 'i18n-iso-countries';
|
||||
import geocoder, { AddressObject, InitOptions } from 'local-reverse-geocoder';
|
||||
import path from 'path';
|
||||
@@ -21,8 +23,8 @@ export type GeoData = AddressObject & {
|
||||
const lookup = promisify<GeoPoint[], number, AddressObject[][]>(geocoder.lookUp).bind(geocoder);
|
||||
|
||||
@Injectable()
|
||||
export class GeocodingRepository implements IGeocodingRepository {
|
||||
private logger = new Logger(GeocodingRepository.name);
|
||||
export class MetadataRepository implements IMetadataRepository {
|
||||
private logger = new Logger(MetadataRepository.name);
|
||||
|
||||
async init(options: Partial<InitOptions>): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
@@ -69,4 +71,22 @@ export class GeocodingRepository implements IGeocodingRepository {
|
||||
|
||||
return { country, state, city };
|
||||
}
|
||||
|
||||
getExifTags(path: string): Promise<ImmichTags | null> {
|
||||
return exiftool
|
||||
.read<ImmichTags>(path, undefined, {
|
||||
...DefaultReadTaskOptions,
|
||||
|
||||
defaultVideosToUTC: true,
|
||||
backfillTimezones: true,
|
||||
inferTimezoneFromDatestamps: true,
|
||||
useMWG: true,
|
||||
numericTags: DefaultReadTaskOptions.numericTags.concat(['FocalLength']),
|
||||
geoTz: (lat, lon) => geotz.find(lat, lon)[0],
|
||||
})
|
||||
.catch((error) => {
|
||||
this.logger.warn(`Error reading exif data (${path}): ${error}`, error?.stack);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user