Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/internal/op/setting.go
1560 views
1
package op
2
3
import (
4
"sort"
5
"strconv"
6
"strings"
7
"time"
8
9
"github.com/Xhofe/go-cache"
10
"github.com/alist-org/alist/v3/internal/db"
11
"github.com/alist-org/alist/v3/internal/model"
12
"github.com/alist-org/alist/v3/pkg/singleflight"
13
"github.com/alist-org/alist/v3/pkg/utils"
14
"github.com/pkg/errors"
15
)
16
17
var settingCache = cache.NewMemCache(cache.WithShards[*model.SettingItem](4))
18
var settingG singleflight.Group[*model.SettingItem]
19
var settingCacheF = func(item *model.SettingItem) {
20
settingCache.Set(item.Key, item, cache.WithEx[*model.SettingItem](time.Hour))
21
}
22
23
var settingGroupCache = cache.NewMemCache(cache.WithShards[[]model.SettingItem](4))
24
var settingGroupG singleflight.Group[[]model.SettingItem]
25
var settingGroupCacheF = func(key string, item []model.SettingItem) {
26
settingGroupCache.Set(key, item, cache.WithEx[[]model.SettingItem](time.Hour))
27
}
28
29
var settingChangingCallbacks = make([]func(), 0)
30
31
func RegisterSettingChangingCallback(f func()) {
32
settingChangingCallbacks = append(settingChangingCallbacks, f)
33
}
34
35
func SettingCacheUpdate() {
36
settingCache.Clear()
37
settingGroupCache.Clear()
38
for _, cb := range settingChangingCallbacks {
39
cb()
40
}
41
}
42
43
func GetPublicSettingsMap() map[string]string {
44
items, _ := GetPublicSettingItems()
45
pSettings := make(map[string]string)
46
for _, item := range items {
47
pSettings[item.Key] = item.Value
48
}
49
return pSettings
50
}
51
52
func GetSettingsMap() map[string]string {
53
items, _ := GetSettingItems()
54
settings := make(map[string]string)
55
for _, item := range items {
56
settings[item.Key] = item.Value
57
}
58
return settings
59
}
60
61
func GetSettingItems() ([]model.SettingItem, error) {
62
if items, ok := settingGroupCache.Get("ALL_SETTING_ITEMS"); ok {
63
return items, nil
64
}
65
items, err, _ := settingGroupG.Do("ALL_SETTING_ITEMS", func() ([]model.SettingItem, error) {
66
_items, err := db.GetSettingItems()
67
if err != nil {
68
return nil, err
69
}
70
settingGroupCacheF("ALL_SETTING_ITEMS", _items)
71
return _items, nil
72
})
73
return items, err
74
}
75
76
func GetPublicSettingItems() ([]model.SettingItem, error) {
77
if items, ok := settingGroupCache.Get("ALL_PUBLIC_SETTING_ITEMS"); ok {
78
return items, nil
79
}
80
items, err, _ := settingGroupG.Do("ALL_PUBLIC_SETTING_ITEMS", func() ([]model.SettingItem, error) {
81
_items, err := db.GetPublicSettingItems()
82
if err != nil {
83
return nil, err
84
}
85
settingGroupCacheF("ALL_PUBLIC_SETTING_ITEMS", _items)
86
return _items, nil
87
})
88
return items, err
89
}
90
91
func GetSettingItemByKey(key string) (*model.SettingItem, error) {
92
if item, ok := settingCache.Get(key); ok {
93
return item, nil
94
}
95
96
item, err, _ := settingG.Do(key, func() (*model.SettingItem, error) {
97
_item, err := db.GetSettingItemByKey(key)
98
if err != nil {
99
return nil, err
100
}
101
settingCacheF(_item)
102
return _item, nil
103
})
104
return item, err
105
}
106
107
func GetSettingItemInKeys(keys []string) ([]model.SettingItem, error) {
108
var items []model.SettingItem
109
for _, key := range keys {
110
item, err := GetSettingItemByKey(key)
111
if err != nil {
112
return nil, err
113
}
114
items = append(items, *item)
115
}
116
return items, nil
117
}
118
119
func GetSettingItemsByGroup(group int) ([]model.SettingItem, error) {
120
key := strconv.Itoa(group)
121
if items, ok := settingGroupCache.Get(key); ok {
122
return items, nil
123
}
124
items, err, _ := settingGroupG.Do(key, func() ([]model.SettingItem, error) {
125
_items, err := db.GetSettingItemsByGroup(group)
126
if err != nil {
127
return nil, err
128
}
129
settingGroupCacheF(key, _items)
130
return _items, nil
131
})
132
return items, err
133
}
134
135
func GetSettingItemsInGroups(groups []int) ([]model.SettingItem, error) {
136
sort.Ints(groups)
137
key := strings.Join(utils.MustSliceConvert(groups, func(i int) string {
138
return strconv.Itoa(i)
139
}), ",")
140
141
if items, ok := settingGroupCache.Get(key); ok {
142
return items, nil
143
}
144
items, err, _ := settingGroupG.Do(key, func() ([]model.SettingItem, error) {
145
_items, err := db.GetSettingItemsInGroups(groups)
146
if err != nil {
147
return nil, err
148
}
149
settingGroupCacheF(key, _items)
150
return _items, nil
151
})
152
return items, err
153
}
154
155
func SaveSettingItems(items []model.SettingItem) error {
156
noHookItems := make([]model.SettingItem, 0)
157
errs := make([]error, 0)
158
for i := range items {
159
if ok, err := HandleSettingItemHook(&items[i]); ok {
160
if err != nil {
161
errs = append(errs, err)
162
} else {
163
err = db.SaveSettingItem(&items[i])
164
if err != nil {
165
errs = append(errs, err)
166
}
167
}
168
} else {
169
noHookItems = append(noHookItems, items[i])
170
}
171
}
172
if len(noHookItems) > 0 {
173
err := db.SaveSettingItems(noHookItems)
174
if err != nil {
175
errs = append(errs, err)
176
}
177
}
178
if len(errs) < len(items)-len(noHookItems)+1 {
179
SettingCacheUpdate()
180
}
181
return utils.MergeErrors(errs...)
182
}
183
184
func SaveSettingItem(item *model.SettingItem) (err error) {
185
// hook
186
if _, err := HandleSettingItemHook(item); err != nil {
187
return err
188
}
189
// update
190
if err = db.SaveSettingItem(item); err != nil {
191
return err
192
}
193
SettingCacheUpdate()
194
return nil
195
}
196
197
func DeleteSettingItemByKey(key string) error {
198
old, err := GetSettingItemByKey(key)
199
if err != nil {
200
return errors.WithMessage(err, "failed to get settingItem")
201
}
202
if !old.IsDeprecated() {
203
return errors.Errorf("setting [%s] is not deprecated", key)
204
}
205
SettingCacheUpdate()
206
return db.DeleteSettingItemByKey(key)
207
}
208
209