go-common/app/interface/main/creative/service/music/service.go

1094 lines
29 KiB
Go
Raw Normal View History

2019-04-22 10:49:16 +00:00
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
}