add support for make, model, lensModel in storage template

pull/24650/head
Rahul Saini 2025-12-17 14:50:15 -05:00
parent de1b448639
commit 6c4281acef
No known key found for this signature in database
GPG Key ID: 67A6A0809B6420DF
8 changed files with 17608 additions and 4 deletions

17564
server/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -324,6 +324,9 @@ export class AssetJobRepository {
'asset.fileCreatedAt',
'asset_exif.timeZone',
'asset_exif.fileSizeInByte',
'asset_exif.make',
'asset_exif.model',
'asset_exif.lensModel',
])
.select((eb) => withFiles(eb, AssetFileType.Sidecar))
.where('asset.deletedAt', 'is', null);

View File

@ -84,6 +84,7 @@ describe(StorageTemplateService.name, () => {
'{{y}}/{{y}}-{{MM}}/{{assetId}}',
'{{y}}/{{y}}-{{WW}}/{{assetId}}',
'{{album}}/{{filename}}',
'{{make}}/{{model}}/{{lensModel}}/{{filename}}',
],
secondOptions: ['s', 'ss', 'SSS'],
weekOptions: ['W', 'WW'],

View File

@ -53,6 +53,7 @@ const storagePresets = [
'{{y}}/{{y}}-{{MM}}/{{assetId}}',
'{{y}}/{{y}}-{{WW}}/{{assetId}}',
'{{album}}/{{filename}}',
'{{make}}/{{model}}/{{lensModel}}/{{filename}}',
];
export interface MoveAssetMetadata {
@ -67,6 +68,9 @@ interface RenderMetadata {
albumName: string | null;
albumStartDate: Date | null;
albumEndDate: Date | null;
make: string | null;
model: string | null;
lensModel: string | null;
}
@Injectable()
@ -115,6 +119,9 @@ export class StorageTemplateService extends BaseService {
albumName: 'album',
albumStartDate: new Date(),
albumEndDate: new Date(),
make: 'FUJIFILM',
model: 'X-T50',
lensModel: 'XF27mm F2.8 R WR',
});
} catch (error) {
this.logger.warn(`Storage template validation failed: ${JSON.stringify(error)}`);
@ -301,6 +308,9 @@ export class StorageTemplateService extends BaseService {
albumName,
albumStartDate,
albumEndDate,
make: asset.make,
model: asset.model,
lensModel: asset.lensModel,
});
const fullPath = path.normalize(path.join(rootPath, storagePath));
let destination = `${fullPath}.${extension}`;
@ -365,7 +375,7 @@ export class StorageTemplateService extends BaseService {
}
private render(template: HandlebarsTemplateDelegate<any>, options: RenderMetadata) {
const { filename, extension, asset, albumName, albumStartDate, albumEndDate } = options;
const { filename, extension, asset, albumName, albumStartDate, albumEndDate, make, model, lensModel } = options;
const substitutions: Record<string, string> = {
filename,
ext: extension,
@ -375,6 +385,9 @@ export class StorageTemplateService extends BaseService {
assetIdShort: asset.id.slice(-12),
//just throw into the root if it doesn't belong to an album
album: (albumName && sanitize(albumName.replaceAll(/\.+/g, ''))) || '',
make: make || '',
model: model || '',
lensModel: lensModel || '',
};
const systemTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;

View File

@ -472,6 +472,9 @@ export type StorageAsset = {
originalFileName: string;
fileSizeInByte: number | null;
files: AssetFile[];
make: string | null;
model: string | null;
lensModel: string | null;
};
export type OnThisDayData = { year: number };

View File

@ -65,6 +65,9 @@ export const assetStub = {
originalFileName: 'IMG_123.jpg',
fileSizeInByte: 12_345,
files: [],
make: 'FUJIFILM',
model: 'X-T50',
lensModel: 'XF27mm F2.8 R WR',
...asset,
}),
noResizePath: Object.freeze({

View File

@ -60,6 +60,9 @@
assetId: 'a8312960-e277-447d-b4ea-56717ccba856',
assetIdShort: '56717ccba856',
album: $t('album_name'),
make: 'FUJIFILM',
model: 'X-T50',
lensModel: 'XF27mm F2.8 R WR',
};
const dt = luxon.DateTime.fromISO(new Date('2022-02-03T04:56:05.250').toISOString());

View File

@ -24,10 +24,8 @@
</ul>
</div>
<div>
<p class="uppercase font-medium text-primary">{$t('other')}</p>
<p class="uppercase font-medium text-primary">{$t('album')}</p>
<ul>
<li>{`{{assetId}}`} - Asset ID</li>
<li>{`{{assetIdShort}}`} - Asset ID (last 12 characters)</li>
<li>{`{{album}}`} - Album Name</li>
<li>
{`{{album-startDate-x}}`} - Album Start Date and Time (e.g. album-startDate-yy).
@ -39,5 +37,21 @@
</li>
</ul>
</div>
<div>
<p class="uppercase font-medium text-primary">{$t('camera')}</p>
<ul>
<li>{`{{make}}`} - FUJIFILM</li>
<li>{`{{model}}`} - X-T50</li>
<li>{`{{lensModel}}`} - XF27mm F2.8 R WR</li>
</ul>
</div>
<div>
<p class="uppercase font-medium text-primary">{$t('other')}</p>
<ul>
<li>{`{{assetId}}`} - Asset ID</li>
<li>{`{{assetIdShort}}`} - Asset ID (last 12 characters)</li>
</ul>
</div>
</div>
</div>