You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1093 lines
29 KiB
1093 lines
29 KiB
package music |
|
|
|
import ( |
|
"context" |
|
"go-common/app/interface/main/creative/conf" |
|
"go-common/app/interface/main/creative/dao/account" |
|
"go-common/app/interface/main/creative/dao/archive" |
|
material "go-common/app/interface/main/creative/dao/material" |
|
music "go-common/app/interface/main/creative/dao/music" |
|
"go-common/app/interface/main/creative/dao/up" |
|
appMdl "go-common/app/interface/main/creative/model/app" |
|
mMdl "go-common/app/interface/main/creative/model/music" |
|
sMdl "go-common/app/interface/main/creative/model/search" |
|
"go-common/app/interface/main/creative/service" |
|
accMdl "go-common/app/service/main/account/model" |
|
"go-common/app/service/main/archive/api" |
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
"go-common/library/net/metadata" |
|
"go-common/library/queue/databus/report" |
|
"go-common/library/sync/errgroup" |
|
"sort" |
|
"time" |
|
) |
|
|
|
const hotvalArcFactor = int(357) |
|
|
|
//Service struct. |
|
type Service struct { |
|
c *conf.Config |
|
music *music.Dao |
|
material *material.Dao |
|
acc *account.Dao |
|
archive *archive.Dao |
|
up *up.Dao |
|
LatestBgm *mMdl.Music |
|
MscWithTypes map[int][]*mMdl.Music |
|
AllMsc map[int64]*mMdl.Music |
|
Types []*mMdl.Category |
|
Subtitles []*mMdl.Subtitle |
|
Fonts []*mMdl.Font |
|
Filters []*mMdl.Filter |
|
FilterWithCategory []*mMdl.FilterCategory |
|
VstickerWithCategory []*mMdl.VstickerCategory |
|
Hotwords []*mMdl.Hotword |
|
Stickers []*mMdl.Sticker |
|
Intros []*mMdl.Intro |
|
Vstickers []*mMdl.VSticker |
|
Transitions []*mMdl.Transition |
|
// from app535 for sticker whitelist |
|
stickerUps map[int64]int64 |
|
Themes []*mMdl.Theme |
|
Cooperates []*mMdl.Cooperate |
|
p *service.Public |
|
} |
|
|
|
//New get service. |
|
func New(c *conf.Config, rpcdaos *service.RPCDaos, p *service.Public) *Service { |
|
s := &Service{ |
|
c: c, |
|
music: music.New(c), |
|
material: material.New(c), |
|
acc: rpcdaos.Acc, |
|
archive: rpcdaos.Arc, |
|
up: rpcdaos.Up, |
|
Types: make([]*mMdl.Category, 0), |
|
MscWithTypes: make(map[int][]*mMdl.Music), |
|
AllMsc: make(map[int64]*mMdl.Music), |
|
Subtitles: make([]*mMdl.Subtitle, 0), |
|
Fonts: make([]*mMdl.Font, 0), |
|
Filters: make([]*mMdl.Filter, 0), |
|
FilterWithCategory: make([]*mMdl.FilterCategory, 0), |
|
VstickerWithCategory: make([]*mMdl.VstickerCategory, 0), |
|
Hotwords: make([]*mMdl.Hotword, 0), |
|
Stickers: make([]*mMdl.Sticker, 0), |
|
Intros: make([]*mMdl.Intro, 0), |
|
Vstickers: make([]*mMdl.VSticker, 0), |
|
Transitions: make([]*mMdl.Transition, 0), |
|
Themes: make([]*mMdl.Theme, 0), |
|
Cooperates: make([]*mMdl.Cooperate, 0), |
|
p: p, |
|
} |
|
s.loadUpSpecialSticker() |
|
s.loadPreValues() |
|
s.loadMaterial() |
|
go s.loadproc() |
|
return s |
|
} |
|
|
|
// loadUpSpecialSticker 拍摄贴纸支持灰度分发,配合Sticker.white字段使用 |
|
func (s *Service) loadUpSpecialSticker() { |
|
ups, err := s.up.UpSpecial(context.TODO(), 18) |
|
if err != nil { |
|
return |
|
} |
|
s.stickerUps = ups |
|
} |
|
func (s *Service) loadproc() { |
|
for { |
|
time.Sleep(time.Duration(2 * time.Minute)) |
|
s.loadPreValues() |
|
s.loadMaterial() |
|
s.loadUpSpecialSticker() |
|
} |
|
} |
|
|
|
func (s *Service) loadMaterial() { |
|
var ( |
|
basic = make(map[string]interface{}) |
|
err error |
|
g = &errgroup.Group{} |
|
ctx = context.TODO() |
|
) |
|
c := context.TODO() |
|
if basic, err = s.material.Basic(c); err != nil { |
|
log.Error("s.material.basic err(%+v)", err) |
|
return |
|
} |
|
if subtitles, ok := basic["subs"].([]*mMdl.Subtitle); ok { |
|
log.Info("s.material.subs (%+d)", len(subtitles)) |
|
s.Subtitles = subtitles |
|
} |
|
if fonts, ok := basic["fons"].([]*mMdl.Font); ok { |
|
log.Info("s.material.fons (%+d)", len(fonts)) |
|
s.Fonts = fonts |
|
} |
|
if hotwords, ok := basic["hots"].([]*mMdl.Hotword); ok { |
|
log.Info("s.material.hots (%+d)", len(hotwords)) |
|
s.Hotwords = hotwords |
|
} |
|
if stickers, ok := basic["stis"].([]*mMdl.Sticker); ok { |
|
log.Info("s.material.stis (%+d)", len(stickers)) |
|
s.Stickers = stickers |
|
} |
|
if intros, ok := basic["ints"].([]*mMdl.Intro); ok { |
|
log.Info("s.material.ints (%+d)", len(intros)) |
|
s.Intros = intros |
|
} |
|
if trans, ok := basic["trans"].([]*mMdl.Transition); ok { |
|
log.Info("s.material.trans (%+d)", len(trans)) |
|
s.Transitions = trans |
|
} |
|
if themes, ok := basic["themes"].([]*mMdl.Theme); ok { |
|
log.Info("s.material.themes (%+d)", len(themes)) |
|
s.Themes = themes |
|
} |
|
g.Go(func() error { |
|
s.getFilterAndItsCategory(ctx) |
|
return nil |
|
}) |
|
g.Go(func() error { |
|
s.getVStickerAndItsCategory(ctx) |
|
return nil |
|
}) |
|
g.Go(func() error { |
|
s.getCooperates(ctx) |
|
return nil |
|
}) |
|
g.Wait() |
|
} |
|
|
|
func (s *Service) loadPreValues() { |
|
var ( |
|
mcategory []*mMdl.Mcategory |
|
resCategorys []*mMdl.Category |
|
tids []int64 |
|
sids []int64 |
|
err error |
|
musicMap map[int64]*mMdl.Music |
|
// latestBgm *mMdl.Music |
|
jointimeMap = make(map[int64]int64) |
|
jointimes = make([]int64, 0) |
|
c = context.TODO() |
|
sidTidMapIdx = make(map[int64][](map[int]int)) |
|
sidTidMapJoinUnix = make(map[int64][](map[int]int64)) |
|
categoryMaps = make(map[int]*mMdl.Category) |
|
) |
|
if mcategory, err = s.music.MCategorys(c); err != nil { |
|
log.Error("s.music.MCategorys err(%+v)", err) |
|
return |
|
} |
|
for _, v := range mcategory { |
|
joinUnix := v.CTime.Time().Unix() |
|
jointimeMap[joinUnix] = v.SID |
|
jointimes = append(jointimes, joinUnix) |
|
tid := v.Tid |
|
tidx := v.Index |
|
sid := v.SID |
|
tids = append(tids, int64(tid)) |
|
sids = append(sids, sid) |
|
if _, ok := sidTidMapIdx[sid]; !ok { |
|
sidTidMapIdx[sid] = make([](map[int]int), 0) |
|
} |
|
sidTidMapIdx[sid] = append(sidTidMapIdx[sid], map[int]int{ |
|
tid: tidx, |
|
}) |
|
if _, ok := sidTidMapJoinUnix[sid]; !ok { |
|
sidTidMapJoinUnix[sid] = make([](map[int]int64), 0) |
|
} |
|
sidTidMapJoinUnix[sid] = append(sidTidMapJoinUnix[sid], map[int]int64{ |
|
tid: joinUnix, |
|
}) |
|
} |
|
if len(tids) > 0 { |
|
if resCategorys, categoryMaps, err = s.music.Categorys(c, tids); err != nil { |
|
log.Error("s.music.Categorys tids(%+v)|err(%+v)", tids, err) |
|
return |
|
} |
|
if len(resCategorys) > 0 && len(sids) > 0 { |
|
if musicMap, err = s.music.Music(c, sids); err != nil { |
|
log.Error("s.music.Music tids(%+v)|sids(%+v)|err(%+v)", tids, sids, err) |
|
return |
|
} |
|
// get last jointime bgm |
|
if len(jointimes) > 0 { |
|
sort.Slice(jointimes, func(i, j int) bool { |
|
return jointimes[i] >= jointimes[j] |
|
}) |
|
lastJoinUnix := jointimes[0] |
|
lastSid := jointimeMap[lastJoinUnix] |
|
if bgm, ok := musicMap[lastSid]; ok { |
|
s.LatestBgm = bgm |
|
} |
|
} |
|
s.AllMsc = musicMap |
|
bgms := make(map[int][]*mMdl.Music) |
|
upNamesMap, _ := s.getUpNames(c, musicMap) |
|
for sid, msc := range musicMap { |
|
if tpsSlice, okM := sidTidMapIdx[sid]; okM { |
|
for _, tpIdx := range tpsSlice { |
|
for tp, idx := range tpIdx { |
|
if _, ok := categoryMaps[tp]; !ok { |
|
continue |
|
} |
|
if _, ok := bgms[tp]; !ok { |
|
bgms[tp] = make([]*mMdl.Music, 0) |
|
} |
|
var ( |
|
junix int64 |
|
upName string |
|
) |
|
if name, okU := upNamesMap[msc.UpMID]; okU { |
|
upName = name |
|
} |
|
for _, Jmap := range sidTidMapJoinUnix[sid] { |
|
if joinUnix, okJ := Jmap[tp]; okJ { |
|
junix = joinUnix |
|
} |
|
} |
|
bgm := &mMdl.Music{ |
|
ID: msc.ID, |
|
TID: tp, |
|
Index: idx, |
|
SID: msc.SID, |
|
Name: msc.Name, |
|
Musicians: upName, |
|
UpMID: msc.UpMID, |
|
Cover: msc.Cover, |
|
Stat: msc.Stat, |
|
Playurl: msc.Playurl, |
|
Duration: msc.Duration, |
|
FileSize: msc.FileSize, |
|
CTime: msc.CTime, |
|
MTime: msc.MTime, |
|
Pubtime: msc.Pubtime, |
|
Tl: msc.Tl, |
|
RecommendPoint: msc.RecommendPoint, |
|
Cooperate: msc.Cooperate, |
|
CooperateURL: msc.CooperateURL, |
|
} |
|
// freash bgm.Tags by joinunix |
|
if junix+86400*7 >= time.Now().Unix() { |
|
bgm.New = 1 |
|
bgm.Tags = []string{"NEW"} |
|
} else { |
|
bgm.Tags = make([]string, 0) |
|
} |
|
if len(msc.Tags) > 0 { |
|
bgm.Tags = append(bgm.Tags, msc.Tags...) |
|
} |
|
topLen := 3 |
|
if len(bgm.Tags) > topLen { |
|
bgm.Tags = bgm.Tags[:topLen] |
|
} |
|
bgms[tp] = append(bgms[tp], bgm) |
|
} |
|
} |
|
} |
|
} |
|
if len(bgms) > 0 { |
|
s.MscWithTypes = bgms |
|
} |
|
var filterdCategorys []*mMdl.Category |
|
for _, t := range resCategorys { |
|
if len(bgms[t.ID]) > 0 { |
|
sort.Slice(bgms[t.ID], func(i, j int) bool { |
|
return bgms[t.ID][i].Index < bgms[t.ID][j].Index |
|
}) |
|
t.Children = bgms[t.ID] |
|
filterdCategorys = append(filterdCategorys, t) |
|
} |
|
} |
|
s.Types = filterdCategorys |
|
} |
|
} |
|
log.Info("loadPreValues (%d)|(%d)", len(s.MscWithTypes), len(s.Types)) |
|
} |
|
|
|
// BgmExt fn |
|
func (s *Service) BgmExt(c context.Context, mid, sid int64) (ret *mMdl.BgmExt, err error) { |
|
var ( |
|
bgm *mMdl.Music |
|
upMid int64 |
|
shouldFollowMids []int64 |
|
g = &errgroup.Group{} |
|
ctx = context.TODO() |
|
extSidMap map[int]int64 |
|
) |
|
log.Warn("BgmExt allMsc(%d)", len(s.AllMsc)) |
|
if v, ok := s.AllMsc[sid]; ok { |
|
bgm = v |
|
ret = &mMdl.BgmExt{ |
|
Msc: bgm, |
|
} |
|
} else { |
|
return |
|
} |
|
log.Warn("BgmExt finish find bgm allMsc(%d)|bgm(%+v)", len(s.AllMsc), bgm) |
|
if bgm == nil { |
|
return |
|
} |
|
log.Warn("BgmExt bgm info (%+v)", bgm) |
|
upMid = bgm.UpMID |
|
ret.ExtMscs, extSidMap = s.UperOtherBgmsFromRecom(ctx, upMid, sid) |
|
ip := metadata.String(c, metadata.RemoteIP) |
|
// step 1: get ext aids and rpc archives |
|
g.Go(func() error { |
|
ret.ExtArcs, ret.Msc.Hotval, err = s.ExtArcsWithSameBgm(ctx, sid) |
|
log.Warn("BgmExt step 1: extArcs(%+v)|hotVal(%+v)|sid(%+d)|err(%+v)", ret.ExtArcs, ret.Msc.Hotval, sid, err) |
|
return nil |
|
}) |
|
// step 2: get ext mscs |
|
g.Go(func() error { |
|
ret.ExtMscs, err = s.ExtSidHotMapAndSort(ctx, ret.ExtMscs, extSidMap) |
|
log.Warn("BgmExt step 2: ExtMscs(%+v)|extSidMap(%+v)|err(%+v)", ret.ExtMscs, extSidMap, err) |
|
return nil |
|
}) |
|
// step 3: get up info and if should follow |
|
g.Go(func() error { |
|
ret.UpProfile, err = s.acc.Profile(ctx, upMid, ip) |
|
log.Warn("BgmExt step 3: profile mid(%+v)", upMid) |
|
return nil |
|
}) |
|
// step 4: get up info and if should follow |
|
g.Go(func() error { |
|
shouldFollowMids, err = s.acc.ShouldFollow(ctx, mid, []int64{upMid}, ip) |
|
if len(shouldFollowMids) == 1 { |
|
ret.ShouldFollow = true |
|
} |
|
log.Warn("BgmExt step 4: shouldFollow(%+v)", ret.ShouldFollow) |
|
return nil |
|
}) |
|
g.Wait() |
|
return |
|
} |
|
|
|
// ExtSidHotMapAndSort fn, sorry ... |
|
func (s *Service) ExtSidHotMapAndSort(c context.Context, ExtMscs []*mMdl.Music, extSidMap map[int]int64) (res []*mMdl.Music, err error) { |
|
var ( |
|
s1total, s2total, s3total int |
|
s1hot, s2hot, s3hot int |
|
) |
|
if len(extSidMap) > 0 { |
|
var ( |
|
g = &errgroup.Group{} |
|
ctx = context.TODO() |
|
) |
|
if sid, ok := extSidMap[1]; ok { |
|
g.Go(func() error { |
|
if _, s1total, err = s.music.ExtAidsWithSameBgm(ctx, sid, 1); err != nil { |
|
log.Error("ExtAidsWithSameBgm S1 error(%v)", err) |
|
} |
|
s1hot = s1total * hotvalArcFactor |
|
return nil |
|
}) |
|
} |
|
if sid, ok := extSidMap[2]; ok { |
|
g.Go(func() error { |
|
if _, s2total, err = s.music.ExtAidsWithSameBgm(ctx, sid, 1); err != nil { |
|
log.Error("ExtAidsWithSameBgm S2 error(%v)", err) |
|
} |
|
s2hot = s2total * hotvalArcFactor |
|
return nil |
|
}) |
|
} |
|
if sid, ok := extSidMap[3]; ok { |
|
g.Go(func() error { |
|
if _, s3total, err = s.music.ExtAidsWithSameBgm(ctx, sid, 1); err != nil { |
|
log.Error("ExtAidsWithSameBgm S3 error(%v)", err) |
|
} |
|
s3hot = s3total * hotvalArcFactor |
|
return nil |
|
}) |
|
} |
|
g.Wait() |
|
} |
|
for idx, v := range ExtMscs { |
|
if idx == 0 { |
|
v.Hotval = s1hot |
|
} |
|
if idx == 1 { |
|
v.Hotval = s2hot |
|
} |
|
if idx == 2 { |
|
v.Hotval = s3hot |
|
} |
|
} |
|
sort.Slice(ExtMscs, func(i, j int) bool { |
|
return ExtMscs[i].Hotval > ExtMscs[j].Hotval |
|
}) |
|
res = ExtMscs |
|
return |
|
} |
|
|
|
// ExtArcsWithSameBgm fn |
|
func (s *Service) ExtArcsWithSameBgm(c context.Context, sid int64) (res []*api.Arc, hot int, err error) { |
|
var ( |
|
arcMap map[int64]*api.Arc |
|
aids []int64 |
|
total int |
|
) |
|
aids, total, err = s.music.ExtAidsWithSameBgm(c, sid, 100) |
|
if len(aids) > 0 { |
|
ip := metadata.String(c, metadata.RemoteIP) |
|
if arcMap, err = s.archive.Archives(c, aids, ip); err != nil { |
|
log.Error("s.archive.Archives Stats (%v) error(%v)", aids, err) |
|
err = ecode.CreativeArcServiceErr |
|
return |
|
} |
|
for _, aid := range aids { |
|
if arc, ok := arcMap[aid]; ok && arc.State >= 0 { |
|
res = append(res, arc) |
|
} |
|
} |
|
} |
|
topLen := 20 |
|
if len(res) > topLen { |
|
res = res[:topLen] |
|
} |
|
hot = total * hotvalArcFactor |
|
return |
|
} |
|
|
|
// UperOtherBgmsFromRecom fn, 最多三个同一个Up主的bgms |
|
func (s *Service) UperOtherBgmsFromRecom(c context.Context, upmid, sid int64) (res []*mMdl.Music, extSidMap map[int]int64) { |
|
extSidMap = make(map[int]int64) |
|
idx := int(1) |
|
for _, mscs := range s.MscWithTypes { |
|
for _, msc := range mscs { |
|
if msc.SID != sid && |
|
msc.UpMID == upmid && |
|
len(extSidMap) < 3 { |
|
res = append(res, msc) |
|
extSidMap[idx] = msc.SID |
|
idx++ |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// BgmView fn |
|
func (s *Service) BgmView(c context.Context, sid int64) (ret *mMdl.Music) { |
|
for _, msc := range s.AllMsc { |
|
if msc.ID == sid { |
|
ret = msc |
|
break |
|
} |
|
} |
|
return |
|
} |
|
|
|
// PreByFrom fn |
|
func (s *Service) PreByFrom(c context.Context, from int) (types []*mMdl.Category) { |
|
if from == 1 { |
|
sort.Slice(s.Types, func(i, j int) bool { |
|
return s.Types[i].CameraIndex <= s.Types[j].CameraIndex |
|
}) |
|
} else { |
|
sort.Slice(s.Types, func(i, j int) bool { |
|
return s.Types[i].Index <= s.Types[j].Index |
|
}) |
|
} |
|
types = s.Types |
|
return |
|
} |
|
|
|
// BgmList fn |
|
func (s *Service) BgmList(c context.Context, tid int) (ret []*mMdl.Music) { |
|
if len(s.MscWithTypes) > 0 { |
|
if mics, ok := s.MscWithTypes[tid]; ok { |
|
ret = mics |
|
} |
|
} |
|
return |
|
} |
|
|
|
// getUpNames fn |
|
func (s *Service) getUpNames(c context.Context, mmap map[int64]*mMdl.Music) (ret map[int64]string, err error) { |
|
var ( |
|
minfos map[int64]*accMdl.Info |
|
mids []int64 |
|
) |
|
ret = make(map[int64]string) |
|
for _, msc := range mmap { |
|
mids = append(mids, msc.UpMID) |
|
} |
|
if len(mids) > 0 { |
|
minfos, err = s.acc.Infos(c, mids, "localhost") |
|
if err != nil { |
|
log.Info("minfos err mids (%+v)|err(%+v)", mids, err) |
|
return |
|
} |
|
for _, info := range minfos { |
|
ret[info.Mid] = info.Name |
|
} |
|
} |
|
return |
|
} |
|
|
|
// Cooperate fn |
|
func (s *Service) Cooperate(c context.Context, id, mid int64) (res *mMdl.Cooperate) { |
|
_, white := s.stickerUps[mid] |
|
for _, v := range s.Cooperates { |
|
if v.White == 1 && !white { |
|
return |
|
} |
|
if v.ID == id { |
|
return v |
|
} |
|
} |
|
return |
|
} |
|
|
|
// Material fn |
|
func (s *Service) Material(c context.Context, id int64, tp int8, mid int64) (res interface{}) { |
|
if _, ok := mMdl.ViewTpMap[tp]; !ok { |
|
return |
|
} |
|
_, white := s.stickerUps[mid] |
|
switch tp { |
|
case appMdl.TypeSubtitle: |
|
for _, v := range s.Subtitles { |
|
if v.White == 1 && !white { |
|
return |
|
} |
|
if v.ID == id { |
|
return v |
|
} |
|
} |
|
case appMdl.TypeFont: |
|
for _, v := range s.Fonts { |
|
if v.White == 1 && !white { |
|
return |
|
} |
|
if v.ID == id { |
|
return v |
|
} |
|
} |
|
case appMdl.TypeFilter: |
|
for _, v := range s.Filters { |
|
if v.White == 1 && !white { |
|
return |
|
} |
|
if v.ID == id { |
|
return v |
|
} |
|
} |
|
case appMdl.TypeSticker: |
|
for _, v := range s.Stickers { |
|
if v.White == 1 && !white { |
|
return |
|
} |
|
if v.ID == id { |
|
return v |
|
} |
|
} |
|
case appMdl.TypeVideoupSticker: |
|
for _, v := range s.Vstickers { |
|
if v.White == 1 && !white { |
|
return |
|
} |
|
if v.ID == id { |
|
return v |
|
} |
|
} |
|
case appMdl.TypeTransition: |
|
for _, v := range s.Transitions { |
|
if v.White == 1 && !white { |
|
return |
|
} |
|
if v.ID == id { |
|
return v |
|
} |
|
} |
|
case appMdl.TypeCooperate: |
|
for _, v := range s.Cooperates { |
|
if v.White == 1 && !white { |
|
return |
|
} |
|
if v.ID == id { |
|
return v |
|
} |
|
} |
|
case appMdl.TypeTheme: |
|
for _, v := range s.Themes { |
|
if v.White == 1 && !white { |
|
return |
|
} |
|
if v.ID == id { |
|
return v |
|
} |
|
} |
|
} |
|
return |
|
} |
|
|
|
// MaterialPre fn |
|
func (s *Service) MaterialPre(c context.Context, mid int64, platStr string, build int) (res map[string]interface{}) { |
|
var ( |
|
hotwords = []*mMdl.Hotword{} |
|
stickers = []*mMdl.Sticker{} |
|
vstickers = []*mMdl.VSticker{} |
|
trans = []*mMdl.Transition{} |
|
cooperates = []*mMdl.Cooperate{} |
|
themes = []*mMdl.Theme{} |
|
intros = []*mMdl.Intro{} |
|
intro = &mMdl.Intro{} |
|
subs = []*mMdl.Subtitle{} |
|
fonts = []*mMdl.Font{} |
|
filters = []*mMdl.Filter{} |
|
filterWithCategory = make([]*mMdl.FilterCategory, 0) |
|
vstickerWithCategory = make([]*mMdl.VstickerCategory, 0) |
|
white bool |
|
) |
|
_, white = s.stickerUps[mid] |
|
for _, v := range s.Subtitles { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
subs = append(subs, v) |
|
} |
|
for _, v := range s.Fonts { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
fonts = append(fonts, v) |
|
} |
|
for _, v := range s.Filters { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
filters = append(filters, v) |
|
} |
|
for _, v := range s.Hotwords { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
hotwords = append(hotwords, v) |
|
} |
|
for _, v := range s.Stickers { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
stickers = append(stickers, v) |
|
} |
|
for _, v := range s.Intros { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
intros = append(intros, v) |
|
} |
|
for _, v := range s.Vstickers { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
vstickers = append(vstickers, v) |
|
} |
|
for _, v := range s.Transitions { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
trans = append(trans, v) |
|
} |
|
for _, v := range s.Themes { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
themes = append(themes, v) |
|
} |
|
for _, v := range s.Cooperates { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
cooperates = append(cooperates, v) |
|
} |
|
for _, fcategory := range s.FilterWithCategory { |
|
fcategoryChilds := make([]*mMdl.Filter, 0) |
|
for _, v := range fcategory.Children { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
fcategoryChilds = append(fcategoryChilds, v) |
|
} |
|
if len(fcategoryChilds) > 0 { |
|
filterWithCategory = append(filterWithCategory, &mMdl.FilterCategory{ |
|
ID: fcategory.ID, |
|
Name: fcategory.Name, |
|
Rank: fcategory.Rank, |
|
Tp: fcategory.Tp, |
|
Children: fcategoryChilds, |
|
}) |
|
} |
|
} |
|
for _, vscategory := range s.VstickerWithCategory { |
|
vscategoryChilds := make([]*mMdl.VSticker, 0) |
|
for _, v := range vscategory.Children { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
vscategoryChilds = append(vscategoryChilds, v) |
|
} |
|
if len(vscategoryChilds) > 0 { |
|
vstickerWithCategory = append(vstickerWithCategory, &mMdl.VstickerCategory{ |
|
ID: vscategory.ID, |
|
Name: vscategory.Name, |
|
Rank: vscategory.Rank, |
|
Tp: vscategory.Tp, |
|
Children: vscategoryChilds, |
|
}) |
|
} |
|
} |
|
if len(intros) > 0 { |
|
intro = intros[0] |
|
} |
|
res = map[string]interface{}{ |
|
"filter": filters, |
|
"filter_with_category": filterWithCategory, |
|
"hotword": hotwords, |
|
"sticker": stickers, |
|
"intro": intro, |
|
"subtitle": subs, |
|
"font": fonts, |
|
"trans": trans, |
|
"themes": themes, |
|
"cooperates": cooperates, |
|
"videoup_sticker": vstickers, |
|
"vsticker_with_category": vstickerWithCategory, |
|
"latests": s.genLatests(intros, filters, subs, fonts, hotwords, stickers, vstickers, trans, cooperates, themes), |
|
} |
|
return |
|
} |
|
|
|
// begin from app 536 |
|
func (s *Service) genLatests(intros []*mMdl.Intro, filters []*mMdl.Filter, subs []*mMdl.Subtitle, fonts []*mMdl.Font, hotwords []*mMdl.Hotword, stickers []*mMdl.Sticker, vstickers []*mMdl.VSticker, trans []*mMdl.Transition, coos []*mMdl.Cooperate, themes []*mMdl.Theme) (latests map[int8]interface{}) { |
|
latests = make(map[int8]interface{}) |
|
latests[appMdl.TypeBGM] = s.LatestBgm |
|
if len(intros) > 0 { |
|
sort.Slice(intros, func(i, j int) bool { |
|
return intros[i].MTime >= intros[j].MTime |
|
}) |
|
latests[appMdl.TypeIntro] = intros[0] |
|
} |
|
if len(themes) > 0 { |
|
cthemes := make([]*mMdl.Theme, len(themes)) |
|
copy(cthemes, themes) |
|
sort.Slice(cthemes, func(i, j int) bool { |
|
return cthemes[i].MTime >= cthemes[j].MTime |
|
}) |
|
latests[appMdl.TypeTheme] = cthemes[0] |
|
} |
|
if len(coos) > 0 { |
|
ccoos := make([]*mMdl.Cooperate, len(coos)) |
|
copy(ccoos, coos) |
|
sort.Slice(ccoos, func(i, j int) bool { |
|
return ccoos[i].MTime >= ccoos[j].MTime |
|
}) |
|
latests[appMdl.TypeCooperate] = ccoos[0] |
|
} |
|
if len(trans) > 0 { |
|
ctrans := make([]*mMdl.Transition, len(trans)) |
|
copy(ctrans, trans) |
|
sort.Slice(ctrans, func(i, j int) bool { |
|
return ctrans[i].MTime >= ctrans[j].MTime |
|
}) |
|
latests[appMdl.TypeTransition] = ctrans[0] |
|
} |
|
if len(vstickers) > 0 { |
|
cvstickers := make([]*mMdl.VSticker, len(vstickers)) |
|
copy(cvstickers, vstickers) |
|
sort.Slice(cvstickers, func(i, j int) bool { |
|
return cvstickers[i].MTime >= cvstickers[j].MTime |
|
}) |
|
latests[appMdl.TypeVideoupSticker] = cvstickers[0] |
|
} |
|
if len(stickers) > 0 { |
|
cstickers := make([]*mMdl.Sticker, len(stickers)) |
|
copy(cstickers, stickers) |
|
sort.Slice(cstickers, func(i, j int) bool { |
|
return cstickers[i].MTime >= cstickers[j].MTime |
|
}) |
|
latests[appMdl.TypeSticker] = cstickers[0] |
|
} |
|
if len(hotwords) > 0 { |
|
chotwords := make([]*mMdl.Hotword, len(hotwords)) |
|
copy(chotwords, hotwords) |
|
sort.Slice(chotwords, func(i, j int) bool { |
|
return chotwords[i].MTime >= chotwords[j].MTime |
|
}) |
|
latests[appMdl.TypeHotWord] = chotwords[0] |
|
} |
|
if len(fonts) > 0 { |
|
cfonts := make([]*mMdl.Font, len(fonts)) |
|
copy(cfonts, fonts) |
|
sort.Slice(cfonts, func(i, j int) bool { |
|
return cfonts[i].MTime >= cfonts[j].MTime |
|
}) |
|
latests[appMdl.TypeFont] = cfonts[0] |
|
} |
|
if len(filters) > 0 { |
|
cfilters := make([]*mMdl.Filter, len(filters)) |
|
copy(cfilters, filters) |
|
sort.Slice(cfilters, func(i, j int) bool { |
|
return cfilters[i].MTime >= cfilters[j].MTime |
|
}) |
|
latests[appMdl.TypeFilter] = cfilters[0] |
|
} |
|
if len(subs) > 0 { |
|
csubs := make([]*mMdl.Subtitle, len(subs)) |
|
copy(csubs, subs) |
|
sort.Slice(csubs, func(i, j int) bool { |
|
return csubs[i].MTime >= csubs[j].MTime |
|
}) |
|
latests[appMdl.TypeSubtitle] = csubs[0] |
|
} |
|
return |
|
} |
|
|
|
// AddBgmFeedBack send to log service |
|
func (s *Service) AddBgmFeedBack(c context.Context, name, musicians, platform string, mid int64) (err error) { |
|
uInfo := &report.UserInfo{ |
|
Mid: mid, |
|
Platform: platform, |
|
Business: 82, // app投稿业务 |
|
Type: 1, //投稿bgm反馈 |
|
Oid: mid, |
|
Action: "add_bgm_feedback", |
|
Ctime: time.Now(), |
|
IP: metadata.String(c, metadata.RemoteIP), |
|
Index: []interface{}{name, musicians, mid}, |
|
} |
|
uInfo.Content = map[string]interface{}{ |
|
"name": name, |
|
"musicians": musicians, |
|
"mid": mid, |
|
} |
|
report.User(uInfo) |
|
log.Info("send AddBgmFeedBack Log data(%+v)", uInfo) |
|
return |
|
} |
|
|
|
// BgmSearch fn |
|
func (s *Service) BgmSearch(c context.Context, kw string, mid int64, pn, ps int) (res *sMdl.BgmSearchRes) { |
|
res = &sMdl.BgmSearchRes{ |
|
Bgms: make([]*mMdl.Music, 0), |
|
Pager: &sMdl.Pager{ |
|
Num: pn, |
|
Size: ps, |
|
Total: 0, |
|
}, |
|
} |
|
if len(kw) == 0 { |
|
return |
|
} |
|
var ( |
|
err error |
|
resIDS = make([]int64, 0) |
|
mids = make([]int64, 0) |
|
pager *sMdl.Pager |
|
minfos map[int64]*accMdl.Info |
|
) |
|
if resIDS, pager, err = s.music.SearchBgmSIDs(c, kw, pn, ps); err != nil { |
|
log.Error("s.music.SearchBgmSIDs kw(%s)|pn(%d)|ps(%d) error(%v)", kw, pn, ps, err) |
|
return |
|
} |
|
for _, sid := range resIDS { |
|
if msc, ok := s.AllMsc[sid]; ok { |
|
res.Bgms = append(res.Bgms, msc) |
|
mids = append(mids, msc.UpMID) |
|
} |
|
} |
|
if len(mids) > 0 { |
|
minfos, err = s.acc.Infos(c, mids, "localhost") |
|
if err != nil { |
|
log.Info("minfos err mids (%+v)|err(%+v)", mids, err) |
|
return |
|
} |
|
for _, v := range res.Bgms { |
|
if up, ok := minfos[v.UpMID]; ok { |
|
v.Musicians = up.Name |
|
} |
|
} |
|
} |
|
if pager != nil { |
|
res.Pager.Total = pager.Total |
|
} |
|
return |
|
} |
|
|
|
func (s *Service) getFilterAndItsCategory(ctx context.Context) { |
|
var ( |
|
err error |
|
filters []*mMdl.Filter |
|
filterMap map[int64]*mMdl.Filter |
|
filterCategory = make([]*mMdl.FilterCategory, 0) |
|
filterBinds []*mMdl.MaterialBind |
|
) |
|
c := context.Background() |
|
if filters, filterMap, err = s.material.Filters(c); err != nil { |
|
log.Error("s.material.Filters err(%+v)", err) |
|
return |
|
} |
|
s.Filters = filters |
|
if filterBinds, err = s.material.CategoryBind(c, appMdl.TypeFilter); err != nil { |
|
log.Error("s.material.CategoryBind err(%+v)", err) |
|
return |
|
} |
|
mapsByCID := make(map[int64]*mMdl.FilterCategory) |
|
for _, bind := range filterBinds { |
|
oldF := filterMap[bind.MID] |
|
if oldF == nil { |
|
continue |
|
} |
|
newF := &mMdl.Filter{ |
|
ID: oldF.ID, |
|
Name: oldF.Name, |
|
Cover: oldF.Cover, |
|
DownloadURL: oldF.DownloadURL, |
|
Rank: bind.BRank, |
|
Extra: oldF.Extra, |
|
Material: oldF.Material, |
|
MTime: oldF.MTime, |
|
New: oldF.New, |
|
Tags: oldF.Tags, |
|
FilterType: oldF.FilterType, |
|
} |
|
if _, ok := mapsByCID[bind.CID]; !ok { |
|
mapsByCID[bind.CID] = &mMdl.FilterCategory{ |
|
ID: bind.CID, |
|
Name: bind.CName, |
|
Rank: bind.CRank, |
|
Tp: bind.Tp, |
|
New: bind.New, |
|
Children: []*mMdl.Filter{newF}, |
|
} |
|
} else { |
|
mapsByCID[bind.CID].Children = append(mapsByCID[bind.CID].Children, newF) |
|
} |
|
} |
|
for _, v := range mapsByCID { |
|
sort.Slice(v.Children, func(i, j int) bool { |
|
return v.Children[i].Rank <= v.Children[j].Rank |
|
}) |
|
filterCategory = append(filterCategory, v) |
|
} |
|
sort.Slice(filterCategory, func(i, j int) bool { |
|
return filterCategory[i].Rank <= filterCategory[j].Rank |
|
}) |
|
s.FilterWithCategory = filterCategory |
|
} |
|
|
|
func (s *Service) getCooperates(ctx context.Context) { |
|
var ( |
|
err error |
|
coos []*mMdl.Cooperate |
|
daids []int64 |
|
darcMap map[int64]*api.Arc |
|
) |
|
c := context.Background() |
|
if coos, daids, err = s.material.Cooperates(c); err != nil { |
|
log.Error("s.material.Cooperates err(%+v)", err) |
|
return |
|
} |
|
ip := metadata.String(c, metadata.RemoteIP) |
|
if len(daids) > 0 { |
|
if darcMap, err = s.archive.Archives(c, daids, ip); err != nil { |
|
log.Error("s.archive.Archives err(%+v)", err) |
|
return |
|
} |
|
} |
|
for _, v := range coos { |
|
mtime := v.MTime.Time() |
|
hot1 := 20000 |
|
hot2 := mtime.Hour()*100 + mtime.Minute() |
|
hot3 := 567 * v.ArcCnt |
|
v.HotVal = hot1 + hot2 + hot3 |
|
if arc, ok := darcMap[v.DemoAID]; ok { |
|
v.Cover = arc.Pic |
|
} |
|
} |
|
s.Cooperates = coos |
|
} |
|
|
|
func (s *Service) getVStickerAndItsCategory(ctx context.Context) { |
|
var ( |
|
err error |
|
vstickers []*mMdl.VSticker |
|
vstickersMap map[int64]*mMdl.VSticker |
|
vstickerCategory = make([]*mMdl.VstickerCategory, 0) |
|
vstickerBinds []*mMdl.MaterialBind |
|
) |
|
c := context.Background() |
|
if vstickers, vstickersMap, err = s.material.Vstickers(c); err != nil { |
|
log.Error("s.material.vstickers err(%+v)", err) |
|
return |
|
} |
|
s.Vstickers = vstickers |
|
if vstickerBinds, err = s.material.CategoryBind(c, appMdl.TypeVideoupSticker); err != nil { |
|
log.Error("s.material.CategoryBind err(%+v)", err) |
|
return |
|
} |
|
mapsByCID := make(map[int64]*mMdl.VstickerCategory) |
|
for _, bind := range vstickerBinds { |
|
oldF := vstickersMap[bind.MID] |
|
if oldF == nil { |
|
continue |
|
} |
|
newF := &mMdl.VSticker{ |
|
ID: oldF.ID, |
|
Name: oldF.Name, |
|
Cover: oldF.Cover, |
|
DownloadURL: oldF.DownloadURL, |
|
Rank: bind.BRank, |
|
Extra: oldF.Extra, |
|
Material: oldF.Material, |
|
} |
|
if _, ok := mapsByCID[bind.CID]; !ok { |
|
mapsByCID[bind.CID] = &mMdl.VstickerCategory{ |
|
ID: bind.CID, |
|
Name: bind.CName, |
|
Rank: bind.CRank, |
|
Tp: bind.Tp, |
|
New: bind.New, |
|
Children: []*mMdl.VSticker{newF}, |
|
} |
|
} else { |
|
mapsByCID[bind.CID].Children = append(mapsByCID[bind.CID].Children, newF) |
|
} |
|
} |
|
for _, v := range mapsByCID { |
|
sort.Slice(v.Children, func(i, j int) bool { |
|
return v.Children[i].Rank <= v.Children[j].Rank |
|
}) |
|
vstickerCategory = append(vstickerCategory, v) |
|
} |
|
sort.Slice(vstickerCategory, func(i, j int) bool { |
|
return vstickerCategory[i].Rank <= vstickerCategory[j].Rank |
|
}) |
|
s.VstickerWithCategory = vstickerCategory |
|
} |
|
|
|
// CooperatePre fn |
|
func (s *Service) CooperatePre(c context.Context, mid int64, platStr string, build int) (cooperates []*mMdl.Cooperate) { |
|
var ( |
|
white bool |
|
) |
|
cooperates = make([]*mMdl.Cooperate, 0) |
|
_, white = s.stickerUps[mid] |
|
for _, v := range s.Cooperates { |
|
if !v.AllowMaterial(v.Material, platStr, build, white) { |
|
continue |
|
} |
|
cooperates = append(cooperates, v) |
|
} |
|
for _, x := range cooperates { |
|
if x.MissionID > 0 { |
|
if mis, ok := s.p.ActMapCache[x.MissionID]; ok { |
|
x.Mission = mis |
|
} |
|
} |
|
} |
|
return |
|
}
|
|
|