diff --git a/scanner/change_detector.go b/scanner/change_detector.go index 91a28160f..9f215603d 100644 --- a/scanner/change_detector.go +++ b/scanner/change_detector.go @@ -2,7 +2,7 @@ package scanner import ( "os" - "path" + "path/filepath" "strings" "time" @@ -63,7 +63,7 @@ func (s *ChangeDetector) loadDir(dirPath string) (children []string, lastUpdated } for _, f := range files { if f.IsDir() { - children = append(children, path.Join(dirPath, f.Name())) + children = append(children, filepath.Join(dirPath, f.Name())) } else { if f.ModTime().After(lastUpdated) { lastUpdated = f.ModTime() diff --git a/scanner/change_detector_test.go b/scanner/change_detector_test.go index 43415481c..0a5b08ed8 100644 --- a/scanner/change_detector_test.go +++ b/scanner/change_detector_test.go @@ -3,7 +3,7 @@ package scanner import ( "io/ioutil" "os" - "path" + "path/filepath" "time" . "github.com/onsi/ginkgo" @@ -34,25 +34,25 @@ var _ = Describe("ChangeDetector", func() { // Add one subfolder lastModifiedSince = time.Now() - err = os.MkdirAll(path.Join(testFolder, "a"), 0700) + err = os.MkdirAll(filepath.Join(testFolder, "a"), 0700) if err != nil { panic(err) } changed, deleted, err = scanner.Scan(lastModifiedSince) Expect(err).To(BeNil()) Expect(deleted).To(BeEmpty()) - Expect(changed).To(ConsistOf(".", "/a")) + Expect(changed).To(ConsistOf(".", P("/a"))) // Add more subfolders lastModifiedSince = time.Now() - err = os.MkdirAll(path.Join(testFolder, "a", "b", "c"), 0700) + err = os.MkdirAll(filepath.Join(testFolder, "a", "b", "c"), 0700) if err != nil { panic(err) } changed, deleted, err = scanner.Scan(lastModifiedSince) Expect(err).To(BeNil()) Expect(deleted).To(BeEmpty()) - Expect(changed).To(ConsistOf("/a", "/a/b", "/a/b/c")) + Expect(changed).To(ConsistOf(P("/a"), P("/a/b"), P("/a/b/c"))) // Scan with no changes lastModifiedSince = time.Now() @@ -63,36 +63,36 @@ var _ = Describe("ChangeDetector", func() { // New file in subfolder lastModifiedSince = time.Now() - _, err = os.Create(path.Join(testFolder, "a", "b", "empty.txt")) + _, err = os.Create(filepath.Join(testFolder, "a", "b", "empty.txt")) if err != nil { panic(err) } changed, deleted, err = scanner.Scan(lastModifiedSince) Expect(err).To(BeNil()) Expect(deleted).To(BeEmpty()) - Expect(changed).To(ConsistOf("/a/b")) + Expect(changed).To(ConsistOf(P("/a/b"))) // Delete file in subfolder lastModifiedSince = time.Now() - err = os.Remove(path.Join(testFolder, "a", "b", "empty.txt")) + err = os.Remove(filepath.Join(testFolder, "a", "b", "empty.txt")) if err != nil { panic(err) } changed, deleted, err = scanner.Scan(lastModifiedSince) Expect(err).To(BeNil()) Expect(deleted).To(BeEmpty()) - Expect(changed).To(ConsistOf("/a/b")) + Expect(changed).To(ConsistOf(P("/a/b"))) // Delete subfolder lastModifiedSince = time.Now() - err = os.Remove(path.Join(testFolder, "a", "b", "c")) + err = os.Remove(filepath.Join(testFolder, "a", "b", "c")) if err != nil { panic(err) } changed, deleted, err = scanner.Scan(lastModifiedSince) Expect(err).To(BeNil()) - Expect(deleted).To(ConsistOf("/a/b/c")) - Expect(changed).To(ConsistOf("/a/b")) + Expect(deleted).To(ConsistOf(P("/a/b/c"))) + Expect(changed).To(ConsistOf(P("/a/b"))) // Only returns changes after lastModifiedSince lastModifiedSince = time.Now() @@ -103,11 +103,11 @@ var _ = Describe("ChangeDetector", func() { Expect(changed).To(BeEmpty()) Expect(changed).To(BeEmpty()) - f, err := os.Create(path.Join(testFolder, "a", "b", "new.txt")) + f, err := os.Create(filepath.Join(testFolder, "a", "b", "new.txt")) f.Close() changed, deleted, err = newScanner.Scan(lastModifiedSince) Expect(err).To(BeNil()) Expect(deleted).To(BeEmpty()) - Expect(changed).To(ConsistOf("/a/b")) + Expect(changed).To(ConsistOf(P("/a/b"))) }) }) diff --git a/scanner/metadata_ffmpeg.go b/scanner/metadata_ffmpeg.go index 5fe6a1c71..daf79aeca 100644 --- a/scanner/metadata_ffmpeg.go +++ b/scanner/metadata_ffmpeg.go @@ -7,6 +7,7 @@ import ( "os" "os/exec" "path" + "path/filepath" "regexp" "strconv" "strings" @@ -56,7 +57,7 @@ func ExtractAllMetadata(dirPath string) (map[string]*Metadata, error) { if f.IsDir() { continue } - filePath := path.Join(dirPath, f.Name()) + filePath := filepath.Join(dirPath, f.Name()) extension := path.Ext(filePath) if !isAudioFile(extension) { continue @@ -95,7 +96,7 @@ var inputRegex = regexp.MustCompile(`(?m)^Input #\d+,.*,\sfrom\s'(.*)'`) func parseOutput(output string) map[string]string { split := map[string]string{} - all := inputRegex.FindAllStringSubmatchIndex(string(output), -1) + all := inputRegex.FindAllStringSubmatchIndex(output, -1) for i, loc := range all { // Filename is the first captured group file := output[loc[2]:loc[3]] diff --git a/scanner/metadata_test.go b/scanner/metadata_test.go index 555e16c1e..08df27cde 100644 --- a/scanner/metadata_test.go +++ b/scanner/metadata_test.go @@ -6,51 +6,54 @@ import ( ) var _ = Describe("Metadata", func() { - It("correctly parses metadata from all files in folder", func() { - mds, err := ExtractAllMetadata("../tests/fixtures") - Expect(err).NotTo(HaveOccurred()) - Expect(mds).To(HaveLen(3)) + // TODO Need to mock `ffmpeg` + XContext("ExtractAllMetadata", func() { + It("correctly parses metadata from all files in folder", func() { + mds, err := ExtractAllMetadata("tests/fixtures") + Expect(err).NotTo(HaveOccurred()) + Expect(mds).To(HaveLen(3)) - m := mds["../tests/fixtures/test.mp3"] - Expect(m.Title()).To(Equal("Song")) - Expect(m.Album()).To(Equal("Album")) - Expect(m.Artist()).To(Equal("Artist")) - Expect(m.AlbumArtist()).To(Equal("Album Artist")) - Expect(m.Composer()).To(Equal("Composer")) - Expect(m.Compilation()).To(BeTrue()) - Expect(m.Genre()).To(Equal("Rock")) - Expect(m.Year()).To(Equal(2014)) - n, t := m.TrackNumber() - Expect(n).To(Equal(2)) - Expect(t).To(Equal(10)) - n, t = m.DiscNumber() - Expect(n).To(Equal(1)) - Expect(t).To(Equal(2)) - Expect(m.HasPicture()).To(BeTrue()) - Expect(m.Duration()).To(Equal(1)) - Expect(m.BitRate()).To(Equal(476)) - Expect(m.FilePath()).To(Equal("../tests/fixtures/test.mp3")) - Expect(m.Suffix()).To(Equal("mp3")) - Expect(m.Size()).To(Equal(60845)) + m := mds["tests/fixtures/test.mp3"] + Expect(m.Title()).To(Equal("Song")) + Expect(m.Album()).To(Equal("Album")) + Expect(m.Artist()).To(Equal("Artist")) + Expect(m.AlbumArtist()).To(Equal("Album Artist")) + Expect(m.Composer()).To(Equal("Composer")) + Expect(m.Compilation()).To(BeTrue()) + Expect(m.Genre()).To(Equal("Rock")) + Expect(m.Year()).To(Equal(2014)) + n, t := m.TrackNumber() + Expect(n).To(Equal(2)) + Expect(t).To(Equal(10)) + n, t = m.DiscNumber() + Expect(n).To(Equal(1)) + Expect(t).To(Equal(2)) + Expect(m.HasPicture()).To(BeTrue()) + Expect(m.Duration()).To(Equal(1)) + Expect(m.BitRate()).To(Equal(476)) + Expect(m.FilePath()).To(Equal("tests/fixtures/test.mp3")) + Expect(m.Suffix()).To(Equal("mp3")) + Expect(m.Size()).To(Equal(60845)) - m = mds["../tests/fixtures/test.ogg"] - Expect(err).To(BeNil()) - Expect(m.Title()).To(BeEmpty()) - Expect(m.HasPicture()).To(BeFalse()) - Expect(m.Duration()).To(Equal(3)) - Expect(m.BitRate()).To(Equal(9)) - Expect(m.Suffix()).To(Equal("ogg")) - Expect(m.FilePath()).To(Equal("../tests/fixtures/test.ogg")) - Expect(m.Size()).To(Equal(4408)) - }) + m = mds["tests/fixtures/test.ogg"] + Expect(err).To(BeNil()) + Expect(m.Title()).To(BeEmpty()) + Expect(m.HasPicture()).To(BeFalse()) + Expect(m.Duration()).To(Equal(3)) + Expect(m.BitRate()).To(Equal(9)) + Expect(m.Suffix()).To(Equal("ogg")) + Expect(m.FilePath()).To(Equal("tests/fixtures/test.ogg")) + Expect(m.Size()).To(Equal(4408)) + }) - It("returns error if path does not exist", func() { - _, err := ExtractAllMetadata("./INVALID/PATH") - Expect(err).To(HaveOccurred()) - }) + It("returns error if path does not exist", func() { + _, err := ExtractAllMetadata("./INVALID/PATH") + Expect(err).To(HaveOccurred()) + }) - It("returns empty map if there are no audio files in path", func() { - Expect(ExtractAllMetadata(".")).To(BeEmpty()) + It("returns empty map if there are no audio files in path", func() { + Expect(ExtractAllMetadata(".")).To(BeEmpty()) + }) }) Context("extractMetadata", func() { @@ -73,7 +76,7 @@ Input #0, mp3, from '/Users/deluan/Music/iTunes/iTunes Media/Music/Compilations/ Stream #0:1: Video: png, rgb24(pc), 500x478 [SAR 2835:2835 DAR 250:239], 90k tbr, 90k tbn, 90k tbc Metadata: comment : Other` - md, _ := extractMetadata("pablo's blues.mp3", outputWithOverlappingTitleTag) + md, _ := extractMetadata("tests/fixtures/test.mp3", outputWithOverlappingTitleTag) Expect(md.Compilation()).To(BeTrue()) }) @@ -99,7 +102,7 @@ Input #0, mp3, from 'groovin.mp3': title : cover comment : Cover (front) At least one output file must be specified` - md, _ := extractMetadata("groovin.mp3", outputWithOverlappingTitleTag) + md, _ := extractMetadata("tests/fixtures/test.mp3", outputWithOverlappingTitleTag) Expect(md.Title()).To(Equal("Groovin' (feat. Daniel Sneijers, Susanne Alt)")) }) @@ -126,7 +129,7 @@ Input #0, flac, from '/Users/deluan/Downloads/06. Back In Black.flac': Stream #0:0: Audio: flac, 44100 Hz, stereo, s16 Side data: replaygain: track gain - -8.510000, track peak - 0.000023, album gain - unknown, album peak - unknown,` - md, _ := extractMetadata("groovin.mp3", outputWithOverlappingTitleTag) + md, _ := extractMetadata("tests/fixtures/test.mp3", outputWithOverlappingTitleTag) Expect(md.Title()).To(Equal("Back In Black")) Expect(md.Album()).To(Equal("Back In Black")) Expect(md.Genre()).To(Equal("Hard Rock")) @@ -189,7 +192,7 @@ Tracklist: 07. Wunderbar 08. Quarta Dimensão ` - md, _ := extractMetadata("modulo.mp3", outputWithMultilineComment) + md, _ := extractMetadata("tests/fixtures/test.mp3", outputWithMultilineComment) Expect(md.Comment()).To(Equal(expectedComment)) }) }) diff --git a/scanner/scanner_suite_test.go b/scanner/scanner_suite_test.go index 1d0fb6849..af9fa41f8 100644 --- a/scanner/scanner_suite_test.go +++ b/scanner/scanner_suite_test.go @@ -1,16 +1,23 @@ package scanner import ( + "os" + "strings" "testing" "github.com/deluan/navidrome/log" + "github.com/deluan/navidrome/tests" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) -// TODO Fix OS dependencies -func xTestScanner(t *testing.T) { +func TestScanner(t *testing.T) { + tests.Init(t, true) log.SetLevel(log.LevelCritical) RegisterFailHandler(Fail) RunSpecs(t, "Scanner Suite") } + +func P(path string) string { + return strings.ReplaceAll(path, "/", string(os.PathSeparator)) +} diff --git a/scanner/tag_scanner.go b/scanner/tag_scanner.go index 7308f9414..1c2e26863 100644 --- a/scanner/tag_scanner.go +++ b/scanner/tag_scanner.go @@ -5,7 +5,6 @@ import ( "crypto/md5" "fmt" "os" - "path" "path/filepath" "sort" "strings" @@ -49,7 +48,11 @@ func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time) erro return nil } - log.Info("Folder changes found", "changed", len(changed), "deleted", len(deleted)) + if log.CurrentLevel() >= log.LevelTrace { + log.Info(ctx, "Folder changes found", "numChanged", len(changed), "numDeleted", len(deleted), "changed", changed, "deleted", deleted) + } else { + log.Info(ctx, "Folder changes found", "numChanged", len(changed), "numDeleted", len(deleted)) + } sort.Strings(changed) sort.Strings(deleted) @@ -128,7 +131,7 @@ func (s *TagScanner) refreshArtists(ctx context.Context, updatedArtists map[stri } func (s *TagScanner) processChangedDir(ctx context.Context, dir string, updatedArtists map[string]bool, updatedAlbums map[string]bool) error { - dir = path.Join(s.rootFolder, dir) + dir = filepath.Join(s.rootFolder, dir) start := time.Now() @@ -186,7 +189,7 @@ func (s *TagScanner) processChangedDir(ctx context.Context, dir string, updatedA } func (s *TagScanner) processDeletedDir(ctx context.Context, dir string, updatedArtists map[string]bool, updatedAlbums map[string]bool) error { - dir = path.Join(s.rootFolder, dir) + dir = filepath.Join(s.rootFolder, dir) ct, err := s.ds.MediaFile(ctx).FindByPath(dir) if err != nil {