photoprism/pkg/fs/dirs.go
Michael Mayer 6847b8b5f9
Complete file browser with symlink support and full folder / file names (#412)
* Backend: Code clean-up

Signed-off-by: Michael Mayer <michael@liquidbytes.net>

* File Browser: Show complete, original file and folder names #408

Signed-off-by: Michael Mayer <michael@liquidbytes.net>

* File Browser: Follow symlinks #201 #403 #407

Warning: Following symlinks can make folder lists non-deterministic
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
2020-07-16 15:43:23 +02:00

157 lines
3 KiB
Go

package fs
import (
"os"
"path/filepath"
"sort"
"strings"
"sync"
"github.com/photoprism/photoprism/pkg/fastwalk"
)
var OriginalPaths = []string{
"/photoprism/photos/originals",
"/photoprism/storage/originals",
"/photoprism/originals",
"photoprism/originals",
"PhotoPrism/Originals",
"photoprism/original",
"PhotoPrism/Original",
"pictures/originals",
"Pictures/Originals",
"pictures/original",
"Pictures/Original",
"photos/originals",
"Photos/Originals",
"storage/originals",
"photos/original",
"Photos/Original",
"originals",
"Originals",
"original",
"Original",
"pictures",
"Pictures",
"photos",
"Photos",
"images",
"Images",
"bilder",
"Bilder",
"fotos",
"Fotos",
"~/photoprism/originals",
"~/PhotoPrism/Originals",
"~/photoprism/original",
"~/PhotoPrism/Original",
"~/pictures/originals",
"~/Pictures/Originals",
"~/pictures/original",
"~/Pictures/Original",
"~/photos/originals",
"~/Photos/Originals",
"~/photos/original",
"~/Photos/Original",
"~/pictures",
"~/Pictures",
"~/photos",
"~/Photos",
"~/images",
"~/Images",
"~/bilder",
"~/Bilder",
"~/fotos",
"~/Fotos",
}
var ImportPaths = []string{
"/photoprism/photos/import",
"/photoprism/storage/import",
"/photoprism/import",
"photoprism/import",
"PhotoPrism/Import",
"pictures/import",
"Pictures/Import",
"photos/import",
"Photos/Import",
"storage/import",
"import",
"Import",
"~/pictures/import",
"~/Pictures/Import",
"~/photoprism/import",
"~/PhotoPrism/Import",
"~/photos/import",
"~/Photos/Import",
"~/import",
"~/Import",
}
// Dirs returns a slice of directories in a path, optional recursively and with symlinks.
//
// Warning: Following symlinks can make the result non-deterministic and hard to test!
func Dirs(root string, recursive bool, followLinks bool) (result []string, err error) {
result = []string{}
ignore := NewIgnoreList(".ppignore", true, false)
mutex := sync.Mutex{}
symlinks := make(map[string]bool)
symlinksMutex := sync.Mutex{}
appendResult := func(fileName string) {
fileName = strings.Replace(fileName, root, "", 1)
mutex.Lock()
defer mutex.Unlock()
result = append(result, fileName)
}
err = fastwalk.Walk(root, func(fileName string, typ os.FileMode) error {
if typ.IsDir() || typ == os.ModeSymlink && followLinks {
if ignore.Ignore(fileName) {
return filepath.SkipDir
}
if fileName != root {
if !recursive {
appendResult(fileName)
return filepath.SkipDir
} else if typ != os.ModeSymlink {
appendResult(fileName)
return nil
} else if resolved, err := filepath.EvalSymlinks(fileName); err == nil {
symlinksMutex.Lock()
defer symlinksMutex.Unlock()
if _, ok := symlinks[resolved]; ok {
return filepath.SkipDir
} else {
symlinks[resolved] = true
appendResult(fileName)
}
return fastwalk.ErrTraverseLink
}
}
}
return nil
})
sort.Strings(result)
return result, err
}
func FindDir(dirs []string) string {
for _, dir := range dirs {
absDir := Abs(dir)
if PathExists(absDir) {
return absDir
}
}
return ""
}