@@ -0,0 +1,100 @@
|
||||
package vidser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"91porn-server/app/service/vidhelpser"
|
||||
"91porn-server/models/commod"
|
||||
"91porn-server/models/v/moduleconfmod"
|
||||
"91porn-server/models/v/vidmod"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var ErrRandomRefreshUnsupported = errors.New("the selected sort does not support random refresh")
|
||||
|
||||
func RefreshModuleVideos(uid uint64, subModuleID primitive.ObjectID, req RefreshModuleVideosReq) (RefreshModuleVideosResp, error) {
|
||||
resp := RefreshModuleVideosResp{
|
||||
AllVideoInfo: []*vidmod.VideoInfoResp{},
|
||||
RefreshMode: moduleconfmod.RefreshModeRandomTopN,
|
||||
RefreshToken: req.RefreshToken,
|
||||
}
|
||||
subModule, err := moduleconfmod.GetByID(subModuleID)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
if !subModule.IsActiveAt(time.Now()) {
|
||||
return resp, nil
|
||||
}
|
||||
subModule.HaiJiaoStyle.EnsureSortRules()
|
||||
candidateN := 0
|
||||
for _, rule := range subModule.HaiJiaoStyle.SortRules {
|
||||
if rule.Val == commod.SortType(req.ModuleSort) && rule.RefreshMode == moduleconfmod.RefreshModeRandomTopN {
|
||||
candidateN = rule.RandomCandidateN
|
||||
break
|
||||
}
|
||||
}
|
||||
if candidateN == 0 {
|
||||
return resp, ErrRandomRefreshUnsupported
|
||||
}
|
||||
|
||||
pageSize := req.PageSize
|
||||
if pageSize <= 0 {
|
||||
pageSize = 20
|
||||
}
|
||||
if pageSize > candidateN {
|
||||
pageSize = candidateN
|
||||
}
|
||||
filter := bson.M{
|
||||
"mId": subModuleID.Hex(),
|
||||
"status": vidmod.CheckPass,
|
||||
"newsType": vidmod.SP,
|
||||
"chosen": false,
|
||||
}
|
||||
opt := options.Find().
|
||||
SetSort(bson.D{
|
||||
{Key: "liaoBaTopSort", Value: -1},
|
||||
{Key: "likeCount", Value: -1},
|
||||
{Key: "reviewAt", Value: -1},
|
||||
{Key: "_id", Value: -1},
|
||||
}).
|
||||
SetLimit(int64(candidateN)).
|
||||
SetProjection(bson.M{"richText": 0})
|
||||
videos, err := vidmod.GetVideoListByCond(filter, opt)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp.CandidateCount = len(videos)
|
||||
deterministicOrderVideos(videos, subModuleID.Hex()+":"+req.RefreshToken)
|
||||
if len(videos) > pageSize {
|
||||
videos = videos[:pageSize]
|
||||
}
|
||||
resp.HasNext = hasNextRefreshCandidate(resp.CandidateCount, len(videos))
|
||||
resp.AllVideoInfo = vidhelpser.NewEncodeVideoInfoNotStatusForUser(uid, videos)
|
||||
if resp.AllVideoInfo == nil {
|
||||
resp.AllVideoInfo = []*vidmod.VideoInfoResp{}
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func hasNextRefreshCandidate(candidateCount, returnedCount int) bool {
|
||||
return candidateCount > returnedCount
|
||||
}
|
||||
|
||||
func deterministicOrderVideos(videos []*vidmod.VideoModel, seed string) {
|
||||
sort.SliceStable(videos, func(i, j int) bool {
|
||||
left := sha256.Sum256([]byte(seed + ":" + videos[i].ID.Hex()))
|
||||
right := sha256.Sum256([]byte(seed + ":" + videos[j].ID.Hex()))
|
||||
cmp := bytes.Compare(left[:], right[:])
|
||||
if cmp == 0 {
|
||||
return videos[i].ID.Hex() < videos[j].ID.Hex()
|
||||
}
|
||||
return cmp < 0
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user