-
Notifications
You must be signed in to change notification settings - Fork 5
/
upload.go
162 lines (136 loc) · 3.14 KB
/
upload.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
package gitdb
import (
"errors"
"fmt"
"io"
"os"
"path"
"path/filepath"
"strings"
)
const uploadDataset = "Bucket"
var validExtensions = map[string]bool{
".html": true,
".pdf": true,
".doc": true,
".xlsx": true,
".csv": true,
".jpg": true,
".gif": true,
".png": true,
".svg": true,
".json": true,
".yaml": true,
".yml": true,
".md": true,
}
//UploadModel represents a file upload
type UploadModel struct {
Bucket string
File string
Path string
UploadedBy string
TimeStampedModel
}
//GetSchema implements Model.GetSchema
func (u *UploadModel) GetSchema() *Schema {
return newSchema(
uploadDataset,
// AutoBlock(u.db.dbDir(), name, BlockByCount, 1000),
u.Bucket,
u.File,
make(map[string]interface{}),
)
}
//Validate implements Model.Validate
func (u *UploadModel) Validate() error {
//todo
return nil
}
func (U *UploadModel) ShouldEncrypt() bool { return false }
//Upload provides API for managing file uploads
type Upload struct {
db *gitdb
model *UploadModel
}
//Get returns an upload by id
func (u *Upload) Get(id string, result *UploadModel) error {
return u.db.Get(id, result)
}
//Delete an upload by id
func (u *Upload) Delete(id string) error {
var data UploadModel
if err := u.Get(id, &data); err != nil {
return err
}
err := u.db.Delete(id)
if err == nil {
err = os.Remove(data.Path)
}
return err
}
//New uploads specified file into bucket
func (u *Upload) New(bucket, file string) error {
err := u.db.Exists(u.id(bucket, file))
if err == nil {
return errors.New("file already exists")
}
return u.upload(bucket, file)
}
//Replace overrides a specified file in bucket
func (u *Upload) Replace(bucket, file string) error {
err := u.db.Exists(u.id(bucket, file))
if err != nil {
return err
}
return u.upload(bucket, file)
}
func (u *Upload) id(bucket, file string) string {
return uploadDataset + "/" + bucket + "/" + u.cleanFileName(file)
}
func (u *Upload) cleanFileName(filename string) string {
//todo a better func to clean up filenames
filename = strings.ReplaceAll(path.Clean(filename), "/", "-")
filename = strings.ReplaceAll(filename, " ", "-")
return filename
}
func (u *Upload) upload(bucket, file string) error {
var src *os.File
var dst *os.File
var err error
if src, err = os.Open(file); err != nil {
return err
}
ext := filepath.Ext(file)
if _, ok := validExtensions[ext]; !ok {
return fmt.Errorf("%s files are not allowed", ext)
}
filename := u.cleanFileName(file)
uploadPath := filepath.Join(u.db.dbDir(), uploadDataset, bucket, filename)
fmt.Println(uploadPath)
if err = os.MkdirAll(path.Dir(uploadPath), os.ModePerm); err != nil {
return err
}
if dst, err = os.Create(uploadPath); err != nil {
return err
}
if _, err = io.Copy(dst, src); err != nil {
return err
}
//neutralise file
if err = dst.Chmod(0640); err != nil {
return err
}
//Uploads/b0/bucket-file.jpg
m := &UploadModel{
Bucket: bucket,
File: filename,
Path: uploadPath,
UploadedBy: u.db.config.User.String(),
}
return u.db.Insert(m)
}
func (g *gitdb) Upload() *Upload {
g.RegisterModel(uploadDataset, &UploadModel{})
return &Upload{db: g}
}