Skip to content

Commit

Permalink
Add support to rescan libraries based on given filters
Browse files Browse the repository at this point in the history
  • Loading branch information
Maran Hidskes committed Jun 25, 2020
1 parent 869b45a commit 16cc67c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 8 deletions.
2 changes: 1 addition & 1 deletion metadata/db/library.go
Expand Up @@ -12,7 +12,7 @@ import (

// LogFields defines some standard fields to include in logs.
func (lib *Library) LogFields() log.Fields {
return log.Fields{"name": lib.Name, "path": lib.FilePath, "backend": lib.Backend}
return log.Fields{"name": lib.Name, "libraryRoot": lib.FilePath, "backend": lib.Backend}
}

// BackendType specifies what kind of Library backend is being used.
Expand Down
26 changes: 19 additions & 7 deletions metadata/managers/library.go
Expand Up @@ -173,9 +173,21 @@ func (man *LibraryManager) checkAndAddProbeJob(node filesystem.Node) {
}
}

// RescanFilesystem goes over the filesystem and parses filenames in the given library.
func (man *LibraryManager) RescanFilesystem() {
log.WithFields(man.Library.LogFields()).Println("Scanning library for changed files.")
// RescanFilesystem goes over the filesystem and parses filenames in the given library. If a filePath is supplied it will only scan the given path for new content.
func (man *LibraryManager) RescanFilesystem(filePath string) {
if filePath == "" {
filePath = man.Library.FilePath
log.Debugln("No filePath supplied, going to scan from the root")
} else {
if strings.Contains(filePath, man.Library.FilePath) {
log.WithFields(log.Fields{"filePath": filePath}).Debugln("Valid filepath supplied, scanning from giving path")
} else {
log.WithFields(log.Fields{"filePath": filePath, "libraryPath": man.Library.FilePath}).Debugln("Given filePath is not part of the library, ignoring.")
filePath = man.Library.FilePath
}
}

log.WithFields(man.Library.LogFields()).WithField("filePath", filePath).Println("Scanning library for changed files.")
stime := time.Now()

// TODO: Move this into db package
Expand All @@ -189,10 +201,10 @@ func (man *LibraryManager) RescanFilesystem() {
// TODO: Should this be in it's own healthCheck method on the library or something?
switch man.Library.Backend {
case db.BackendLocal:
rootNode, err = filesystem.LocalNodeFromPath(man.Library.FilePath)
rootNode, err = filesystem.LocalNodeFromPath(filePath)
case db.BackendRclone:
rootNode, err = filesystem.RcloneNodeFromPath(
path.Join(man.Library.RcloneName, man.Library.FilePath))
path.Join(man.Library.RcloneName, filePath))
}

if err != nil {
Expand All @@ -214,7 +226,7 @@ func (man *LibraryManager) RescanFilesystem() {
man.RecursiveProbe(rootNode)

dur := time.Since(stime)
log.Printf("Probing library '%s' took %f seconds", man.Library.FilePath, dur.Seconds())
log.Printf("Scanning library took %f seconds", dur.Seconds())
man.Library.RefreshCompletedAt = time.Now()
db.SaveLibrary(man.Library)

Expand Down Expand Up @@ -429,7 +441,7 @@ func (man *LibraryManager) RefreshAll() {
man.AddWatcher(man.Library.FilePath)
}

man.RescanFilesystem()
man.RescanFilesystem("")
man.IdentifyUnidentifiedFiles()
}

Expand Down
48 changes: 48 additions & 0 deletions metadata/resolvers/library.go
Expand Up @@ -2,11 +2,13 @@ package resolvers

import (
"context"
"fmt"
log "github.com/sirupsen/logrus"
"gitlab.com/olaris/olaris-server/metadata/db"
mhelpers "gitlab.com/olaris/olaris-server/metadata/helpers"
"path/filepath"
"strconv"
"strings"
"time"
)

Expand Down Expand Up @@ -138,6 +140,52 @@ func (r *Resolver) RefreshAgentMetadata(ctx context.Context, args struct {
return false
}

// RescanLibrary can scan (parts) of a Library
func (r *Resolver) RescanLibrary(ctx context.Context, args struct {
ID *int32
FilePath *string
}) bool {
err := ifAdmin(ctx)
if err != nil {
return false
}

// No specific library is given
if args.ID == nil {
if args.FilePath == nil {
return false
}

// A valid filepath has been given so let's look in all libraries for the given path
validLibFound := false
for _, man := range r.libs {
if strings.Contains(*args.FilePath, man.Library.FilePath) {
validLibFound = true
go mhelpers.WithLock(func() {
man.RescanFilesystem(*args.FilePath)
}, fmt.Sprintf("refresh-lib-%s", strconv.Itoa(int(man.Library.ID))))
}
}
return validLibFound
}

// A specific library has been given
libId := uint(*args.ID)
man := r.libs[libId]

// No specific filepath has been given so we can refresh the whole library.
if args.FilePath == nil {
go mhelpers.WithLock(func() {
man.RefreshAll()
}, fmt.Sprintf("refresh-lib-%s", strconv.Itoa(int(man.Library.ID))))
} else {
go mhelpers.WithLock(func() {
man.RescanFilesystem(*args.FilePath)
}, fmt.Sprintf("refresh-lib-%s", strconv.Itoa(int(man.Library.ID))))
}
return true
}

// RescanLibraries rescans all libraries for new files.
func (r *Resolver) RescanLibraries(ctx context.Context) bool {
err := ifAdmin(ctx)
Expand Down
6 changes: 6 additions & 0 deletions metadata/resolvers/schema.graphql
Expand Up @@ -69,6 +69,12 @@ type Mutation {
# Rescan all library paths for new files that are not indexed yet.
rescanLibraries(): Boolean!

# Rescan a library based on the given filters.
# 1. If supply a "ID" it will refresh the entire library
# 2. If you supply it an "ID" and a "filepath" it will only scan the specific filepath in the given library
# 3. If you supply just a "filepath" it will loop over all libraries seeing if any of the given libraries match the given path and then scan only that path.
rescanLibrary(id: Int, filepath: String): Boolean!

# Tag an unidentified MovieFile
updateMovieFileMetadata(input: UpdateMovieFileMetadataInput!): UpdateMovieFileMetadataPayload!

Expand Down

0 comments on commit 16cc67c

Please sign in to comment.