@@ -17,6 +17,7 @@ import (
17
17
"sync/atomic"
18
18
"time"
19
19
20
+ "github.com/djherbis/times"
20
21
"github.com/fsnotify/fsnotify"
21
22
"github.com/jinzhu/gorm"
22
23
"github.com/rainycape/unidecode"
@@ -314,17 +315,18 @@ func (s *Scanner) scanDir(tx *db.DB, st *State, absPath string) error {
314
315
}
315
316
316
317
func (s * Scanner ) populateTrackAndArtists (tx * db.DB , st * State , i int , album * db.Album , basename string , absPath string ) error {
317
- stat , err := os .Stat (absPath )
318
+ // useful to get the real create/birth time for filesystems and kernels which support it
319
+ timeSpec , err := times .Stat (absPath )
318
320
if err != nil {
319
- return fmt .Errorf ("stating %q: %w" , basename , err )
321
+ return fmt .Errorf ("get times %q: %w" , basename , err )
320
322
}
321
323
322
324
var track db.Track
323
325
if err := tx .Where ("album_id=? AND filename=?" , album .ID , filepath .Base (basename )).First (& track ).Error ; err != nil && ! errors .Is (err , gorm .ErrRecordNotFound ) {
324
326
return fmt .Errorf ("query track: %w" , err )
325
327
}
326
328
327
- if ! st .isFull && track .ID != 0 && stat .ModTime ().Before (track .UpdatedAt ) {
329
+ if ! st .isFull && track .ID != 0 && timeSpec .ModTime ().Before (track .UpdatedAt ) {
328
330
st .seenTracks [track .ID ] = struct {}{}
329
331
return nil
330
332
}
@@ -363,7 +365,7 @@ func (s *Scanner) populateTrackAndArtists(tx *db.DB, st *State, i int, album *db
363
365
return fmt .Errorf ("populate track artists: %w" , err )
364
366
}
365
367
366
- if err := populateAlbum (tx , album , trags , stat . ModTime ()); err != nil {
368
+ if err := populateAlbum (tx , album , trags , timeSpec . ChangeTime (), timeSpec . BirthTime ()); err != nil {
367
369
return fmt .Errorf ("populate album: %w" , err )
368
370
}
369
371
@@ -372,6 +374,10 @@ func (s *Scanner) populateTrackAndArtists(tx *db.DB, st *State, i int, album *db
372
374
}
373
375
}
374
376
377
+ stat , err := os .Stat (absPath )
378
+ if err != nil {
379
+ return fmt .Errorf ("stating %q: %w" , basename , err )
380
+ }
375
381
if err := populateTrack (tx , album , & track , trags , basename , int (stat .Size ())); err != nil {
376
382
return fmt .Errorf ("process %q: %w" , basename , err )
377
383
}
@@ -402,17 +408,17 @@ func (s *Scanner) populateTrackAndArtists(tx *db.DB, st *State, i int, album *db
402
408
return nil
403
409
}
404
410
405
- func populateAlbum (tx * db.DB , album * db.Album , trags tagcommon.Info , modTime time.Time ) error {
411
+ func populateAlbum (tx * db.DB , album * db.Album , trags tagcommon.Info , modifiedAt , createdAt time.Time ) error {
406
412
albumName := tagcommon .MustAlbum (trags )
407
413
album .TagTitle = albumName
408
414
album .TagTitleUDec = decoded (albumName )
409
415
album .TagAlbumArtist = tagcommon .MustAlbumArtist (trags )
410
416
album .TagBrainzID = trags .AlbumBrainzID ()
411
417
album .TagYear = trags .Year ()
412
418
413
- album .ModifiedAt = modTime
414
- if album .CreatedAt .After (modTime ) {
415
- album .CreatedAt = modTime // reset created at to match filesytem for new albums
419
+ album .ModifiedAt = modifiedAt
420
+ if album .CreatedAt .After (createdAt ) {
421
+ album .CreatedAt = createdAt // reset created at to match filesytem for new albums
416
422
}
417
423
418
424
if err := tx .Save (& album ).Error ; err != nil {
0 commit comments