-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocal.go
149 lines (111 loc) · 2.88 KB
/
local.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
package filesystem
import (
"errors"
"io"
"io/ioutil"
"os"
"path/filepath"
)
// Local represents the configuration
// for the local filesystem
type Local struct {
Path string
}
// Validate implementation of the Configurable interface
func (l *Local) Validate() error {
if len(l.Path) == 0 {
return errors.New("path cannot be empty")
}
return nil
}
// Name implementation of the Configurable interface
func (l *Local) Name() string {
return "local"
}
type local struct {
path string
streamFile *os.File
streamChannel chan string
}
// Init implementation of the Configurable interface
func (l *local) Init(configuration Configurable) (Storeable, error) {
config := configuration.(*Local)
l.path = config.Path
return l, nil
}
// Put implementation of the Storeable interface
func (l *local) Put(name string, reader io.Reader) error {
path := filepath.Join(l.path, filepath.FromSlash(name))
if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
return err
}
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, reader)
return err
}
// List implementation of the Storeable interface
func (l *local) List(name string) ([]string, error) {
dirs, err := ioutil.ReadDir(filepath.Join(l.path, filepath.FromSlash(name)))
if err != nil {
return nil, err
}
names := []string{}
for _, dir := range dirs {
names = append(names, dir.Name())
}
return names, nil
}
// Open implementation of the Storeable interface
func (l *local) Open(name string) (io.Reader, error) {
return os.Open(filepath.Join(l.path, filepath.FromSlash(name)))
}
// OpenStream implementation of the Storeable interface
func (l *local) OpenStream(name string) error {
path := filepath.Join(l.path, filepath.FromSlash(name))
if err := os.MkdirAll(filepath.Dir(path), 0777); err != nil {
return err
}
file, err := os.Create(path)
if err != nil {
return err
}
l.streamFile = file
l.streamChannel = make(chan string)
return nil
}
// Stream implementation of the Storeable interface
func (l *local) Stream() error {
if l.streamFile == nil || l.streamChannel == nil {
return errors.New("please open a stream")
}
for line := range l.streamChannel {
n, err := l.streamFile.Write([]byte(line))
if err != nil {
return err
}
if n != len(line) {
return errors.New("failed to write data")
}
}
return nil
}
// Channel implementation of the Storeable interface
func (l *local) Channel(data string) {
l.streamChannel <- data
}
// Remove implementation of the Storeable interface
func (l *local) Remove(name string) error {
return os.Remove(filepath.Join(l.path, filepath.FromSlash(name)))
}
// Close implementation of the Storeable interface
func (l *local) Close() error {
if l.streamFile == nil || l.streamChannel == nil {
return errors.New("please open a stream")
}
close(l.streamChannel)
return l.streamFile.Close()
}