package dir import ( "io/fs" "os" "path" "path/filepath" "strings" "time" ) type Directory struct { Name string `json:"name" xml:"name" text:"Name"` Path string `json:"path" xml:"path" text:"Path"` Date string `json:"date" xml:"date" text:"Date"` Parent string `json:"parent" xml:"parent" text:"Parent"` Files []File `json:"files" xml:"files>file" text:"Files"` } type File struct { Name string `json:"name" xml:"name" text:"Name"` Date string `json:"date" xml:"date" text:"Date"` Path string `json:"path" xml:"path" text:"Path"` Kind string `json:"kind" xml:"kind" text:"Kind"` IsDir bool `json:"isDir" xml:"isdir" text:"Directory"` } func Read(startPath string, handle func(interface{})) error { err := filepath.WalkDir(startPath, func(fpath string, d fs.DirEntry, err error) error { if err != nil { return err } if d.IsDir() { dirInfo, err := os.Stat(fpath) if err != nil { return err } dir := Directory{ Name: filepath.Base(fpath), Path: fpath, Date: dirInfo.ModTime().Format(time.RFC3339), Files: []File{}, Parent: path.Dir(fpath), } // Populate files and subdirectories within the current directory entries, err := os.ReadDir(fpath) if err != nil { return err } for _, entry := range entries { entryPath := filepath.Join(fpath, entry.Name()) info, err := entry.Info() if err != nil { // Log the error but continue processing other entries println("Error getting info for:", entryPath, "-", err.Error()) continue } file := File{ Name: entry.Name(), Date: info.ModTime().Format(time.RFC3339), Path: entryPath, IsDir: entry.IsDir(), } if !entry.IsDir() { file.Kind = getFileKind(entryPath) } else { file.Kind = "directory" } dir.Files = append(dir.Files, file) } handle(dir) } return nil }) if err != nil { return err } return nil } func getFileKind(path string) string { ext := filepath.Ext(path) if ext != "" { return strings.TrimPrefix(ext, ".") } return "unknown" }