photoprism/pkg/fs/dirs.go
Michael Mayer 5ec90a5fff Index: Skip redundant thumbs and support symbolic file links #1049 #1874
Signed-off-by: Michael Mayer <michael@photoprism.app>
2022-07-06 23:01:54 +02:00

193 lines
3.9 KiB
Go

package fs
import (
"os"
"path/filepath"
"sort"
"strings"
"sync"
"github.com/photoprism/photoprism/pkg/fastwalk"
)
var OriginalPaths = []string{
"/photoprism/storage/media/originals",
"/photoprism/media/originals",
"/photoprism/originals",
"/opt/photoprism/storage/media/originals",
"/opt/photoprism/media/originals",
"/opt/photoprism/originals",
"/media/originals",
"/storage/originals",
"/originals",
"media/originals",
"storage/originals",
"photoprism/originals",
"PhotoPrism/Originals",
"photoprism/original",
"PhotoPrism/Original",
"pictures/originals",
"Pictures/Originals",
"pictures/original",
"Pictures/Original",
"photos/originals",
"Photos/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/lib/photoprism/originals",
}
var ImportPaths = []string{
"/photoprism/storage/media/import",
"/photoprism/media/import",
"/photoprism/import",
"/opt/photoprism/storage/media/import",
"/opt/photoprism/media/import",
"/opt/photoprism/import",
"/media/import",
"/storage/import",
"/import",
"media/import",
"storage/import",
"photoprism/import",
"PhotoPrism/Import",
"pictures/import",
"Pictures/Import",
"photos/import",
"Photos/Import",
"import",
"Import",
"~/pictures/import",
"~/Pictures/Import",
"~/photoprism/import",
"~/PhotoPrism/Import",
"~/photos/import",
"~/Photos/Import",
"~/import",
"~/Import",
"/var/lib/photoprism/import",
}
var AssetPaths = []string{
"/opt/photoprism/assets",
"/photoprism/assets",
"~/.photoprism/assets",
"~/photoprism/assets",
"photoprism/assets",
"assets",
"/var/lib/photoprism/assets",
}
// 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{}
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)
}
// Ignore hidden folders as well as those listed in an optional ".ppignore" file.
ignore := NewIgnoreList(IgnoreFile, true, false)
_ = ignore.Dir(root)
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
}
// Skip if symlink does not point to existing directory.
if typ == os.ModeSymlink {
if info, err := os.Stat(fileName); err != nil || !info.IsDir() {
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 := Resolve(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 ""
}