Prechádzať zdrojové kódy

feat: function to scan a directory recursively for ogg files

Fela Maslen 5 rokov pred
rodič
commit
c73cdbbb65

+ 52 - 14
music-player/pkg/read/read_files.go

@@ -3,6 +3,8 @@ package read
 import (
   "os"
   "fmt"
+  "io/ioutil"
+  "path/filepath"
 
   tag "github.com/dhowden/tag"
 
@@ -36,29 +38,65 @@ func ReadFile(fileName string) (song *Song, err error) {
   return &result, nil
 }
 
-func ReadMultipleFiles(files chan string, doneChan chan bool) (chan *Song, chan bool) {
+func ReadMultipleFiles(files chan string) chan *Song {
   songs := make(chan *Song)
-  processed := make(chan bool)
-
-  done := false
 
   go func() {
-    for !done {
+    defer close(songs)
+
+    for {
       select {
-      case file := <- files:
-        song, err := ReadFile(file)
-        if err == nil {
-          songs <- song
+      case file, more := <- files:
+        if more {
+          song, err := ReadFile(file)
+          if err == nil {
+            songs <- song
+          } else {
+            fmt.Printf("Error reading file (%s): %s\n", file, err)
+          }
         } else {
-          fmt.Printf("Error reading file (%s): %s", file, err)
+          return
         }
-      case <- doneChan:
-        done = true
       }
     }
+  }()
+
+  return songs
+}
+
+func isValidFile(file string) bool {
+  // TODO: support FLAC/MP3
+  return filepath.Ext(file) == ".ogg"
+}
+
+func recursiveDirScan(directory string, output chan string, root bool) {
+  files, err := ioutil.ReadDir(directory)
+  if err != nil {
+    fmt.Printf("Error scanning directory (%s): %s", directory, err)
+    return
+  }
 
-    processed <- true
+  for _, file := range(files) {
+    relativePath := filepath.Join(directory, file.Name())
+
+    if file.IsDir() {
+      recursiveDirScan(relativePath, output, false)
+    } else if isValidFile(file.Name()) {
+      output <- relativePath
+    }
+  }
+
+  if (root) {
+    close(output)
+  }
+}
+
+func ScanDirectory(directory string) chan string {
+  files := make(chan string)
+  
+  go func() {
+    recursiveDirScan(directory, files, true)
   }()
 
-  return songs, processed
+  return files
 }

+ 27 - 7
music-player/pkg/read/read_files_test.go

@@ -25,14 +25,13 @@ func TestReadFile(t *testing.T) {
 
 func TestReadMultipleFiles(t *testing.T) {
   files := make(chan string, 1)
-  done := make(chan bool)
 
   go func() {
     files <- testFile
-    done <- true
+    close(files)
   }()
 
-  outputChan, doneChan := ReadMultipleFiles(files, done)
+  outputChan := ReadMultipleFiles(files)
 
   var results []*Song
 
@@ -40,10 +39,11 @@ func TestReadMultipleFiles(t *testing.T) {
 
   for !outputDone {
     select {
-    case result := <- outputChan:
-      results = append(results, result)
-    case <- doneChan:
-      outputDone = true
+    case result, more := <- outputChan:
+      if more {
+        results = append(results, result)
+      }
+      outputDone = !more
     }
   }
 
@@ -56,3 +56,23 @@ func TestReadMultipleFiles(t *testing.T) {
     length: testLengthSeconds,
   })
 }
+
+func TestScanDirectory(t *testing.T) {
+  files := ScanDirectory(".")
+
+  var results []string
+
+  done := false
+
+  for !done {
+    select {
+    case result, more := <- files:
+      if more {
+        results = append(results, result)
+      }
+      done = !more
+    }
+  }
+
+  assert.Equal(t, results, []string{testFile})
+}