-
Notifications
You must be signed in to change notification settings - Fork 0
/
paths.go
127 lines (107 loc) · 2.59 KB
/
paths.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"code.cloudfoundry.org/bytefmt"
"encoding/base64"
"errors"
"io/ioutil"
"log"
"os"
"path"
"sort"
"strings"
"time"
)
type FileID string
type Path struct {
ID FileID
Path string
Name string
ModTime time.Time
Size int64
DisplaySize string
IsDir bool
Status Status
}
type Status string
const (
StatusUnknown Status = "unknown"
StatusError Status = "error"
StatusReady Status = "ready"
StatusPending Status = "pending"
StatusInProgress Status = "inprogress"
StatusDone Status = "done"
)
func NewPath(file os.FileInfo, dirPath string) (*Path, error) {
fulPath := path.Clean(dirPath + string(os.PathSeparator) + file.Name())
relPath := fulPath[len(settings.LocalRoot):]
fileID := FileID(base64.RawURLEncoding.EncodeToString([]byte(relPath)))
status, err := getFileStatus(fileID)
if err != nil {
return nil, err
}
p := &Path{
ID: fileID,
Path: fulPath,
Name: file.Name(),
ModTime: file.ModTime().In(getLocTime()),
Size: file.Size(),
DisplaySize: bytefmt.ByteSize(uint64(file.Size())),
IsDir: file.IsDir(),
Status: status,
}
return p, nil
}
func getPath(relPath string) (*Path, error) {
rootPath := path.Clean(settings.LocalRoot)
fulPath := path.Clean(rootPath + string(os.PathSeparator) + relPath)
fileInfo, err := os.Stat(fulPath)
if err != nil {
return nil, err
}
return NewPath(fileInfo, path.Dir(fulPath))
}
func listPaths(dirPath string) ([]*Path, error) {
dirPath = path.Clean(dirPath)
if strings.Contains(dirPath, settings.LocalRoot) == false {
log.Printf("Target Path: %s", dirPath)
return nil, errors.New("path outside of defined root")
}
fileInfoArr, err := ioutil.ReadDir(dirPath)
if err != nil {
return nil, err
}
var pathArr []*Path
for _, file := range fileInfoArr {
pathSt, err := NewPath(file, dirPath)
if err != nil {
return nil, err
}
pathArr = append(pathArr, pathSt)
}
sort.Slice(pathArr, func(i, j int) bool {
iDate := makeSortKey(pathArr[i])
jDate := makeSortKey(pathArr[j])
if iDate == jDate {
// dates are equal, sort Name ASC
return pathArr[i].Name < pathArr[j].Name
}
// sort Date DESC
return iDate > jDate
})
return pathArr, nil
}
func makeSortKey(path *Path) string {
return path.ModTime.Format("20060102")
}
var locTime *time.Location
func getLocTime() *time.Location {
if locTime != nil {
return locTime
}
loc, err := time.LoadLocation(settings.LocalTime)
if err != nil {
log.Fatalf("Unable to local time location: %v", err)
}
locTime = loc
return locTime
}