From d9993c5877a013d1aea35d00bea0d7f6d3fe33ea Mon Sep 17 00:00:00 2001
From: Deluan <deluan@deluan.com>
Date: Thu, 13 Feb 2020 10:03:52 -0500
Subject: [PATCH] refactor: separate metadata extraction from audio files
 scanning

---
 scanner/metadata_ffmpeg.go | 18 ++++++++++--------
 scanner/metadata_test.go   | 15 +++++++++++----
 scanner/tag_scanner.go     | 13 ++++++++++++-
 3 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/scanner/metadata_ffmpeg.go b/scanner/metadata_ffmpeg.go
index 87217e2a4..effa7fee4 100644
--- a/scanner/metadata_ffmpeg.go
+++ b/scanner/metadata_ffmpeg.go
@@ -43,7 +43,7 @@ func (m *Metadata) FilePath() string            { return m.filePath }
 func (m *Metadata) Suffix() string              { return m.suffix }
 func (m *Metadata) Size() int                   { return int(m.fileInfo.Size()) }
 
-func ExtractAllMetadata(dirPath string) (map[string]*Metadata, error) {
+func LoadAllAudioFiles(dirPath string) ([]os.FileInfo, error) {
 	dir, err := os.Open(dirPath)
 	if err != nil {
 		return nil, err
@@ -52,7 +52,7 @@ func ExtractAllMetadata(dirPath string) (map[string]*Metadata, error) {
 	if err != nil {
 		return nil, err
 	}
-	var audioFiles []string
+	var audioFiles []os.FileInfo
 	for _, f := range files {
 		if f.IsDir() {
 			continue
@@ -62,16 +62,18 @@ func ExtractAllMetadata(dirPath string) (map[string]*Metadata, error) {
 		if !isAudioFile(extension) {
 			continue
 		}
-		audioFiles = append(audioFiles, filePath)
+		fi, err := os.Stat(filePath)
+		if err != nil {
+			log.Error("Could not stat file", "filePath", filePath, err)
+		} else {
+			audioFiles = append(audioFiles, fi)
+		}
 	}
 
-	if len(audioFiles) == 0 {
-		return map[string]*Metadata{}, nil
-	}
-	return probe(audioFiles)
+	return audioFiles, nil
 }
 
-func probe(inputs []string) (map[string]*Metadata, error) {
+func ExtractAllMetadata(inputs []string) (map[string]*Metadata, error) {
 	cmdLine, args := createProbeCommand(inputs)
 
 	log.Trace("Executing command", "arg0", cmdLine, "args", args)
diff --git a/scanner/metadata_test.go b/scanner/metadata_test.go
index a373e6d85..6fbcce5aa 100644
--- a/scanner/metadata_test.go
+++ b/scanner/metadata_test.go
@@ -9,9 +9,9 @@ var _ = Describe("Metadata", func() {
 	// TODO Need to mock `ffmpeg`
 	XContext("ExtractAllMetadata", func() {
 		It("correctly parses metadata from all files in folder", func() {
-			mds, err := ExtractAllMetadata("tests/fixtures")
+			mds, err := ExtractAllMetadata([]string{"tests/fixtures/test.mp3", "tests/fixtures/test.ogg"})
 			Expect(err).NotTo(HaveOccurred())
-			Expect(mds).To(HaveLen(3))
+			Expect(mds).To(HaveLen(2))
 
 			m := mds["tests/fixtures/test.mp3"]
 			Expect(m.Title()).To(Equal("Song"))
@@ -45,14 +45,21 @@ var _ = Describe("Metadata", func() {
 			Expect(m.FilePath()).To(Equal("tests/fixtures/test.ogg"))
 			Expect(m.Size()).To(Equal(4408))
 		})
+	})
 
+	Context("LoadAllAudioFiles", func() {
+		It("return all audiofiles from the folder", func() {
+			files, err := LoadAllAudioFiles("tests/fixtures")
+			Expect(err).ToNot(HaveOccurred())
+			Expect(files).To(HaveLen(3))
+		})
 		It("returns error if path does not exist", func() {
-			_, err := ExtractAllMetadata("./INVALID/PATH")
+			_, err := LoadAllAudioFiles("./INVALID/PATH")
 			Expect(err).To(HaveOccurred())
 		})
 
 		It("returns empty map if there are no audio files in path", func() {
-			Expect(ExtractAllMetadata(".")).To(BeEmpty())
+			Expect(LoadAllAudioFiles(".")).To(BeEmpty())
 		})
 	})
 
diff --git a/scanner/tag_scanner.go b/scanner/tag_scanner.go
index be7e34350..afbda25fd 100644
--- a/scanner/tag_scanner.go
+++ b/scanner/tag_scanner.go
@@ -207,10 +207,21 @@ func (s *TagScanner) processDeletedDir(ctx context.Context, dir string, updatedA
 }
 
 func (s *TagScanner) loadTracks(dirPath string) (model.MediaFiles, error) {
-	mds, err := ExtractAllMetadata(dirPath)
+	audioFiles, err := LoadAllAudioFiles(dirPath)
 	if err != nil {
 		return nil, err
 	}
+
+	filePaths := make([]string, len(audioFiles))
+	for i, _ := range audioFiles {
+		filePaths[i] = filepath.Join(dirPath, audioFiles[i].Name())
+	}
+
+	mds, err := ExtractAllMetadata(filePaths)
+	if err != nil {
+		return nil, err
+	}
+
 	var mfs model.MediaFiles
 	for _, md := range mds {
 		mf := s.toMediaFile(md)