Initial commit: web_hghl_server
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
package configser
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"videoweb/app/api/proto"
|
||||
"videoweb/pub/common/log"
|
||||
"videoweb/pub/common/netutil"
|
||||
"videoweb/pub/models/videoinformationmod"
|
||||
"videoweb/pub/pubdef"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
var (
|
||||
VideoRankMgr periodRankCache[proto.ContentData]
|
||||
videoRankRefreshLock sync.Mutex
|
||||
)
|
||||
|
||||
func UpdateVideoRankCache() {
|
||||
ctx := context.Background()
|
||||
imgCdn := GetConfigInfo().ImgCdn
|
||||
VideoRankMgr.replace(
|
||||
buildVideoRankList(ctx, imgCdn, RankPeriodTotal),
|
||||
buildVideoRankList(ctx, imgCdn, RankPeriodWeek),
|
||||
buildVideoRankList(ctx, imgCdn, RankPeriodMonth),
|
||||
buildVideoRankList(ctx, imgCdn, RankPeriodYear),
|
||||
)
|
||||
}
|
||||
|
||||
func refreshVideoRankCacheIfEmpty() {
|
||||
if VideoRankMgr.hasAny() {
|
||||
return
|
||||
}
|
||||
videoRankRefreshLock.Lock()
|
||||
defer videoRankRefreshLock.Unlock()
|
||||
if VideoRankMgr.hasAny() {
|
||||
return
|
||||
}
|
||||
UpdateVideoRankCache()
|
||||
}
|
||||
|
||||
func GetVideoRankList(p RankPeriod, limit int) []proto.ContentData {
|
||||
return VideoRankMgr.get(p, limit, refreshVideoRankCacheIfEmpty)
|
||||
}
|
||||
|
||||
func videoPeriodWatchField(p RankPeriod) string {
|
||||
switch p {
|
||||
case RankPeriodWeek:
|
||||
return videoinformationmod.FN.VideoInformation.Real.WeekWatchs
|
||||
case RankPeriodMonth:
|
||||
return videoinformationmod.FN.VideoInformation.Real.MonthWatchs
|
||||
case RankPeriodYear:
|
||||
return videoinformationmod.FN.VideoInformation.Real.YearWatchs
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func videoToContentData(item *videoinformationmod.VideoInformation, imgCdn string) proto.ContentData {
|
||||
tagNames, tagSlugs := VideoTagNamesAndSlugs(item.Tags)
|
||||
return proto.ContentData{
|
||||
Id: item.Id,
|
||||
Title: item.Title,
|
||||
Slug: item.Slug,
|
||||
AddedTime: item.AddedTime,
|
||||
CoverImg: netutil.MergeURL(imgCdn, item.CoverImg),
|
||||
Tags: item.Tags,
|
||||
TagsName: tagNames,
|
||||
TagSlugs: tagSlugs,
|
||||
WatchNum: item.Real.WatchTimes + item.Fake.WatchTimes,
|
||||
LikeNum: item.Real.Likes + item.Fake.Likes,
|
||||
}
|
||||
}
|
||||
|
||||
func videoToRankContentData(item *videoinformationmod.VideoInformation, imgCdn string, p RankPeriod) proto.ContentData {
|
||||
data := videoToContentData(item, imgCdn)
|
||||
data.WatchNum = periodWatchNum(p, item.Real.WeekWatchs, item.Real.MonthWatchs, item.Real.YearWatchs, data.WatchNum)
|
||||
return data
|
||||
}
|
||||
|
||||
func buildVideoRankList(ctx context.Context, imgCdn string, p RankPeriod) []proto.ContentData {
|
||||
var ranked videoinformationmod.VideoInformationList
|
||||
if p == RankPeriodTotal {
|
||||
if err := videoinformationmod.AggregateVideoInformations(ctx, &ranked, contentLikeRankPipeline(
|
||||
videoinformationmod.FN.VideoInformation.Status, pubdef.InformationStatusVerifyOK,
|
||||
videoinformationmod.FN.VideoInformation.Real.Likes, videoinformationmod.FN.VideoInformation.Fake.Likes,
|
||||
videoinformationmod.FN.VideoInformation.UpdatedAt, videoinformationmod.FN.VideoInformation.Id,
|
||||
rankLimit,
|
||||
)); err != nil {
|
||||
log.Warn("buildVideoRankList like rank query failed", log.E(err))
|
||||
ranked = videoinformationmod.VideoInformationList{}
|
||||
}
|
||||
} else {
|
||||
watchField := videoPeriodWatchField(p)
|
||||
list, err := videoinformationmod.FindManyVideoInformations(ctx, bson.M{
|
||||
videoinformationmod.FN.VideoInformation.Status: pubdef.InformationStatusVerifyOK,
|
||||
watchField: bson.M{"$gt": 0},
|
||||
}, contentWatchRankOpts(watchField, videoinformationmod.FN.VideoInformation.UpdatedAt, videoinformationmod.FN.VideoInformation.Id, rankLimit))
|
||||
if err != nil {
|
||||
log.Warn("buildVideoRankList watch rank query failed", log.Any("period", p), log.E(err))
|
||||
ranked = videoinformationmod.VideoInformationList{}
|
||||
} else {
|
||||
ranked = list
|
||||
}
|
||||
}
|
||||
if int64(len(ranked)) < rankLimit {
|
||||
needFill := rankLimit - int64(len(ranked))
|
||||
excludeIds := make([]int64, 0, len(ranked))
|
||||
for _, v := range ranked {
|
||||
excludeIds = append(excludeIds, v.Id)
|
||||
}
|
||||
var filled videoinformationmod.VideoInformationList
|
||||
if err := videoinformationmod.AggregateVideoInformations(ctx, &filled, contentRankFillPipeline(
|
||||
videoinformationmod.FN.VideoInformation.Id, videoinformationmod.FN.VideoInformation.Status,
|
||||
pubdef.InformationStatusVerifyOK, excludeIds, needFill,
|
||||
)); err != nil {
|
||||
log.Warn("buildVideoRankList fill sample failed", log.Any("period", p), log.E(err))
|
||||
} else {
|
||||
ranked = append(ranked, filled...)
|
||||
}
|
||||
}
|
||||
result := make([]proto.ContentData, 0, len(ranked))
|
||||
for _, item := range ranked {
|
||||
result = append(result, videoToRankContentData(item, imgCdn, p))
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user