110 lines
2.3 KiB
Go
110 lines
2.3 KiB
Go
package report
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"strings"
|
|
"time"
|
|
|
|
"b612.me/apps/b612/gdu/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.AddFile(file)
|
|
case []interface{}:
|
|
subdir, err := processDir(item)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
subdir.Parent = dir
|
|
dir.AddFile(subdir)
|
|
}
|
|
}
|
|
|
|
return dir, nil
|
|
}
|