Spaces:
Running
Running
package op | |
import ( | |
"sort" | |
"strconv" | |
"strings" | |
"time" | |
"github.com/Xhofe/go-cache" | |
"github.com/alist-org/alist/v3/internal/db" | |
"github.com/alist-org/alist/v3/internal/model" | |
"github.com/alist-org/alist/v3/pkg/singleflight" | |
"github.com/alist-org/alist/v3/pkg/utils" | |
"github.com/pkg/errors" | |
) | |
var settingCache = cache.NewMemCache(cache.WithShards[*model.SettingItem](4)) | |
var settingG singleflight.Group[*model.SettingItem] | |
var settingCacheF = func(item *model.SettingItem) { | |
settingCache.Set(item.Key, item, cache.WithEx[*model.SettingItem](time.Hour)) | |
} | |
var settingGroupCache = cache.NewMemCache(cache.WithShards[[]model.SettingItem](4)) | |
var settingGroupG singleflight.Group[[]model.SettingItem] | |
var settingGroupCacheF = func(key string, item []model.SettingItem) { | |
settingGroupCache.Set(key, item, cache.WithEx[[]model.SettingItem](time.Hour)) | |
} | |
func settingCacheUpdate() { | |
settingCache.Clear() | |
settingGroupCache.Clear() | |
} | |
func GetPublicSettingsMap() map[string]string { | |
items, _ := GetPublicSettingItems() | |
pSettings := make(map[string]string) | |
for _, item := range items { | |
pSettings[item.Key] = item.Value | |
} | |
return pSettings | |
} | |
func GetSettingsMap() map[string]string { | |
items, _ := GetSettingItems() | |
settings := make(map[string]string) | |
for _, item := range items { | |
settings[item.Key] = item.Value | |
} | |
return settings | |
} | |
func GetSettingItems() ([]model.SettingItem, error) { | |
if items, ok := settingGroupCache.Get("ALL_SETTING_ITEMS"); ok { | |
return items, nil | |
} | |
items, err, _ := settingGroupG.Do("ALL_SETTING_ITEMS", func() ([]model.SettingItem, error) { | |
_items, err := db.GetSettingItems() | |
if err != nil { | |
return nil, err | |
} | |
settingGroupCacheF("ALL_SETTING_ITEMS", _items) | |
return _items, nil | |
}) | |
return items, err | |
} | |
func GetPublicSettingItems() ([]model.SettingItem, error) { | |
if items, ok := settingGroupCache.Get("ALL_PUBLIC_SETTING_ITEMS"); ok { | |
return items, nil | |
} | |
items, err, _ := settingGroupG.Do("ALL_PUBLIC_SETTING_ITEMS", func() ([]model.SettingItem, error) { | |
_items, err := db.GetPublicSettingItems() | |
if err != nil { | |
return nil, err | |
} | |
settingGroupCacheF("ALL_PUBLIC_SETTING_ITEMS", _items) | |
return _items, nil | |
}) | |
return items, err | |
} | |
func GetSettingItemByKey(key string) (*model.SettingItem, error) { | |
if item, ok := settingCache.Get(key); ok { | |
return item, nil | |
} | |
item, err, _ := settingG.Do(key, func() (*model.SettingItem, error) { | |
_item, err := db.GetSettingItemByKey(key) | |
if err != nil { | |
return nil, err | |
} | |
settingCacheF(_item) | |
return _item, nil | |
}) | |
return item, err | |
} | |
func GetSettingItemInKeys(keys []string) ([]model.SettingItem, error) { | |
var items []model.SettingItem | |
for _, key := range keys { | |
item, err := GetSettingItemByKey(key) | |
if err != nil { | |
return nil, err | |
} | |
items = append(items, *item) | |
} | |
return items, nil | |
} | |
func GetSettingItemsByGroup(group int) ([]model.SettingItem, error) { | |
key := strconv.Itoa(group) | |
if items, ok := settingGroupCache.Get(key); ok { | |
return items, nil | |
} | |
items, err, _ := settingGroupG.Do(key, func() ([]model.SettingItem, error) { | |
_items, err := db.GetSettingItemsByGroup(group) | |
if err != nil { | |
return nil, err | |
} | |
settingGroupCacheF(key, _items) | |
return _items, nil | |
}) | |
return items, err | |
} | |
func GetSettingItemsInGroups(groups []int) ([]model.SettingItem, error) { | |
sort.Ints(groups) | |
key := strings.Join(utils.MustSliceConvert(groups, func(i int) string { | |
return strconv.Itoa(i) | |
}), ",") | |
if items, ok := settingGroupCache.Get(key); ok { | |
return items, nil | |
} | |
items, err, _ := settingGroupG.Do(key, func() ([]model.SettingItem, error) { | |
_items, err := db.GetSettingItemsInGroups(groups) | |
if err != nil { | |
return nil, err | |
} | |
settingGroupCacheF(key, _items) | |
return _items, nil | |
}) | |
return items, err | |
} | |
func SaveSettingItems(items []model.SettingItem) error { | |
noHookItems := make([]model.SettingItem, 0) | |
errs := make([]error, 0) | |
for i := range items { | |
if ok, err := HandleSettingItemHook(&items[i]); ok { | |
if err != nil { | |
errs = append(errs, err) | |
} else { | |
err = db.SaveSettingItem(&items[i]) | |
if err != nil { | |
errs = append(errs, err) | |
} | |
} | |
} else { | |
noHookItems = append(noHookItems, items[i]) | |
} | |
} | |
if len(noHookItems) > 0 { | |
err := db.SaveSettingItems(noHookItems) | |
if err != nil { | |
errs = append(errs, err) | |
} | |
} | |
if len(errs) < len(items)-len(noHookItems)+1 { | |
settingCacheUpdate() | |
} | |
return utils.MergeErrors(errs...) | |
} | |
func SaveSettingItem(item *model.SettingItem) (err error) { | |
// hook | |
if _, err := HandleSettingItemHook(item); err != nil { | |
return err | |
} | |
// update | |
if err = db.SaveSettingItem(item); err != nil { | |
return err | |
} | |
settingCacheUpdate() | |
return nil | |
} | |
func DeleteSettingItemByKey(key string) error { | |
old, err := GetSettingItemByKey(key) | |
if err != nil { | |
return errors.WithMessage(err, "failed to get settingItem") | |
} | |
if !old.IsDeprecated() { | |
return errors.Errorf("setting [%s] is not deprecated", key) | |
} | |
settingCacheUpdate() | |
return db.DeleteSettingItemByKey(key) | |
} | |