go-common/app/interface/main/creative/service/music/service.go
2019-04-22 18:49:16 +08:00

1094 lines
29 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}