package filesystem import ( "fmt" "io/fs" "os" "path/filepath" "github.com/op/go-logging" ) var log = logging.MustGetLogger("mediasrv-server") type File struct { Path string `json:"path"` Name string `json:"name"` } type Dir struct { Path string `json:"path"` Name string `json:"name"` SubDirs []Dir `json:"subDirs,omitempty"` SubFiles []File `json:"subFiles,omitempty"` } func printDir(d Dir, offset int) { for i := 0; i < offset; i++ { fmt.Print(" ") } fmt.Printf("%v\n", d.Name) for _, subFile := range d.SubFiles { for i := 0; i < offset+1; i++ { fmt.Print(" ") } fmt.Printf("%v\n", subFile.Name) } for _, subDir := range d.SubDirs { printDir(subDir, offset+1) } } func GetFilesystem(dir string) (Dir, error) { var err error root := Dir{ Path: dir, Name: filepath.Base(dir), } currentDir := &root dirStack := make([]*Dir, 1000) subStack := make([][]fs.DirEntry, 1000) ind := 0 outer: for { var subDirs []fs.DirEntry if len(currentDir.SubDirs) > 0 { subDirs = subStack[ind] } else { subDirs, err = os.ReadDir(currentDir.Path) if err != nil { return Dir{}, err } } for i, subDir := range subDirs { subPath := filepath.Join(currentDir.Path, subDir.Name()) if subDir.IsDir() { dirStack[ind] = currentDir subStack[ind] = subDirs[i+1:] ind++ newDir := Dir{ Path: subPath, Name: subDir.Name(), } currentDir.SubDirs = append(currentDir.SubDirs, newDir) currentDir = ¤tDir.SubDirs[len(currentDir.SubDirs)-1] continue outer } else { currentDir.SubFiles = append(currentDir.SubFiles, File{ Path: subPath, Name: subDir.Name(), }) } } if ind == 0 { break } ind-- currentDir = dirStack[ind] } //printDir(root, 0) return root, nil }