package fs import ( "errors" "git.giftfish.de/ston1th/docstore/pkg/core" "os" "path/filepath" "sort" "strings" ) const ( DirMode = 0750 FileMode = 0640 ) // Directory represents a directory and its contents type Directory struct { Dirs core.Paths Files core.Paths } type Filesystem struct { Base string } func NewFilesystem(base string) (fs *Filesystem, err error) { fi, err := os.Stat(base) if err != nil { return } if !fi.IsDir() { err = errors.New("base dir '" + base + "' is not a directory") } fs = &Filesystem{base} return } func (fs *Filesystem) ReadDir(path string) (d *Directory) { path = Clean(path) combined := filepath.Join(fs.Base, path) f, err := os.Open(combined) if err != nil { return } names, err := f.Readdirnames(0) if err != nil { return } d = new(Directory) for _, n := range names { fi, err := os.Stat(filepath.Join(combined, n)) if err != nil { continue } m := fi.Mode() if m.IsDir() { d.Dirs = append(d.Dirs, core.Path{Name: n, Abs: filepath.Join(path, n)}) continue } if m.IsRegular() { d.Files = append(d.Files, core.Path{Name: n, Abs: filepath.Join(path, n)}) } } sort.Sort(d.Dirs) sort.Sort(d.Files) return } func (fs *Filesystem) Recursive(p string) (paths core.Paths) { p = Clean(p) p, _ = filepath.Split(p) if len(p) >= 2 { p = p[:len(p)-1] } filepath.Walk(fs.Base, func(path string, info os.FileInfo, err error) error { if err != nil { return nil } if info.IsDir() { a := strings.TrimPrefix(path, fs.Base) if a == "" { a = "/" } paths = append(paths, core.Path{Abs: a, Flag: a == p}) } return nil }) sort.Sort(paths) return } func (fs *Filesystem) RecursiveFiles(p string) (files []string) { p = Clean(p) fullpath := filepath.Join(fs.Base, p) filepath.Walk(fullpath, func(path string, info os.FileInfo, err error) error { if err != nil { return nil } if info.Mode().IsRegular() { files = append(files, strings.TrimPrefix(path, fullpath)) } return nil }) return } func Paths(path string) (p core.Paths) { path = Clean(path) s := strings.Split(path, string(filepath.Separator)) for i, v := range s[1:] { if v == "" { continue } if i == 0 { p = append(p, core.Path{Name: v, Abs: "/" + v}) continue } p = append(p, core.Path{Name: v, Abs: filepath.Join(p[i-1].Abs, v)}) } if len(p) != 0 { p[len(p)-1].Flag = true } return }