mirror of https://github.com/Xhofe/alist
199 lines
4.9 KiB
Go
199 lines
4.9 KiB
Go
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)
|
|
}
|