mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
fix(server): refresh unedited asset dimensions on metadata extraction (#27220)
This commit is contained in:
@@ -345,6 +345,7 @@ export const columns = {
|
|||||||
'asset.type',
|
'asset.type',
|
||||||
'asset.width',
|
'asset.width',
|
||||||
'asset.height',
|
'asset.height',
|
||||||
|
'asset.isEdited',
|
||||||
],
|
],
|
||||||
assetFiles: ['asset_file.id', 'asset_file.path', 'asset_file.type', 'asset_file.isEdited'],
|
assetFiles: ['asset_file.id', 'asset_file.path', 'asset_file.type', 'asset_file.isEdited'],
|
||||||
assetFilesForThumbnail: [
|
assetFilesForThumbnail: [
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ select
|
|||||||
"asset"."type",
|
"asset"."type",
|
||||||
"asset"."width",
|
"asset"."width",
|
||||||
"asset"."height",
|
"asset"."height",
|
||||||
|
"asset"."isEdited",
|
||||||
(
|
(
|
||||||
select
|
select
|
||||||
coalesce(json_agg(agg), '[]')
|
coalesce(json_agg(agg), '[]')
|
||||||
|
|||||||
@@ -1641,12 +1641,32 @@ describe(MetadataService.name, () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not overwrite existing width/height if they already exist', async () => {
|
it('should overwrite existing width/height for unedited assets', async () => {
|
||||||
const asset = AssetFactory.create({ width: 1920, height: 1080 });
|
const asset = AssetFactory.create({ width: 1920, height: 1080, isEdited: false });
|
||||||
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(getForMetadataExtraction(asset));
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(getForMetadataExtraction(asset));
|
||||||
mockReadTags({ ImageWidth: 1280, ImageHeight: 720 });
|
mockReadTags({ ImageWidth: 1280, ImageHeight: 720 });
|
||||||
|
|
||||||
await sut.handleMetadataExtraction({ id: asset.id });
|
await sut.handleMetadataExtraction({ id: asset.id });
|
||||||
|
expect(mocks.asset.update).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
width: 1280,
|
||||||
|
height: 720,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not overwrite existing width/height for edited assets', async () => {
|
||||||
|
const asset = AssetFactory.create({ width: 1920, height: 1080, isEdited: true });
|
||||||
|
mocks.assetJob.getForMetadataExtraction.mockResolvedValue(getForMetadataExtraction(asset));
|
||||||
|
mockReadTags({ ImageWidth: 1280, ImageHeight: 720 });
|
||||||
|
|
||||||
|
await sut.handleMetadataExtraction({ id: asset.id });
|
||||||
|
expect(mocks.asset.update).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
width: undefined,
|
||||||
|
height: undefined,
|
||||||
|
}),
|
||||||
|
);
|
||||||
expect(mocks.asset.update).not.toHaveBeenCalledWith(
|
expect(mocks.asset.update).not.toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
width: 1280,
|
width: 1280,
|
||||||
|
|||||||
@@ -327,10 +327,9 @@ export class MetadataService extends BaseService {
|
|||||||
fileCreatedAt: dates.dateTimeOriginal ?? undefined,
|
fileCreatedAt: dates.dateTimeOriginal ?? undefined,
|
||||||
fileModifiedAt: stats.mtime,
|
fileModifiedAt: stats.mtime,
|
||||||
|
|
||||||
// only update the dimensions if they don't already exist
|
// Keep unedited assets in sync with the file on disk, but don't overwrite edited dimensions.
|
||||||
// we don't want to overwrite width/height that are modified by edits
|
width: !asset.isEdited || asset.width == null ? assetWidth : undefined,
|
||||||
width: asset.width == null ? assetWidth : undefined,
|
height: !asset.isEdited || asset.height == null ? assetHeight : undefined,
|
||||||
height: asset.height == null ? assetHeight : undefined,
|
|
||||||
}),
|
}),
|
||||||
async () => {
|
async () => {
|
||||||
await this.assetRepository.upsertExif(exifData, { lockedPropertiesBehavior: 'skip' });
|
await this.assetRepository.upsertExif(exifData, { lockedPropertiesBehavior: 'skip' });
|
||||||
|
|||||||
@@ -138,6 +138,7 @@ export const getForMetadataExtraction = (asset: ReturnType<AssetFactory['build']
|
|||||||
originalPath: asset.originalPath,
|
originalPath: asset.originalPath,
|
||||||
ownerId: asset.ownerId,
|
ownerId: asset.ownerId,
|
||||||
type: asset.type,
|
type: asset.type,
|
||||||
|
isEdited: asset.isEdited,
|
||||||
width: asset.width,
|
width: asset.width,
|
||||||
height: asset.height,
|
height: asset.height,
|
||||||
faces: asset.faces.map((face) => getDehydrated(face)),
|
faces: asset.faces.map((face) => getDehydrated(face)),
|
||||||
|
|||||||
Reference in New Issue
Block a user