5ec90a5fff
Signed-off-by: Michael Mayer <michael@photoprism.app>
193 lines
3.9 KiB
Go
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 ""
|
|
}
|