-
Notifications
You must be signed in to change notification settings - Fork 5
/
localTempHandler.go
196 lines (155 loc) · 4.06 KB
/
localTempHandler.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package attachment
import (
"errors"
"github.com/Scribblerockerz/cryptletter/pkg/utils"
"io/fs"
"io/ioutil"
"os"
"path"
"path/filepath"
)
type localTempHandler struct {
list utils.DismissiveList
defaultTTL int64
storagePath string
}
func (l localTempHandler) getStorageDir() (string, error) {
storagePath := l.storagePath
if !path.IsAbs(storagePath) {
storagePath, _ = filepath.Abs(path.Join(utils.GetConfigRootDir(), storagePath))
}
stat, err := os.Stat(storagePath)
if os.IsNotExist(err) {
err = os.Mkdir(l.storagePath, 0755)
return "", err
}
if !stat.IsDir() {
return "", errors.New("storage directory can not be a file")
}
return storagePath, nil
}
//Put will place data into the storage directory
func (l localTempHandler) Put(fileData string) (string, error) {
storageDir, err := l.getStorageDir()
if err != nil {
return "", err
}
tmpFile, err := ioutil.TempFile(storageDir, "att-")
if err != nil {
return "", err
}
defer tmpFile.Close()
if _, err = tmpFile.Write([]byte(fileData)); err != nil {
return "", errors.New("failed to write to temporary file")
}
identifier := path.Base(tmpFile.Name())
// Add file to the list of tracked resources
err = l.list.Add(identifier, l.defaultTTL)
if err != nil {
return "", err
}
return identifier, nil
}
//Get will retrieve file data by a given identifier
func (l localTempHandler) Get(identifier string) (string, error) {
// Add file to the list of tracked resources
if !l.list.Has(identifier) {
return "", errors.New("unable to read file by identifier")
}
storageDir, err := l.getStorageDir()
if err != nil {
return "", err
}
filePath := path.Join(storageDir, identifier)
data, err := ioutil.ReadFile(filePath)
if err != nil {
return "", errors.New("unable to read file by identifier")
}
return string(data), nil
}
//Delete will remove stored files by identifier
func (l localTempHandler) Delete(identifier string) error {
// Delete identifier from tracked resources
l.list.Del(identifier)
storageDir, err := l.getStorageDir()
if err != nil {
return err
}
filePath := path.Join(storageDir, identifier)
_, err = os.Stat(filePath)
if os.IsNotExist(err) {
return nil
}
err = os.Remove(filePath)
if err != nil {
return errors.New("unable to remove file by identifier")
}
return nil
}
//SetTTL will update the TTL of an identifier
func (l localTempHandler) SetTTL(identifier string, ttl int64) error {
return l.list.Set(identifier, ttl)
}
//Cleanup will sync the known file identifiers with the unknown and clean them up
func (l localTempHandler) Cleanup() error {
// Get storage directory
// Get all known files from the list.All()
// Iterate over the storage directory and remove everything which is not on the list.All()
trackedIdentifier, err := l.list.All()
if err != nil {
return err
}
storageDir, err := l.getStorageDir()
if err != nil {
return err
}
err = filepath.WalkDir(storageDir, func(p string, info fs.DirEntry, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
if utils.ListContainsString(trackedIdentifier, info.Name()) {
return nil
}
err = os.Remove(path.Join(storageDir, info.Name()))
if err != nil {
return errors.New("unable to remove timed out file " + info.Name())
}
return nil
})
return nil
}
//DropAll will clear the storage dir and the list
func (l localTempHandler) DropAll() error {
storageDir, err := l.getStorageDir()
if err != nil {
return err
}
_, err = os.Stat(storageDir)
if !os.IsNotExist(err) {
err = os.Remove(storageDir)
if err != nil {
return err
}
}
return l.list.Drp()
}
//ListTimetable will list all known entries from the dismissive list
func (l localTempHandler) ListTimetable() ([]string, error) {
return l.list.All()
}
const (
LocalHostType = "local"
)
func (l localTempHandler) HostType() string {
return LocalHostType
}
func NewLocalTempHandler(defaultTTL int64, storagePath string) Handler {
return &localTempHandler{
list: utils.NewDismissiveList("local-files"),
defaultTTL: defaultTTL,
storagePath: storagePath,
}
}