/
files.go
100 lines (86 loc) · 2.43 KB
/
files.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
package http
import (
"bytes"
"crypto/sha1"
"encoding/hex"
"fmt"
"strings"
"github.com/Laisky/errors/v2"
gmw "github.com/Laisky/gin-middlewares/v5"
"github.com/Laisky/zap"
"github.com/gin-gonic/gin"
"github.com/minio/minio-go/v7"
"github.com/Laisky/go-ramjet/internal/tasks/gptchat/config"
"github.com/Laisky/go-ramjet/internal/tasks/gptchat/s3"
)
// UploadFiles upload files
func UploadFiles(ctx *gin.Context) {
logger := gmw.GetLogger(ctx)
user, err := getUserByAuthHeader(ctx)
if AbortErr(ctx, err) {
return
}
if user.IsFree {
AbortErr(ctx, errors.New("free user cannot upload files. "+
"you need upgrade to a paid membership, "+
"more info at https://wiki.laisky.com/projects/gpt/pay/cn/"))
return
}
// err = checkUserExternalBilling(ctx, user, db.PriceUploadFile, "upload file")
// if AbortErr(ctx, errors.Wrap(err, "check user external billing")) {
// return
// }
file, err := ctx.FormFile("file")
if AbortErr(ctx, errors.Wrap(err, "get file from form")) {
return
}
if file.Size > int64(config.Config.LimitUploadFileBytes) {
AbortErr(ctx, errors.Errorf("file size should not exceed %d bytes",
config.Config.LimitUploadFileBytes))
return
}
ext := ctx.PostForm("file_ext")
if ext == "" {
AbortErr(ctx, errors.New("should set file extension by `ext`"))
return
} else if !strings.HasPrefix(ext, ".") {
AbortErr(ctx, errors.New("file extension should start with dot"))
return
}
fileContent, err := file.Open()
if AbortErr(ctx, errors.Wrap(err, "open file")) {
return
}
var buf bytes.Buffer
_, err = buf.ReadFrom(fileContent)
if AbortErr(ctx, errors.Wrap(err, "read file content")) {
return
}
fileBytes := buf.Bytes()
fileHashBytes := sha1.Sum(fileBytes)
fileHash := hex.EncodeToString(fileHashBytes[:])
objkeyPrefix := fmt.Sprintf("user-files/%s/%s/%s",
fileHash[:2], fileHash[2:4], fileHash)
s3cli := s3.GetCli()
_, err = s3cli.PutObject(ctx,
config.Config.S3.Bucket,
objkeyPrefix+ext,
bytes.NewReader(fileBytes),
int64(len(fileBytes)),
minio.PutObjectOptions{
ContentType: "application/octet-stream",
},
)
if AbortErr(ctx, errors.Wrap(err, "upload file")) {
return
}
logger.Info("upload file success",
zap.String("user", user.UserName),
zap.String("file", file.Filename),
zap.String("ext", ext),
zap.String("objkey", objkeyPrefix+ext),
)
ctx.JSON(200, gin.H{
"url": fmt.Sprintf("https://s3.laisky.com/%s/%s", config.Config.S3.Bucket, objkeyPrefix+ext),
})
}