mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-09-19 20:26:26 +08:00
140 lines
3.9 KiB
Go
140 lines
3.9 KiB
Go
![]() |
package op
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
stdpath "path"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/OpenListTeam/OpenList/v4/internal/db"
|
||
|
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||
|
"github.com/OpenListTeam/OpenList/v4/pkg/singleflight"
|
||
|
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
|
||
|
"github.com/OpenListTeam/go-cache"
|
||
|
"github.com/pkg/errors"
|
||
|
log "github.com/sirupsen/logrus"
|
||
|
)
|
||
|
|
||
|
func makeJoined(sdb []model.SharingDB) []model.Sharing {
|
||
|
creator := make(map[uint]*model.User)
|
||
|
return utils.MustSliceConvert(sdb, func(s model.SharingDB) model.Sharing {
|
||
|
var c *model.User
|
||
|
var ok bool
|
||
|
if c, ok = creator[s.CreatorId]; !ok {
|
||
|
var err error
|
||
|
if c, err = GetUserById(s.CreatorId); err != nil {
|
||
|
c = nil
|
||
|
} else {
|
||
|
creator[s.CreatorId] = c
|
||
|
}
|
||
|
}
|
||
|
var files []string
|
||
|
if err := utils.Json.UnmarshalFromString(s.FilesRaw, &files); err != nil {
|
||
|
files = make([]string, 0)
|
||
|
}
|
||
|
return model.Sharing{
|
||
|
SharingDB: &s,
|
||
|
Files: files,
|
||
|
Creator: c,
|
||
|
}
|
||
|
})
|
||
|
}
|
||
|
|
||
|
var sharingCache = cache.NewMemCache(cache.WithShards[*model.Sharing](8))
|
||
|
var sharingG singleflight.Group[*model.Sharing]
|
||
|
|
||
|
func GetSharingById(id string, refresh ...bool) (*model.Sharing, error) {
|
||
|
if !utils.IsBool(refresh...) {
|
||
|
if sharing, ok := sharingCache.Get(id); ok {
|
||
|
log.Debugf("use cache when get sharing %s", id)
|
||
|
return sharing, nil
|
||
|
}
|
||
|
}
|
||
|
sharing, err, _ := sharingG.Do(id, func() (*model.Sharing, error) {
|
||
|
s, err := db.GetSharingById(id)
|
||
|
if err != nil {
|
||
|
return nil, errors.WithMessagef(err, "failed get sharing [%s]", id)
|
||
|
}
|
||
|
creator, err := GetUserById(s.CreatorId)
|
||
|
if err != nil {
|
||
|
return nil, errors.WithMessagef(err, "failed get sharing creator [%s]", id)
|
||
|
}
|
||
|
var files []string
|
||
|
if err = utils.Json.UnmarshalFromString(s.FilesRaw, &files); err != nil {
|
||
|
files = make([]string, 0)
|
||
|
}
|
||
|
return &model.Sharing{
|
||
|
SharingDB: s,
|
||
|
Files: files,
|
||
|
Creator: creator,
|
||
|
}, nil
|
||
|
})
|
||
|
return sharing, err
|
||
|
}
|
||
|
|
||
|
func GetSharings(pageIndex, pageSize int) ([]model.Sharing, int64, error) {
|
||
|
s, cnt, err := db.GetSharings(pageIndex, pageSize)
|
||
|
if err != nil {
|
||
|
return nil, 0, errors.WithStack(err)
|
||
|
}
|
||
|
return makeJoined(s), cnt, nil
|
||
|
}
|
||
|
|
||
|
func GetSharingsByCreatorId(userId uint, pageIndex, pageSize int) ([]model.Sharing, int64, error) {
|
||
|
s, cnt, err := db.GetSharingsByCreatorId(userId, pageIndex, pageSize)
|
||
|
if err != nil {
|
||
|
return nil, 0, errors.WithStack(err)
|
||
|
}
|
||
|
return makeJoined(s), cnt, nil
|
||
|
}
|
||
|
|
||
|
func GetSharingUnwrapPath(sharing *model.Sharing, path string) (unwrapPath string, err error) {
|
||
|
if len(sharing.Files) == 0 {
|
||
|
return "", errors.New("cannot get actual path of an invalid sharing")
|
||
|
}
|
||
|
if len(sharing.Files) == 1 {
|
||
|
return stdpath.Join(sharing.Files[0], path), nil
|
||
|
}
|
||
|
path = utils.FixAndCleanPath(path)[1:]
|
||
|
if len(path) == 0 {
|
||
|
return "", errors.New("cannot get actual path of a sharing root path")
|
||
|
}
|
||
|
mapPath := ""
|
||
|
child, rest, _ := strings.Cut(path, "/")
|
||
|
for _, c := range sharing.Files {
|
||
|
if child == stdpath.Base(c) {
|
||
|
mapPath = c
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if mapPath == "" {
|
||
|
return "", fmt.Errorf("failed find child [%s] of sharing [%s]", child, sharing.ID)
|
||
|
}
|
||
|
return stdpath.Join(mapPath, rest), nil
|
||
|
}
|
||
|
|
||
|
func CreateSharing(sharing *model.Sharing) (id string, err error) {
|
||
|
sharing.CreatorId = sharing.Creator.ID
|
||
|
sharing.FilesRaw, err = utils.Json.MarshalToString(utils.MustSliceConvert(sharing.Files, utils.FixAndCleanPath))
|
||
|
if err != nil {
|
||
|
return "", errors.WithStack(err)
|
||
|
}
|
||
|
return db.CreateSharing(sharing.SharingDB)
|
||
|
}
|
||
|
|
||
|
func UpdateSharing(sharing *model.Sharing, skipMarshal ...bool) (err error) {
|
||
|
if !utils.IsBool(skipMarshal...) {
|
||
|
sharing.CreatorId = sharing.Creator.ID
|
||
|
sharing.FilesRaw, err = utils.Json.MarshalToString(utils.MustSliceConvert(sharing.Files, utils.FixAndCleanPath))
|
||
|
if err != nil {
|
||
|
return errors.WithStack(err)
|
||
|
}
|
||
|
}
|
||
|
sharingCache.Del(sharing.ID)
|
||
|
return db.UpdateSharing(sharing.SharingDB)
|
||
|
}
|
||
|
|
||
|
func DeleteSharing(sid string) error {
|
||
|
sharingCache.Del(sid)
|
||
|
return db.DeleteSharingById(sid)
|
||
|
}
|