mirror of
https://github.com/navidrome/navidrome.git
synced 2025-06-05 18:03:10 +03:00
Fix ChangeDetector to keep the dirMap from last scan
This commit is contained in:
parent
e55dfff485
commit
ea9ed4a287
@ -118,6 +118,9 @@ func (r *mediaFileRepository) DeleteByPath(path string) error {
|
|||||||
}
|
}
|
||||||
filtered = append(filtered, mf.ID)
|
filtered = append(filtered, mf.ID)
|
||||||
}
|
}
|
||||||
|
if len(filtered) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
_, err = r.newQuery(o).Filter("id__in", filtered).Delete()
|
_, err = r.newQuery(o).Filter("id__in", filtered).Delete()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -11,26 +11,24 @@ import (
|
|||||||
|
|
||||||
type ChangeDetector struct {
|
type ChangeDetector struct {
|
||||||
rootFolder string
|
rootFolder string
|
||||||
lastUpdate time.Time
|
|
||||||
dirMap map[string]time.Time
|
dirMap map[string]time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChangeDetector(rootFolder string, lastUpdate time.Time) *ChangeDetector {
|
func NewChangeDetector(rootFolder string) *ChangeDetector {
|
||||||
return &ChangeDetector{
|
return &ChangeDetector{
|
||||||
rootFolder: rootFolder,
|
rootFolder: rootFolder,
|
||||||
lastUpdate: lastUpdate,
|
|
||||||
dirMap: map[string]time.Time{},
|
dirMap: map[string]time.Time{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ChangeDetector) Scan() (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(map[string]time.Time)
|
||||||
err = s.loadMap(s.rootFolder, newMap)
|
err = s.loadMap(s.rootFolder, newMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
changed, deleted, err = s.checkForUpdates(s.dirMap, newMap)
|
changed, deleted, err = s.checkForUpdates(lastModifiedSince, newMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -95,17 +93,17 @@ func (s *ChangeDetector) getRelativePath(subfolder string) string {
|
|||||||
return dir
|
return dir
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ChangeDetector) checkForUpdates(oldMap map[string]time.Time, newMap map[string]time.Time) (changed []string, deleted []string, err error) {
|
func (s *ChangeDetector) checkForUpdates(lastModifiedSince time.Time, newMap map[string]time.Time) (changed []string, deleted []string, err error) {
|
||||||
for dir, lastUpdated := range newMap {
|
for dir, lastUpdated := range newMap {
|
||||||
oldLastUpdated, ok := oldMap[dir]
|
oldLastUpdated, ok := s.dirMap[dir]
|
||||||
if !ok {
|
if !ok {
|
||||||
oldLastUpdated = s.lastUpdate
|
oldLastUpdated = lastModifiedSince
|
||||||
}
|
}
|
||||||
if lastUpdated.After(oldLastUpdated) {
|
if lastUpdated.After(oldLastUpdated) {
|
||||||
changed = append(changed, dir)
|
changed = append(changed, dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for dir := range oldMap {
|
for dir := range s.dirMap {
|
||||||
if _, ok := newMap[dir]; !ok {
|
if _, ok := newMap[dir]; !ok {
|
||||||
deleted = append(deleted, dir)
|
deleted = append(deleted, dir)
|
||||||
}
|
}
|
||||||
|
@ -14,18 +14,20 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
var testFolder string
|
var testFolder string
|
||||||
var scanner *ChangeDetector
|
var scanner *ChangeDetector
|
||||||
|
|
||||||
|
lastModifiedSince := time.Time{}
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
testFolder, _ = ioutil.TempDir("", "cloudsonic_tests")
|
testFolder, _ = ioutil.TempDir("", "cloudsonic_tests")
|
||||||
err := os.MkdirAll(testFolder, 0700)
|
err := os.MkdirAll(testFolder, 0700)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
scanner = NewChangeDetector(testFolder, time.Time{})
|
scanner = NewChangeDetector(testFolder)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("detects changes recursively", func() {
|
It("detects changes recursively", func() {
|
||||||
// Scan empty folder
|
// Scan empty folder
|
||||||
changed, deleted, err := scanner.Scan()
|
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("."))
|
Expect(changed).To(ConsistOf("."))
|
||||||
@ -35,7 +37,7 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan()
|
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(".", "/a"))
|
||||||
@ -45,13 +47,13 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan()
|
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("/a", "/a/b", "/a/b/c"))
|
||||||
|
|
||||||
// Scan with no changes
|
// Scan with no changes
|
||||||
changed, deleted, err = scanner.Scan()
|
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())
|
||||||
@ -61,7 +63,7 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan()
|
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("/a/b"))
|
||||||
@ -71,7 +73,7 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan()
|
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("/a/b"))
|
||||||
@ -81,21 +83,22 @@ var _ = Describe("ChangeDetector", func() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
changed, deleted, err = scanner.Scan()
|
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("/a/b/c"))
|
||||||
Expect(changed).To(ConsistOf("/a/b"))
|
Expect(changed).To(ConsistOf("/a/b"))
|
||||||
|
|
||||||
// Only returns changes after lastUpdate
|
// Only returns changes after lastModifiedSince
|
||||||
newScanner := NewChangeDetector(testFolder, time.Now())
|
lastModifiedSince = time.Now()
|
||||||
changed, deleted, err = newScanner.Scan()
|
newScanner := NewChangeDetector(testFolder)
|
||||||
|
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(BeEmpty())
|
Expect(changed).To(BeEmpty())
|
||||||
Expect(changed).To(BeEmpty())
|
Expect(changed).To(BeEmpty())
|
||||||
|
|
||||||
_, err = os.Create(path.Join(testFolder, "a", "b", "new.txt"))
|
_, err = os.Create(path.Join(testFolder, "a", "b", "new.txt"))
|
||||||
changed, deleted, err = newScanner.Scan()
|
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("/a/b"))
|
||||||
|
@ -76,16 +76,16 @@ func (s *Scanner) RescanAll(fullRescan bool) error {
|
|||||||
|
|
||||||
func (s *Scanner) Status() []StatusInfo { return nil }
|
func (s *Scanner) Status() []StatusInfo { return nil }
|
||||||
|
|
||||||
func (i *Scanner) getLastModifiedSince(folder string) time.Time {
|
func (s *Scanner) getLastModifiedSince(folder string) time.Time {
|
||||||
ms, err := i.repos.property.Get(model.PropLastScan + "-" + folder)
|
ms, err := s.repos.property.Get(model.PropLastScan + "-" + folder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
if ms == "" {
|
if ms == "" {
|
||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
s, _ := strconv.ParseInt(ms, 10, 64)
|
i, _ := strconv.ParseInt(ms, 10, 64)
|
||||||
return time.Unix(0, s*int64(time.Millisecond))
|
return time.Unix(0, i*int64(time.Millisecond))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scanner) updateLastModifiedSince(folder string, t time.Time) {
|
func (s *Scanner) updateLastModifiedSince(folder string, t time.Time) {
|
||||||
|
@ -18,12 +18,14 @@ import (
|
|||||||
type TagScanner struct {
|
type TagScanner struct {
|
||||||
rootFolder string
|
rootFolder string
|
||||||
repos Repositories
|
repos Repositories
|
||||||
|
detector *ChangeDetector
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTagScanner(rootFolder string, repos Repositories) *TagScanner {
|
func NewTagScanner(rootFolder string, repos Repositories) *TagScanner {
|
||||||
return &TagScanner{
|
return &TagScanner{
|
||||||
rootFolder: rootFolder,
|
rootFolder: rootFolder,
|
||||||
repos: repos,
|
repos: repos,
|
||||||
|
detector: NewChangeDetector(rootFolder),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,8 +43,7 @@ func NewTagScanner(rootFolder string, repos Repositories) *TagScanner {
|
|||||||
// Delete all empty albums, delete all empty Artists
|
// Delete all empty albums, delete all empty Artists
|
||||||
// Recreate ArtistIndex
|
// Recreate ArtistIndex
|
||||||
func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time) error {
|
func (s *TagScanner) Scan(ctx context.Context, lastModifiedSince time.Time) error {
|
||||||
detector := NewChangeDetector(s.rootFolder, lastModifiedSince)
|
changed, deleted, err := s.detector.Scan(lastModifiedSince)
|
||||||
changed, deleted, err := detector.Scan()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user