@@ -28,6 +28,7 @@ const storagePresets = [
28
28
'{{y}}/{{MMMM}}-{{dd}}/{{filename}}' ,
29
29
'{{y}}/{{MM}}/{{filename}}' ,
30
30
'{{y}}/{{#if album}}{{album}}{{else}}Other/{{MM}}{{/if}}/{{filename}}' ,
31
+ '{{#if album}}{{album-startDate-y}}/{{album}}{{else}}{{y}}/Other/{{MM}}{{/if}}/{{filename}}' ,
31
32
'{{y}}/{{MMM}}/{{filename}}' ,
32
33
'{{y}}/{{MMMM}}/{{filename}}' ,
33
34
'{{y}}/{{MM}}/{{dd}}/{{filename}}' ,
@@ -54,6 +55,8 @@ interface RenderMetadata {
54
55
filename : string ;
55
56
extension : string ;
56
57
albumName : string | null ;
58
+ albumStartDate : Date | null ;
59
+ albumEndDate : Date | null ;
57
60
}
58
61
59
62
@Injectable ( )
@@ -62,6 +65,7 @@ export class StorageTemplateService extends BaseService {
62
65
compiled : HandlebarsTemplateDelegate < any > ;
63
66
raw : string ;
64
67
needsAlbum : boolean ;
68
+ needsAlbumMetadata : boolean ;
65
69
} | null = null ;
66
70
67
71
private get template ( ) {
@@ -99,6 +103,8 @@ export class StorageTemplateService extends BaseService {
99
103
filename : 'IMG_123' ,
100
104
extension : 'jpg' ,
101
105
albumName : 'album' ,
106
+ albumStartDate : new Date ( ) ,
107
+ albumEndDate : new Date ( ) ,
102
108
} ) ;
103
109
} catch ( error ) {
104
110
this . logger . warn ( `Storage template validation failed: ${ JSON . stringify ( error ) } ` ) ;
@@ -255,16 +261,29 @@ export class StorageTemplateService extends BaseService {
255
261
}
256
262
257
263
let albumName = null ;
264
+ let albumStartDate = null ;
265
+ let albumEndDate = null ;
258
266
if ( this . template . needsAlbum ) {
259
267
const albums = await this . albumRepository . getByAssetId ( asset . ownerId , asset . id ) ;
260
- albumName = albums ?. [ 0 ] ?. albumName || null ;
268
+ const album = albums ?. [ 0 ] ;
269
+ if ( album ) {
270
+ albumName = album . albumName || null ;
271
+
272
+ if ( this . template . needsAlbumMetadata ) {
273
+ const [ metadata ] = await this . albumRepository . getMetadataForIds ( [ album . id ] ) ;
274
+ albumStartDate = metadata ?. startDate || null ;
275
+ albumEndDate = metadata ?. endDate || null ;
276
+ }
277
+ }
261
278
}
262
279
263
280
const storagePath = this . render ( this . template . compiled , {
264
281
asset,
265
282
filename : sanitized ,
266
283
extension,
267
284
albumName,
285
+ albumStartDate,
286
+ albumEndDate,
268
287
} ) ;
269
288
const fullPath = path . normalize ( path . join ( rootPath , storagePath ) ) ;
270
289
let destination = `${ fullPath } .${ extension } ` ;
@@ -323,12 +342,13 @@ export class StorageTemplateService extends BaseService {
323
342
return {
324
343
raw : template ,
325
344
compiled : handlebar . compile ( template , { knownHelpers : undefined , strict : true } ) ,
326
- needsAlbum : template . includes ( '{{album}}' ) ,
345
+ needsAlbum : template . includes ( 'album' ) ,
346
+ needsAlbumMetadata : template . includes ( 'album-startDate' ) || template . includes ( 'album-endDate' ) ,
327
347
} ;
328
348
}
329
349
330
350
private render ( template : HandlebarsTemplateDelegate < any > , options : RenderMetadata ) {
331
- const { filename, extension, asset, albumName } = options ;
351
+ const { filename, extension, asset, albumName, albumStartDate , albumEndDate } = options ;
332
352
const substitutions : Record < string , string > = {
333
353
filename,
334
354
ext : extension ,
@@ -346,6 +366,15 @@ export class StorageTemplateService extends BaseService {
346
366
347
367
for ( const token of Object . values ( storageTokens ) . flat ( ) ) {
348
368
substitutions [ token ] = dt . toFormat ( token ) ;
369
+ if ( albumName ) {
370
+ // Use system time zone for album dates to ensure all assets get the exact same date.
371
+ substitutions [ 'album-startDate-' + token ] = albumStartDate
372
+ ? DateTime . fromJSDate ( albumStartDate , { zone : systemTimeZone } ) . toFormat ( token )
373
+ : '' ;
374
+ substitutions [ 'album-endDate-' + token ] = albumEndDate
375
+ ? DateTime . fromJSDate ( albumEndDate , { zone : systemTimeZone } ) . toFormat ( token )
376
+ : '' ;
377
+ }
349
378
}
350
379
351
380
return template ( substitutions ) . replaceAll ( / \/ { 2 , } / gm, '/' ) ;
0 commit comments