Initial DDC release
This commit is contained in:
commit
434f6441da
57 files changed
+4606
No files matched your search
Executable
+85
@@ -0,0 +1,85 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"ddc/internal/extract"
|
||||
)
|
||||
|
||||
const (
|
||||
maxTreeEntries = 20000
|
||||
maxTreeDepth = 32
|
||||
)
|
||||
|
||||
type Node struct {
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
IsDir bool `json:"isDir"`
|
||||
IsArchive bool `json:"isArchive"`
|
||||
Size int64 `json:"size"`
|
||||
Children []Node `json:"children,omitempty"`
|
||||
}
|
||||
|
||||
func BuildTree(root string) ([]Node, error) {
|
||||
entryCount := 0
|
||||
return readLevel(root, "", 0, &entryCount)
|
||||
}
|
||||
|
||||
func readLevel(root, relative string, depth int, entryCount *int) ([]Node, error) {
|
||||
entries, err := os.ReadDir(filepath.Join(root, relative))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodes := make([]Node, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
if *entryCount >= maxTreeEntries {
|
||||
break
|
||||
}
|
||||
entryType := entry.Type()
|
||||
if entry.Name() == PartFileName || (!entryType.IsDir() && !entryType.IsRegular()) {
|
||||
continue
|
||||
}
|
||||
*entryCount++
|
||||
|
||||
node := Node{
|
||||
Name: entry.Name(),
|
||||
Path: path.Join(filepath.ToSlash(relative), entry.Name()),
|
||||
IsDir: entry.IsDir(),
|
||||
}
|
||||
|
||||
if node.IsDir {
|
||||
if depth < maxTreeDepth {
|
||||
children, err := readLevel(root, filepath.Join(relative, entry.Name()), depth+1, entryCount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node.Children = children
|
||||
for _, child := range children {
|
||||
node.Size += child.Size
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info, err := entry.Info()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
node.Size = info.Size()
|
||||
node.IsArchive = extract.IsArchive(entry.Name())
|
||||
}
|
||||
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
|
||||
sort.SliceStable(nodes, func(first, second int) bool {
|
||||
if nodes[first].IsDir != nodes[second].IsDir {
|
||||
return nodes[first].IsDir
|
||||
}
|
||||
return strings.ToLower(nodes[first].Name) < strings.ToLower(nodes[second].Name)
|
||||
})
|
||||
return nodes, nil
|
||||
}
|
||||
Reference in new issue
Block a user