fix: use filepath.Join instead of path.Join
This commit is contained in:
@@ -2,7 +2,7 @@ package scanner
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ func (s *ChangeDetector) loadDir(dirPath string) (children []string, lastUpdated
|
|||||||
}
|
}
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
children = append(children, path.Join(dirPath, f.Name()))
|
children = append(children, filepath.Join(dirPath, f.Name()))
|
||||||
} else {
|
} else {
|
||||||
if f.ModTime().After(lastUpdated) {
|
if f.ModTime().After(lastUpdated) {
|
||||||
lastUpdated = f.ModTime()
|
lastUpdated = f.ModTime()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package scanner
|
|||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
@@ -34,25 +34,25 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
|
|
||||||
// Add one subfolder
|
// Add one subfolder
|
||||||
lastModifiedSince = time.Now()
|
lastModifiedSince = time.Now()
|
||||||
err = os.MkdirAll(path.Join(testFolder, "a"), 0700)
|
err = os.MkdirAll(filepath.Join(testFolder, "a"), 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(deleted).To(BeEmpty())
|
Expect(deleted).To(BeEmpty())
|
||||||
Expect(changed).To(ConsistOf(".", "/a"))
|
Expect(changed).To(ConsistOf(".", P("/a")))
|
||||||
|
|
||||||
// Add more subfolders
|
// Add more subfolders
|
||||||
lastModifiedSince = time.Now()
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(deleted).To(BeEmpty())
|
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
|
// Scan with no changes
|
||||||
lastModifiedSince = time.Now()
|
lastModifiedSince = time.Now()
|
||||||
@@ -63,36 +63,36 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
|
|
||||||
// New file in subfolder
|
// New file in subfolder
|
||||||
lastModifiedSince = time.Now()
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(deleted).To(BeEmpty())
|
Expect(deleted).To(BeEmpty())
|
||||||
Expect(changed).To(ConsistOf("/a/b"))
|
Expect(changed).To(ConsistOf(P("/a/b")))
|
||||||
|
|
||||||
// Delete file in subfolder
|
// Delete file in subfolder
|
||||||
lastModifiedSince = time.Now()
|
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 {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(deleted).To(BeEmpty())
|
Expect(deleted).To(BeEmpty())
|
||||||
Expect(changed).To(ConsistOf("/a/b"))
|
Expect(changed).To(ConsistOf(P("/a/b")))
|
||||||
|
|
||||||
// Delete subfolder
|
// Delete subfolder
|
||||||
lastModifiedSince = time.Now()
|
lastModifiedSince = time.Now()
|
||||||
err = os.Remove(path.Join(testFolder, "a", "b", "c"))
|
err = os.Remove(filepath.Join(testFolder, "a", "b", "c"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
changed, deleted, err = scanner.Scan(lastModifiedSince)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(deleted).To(ConsistOf("/a/b/c"))
|
Expect(deleted).To(ConsistOf(P("/a/b/c")))
|
||||||
Expect(changed).To(ConsistOf("/a/b"))
|
Expect(changed).To(ConsistOf(P("/a/b")))
|
||||||
|
|
||||||
// Only returns changes after lastModifiedSince
|
// Only returns changes after lastModifiedSince
|
||||||
lastModifiedSince = time.Now()
|
lastModifiedSince = time.Now()
|
||||||
@@ -103,11 +103,11 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
Expect(changed).To(BeEmpty())
|
Expect(changed).To(BeEmpty())
|
||||||
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()
|
f.Close()
|
||||||
changed, deleted, err = newScanner.Scan(lastModifiedSince)
|
changed, deleted, err = newScanner.Scan(lastModifiedSince)
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(deleted).To(BeEmpty())
|
Expect(deleted).To(BeEmpty())
|
||||||
Expect(changed).To(ConsistOf("/a/b"))
|
Expect(changed).To(ConsistOf(P("/a/b")))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -56,7 +57,7 @@ func ExtractAllMetadata(dirPath string) (map[string]*Metadata, error) {
|
|||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
filePath := path.Join(dirPath, f.Name())
|
filePath := filepath.Join(dirPath, f.Name())
|
||||||
extension := path.Ext(filePath)
|
extension := path.Ext(filePath)
|
||||||
if !isAudioFile(extension) {
|
if !isAudioFile(extension) {
|
||||||
continue
|
continue
|
||||||
@@ -95,7 +96,7 @@ var inputRegex = regexp.MustCompile(`(?m)^Input #\d+,.*,\sfrom\s'(.*)'`)
|
|||||||
|
|
||||||
func parseOutput(output string) map[string]string {
|
func parseOutput(output string) map[string]string {
|
||||||
split := map[string]string{}
|
split := map[string]string{}
|
||||||
all := inputRegex.FindAllStringSubmatchIndex(string(output), -1)
|
all := inputRegex.FindAllStringSubmatchIndex(output, -1)
|
||||||
for i, loc := range all {
|
for i, loc := range all {
|
||||||
// Filename is the first captured group
|
// Filename is the first captured group
|
||||||
file := output[loc[2]:loc[3]]
|
file := output[loc[2]:loc[3]]
|
||||||
|
|||||||
+48
-45
@@ -6,51 +6,54 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("Metadata", func() {
|
var _ = Describe("Metadata", func() {
|
||||||
It("correctly parses metadata from all files in folder", func() {
|
// TODO Need to mock `ffmpeg`
|
||||||
mds, err := ExtractAllMetadata("../tests/fixtures")
|
XContext("ExtractAllMetadata", func() {
|
||||||
Expect(err).NotTo(HaveOccurred())
|
It("correctly parses metadata from all files in folder", func() {
|
||||||
Expect(mds).To(HaveLen(3))
|
mds, err := ExtractAllMetadata("tests/fixtures")
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(mds).To(HaveLen(3))
|
||||||
|
|
||||||
m := mds["../tests/fixtures/test.mp3"]
|
m := mds["tests/fixtures/test.mp3"]
|
||||||
Expect(m.Title()).To(Equal("Song"))
|
Expect(m.Title()).To(Equal("Song"))
|
||||||
Expect(m.Album()).To(Equal("Album"))
|
Expect(m.Album()).To(Equal("Album"))
|
||||||
Expect(m.Artist()).To(Equal("Artist"))
|
Expect(m.Artist()).To(Equal("Artist"))
|
||||||
Expect(m.AlbumArtist()).To(Equal("Album Artist"))
|
Expect(m.AlbumArtist()).To(Equal("Album Artist"))
|
||||||
Expect(m.Composer()).To(Equal("Composer"))
|
Expect(m.Composer()).To(Equal("Composer"))
|
||||||
Expect(m.Compilation()).To(BeTrue())
|
Expect(m.Compilation()).To(BeTrue())
|
||||||
Expect(m.Genre()).To(Equal("Rock"))
|
Expect(m.Genre()).To(Equal("Rock"))
|
||||||
Expect(m.Year()).To(Equal(2014))
|
Expect(m.Year()).To(Equal(2014))
|
||||||
n, t := m.TrackNumber()
|
n, t := m.TrackNumber()
|
||||||
Expect(n).To(Equal(2))
|
Expect(n).To(Equal(2))
|
||||||
Expect(t).To(Equal(10))
|
Expect(t).To(Equal(10))
|
||||||
n, t = m.DiscNumber()
|
n, t = m.DiscNumber()
|
||||||
Expect(n).To(Equal(1))
|
Expect(n).To(Equal(1))
|
||||||
Expect(t).To(Equal(2))
|
Expect(t).To(Equal(2))
|
||||||
Expect(m.HasPicture()).To(BeTrue())
|
Expect(m.HasPicture()).To(BeTrue())
|
||||||
Expect(m.Duration()).To(Equal(1))
|
Expect(m.Duration()).To(Equal(1))
|
||||||
Expect(m.BitRate()).To(Equal(476))
|
Expect(m.BitRate()).To(Equal(476))
|
||||||
Expect(m.FilePath()).To(Equal("../tests/fixtures/test.mp3"))
|
Expect(m.FilePath()).To(Equal("tests/fixtures/test.mp3"))
|
||||||
Expect(m.Suffix()).To(Equal("mp3"))
|
Expect(m.Suffix()).To(Equal("mp3"))
|
||||||
Expect(m.Size()).To(Equal(60845))
|
Expect(m.Size()).To(Equal(60845))
|
||||||
|
|
||||||
m = mds["../tests/fixtures/test.ogg"]
|
m = mds["tests/fixtures/test.ogg"]
|
||||||
Expect(err).To(BeNil())
|
Expect(err).To(BeNil())
|
||||||
Expect(m.Title()).To(BeEmpty())
|
Expect(m.Title()).To(BeEmpty())
|
||||||
Expect(m.HasPicture()).To(BeFalse())
|
Expect(m.HasPicture()).To(BeFalse())
|
||||||
Expect(m.Duration()).To(Equal(3))
|
Expect(m.Duration()).To(Equal(3))
|
||||||
Expect(m.BitRate()).To(Equal(9))
|
Expect(m.BitRate()).To(Equal(9))
|
||||||
Expect(m.Suffix()).To(Equal("ogg"))
|
Expect(m.Suffix()).To(Equal("ogg"))
|
||||||
Expect(m.FilePath()).To(Equal("../tests/fixtures/test.ogg"))
|
Expect(m.FilePath()).To(Equal("tests/fixtures/test.ogg"))
|
||||||
Expect(m.Size()).To(Equal(4408))
|
Expect(m.Size()).To(Equal(4408))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns error if path does not exist", func() {
|
It("returns error if path does not exist", func() {
|
||||||
_, err := ExtractAllMetadata("./INVALID/PATH")
|
_, err := ExtractAllMetadata("./INVALID/PATH")
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).To(HaveOccurred())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("returns empty map if there are no audio files in path", func() {
|
It("returns empty map if there are no audio files in path", func() {
|
||||||
Expect(ExtractAllMetadata(".")).To(BeEmpty())
|
Expect(ExtractAllMetadata(".")).To(BeEmpty())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Context("extractMetadata", func() {
|
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
|
Stream #0:1: Video: png, rgb24(pc), 500x478 [SAR 2835:2835 DAR 250:239], 90k tbr, 90k tbn, 90k tbc
|
||||||
Metadata:
|
Metadata:
|
||||||
comment : Other`
|
comment : Other`
|
||||||
md, _ := extractMetadata("pablo's blues.mp3", outputWithOverlappingTitleTag)
|
md, _ := extractMetadata("tests/fixtures/test.mp3", outputWithOverlappingTitleTag)
|
||||||
Expect(md.Compilation()).To(BeTrue())
|
Expect(md.Compilation()).To(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -99,7 +102,7 @@ Input #0, mp3, from 'groovin.mp3':
|
|||||||
title : cover
|
title : cover
|
||||||
comment : Cover (front)
|
comment : Cover (front)
|
||||||
At least one output file must be specified`
|
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)"))
|
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
|
Stream #0:0: Audio: flac, 44100 Hz, stereo, s16
|
||||||
Side data:
|
Side data:
|
||||||
replaygain: track gain - -8.510000, track peak - 0.000023, album gain - unknown, album peak - unknown,`
|
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.Title()).To(Equal("Back In Black"))
|
||||||
Expect(md.Album()).To(Equal("Back In Black"))
|
Expect(md.Album()).To(Equal("Back In Black"))
|
||||||
Expect(md.Genre()).To(Equal("Hard Rock"))
|
Expect(md.Genre()).To(Equal("Hard Rock"))
|
||||||
@@ -189,7 +192,7 @@ Tracklist:
|
|||||||
07. Wunderbar
|
07. Wunderbar
|
||||||
08. Quarta Dimensão
|
08. Quarta Dimensão
|
||||||
`
|
`
|
||||||
md, _ := extractMetadata("modulo.mp3", outputWithMultilineComment)
|
md, _ := extractMetadata("tests/fixtures/test.mp3", outputWithMultilineComment)
|
||||||
Expect(md.Comment()).To(Equal(expectedComment))
|
Expect(md.Comment()).To(Equal(expectedComment))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,16 +1,23 @@
|
|||||||
package scanner
|
package scanner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/deluan/navidrome/log"
|
"github.com/deluan/navidrome/log"
|
||||||
|
"github.com/deluan/navidrome/tests"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO Fix OS dependencies
|
func TestScanner(t *testing.T) {
|
||||||
func xTestScanner(t *testing.T) {
|
tests.Init(t, true)
|
||||||
log.SetLevel(log.LevelCritical)
|
log.SetLevel(log.LevelCritical)
|
||||||
RegisterFailHandler(Fail)
|
RegisterFailHandler(Fail)
|
||||||
RunSpecs(t, "Scanner Suite")
|
RunSpecs(t, "Scanner Suite")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func P(path string) string {
|
||||||
|
return strings.ReplaceAll(path, "/", string(os.PathSeparator))
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -49,7 +48,11 @@ func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time) erro
|
|||||||
return nil
|
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(changed)
|
||||||
sort.Strings(deleted)
|
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 {
|
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()
|
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 {
|
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)
|
ct, err := s.ds.MediaFile(ctx).FindByPath(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user