From 40841ab9177616a0af22022515832adea272f543 Mon Sep 17 00:00:00 2001 From: certuna <62144283+certuna@users.noreply.github.com> Date: Sat, 11 Nov 2023 23:13:07 +0100 Subject: [PATCH] Small date mapping fix (#2584) * Update mapping.go fallback in the case there's no Date tagged but Original Date or Release Date are tagged * Add tests --------- Co-authored-by: Deluan --- scanner/mapping.go | 8 ++ scanner/mapping_internal_test.go | 188 ++++++++++++++++++++++--------- 2 files changed, 145 insertions(+), 51 deletions(-) diff --git a/scanner/mapping.go b/scanner/mapping.go index 610420af466..734fd2e5e03 100644 --- a/scanner/mapping.go +++ b/scanner/mapping.go @@ -186,5 +186,13 @@ func (s mediaFileMapper) mapDates(md metadata.Tags) (int, string, int, string, i if taggedLikePicard { return originalYear, originalDate, originalYear, originalDate, year, date } + // when there's no Date, first fall back to Original Date, then to Release Date. + if year == 0 { + if originalYear > 0 { + year, date = originalYear, originalDate + } else { + year, date = releaseYear, releaseDate + } + } return year, date, originalYear, originalDate, releaseYear, releaseDate } diff --git a/scanner/mapping_internal_test.go b/scanner/mapping_internal_test.go index 35c975c5b37..4687efeab6b 100644 --- a/scanner/mapping_internal_test.go +++ b/scanner/mapping_internal_test.go @@ -14,10 +14,10 @@ import ( var _ = Describe("mapping", func() { Describe("mediaFileMapper", func() { var mapper *mediaFileMapper - BeforeEach(func() { - mapper = newMediaFileMapper("/music", nil) - }) Describe("mapTrackTitle", func() { + BeforeEach(func() { + mapper = newMediaFileMapper("/music", nil) + }) It("returns the Title when it is available", func() { md := metadata.NewTag("/music/artist/album01/Song.mp3", nil, metadata.ParsedTags{"title": []string{"This is not a love song"}}) Expect(mapper.mapTrackTitle(md)).To(Equal("This is not a love song")) @@ -27,7 +27,141 @@ var _ = Describe("mapping", func() { Expect(mapper.mapTrackTitle(md)).To(Equal("artist/album01/Song")) }) }) + + Describe("mapGenres", func() { + var gr model.GenreRepository + var ctx context.Context + + BeforeEach(func() { + ctx = context.Background() + ds := &tests.MockDataStore{} + gr = ds.Genre(ctx) + gr = newCachedGenreRepository(ctx, gr) + mapper = newMediaFileMapper("/", gr) + }) + + It("returns empty if no genres are available", func() { + g, gs := mapper.mapGenres(nil) + Expect(g).To(BeEmpty()) + Expect(gs).To(BeEmpty()) + }) + + It("returns genres", func() { + g, gs := mapper.mapGenres([]string{"Rock", "Electronic"}) + Expect(g).To(Equal("Rock")) + Expect(gs).To(HaveLen(2)) + Expect(gs[0].Name).To(Equal("Rock")) + Expect(gs[1].Name).To(Equal("Electronic")) + }) + + It("parses multi-valued genres", func() { + g, gs := mapper.mapGenres([]string{"Rock;Dance", "Electronic", "Rock"}) + Expect(g).To(Equal("Rock")) + Expect(gs).To(HaveLen(3)) + Expect(gs[0].Name).To(Equal("Rock")) + Expect(gs[1].Name).To(Equal("Dance")) + Expect(gs[2].Name).To(Equal("Electronic")) + }) + It("trims genres names", func() { + _, gs := mapper.mapGenres([]string{"Rock ; Dance", " Electronic "}) + Expect(gs).To(HaveLen(3)) + Expect(gs[0].Name).To(Equal("Rock")) + Expect(gs[1].Name).To(Equal("Dance")) + Expect(gs[2].Name).To(Equal("Electronic")) + }) + It("does not break on spaces", func() { + _, gs := mapper.mapGenres([]string{"New Wave"}) + Expect(gs).To(HaveLen(1)) + Expect(gs[0].Name).To(Equal("New Wave")) + }) + }) + + Describe("mapDates", func() { + var md metadata.Tags + BeforeEach(func() { + mapper = newMediaFileMapper("/", nil) + }) + Context("when all date fields are provided", func() { + BeforeEach(func() { + md = metadata.NewTag("/music/artist/album01/Song.mp3", nil, metadata.ParsedTags{ + "date": []string{"2023-03-01"}, + "originaldate": []string{"2022-05-10"}, + "releasedate": []string{"2023-01-15"}, + }) + }) + + It("should map all date fields correctly", func() { + year, date, originalYear, originalDate, releaseYear, releaseDate := mapper.mapDates(md) + Expect(year).To(Equal(2023)) + Expect(date).To(Equal("2023-03-01")) + Expect(originalYear).To(Equal(2022)) + Expect(originalDate).To(Equal("2022-05-10")) + Expect(releaseYear).To(Equal(2023)) + Expect(releaseDate).To(Equal("2023-01-15")) + }) + }) + + Context("when date field is missing", func() { + BeforeEach(func() { + md = metadata.NewTag("/music/artist/album01/Song.mp3", nil, metadata.ParsedTags{ + "originaldate": []string{"2022-05-10"}, + "releasedate": []string{"2023-01-15"}, + }) + }) + + It("should fallback to original date if date is missing", func() { + year, date, _, _, _, _ := mapper.mapDates(md) + Expect(year).To(Equal(2022)) + Expect(date).To(Equal("2022-05-10")) + }) + }) + + Context("when original and release dates are missing", func() { + BeforeEach(func() { + md = metadata.NewTag("/music/artist/album01/Song.mp3", nil, metadata.ParsedTags{ + "date": []string{"2023-03-01"}, + }) + }) + + It("should only map the date field", func() { + year, date, originalYear, originalDate, releaseYear, releaseDate := mapper.mapDates(md) + Expect(year).To(Equal(2023)) + Expect(date).To(Equal("2023-03-01")) + Expect(originalYear).To(BeZero()) + Expect(originalDate).To(BeEmpty()) + Expect(releaseYear).To(BeZero()) + Expect(releaseDate).To(BeEmpty()) + }) + }) + + Context("when date fields are in an incorrect format", func() { + BeforeEach(func() { + md = metadata.NewTag("/music/artist/album01/Song.mp3", nil, metadata.ParsedTags{ + "date": []string{"invalid-date"}, + }) + }) + + It("should handle invalid date formats gracefully", func() { + year, date, _, _, _, _ := mapper.mapDates(md) + Expect(year).To(BeZero()) + Expect(date).To(BeEmpty()) + }) + }) + + Context("when all date fields are missing", func() { + It("should return zero values for all date fields", func() { + year, date, originalYear, originalDate, releaseYear, releaseDate := mapper.mapDates(md) + Expect(year).To(BeZero()) + Expect(date).To(BeEmpty()) + Expect(originalYear).To(BeZero()) + Expect(originalDate).To(BeEmpty()) + Expect(releaseYear).To(BeZero()) + Expect(releaseDate).To(BeEmpty()) + }) + }) + }) }) + Describe("sanitizeFieldForSorting", func() { BeforeEach(func() { conf.Server.IgnoredArticles = "The O" @@ -42,52 +176,4 @@ var _ = Describe("mapping", func() { Expect(sanitizeFieldForSorting("Õ Blésq Blom")).To(Equal("Blesq Blom")) }) }) - - Describe("mapGenres", func() { - var mapper *mediaFileMapper - var gr model.GenreRepository - var ctx context.Context - BeforeEach(func() { - ctx = context.Background() - ds := &tests.MockDataStore{} - gr = ds.Genre(ctx) - gr = newCachedGenreRepository(ctx, gr) - mapper = newMediaFileMapper("/", gr) - }) - - It("returns empty if no genres are available", func() { - g, gs := mapper.mapGenres(nil) - Expect(g).To(BeEmpty()) - Expect(gs).To(BeEmpty()) - }) - - It("returns genres", func() { - g, gs := mapper.mapGenres([]string{"Rock", "Electronic"}) - Expect(g).To(Equal("Rock")) - Expect(gs).To(HaveLen(2)) - Expect(gs[0].Name).To(Equal("Rock")) - Expect(gs[1].Name).To(Equal("Electronic")) - }) - - It("parses multi-valued genres", func() { - g, gs := mapper.mapGenres([]string{"Rock;Dance", "Electronic", "Rock"}) - Expect(g).To(Equal("Rock")) - Expect(gs).To(HaveLen(3)) - Expect(gs[0].Name).To(Equal("Rock")) - Expect(gs[1].Name).To(Equal("Dance")) - Expect(gs[2].Name).To(Equal("Electronic")) - }) - It("trims genres names", func() { - _, gs := mapper.mapGenres([]string{"Rock ; Dance", " Electronic "}) - Expect(gs).To(HaveLen(3)) - Expect(gs[0].Name).To(Equal("Rock")) - Expect(gs[1].Name).To(Equal("Dance")) - Expect(gs[2].Name).To(Equal("Electronic")) - }) - It("does not break on spaces", func() { - _, gs := mapper.mapGenres([]string{"New Wave"}) - Expect(gs).To(HaveLen(1)) - Expect(gs[0].Name).To(Equal("New Wave")) - }) - }) })