Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/op/label_file_binding.go
1560 views
1
package op
2
3
import (
4
"fmt"
5
"github.com/alist-org/alist/v3/internal/db"
6
"github.com/alist-org/alist/v3/internal/model"
7
"github.com/pkg/errors"
8
"strconv"
9
"strings"
10
"time"
11
)
12
13
type CreateLabelFileBinDingReq struct {
14
Id string `json:"id"`
15
Path string `json:"path"`
16
Name string `json:"name"`
17
Size int64 `json:"size"`
18
IsDir bool `json:"is_dir"`
19
Modified time.Time `json:"modified"`
20
Created time.Time `json:"created"`
21
Sign string `json:"sign"`
22
Thumb string `json:"thumb"`
23
Type int `json:"type"`
24
HashInfoStr string `json:"hashinfo"`
25
LabelIds string `json:"label_ids"`
26
LabelIDs []uint64 `json:"labelIdList"`
27
}
28
29
type ObjLabelResp struct {
30
Id string `json:"id"`
31
Path string `json:"path"`
32
Name string `json:"name"`
33
Size int64 `json:"size"`
34
IsDir bool `json:"is_dir"`
35
Modified time.Time `json:"modified"`
36
Created time.Time `json:"created"`
37
Sign string `json:"sign"`
38
Thumb string `json:"thumb"`
39
Type int `json:"type"`
40
HashInfoStr string `json:"hashinfo"`
41
LabelList []model.Label `json:"label_list"`
42
}
43
44
func GetLabelByFileName(userId uint, fileName string) ([]model.Label, error) {
45
labelIds, err := db.GetLabelIds(userId, fileName)
46
if err != nil {
47
return nil, errors.WithMessage(err, "failed get label_file_binding")
48
}
49
var labels []model.Label
50
if len(labelIds) > 0 {
51
if labels, err = db.GetLabelByIds(labelIds); err != nil {
52
return nil, errors.WithMessage(err, "failed labels in database")
53
}
54
}
55
return labels, nil
56
}
57
58
func GetLabelsByFileNamesPublic(fileNames []string) (map[string][]model.Label, error) {
59
return db.GetLabelsByFileNamesPublic(fileNames)
60
}
61
62
func CreateLabelFileBinDing(req CreateLabelFileBinDingReq, userId uint) error {
63
if err := db.DelLabelFileBinDingByFileName(userId, req.Name); err != nil {
64
return errors.WithMessage(err, "failed del label_file_bin_ding in database")
65
}
66
67
ids, err := collectLabelIDs(req)
68
if err != nil {
69
return err
70
}
71
if len(ids) == 0 {
72
return nil
73
}
74
75
for _, id := range ids {
76
if err = db.CreateLabelFileBinDing(req.Name, uint(id), userId); err != nil {
77
return errors.WithMessage(err, "failed labels in database")
78
}
79
}
80
81
if !db.GetFileByNameExists(req.Name) {
82
objFile := model.ObjFile{
83
Id: req.Id,
84
UserId: userId,
85
Path: req.Path,
86
Name: req.Name,
87
Size: req.Size,
88
IsDir: req.IsDir,
89
Modified: req.Modified,
90
Created: req.Created,
91
Sign: req.Sign,
92
Thumb: req.Thumb,
93
Type: req.Type,
94
HashInfoStr: req.HashInfoStr,
95
}
96
if err := db.CreateObjFile(objFile); err != nil {
97
return errors.WithMessage(err, "failed file in database")
98
}
99
}
100
return nil
101
}
102
103
func GetFileByLabel(userId uint, labelId string) (result []ObjLabelResp, err error) {
104
labelMap := strings.Split(labelId, ",")
105
var labelIds []uint
106
var labelsFile []model.LabelFileBinding
107
var labels []model.Label
108
var labelsFileMap = make(map[string][]model.Label)
109
var labelsMap = make(map[uint]model.Label)
110
if labelIds, err = StringSliceToUintSlice(labelMap); err != nil {
111
return nil, errors.WithMessage(err, "failed string to uint err")
112
}
113
//查询标签信息
114
if labels, err = db.GetLabelByIds(labelIds); err != nil {
115
return nil, errors.WithMessage(err, "failed labels in database")
116
}
117
for _, val := range labels {
118
labelsMap[val.ID] = val
119
}
120
//查询标签对应文件名列表
121
if labelsFile, err = db.GetLabelFileBinDingByLabelId(labelIds, userId); err != nil {
122
return nil, errors.WithMessage(err, "failed labels in database")
123
}
124
for _, value := range labelsFile {
125
var labelTemp model.Label
126
labelTemp = labelsMap[value.LabelId]
127
labelsFileMap[value.FileName] = append(labelsFileMap[value.FileName], labelTemp)
128
}
129
for index, v := range labelsFileMap {
130
objFile, err := db.GetFileByName(index, userId)
131
if err != nil {
132
return nil, errors.WithMessage(err, "failed GetFileByName in database")
133
}
134
objLabel := ObjLabelResp{
135
Id: objFile.Id,
136
Path: objFile.Path,
137
Name: objFile.Name,
138
Size: objFile.Size,
139
IsDir: objFile.IsDir,
140
Modified: objFile.Modified,
141
Created: objFile.Created,
142
Sign: objFile.Sign,
143
Thumb: objFile.Thumb,
144
Type: objFile.Type,
145
HashInfoStr: objFile.HashInfoStr,
146
LabelList: v,
147
}
148
result = append(result, objLabel)
149
}
150
return result, nil
151
}
152
153
func StringSliceToUintSlice(strSlice []string) ([]uint, error) {
154
uintSlice := make([]uint, len(strSlice))
155
for i, str := range strSlice {
156
// 使用strconv.ParseUint将字符串转换为uint64
157
uint64Value, err := strconv.ParseUint(str, 10, 64)
158
if err != nil {
159
return nil, err // 如果转换失败,返回错误
160
}
161
// 将uint64值转换为uint(注意:这里可能存在精度损失,如果uint64值超出了uint的范围)
162
uintSlice[i] = uint(uint64Value)
163
}
164
return uintSlice, nil
165
}
166
167
func RestoreLabelFileBindings(bindings []model.LabelFileBinding, keepIDs bool, override bool) error {
168
return db.RestoreLabelFileBindings(bindings, keepIDs, override)
169
}
170
171
func collectLabelIDs(req CreateLabelFileBinDingReq) ([]uint64, error) {
172
if len(req.LabelIDs) > 0 {
173
return req.LabelIDs, nil
174
}
175
s := strings.TrimSpace(req.LabelIds)
176
if s == "" {
177
return nil, nil
178
}
179
replacer := strings.NewReplacer(",", ",", "、", ",", ";", ",", ";", ",")
180
s = replacer.Replace(s)
181
parts := strings.Split(s, ",")
182
ids := make([]uint64, 0, len(parts))
183
for _, p := range parts {
184
p = strings.TrimSpace(p)
185
if p == "" {
186
continue
187
}
188
id, err := strconv.ParseUint(p, 10, 64)
189
if err != nil {
190
return nil, fmt.Errorf("invalid label ID '%s': %v", p, err)
191
}
192
ids = append(ids, id)
193
}
194
return ids, nil
195
}
196
197