|
@@ -5,10 +5,12 @@ import (
|
|
|
"path/filepath"
|
|
"path/filepath"
|
|
|
|
|
|
|
|
config "github.com/felamaslen/go-music-player/pkg/config"
|
|
config "github.com/felamaslen/go-music-player/pkg/config"
|
|
|
|
|
+ "github.com/felamaslen/go-music-player/pkg/database"
|
|
|
"github.com/felamaslen/go-music-player/pkg/logger"
|
|
"github.com/felamaslen/go-music-player/pkg/logger"
|
|
|
|
|
+ "github.com/jmoiron/sqlx"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-func ReadMultipleFiles(basePath string, files chan string) chan *Song {
|
|
|
|
|
|
|
+func ReadMultipleFiles(basePath string, files chan *File) chan *Song {
|
|
|
var l = logger.CreateLogger(config.GetConfig().LogLevel)
|
|
var l = logger.CreateLogger(config.GetConfig().LogLevel)
|
|
|
|
|
|
|
|
songs := make(chan *Song)
|
|
songs := make(chan *Song)
|
|
@@ -23,13 +25,13 @@ func ReadMultipleFiles(basePath string, files chan string) chan *Song {
|
|
|
select {
|
|
select {
|
|
|
case file, more := <- files:
|
|
case file, more := <- files:
|
|
|
if more {
|
|
if more {
|
|
|
- l.Verbose("Reading file: %s\n", file)
|
|
|
|
|
|
|
+ l.Verbose("Reading file: %s\n", file.RelativePath)
|
|
|
song, err := ReadFile(basePath, file)
|
|
song, err := ReadFile(basePath, file)
|
|
|
|
|
|
|
|
if err == nil {
|
|
if err == nil {
|
|
|
songs <- song
|
|
songs <- song
|
|
|
} else {
|
|
} else {
|
|
|
- l.Error("Error reading file (%s): %s\n", file, err)
|
|
|
|
|
|
|
+ l.Error("Error reading file (%s): %s\n", file.RelativePath, err)
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
return
|
|
return
|
|
@@ -46,47 +48,89 @@ func isValidFile(file string) bool {
|
|
|
return filepath.Ext(file) == ".ogg"
|
|
return filepath.Ext(file) == ".ogg"
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func recursiveDirScan(l *logger.Logger, directory string, output *chan string, root bool, basePath string) {
|
|
|
|
|
- if (root) {
|
|
|
|
|
- l.Verbose("Scanning root directory: %s\n", directory)
|
|
|
|
|
|
|
+func recursiveDirScan(
|
|
|
|
|
+ db *sqlx.DB,
|
|
|
|
|
+ l *logger.Logger,
|
|
|
|
|
+ output *chan *File,
|
|
|
|
|
+ rootDirectory string,
|
|
|
|
|
+ relativePath string,
|
|
|
|
|
+ isRoot bool,
|
|
|
|
|
+) {
|
|
|
|
|
+ directoryToScan := filepath.Join(rootDirectory, relativePath)
|
|
|
|
|
+
|
|
|
|
|
+ if (isRoot) {
|
|
|
|
|
+ l.Verbose("Scanning root directory: %s\n", directoryToScan)
|
|
|
|
|
|
|
|
defer func() {
|
|
defer func() {
|
|
|
l.Verbose("Finished recursive directory scan")
|
|
l.Verbose("Finished recursive directory scan")
|
|
|
close(*output)
|
|
close(*output)
|
|
|
}()
|
|
}()
|
|
|
} else {
|
|
} else {
|
|
|
- l.Debug("Scanning subdirectory: %s\n", directory)
|
|
|
|
|
|
|
+ l.Debug("Scanning subdirectory: %s\n", directoryToScan)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- files, err := ioutil.ReadDir(directory)
|
|
|
|
|
|
|
+ files, err := ioutil.ReadDir(directoryToScan)
|
|
|
|
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
- l.Fatal("Error scanning directory: (%s): %s", directory, err)
|
|
|
|
|
|
|
+ l.Fatal("Error scanning directory: (%s): %s", directoryToScan, err)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for _, file := range(files) {
|
|
for _, file := range(files) {
|
|
|
- absolutePath := filepath.Join(directory, file.Name())
|
|
|
|
|
- relativePath := filepath.Join(basePath, file.Name())
|
|
|
|
|
|
|
+ fileRelativePath := filepath.Join(relativePath, file.Name())
|
|
|
|
|
|
|
|
if file.IsDir() {
|
|
if file.IsDir() {
|
|
|
- recursiveDirScan(l, absolutePath, output, false, relativePath)
|
|
|
|
|
|
|
+ recursiveDirScan(
|
|
|
|
|
+ db,
|
|
|
|
|
+ l,
|
|
|
|
|
+ output,
|
|
|
|
|
+ rootDirectory,
|
|
|
|
|
+ fileRelativePath,
|
|
|
|
|
+ false,
|
|
|
|
|
+ )
|
|
|
} else if isValidFile(file.Name()) {
|
|
} else if isValidFile(file.Name()) {
|
|
|
- l.Verbose("Found file: %s\n", relativePath)
|
|
|
|
|
-
|
|
|
|
|
- *output <- relativePath
|
|
|
|
|
|
|
+ modifiedDate := file.ModTime().Unix()
|
|
|
|
|
+
|
|
|
|
|
+ var existingCount = 0
|
|
|
|
|
+
|
|
|
|
|
+ err := db.Get(
|
|
|
|
|
+ &existingCount,
|
|
|
|
|
+ `
|
|
|
|
|
+ select count(*) from songs
|
|
|
|
|
+ where base_path = $1 and relative_path = $2 and modified_date = $3
|
|
|
|
|
+ `,
|
|
|
|
|
+ rootDirectory,
|
|
|
|
|
+ fileRelativePath,
|
|
|
|
|
+ modifiedDate,
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if err == nil && existingCount == 0 {
|
|
|
|
|
+ l.Verbose("Found file: %s\n", fileRelativePath)
|
|
|
|
|
+
|
|
|
|
|
+ *output <- &File{
|
|
|
|
|
+ RelativePath: fileRelativePath,
|
|
|
|
|
+ ModifiedDate: modifiedDate,
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func ScanDirectory(directory string) chan string {
|
|
|
|
|
|
|
+func ScanDirectory(directory string) chan *File {
|
|
|
|
|
+ db := database.GetConnection()
|
|
|
l := logger.CreateLogger(config.GetConfig().LogLevel)
|
|
l := logger.CreateLogger(config.GetConfig().LogLevel)
|
|
|
|
|
|
|
|
- files := make(chan string)
|
|
|
|
|
|
|
+ files := make(chan *File)
|
|
|
|
|
|
|
|
go func() {
|
|
go func() {
|
|
|
- recursiveDirScan(l, directory, &files, true, "")
|
|
|
|
|
|
|
+ recursiveDirScan(
|
|
|
|
|
+ db,
|
|
|
|
|
+ l,
|
|
|
|
|
+ &files,
|
|
|
|
|
+ directory,
|
|
|
|
|
+ "",
|
|
|
|
|
+ true,
|
|
|
|
|
+ )
|
|
|
}()
|
|
}()
|
|
|
|
|
|
|
|
return files
|
|
return files
|