From ef2f231d5b2debbc4325bc2ac048021995dbc857 Mon Sep 17 00:00:00 2001 From: Michael Mayer Date: Mon, 25 Jan 2021 21:41:57 +0100 Subject: [PATCH] Indexer: Improve taken date fallback when other metadata is missing #930 --- internal/entity/photo.go | 22 ++++++++++++++++++++-- internal/entity/photo_test.go | 19 +++++++++++++++++++ internal/photoprism/index_mediafile.go | 11 ++++++----- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/internal/entity/photo.go b/internal/entity/photo.go index 1c1d27e2f..129e9a1c9 100644 --- a/internal/entity/photo.go +++ b/internal/entity/photo.go @@ -857,19 +857,34 @@ func (m *Photo) SetTakenAt(taken, local time.Time, zone, source string) { return } - m.TakenAt = taken.Round(time.Second).UTC() + // Round times to avoid jitter. + taken = taken.Round(time.Second).UTC() + local = local.Round(time.Second) + + // Don't update older date. + if SrcPriority[source] <= SrcPriority[SrcName] && !m.TakenAt.IsZero() && taken.After(m.TakenAt) { + return + } + + m.TakenAt = taken m.TakenSrc = source if local.IsZero() || local.Year() < 1000 { m.TakenAtLocal = m.TakenAt } else { - m.TakenAtLocal = local.Round(time.Second) + m.TakenAtLocal = local } + // Set time zone. if zone != "" { m.TimeZone = zone } + // Apply time zone. + if m.TimeZone != "" { + m.TakenAt = m.GetTakenAt() + } + m.UpdateDateFields() } @@ -883,7 +898,10 @@ func (m *Photo) SetTimeZone(zone, source string) { return } + // Set time zone. m.TimeZone = zone + + // Apply time zone. m.TakenAt = m.GetTakenAt() } diff --git a/internal/entity/photo_test.go b/internal/entity/photo_test.go index 6233e09ad..222822732 100644 --- a/internal/entity/photo_test.go +++ b/internal/entity/photo_test.go @@ -557,11 +557,30 @@ func TestPhoto_SetTakenAt(t *testing.T) { m := PhotoFixtures.Get("Photo15") assert.Equal(t, time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), m.TakenAt) assert.Equal(t, time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), m.TakenAtLocal) + m.SetTakenAt(time.Date(2019, 12, 11, 9, 7, 18, 0, time.UTC), time.Date(2019, 12, 11, 10, 7, 18, 0, time.UTC), "", SrcMeta) + assert.Equal(t, time.Date(2019, 12, 11, 9, 7, 18, 0, time.UTC), m.TakenAt) assert.Equal(t, time.Date(2019, 12, 11, 10, 7, 18, 0, time.UTC), m.TakenAtLocal) }) + t.Run("fallback and time zone", func(t *testing.T) { + m := PhotoFixtures.Get("Photo15") + assert.Equal(t, time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), m.TakenAt) + assert.Equal(t, time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), m.TakenAtLocal) + + m.SetTakenAt(time.Date(2019, 12, 11, 9, 7, 18, 0, time.UTC), + time.Date(2019, 12, 11, 10, 7, 18, 0, time.UTC), "", SrcName) + + assert.Equal(t, time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), m.TakenAt) + assert.Equal(t, time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), m.TakenAtLocal) + + m.SetTakenAt(time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), + time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), "Europe/Berlin", SrcName) + + assert.Equal(t, time.Date(2013, 11, 11, 8, 7, 18, 0, time.UTC), m.TakenAt) + assert.Equal(t, time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), m.TakenAtLocal) + }) t.Run("time > max year", func(t *testing.T) { m := PhotoFixtures.Get("Photo15") assert.Equal(t, time.Date(2013, 11, 11, 9, 7, 18, 0, time.UTC), m.TakenAt) diff --git a/internal/photoprism/index_mediafile.go b/internal/photoprism/index_mediafile.go index 3d2dcd556..3d741e20b 100644 --- a/internal/photoprism/index_mediafile.go +++ b/internal/photoprism/index_mediafile.go @@ -521,6 +521,12 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) ( } } + // Try to set taken date based on file mod time or name if other metadata is missing: + if m.IsMedia() && (photo.TakenSrc == entity.SrcAuto || photo.TakenSrc == entity.SrcName) { + takenUtc, takenSrc := m.TakenAt() + photo.SetTakenAt(takenUtc, takenUtc, "", takenSrc) + } + // file obviously exists: remove deleted and missing flags file.DeletedAt = nil file.FileMissing = false @@ -588,11 +594,6 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) ( photo.PhotoExposure = m.Exposure() } - if photo.TakenSrc == entity.SrcAuto || photo.TakenSrc == entity.SrcName { - takenUtc, takenSrc := m.TakenAt() - photo.SetTakenAt(takenUtc, takenUtc, "", takenSrc) - } - var locLabels classify.Labels locKeywords, locLabels = photo.UpdateLocation()