mirror of
https://github.com/immich-app/immich.git
synced 2026-02-28 01:29:04 +03:00
@@ -919,7 +919,7 @@ describe(MetadataService.name, () => {
|
||||
Orientation: 0,
|
||||
ProfileDescription: 'extensive description',
|
||||
ProjectionType: 'equirectangular',
|
||||
tz: 'UTC-11:30',
|
||||
zone: 'UTC-11:30',
|
||||
TagsList: ['parent/child'],
|
||||
Rating: 3,
|
||||
};
|
||||
@@ -955,7 +955,7 @@ describe(MetadataService.name, () => {
|
||||
orientation: tags.Orientation?.toString(),
|
||||
profileDescription: tags.ProfileDescription,
|
||||
projectionType: 'EQUIRECTANGULAR',
|
||||
timeZone: tags.tz,
|
||||
timeZone: tags.zone,
|
||||
rating: tags.Rating,
|
||||
country: null,
|
||||
state: null,
|
||||
@@ -987,7 +987,7 @@ describe(MetadataService.name, () => {
|
||||
|
||||
const tags: ImmichTags = {
|
||||
DateTimeOriginal: ExifDateTime.fromISO(someDate + '+00:00'),
|
||||
tz: undefined,
|
||||
zone: undefined,
|
||||
};
|
||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(asset);
|
||||
mockReadTags(tags);
|
||||
|
||||
@@ -527,6 +527,15 @@ export class MetadataService extends BaseService {
|
||||
for (const tag of EXIF_DATE_TAGS) {
|
||||
delete mediaTags[tag];
|
||||
}
|
||||
|
||||
// exiftool-vendored derives tz information from the date.
|
||||
// if the sidecar file has date information, we also assume the tz information come from there.
|
||||
//
|
||||
// this is especially important in the case of UTC+0 where exiftool-vendored does not return tz/zone fields
|
||||
// and as such the tags aren't overwritten when returning all tags.
|
||||
for (const tag of ['zone', 'tz', 'tzSource'] as const) {
|
||||
delete mediaTags[tag];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,8 +906,8 @@ export class MetadataService extends BaseService {
|
||||
}
|
||||
|
||||
// timezone
|
||||
let timeZone = exifTags.tz ?? null;
|
||||
if (timeZone == null && dateTime?.rawValue?.endsWith('+00:00')) {
|
||||
let timeZone = exifTags.zone ?? null;
|
||||
if (timeZone == null && (dateTime?.rawValue?.endsWith('Z') || dateTime?.rawValue?.endsWith('+00:00'))) {
|
||||
// exiftool-vendored returns "no timezone" information even though "+00:00" might be set explicitly
|
||||
// https://github.com/photostructure/exiftool-vendored.js/issues/203
|
||||
timeZone = 'UTC+0';
|
||||
@@ -906,7 +915,7 @@ export class MetadataService extends BaseService {
|
||||
|
||||
if (timeZone) {
|
||||
this.logger.verbose(
|
||||
`Found timezone ${timeZone} via ${exifTags.tzSource} for asset ${asset.id}: ${asset.originalPath}`,
|
||||
`Found timezone ${timeZone} via ${exifTags.zoneSource} for asset ${asset.id}: ${asset.originalPath}`,
|
||||
);
|
||||
} else {
|
||||
this.logger.debug(`No timezone information found for asset ${asset.id}: ${asset.originalPath}`);
|
||||
|
||||
@@ -398,6 +398,23 @@ describe(AssetService.name, () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should update dateTimeOriginal with time zone UTC+0', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
ctx.getMock(JobRepository).queue.mockResolvedValue();
|
||||
const { user } = await ctx.newUser();
|
||||
const auth = factory.auth({ user });
|
||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||
await ctx.newExif({ assetId: asset.id, description: 'test', timeZone: 'UTC-7' });
|
||||
|
||||
await sut.update(auth, asset.id, { dateTimeOriginal: '2023-11-19T18:11:00.000Z' });
|
||||
|
||||
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-19T18:11:00+00:00', timeZone: 'UTC' }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateAll', () => {
|
||||
@@ -456,7 +473,7 @@ describe(AssetService.name, () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should relatively update an assets with timezone', async () => {
|
||||
it('should relatively update assets with timezone', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
const { user } = await ctx.newUser();
|
||||
@@ -477,7 +494,7 @@ describe(AssetService.name, () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should relatively update an assets and set a timezone', async () => {
|
||||
it('should relatively update assets and set a timezone', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
const { user } = await ctx.newUser();
|
||||
@@ -497,6 +514,26 @@ describe(AssetService.name, () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should set asset time zones to UTC', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
const { user } = await ctx.newUser();
|
||||
const auth = factory.auth({ user });
|
||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||
await ctx.newExif({ assetId: asset.id, dateTimeOriginal: '2023-11-19T18:11:00', timeZone: 'UTC-7' });
|
||||
|
||||
await sut.updateAll(auth, { ids: [asset.id], timeZone: 'UTC' });
|
||||
|
||||
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
exifInfo: expect.objectContaining({
|
||||
dateTimeOriginal: '2023-11-19T18:11:00+00:00',
|
||||
timeZone: 'UTC',
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should update dateTimeOriginal', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
@@ -530,6 +567,23 @@ describe(AssetService.name, () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should update dateTimeOriginal with UTC time zone', async () => {
|
||||
const { sut, ctx } = setup();
|
||||
ctx.getMock(JobRepository).queueAll.mockResolvedValue();
|
||||
const { user } = await ctx.newUser();
|
||||
const auth = factory.auth({ user });
|
||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||
await ctx.newExif({ assetId: asset.id, description: 'test', timeZone: 'UTC-7' });
|
||||
|
||||
await sut.updateAll(auth, { ids: [asset.id], dateTimeOriginal: '2023-11-19T18:11:00.000Z' });
|
||||
|
||||
await expect(ctx.get(AssetRepository).getById(asset.id, { exifInfo: true })).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
exifInfo: expect.objectContaining({ dateTimeOriginal: '2023-11-19T18:11:00+00:00', timeZone: 'UTC' }),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('upsertBulkMetadata', () => {
|
||||
|
||||
Reference in New Issue
Block a user