mirror of
https://github.com/navidrome/navidrome.git
synced 2025-06-07 10:53:22 +03:00
Handle folder moves in Scanner
This commit is contained in:
parent
8ae4fdd5b2
commit
58a080eded
@ -9,22 +9,28 @@ import (
|
|||||||
"github.com/cloudsonic/sonic-server/log"
|
"github.com/cloudsonic/sonic-server/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type dirInfo struct {
|
||||||
|
mdate time.Time
|
||||||
|
maybe bool
|
||||||
|
}
|
||||||
|
type dirInfoMap map[string]dirInfo
|
||||||
|
|
||||||
type ChangeDetector struct {
|
type ChangeDetector struct {
|
||||||
rootFolder string
|
rootFolder string
|
||||||
dirMap map[string]time.Time
|
dirMap dirInfoMap
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChangeDetector(rootFolder string) *ChangeDetector {
|
func NewChangeDetector(rootFolder string) *ChangeDetector {
|
||||||
return &ChangeDetector{
|
return &ChangeDetector{
|
||||||
rootFolder: rootFolder,
|
rootFolder: rootFolder,
|
||||||
dirMap: map[string]time.Time{},
|
dirMap: dirInfoMap{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ChangeDetector) Scan(lastModifiedSince time.Time) (changed []string, deleted []string, err error) {
|
func (s *ChangeDetector) Scan(lastModifiedSince time.Time) (changed []string, deleted []string, err error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
newMap := make(map[string]time.Time)
|
newMap := make(dirInfoMap)
|
||||||
err = s.loadMap(s.rootFolder, newMap)
|
err = s.loadMap(newMap, s.rootFolder, lastModifiedSince, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -67,20 +73,21 @@ func (s *ChangeDetector) loadDir(dirPath string) (children []string, lastUpdated
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ChangeDetector) loadMap(rootPath string, dirMap map[string]time.Time) error {
|
func (s *ChangeDetector) loadMap(dirMap dirInfoMap, rootPath string, since time.Time, maybe bool) error {
|
||||||
children, lastUpdated, err := s.loadDir(rootPath)
|
children, lastUpdated, err := s.loadDir(rootPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
maybe = maybe || lastUpdated.After(since)
|
||||||
for _, c := range children {
|
for _, c := range children {
|
||||||
err := s.loadMap(c, dirMap)
|
err := s.loadMap(dirMap, c, since, maybe)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dir := s.getRelativePath(rootPath)
|
dir := s.getRelativePath(rootPath)
|
||||||
dirMap[dir] = lastUpdated
|
dirMap[dir] = dirInfo{mdate: lastUpdated, maybe: maybe}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -93,11 +100,16 @@ func (s *ChangeDetector) getRelativePath(subfolder string) string {
|
|||||||
return dir
|
return dir
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ChangeDetector) checkForUpdates(lastModifiedSince time.Time, newMap map[string]time.Time) (changed []string, deleted []string, err error) {
|
func (s *ChangeDetector) checkForUpdates(lastModifiedSince time.Time, newMap dirInfoMap) (changed []string, deleted []string, err error) {
|
||||||
for dir, lastUpdated := range newMap {
|
for dir, newEntry := range newMap {
|
||||||
oldLastUpdated, ok := s.dirMap[dir]
|
lastUpdated := newEntry.mdate
|
||||||
if !ok {
|
oldLastUpdated := lastModifiedSince
|
||||||
oldLastUpdated = lastModifiedSince
|
if oldEntry, ok := s.dirMap[dir]; ok {
|
||||||
|
oldLastUpdated = oldEntry.mdate
|
||||||
|
} else {
|
||||||
|
if newEntry.maybe {
|
||||||
|
oldLastUpdated = time.Time{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if lastUpdated.After(oldLastUpdated) {
|
if lastUpdated.After(oldLastUpdated) {
|
||||||
changed = append(changed, dir)
|
changed = append(changed, dir)
|
||||||
|
@ -33,6 +33,7 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
Expect(changed).To(ConsistOf("."))
|
Expect(changed).To(ConsistOf("."))
|
||||||
|
|
||||||
// Add one subfolder
|
// Add one subfolder
|
||||||
|
lastModifiedSince = time.Now()
|
||||||
err = os.MkdirAll(path.Join(testFolder, "a"), 0700)
|
err = os.MkdirAll(path.Join(testFolder, "a"), 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -43,6 +44,7 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
Expect(changed).To(ConsistOf(".", "/a"))
|
Expect(changed).To(ConsistOf(".", "/a"))
|
||||||
|
|
||||||
// Add more subfolders
|
// Add more subfolders
|
||||||
|
lastModifiedSince = time.Now()
|
||||||
err = os.MkdirAll(path.Join(testFolder, "a", "b", "c"), 0700)
|
err = os.MkdirAll(path.Join(testFolder, "a", "b", "c"), 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -53,12 +55,14 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
Expect(changed).To(ConsistOf("/a", "/a/b", "/a/b/c"))
|
Expect(changed).To(ConsistOf("/a", "/a/b", "/a/b/c"))
|
||||||
|
|
||||||
// Scan with no changes
|
// Scan with no changes
|
||||||
|
lastModifiedSince = time.Now()
|
||||||
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(BeEmpty())
|
Expect(changed).To(BeEmpty())
|
||||||
|
|
||||||
// New file in subfolder
|
// New file in subfolder
|
||||||
|
lastModifiedSince = time.Now()
|
||||||
_, err = os.Create(path.Join(testFolder, "a", "b", "empty.txt"))
|
_, err = os.Create(path.Join(testFolder, "a", "b", "empty.txt"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -69,6 +73,7 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
Expect(changed).To(ConsistOf("/a/b"))
|
Expect(changed).To(ConsistOf("/a/b"))
|
||||||
|
|
||||||
// Delete file in subfolder
|
// Delete file in subfolder
|
||||||
|
lastModifiedSince = time.Now()
|
||||||
err = os.Remove(path.Join(testFolder, "a", "b", "empty.txt"))
|
err = os.Remove(path.Join(testFolder, "a", "b", "empty.txt"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -79,6 +84,7 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
Expect(changed).To(ConsistOf("/a/b"))
|
Expect(changed).To(ConsistOf("/a/b"))
|
||||||
|
|
||||||
// Delete subfolder
|
// Delete subfolder
|
||||||
|
lastModifiedSince = time.Now()
|
||||||
err = os.Remove(path.Join(testFolder, "a", "b", "c"))
|
err = os.Remove(path.Join(testFolder, "a", "b", "c"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -97,7 +103,8 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
Expect(changed).To(BeEmpty())
|
Expect(changed).To(BeEmpty())
|
||||||
Expect(changed).To(BeEmpty())
|
Expect(changed).To(BeEmpty())
|
||||||
|
|
||||||
_, err = os.Create(path.Join(testFolder, "a", "b", "new.txt"))
|
f, err := os.Create(path.Join(testFolder, "a", "b", "new.txt"))
|
||||||
|
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())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user