-
-
Notifications
You must be signed in to change notification settings - Fork 620
/
fs.go
103 lines (85 loc) · 2.37 KB
/
fs.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
package fs
import (
"io/ioutil"
"net/http"
"os"
"path"
"path/filepath"
"strconv"
"github.com/getfider/fider/app/models"
"github.com/getfider/fider/app/pkg/blob"
"github.com/getfider/fider/app/pkg/errors"
)
var perm os.FileMode = 0744
var _ blob.Storage = (*Storage)(nil)
// Storage stores blobs on FileSystem
type Storage struct {
path string
tenant *models.Tenant
}
// NewStorage creates a new FileSystem Storage
func NewStorage(path string) *Storage {
err := os.MkdirAll(path, perm)
if err != nil {
panic(errors.Wrap(err, "failed to create path '%s'", path))
}
return &Storage{
path: path,
}
}
// SetCurrentTenant to current context
func (s *Storage) SetCurrentTenant(tenant *models.Tenant) {
s.tenant = tenant
}
func (s *Storage) keyFullPath(key string) string {
if s.tenant != nil {
return path.Join(s.path, "tenants", strconv.Itoa(s.tenant.ID), key)
}
return path.Join(s.path, key)
}
// Get returns a blob with given key
func (s *Storage) Get(key string) (*blob.Blob, error) {
fullPath := s.keyFullPath(key)
stats, err := os.Stat(fullPath)
if err != nil {
if os.IsNotExist(err) {
return nil, blob.ErrNotFound
}
return nil, errors.Wrap(err, "failed to get stats '%s' from FileSystem", key)
}
file, err := ioutil.ReadFile(fullPath)
if err != nil {
return nil, errors.Wrap(err, "failed to get read '%s' from FileSystem", key)
}
return &blob.Blob{
Key: key,
Size: stats.Size(),
ContentType: http.DetectContentType(file),
Object: file,
}, nil
}
// Delete a blob with given key
func (s *Storage) Delete(key string) error {
fullPath := s.keyFullPath(key)
err := os.Remove(fullPath)
if err != nil && !os.IsNotExist(err) {
return errors.Wrap(err, "failed to delete file '%s' from FileSystem", key)
}
return nil
}
// Put a blob with given key and content. Blobs with same key are replaced.
func (s *Storage) Put(key string, content []byte, contentType string) error {
if err := blob.ValidateKey(key); err != nil {
return errors.Wrap(err, "failed to validate blob key '%s'", key)
}
fullPath := s.keyFullPath(key)
err := os.MkdirAll(filepath.Dir(fullPath), perm)
if err != nil {
return errors.Wrap(err, "failed to create folder '%s' on FileSystem", fullPath)
}
err = ioutil.WriteFile(fullPath, content, perm)
if err != nil {
return errors.Wrap(err, "failed to create file '%s' on FileSystem", fullPath)
}
return nil
}