1
0
mirror of https://github.com/immich-app/immich.git synced 2025-01-12 15:32:36 +02:00

fix(server): don't associate assets with Null Island (#5623)

* Don't associate assets with Null Island

* Fix lint
This commit is contained in:
Sushain Cherivirala 2023-12-11 07:00:23 -08:00 committed by GitHub
parent 960b68b02f
commit e3e4fb40fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 28 deletions

View File

@ -304,6 +304,18 @@ describe(MetadataService.name, () => {
});
});
it('should discard latitude and longitude on null island', async () => {
assetMock.getByIds.mockResolvedValue([assetStub.withLocation]);
metadataMock.readTags.mockResolvedValue({
GPSLatitude: 0,
GPSLongitude: 0,
});
await sut.handleMetadataExtraction({ id: assetStub.image.id });
expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
expect(assetMock.upsertExif).toHaveBeenCalledWith(expect.objectContaining({ latitude: null, longitude: null }));
});
it('should not apply motion photos if asset is video', async () => {
assetMock.getByIds.mockResolvedValue([{ ...assetStub.livePhotoMotionAsset, isVisible: true }]);
mediaMock.probe.mockResolvedValue(probeStub.matroskaContainer);

View File

@ -432,35 +432,40 @@ export class MetadataService {
this.logger.verbose('Exif Tags', tags);
return {
exifData: {
// altitude: tags.GPSAltitude ?? null,
assetId: asset.id,
bitsPerSample: this.getBitsPerSample(tags),
colorspace: tags.ColorSpace ?? null,
dateTimeOriginal: this.getDateTimeOriginal(tags) ?? asset.fileCreatedAt,
exifImageHeight: validate(tags.ImageHeight),
exifImageWidth: validate(tags.ImageWidth),
exposureTime: tags.ExposureTime ?? null,
fileSizeInByte: stats.size,
fNumber: validate(tags.FNumber),
focalLength: validate(tags.FocalLength),
fps: validate(tags.VideoFrameRate),
iso: validate(tags.ISO),
latitude: validate(tags.GPSLatitude),
lensModel: tags.LensModel ?? null,
livePhotoCID: (tags.ContentIdentifier || tags.MediaGroupUUID) ?? null,
longitude: validate(tags.GPSLongitude),
make: tags.Make ?? null,
model: tags.Model ?? null,
modifyDate: exifDate(tags.ModifyDate) ?? asset.fileModifiedAt,
orientation: validate(tags.Orientation)?.toString() ?? null,
profileDescription: tags.ProfileDescription || tags.ProfileName || null,
projectionType: tags.ProjectionType ? String(tags.ProjectionType).toUpperCase() : null,
timeZone: tags.tz ?? null,
},
tags,
const exifData = {
// altitude: tags.GPSAltitude ?? null,
assetId: asset.id,
bitsPerSample: this.getBitsPerSample(tags),
colorspace: tags.ColorSpace ?? null,
dateTimeOriginal: this.getDateTimeOriginal(tags) ?? asset.fileCreatedAt,
exifImageHeight: validate(tags.ImageHeight),
exifImageWidth: validate(tags.ImageWidth),
exposureTime: tags.ExposureTime ?? null,
fileSizeInByte: stats.size,
fNumber: validate(tags.FNumber),
focalLength: validate(tags.FocalLength),
fps: validate(tags.VideoFrameRate),
iso: validate(tags.ISO),
latitude: validate(tags.GPSLatitude),
lensModel: tags.LensModel ?? null,
livePhotoCID: (tags.ContentIdentifier || tags.MediaGroupUUID) ?? null,
longitude: validate(tags.GPSLongitude),
make: tags.Make ?? null,
model: tags.Model ?? null,
modifyDate: exifDate(tags.ModifyDate) ?? asset.fileModifiedAt,
orientation: validate(tags.Orientation)?.toString() ?? null,
profileDescription: tags.ProfileDescription || tags.ProfileName || null,
projectionType: tags.ProjectionType ? String(tags.ProjectionType).toUpperCase() : null,
timeZone: tags.tz ?? null,
};
if (exifData.latitude === 0 && exifData.longitude === 0) {
console.warn('Exif data has latitude and longitude of 0, setting to null');
exifData.latitude = null;
exifData.longitude = null;
}
return { exifData, tags };
}
private getDateTimeOriginal(tags: ImmichTags | Tags | null) {

View File

@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
export class DropNullIslandLatLong1702257380990 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
'UPDATE "exif" SET latitude = NULL, longitude = NULL WHERE latitude = 0 AND longitude = 0;',
);
}
public async down(): Promise<void> {
// There's no way to know which assets used to have 0/0 lat-long if we've
// already run this migration.
}
}