forked from dundee/gdu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimport.go
109 lines (95 loc) · 2.31 KB
/
import.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package report
import (
"bytes"
"encoding/json"
"errors"
"io"
"strings"
"time"
"github.com/dundee/gdu/v5/pkg/analyze"
)
// ReadAnalysis reads analysis report from JSON file and returns directory item
func ReadAnalysis(input io.Reader) (*analyze.Dir, error) {
var data interface{}
var buff bytes.Buffer
if _, err := buff.ReadFrom(input); err != nil {
return nil, err
}
if err := json.Unmarshal(buff.Bytes(), &data); err != nil {
return nil, err
}
dataArray, ok := data.([]interface{})
if !ok {
return nil, errors.New("JSON file does not contain top level array")
}
if len(dataArray) < 4 {
return nil, errors.New("Top level array must have at least 4 items")
}
items, ok := dataArray[3].([]interface{})
if !ok {
return nil, errors.New("Array of maps not found in the top level array on 4th position")
}
return processDir(items)
}
func processDir(items []interface{}) (*analyze.Dir, error) {
dir := &analyze.Dir{
File: &analyze.File{
Flag: ' ',
},
}
dirMap, ok := items[0].(map[string]interface{})
if !ok {
return nil, errors.New("Directory item is not a map")
}
name, ok := dirMap["name"].(string)
if !ok {
return nil, errors.New("Directory name is not a string")
}
if mtime, ok := dirMap["mtime"].(float64); ok {
dir.Mtime = time.Unix(int64(mtime), 0)
}
slashPos := strings.LastIndex(name, "/")
if slashPos > -1 {
dir.Name = name[slashPos+1:]
dir.BasePath = name[:slashPos+1]
} else {
dir.Name = name
}
for _, v := range items[1:] {
switch item := v.(type) {
case map[string]interface{}:
file := &analyze.File{}
file.Name = item["name"].(string)
if asize, ok := item["asize"].(float64); ok {
file.Size = int64(asize)
}
if dsize, ok := item["dsize"].(float64); ok {
file.Usage = int64(dsize)
}
if mtime, ok := item["mtime"].(float64); ok {
file.Mtime = time.Unix(int64(mtime), 0)
}
if _, ok := item["notreg"].(bool); ok {
file.Flag = '@'
} else {
file.Flag = ' '
}
if mli, ok := item["ino"].(float64); ok {
file.Mli = uint64(mli)
}
if _, ok := item["hlnkc"].(bool); ok {
file.Flag = 'H'
}
file.Parent = dir
dir.Files.Append(file)
case []interface{}:
subdir, err := processDir(item)
if err != nil {
return nil, err
}
subdir.Parent = dir
dir.Files.Append(subdir)
}
}
return dir, nil
}