723 lines
18 KiB
Go
723 lines
18 KiB
Go
package resource
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
|
|
"go-common/app/interface/main/web-show/dao/resource"
|
|
rsmdl "go-common/app/interface/main/web-show/model/resource"
|
|
"go-common/app/service/main/archive/api"
|
|
arcmdl "go-common/app/service/main/archive/model/archive"
|
|
locmdl "go-common/app/service/main/location/model"
|
|
"go-common/library/log"
|
|
"go-common/library/net/metadata"
|
|
)
|
|
|
|
const (
|
|
_nullImage = "https://static.hdslb.com/images/transparent.gif"
|
|
_videoPrefix = "http://www.bilibili.com/video/av"
|
|
_bangumiPrefix = "bilibili://bangumi/season/"
|
|
_GamePrefix = "bilibili://game/"
|
|
_LivePrefix = "bilibili://live/"
|
|
_AVprefix = "bilibili://video/"
|
|
_topicPrefix = "//www.bilibili.com/tag/"
|
|
)
|
|
|
|
var (
|
|
_emptyRelation = []*rsmdl.Relation{}
|
|
_emptyAsgs = []*rsmdl.Assignment{}
|
|
_contractMap = map[string]struct{}{
|
|
"banner": struct{}{},
|
|
"focus": struct{}{},
|
|
"promote": struct{}{},
|
|
"app_banner": struct{}{},
|
|
"text_link": struct{}{},
|
|
"frontpage": struct{}{},
|
|
}
|
|
_bannerID = map[int64]struct{}{
|
|
142: struct{}{},
|
|
1576: struct{}{},
|
|
1580: struct{}{},
|
|
1584: struct{}{},
|
|
1588: struct{}{},
|
|
1592: struct{}{},
|
|
1596: struct{}{},
|
|
1600: struct{}{},
|
|
1604: struct{}{},
|
|
1608: struct{}{},
|
|
1612: struct{}{},
|
|
1616: struct{}{},
|
|
1620: struct{}{},
|
|
1622: struct{}{},
|
|
1634: struct{}{},
|
|
1920: struct{}{},
|
|
2260: struct{}{},
|
|
2210: struct{}{},
|
|
}
|
|
_cpmGrayRate = int64(0)
|
|
_white = map[int64]struct{}{}
|
|
_cpmOn = true
|
|
_RelationResID = 162
|
|
)
|
|
|
|
// URLMonitor return all urls configured
|
|
func (s *Service) URLMonitor(c context.Context, pf int) (urls map[string]string) {
|
|
return s.urlMonitor[pf]
|
|
}
|
|
|
|
// GrayRate return gray percent
|
|
func (s *Service) GrayRate(c context.Context) (r int64, ws []int64, swt bool) {
|
|
r = _cpmGrayRate
|
|
for w := range _white {
|
|
ws = append(ws, w)
|
|
}
|
|
swt = _cpmOn
|
|
return
|
|
}
|
|
|
|
// SetGrayRate set gray percent
|
|
func (s *Service) SetGrayRate(c context.Context, swt bool, rate int64, white []int64) {
|
|
_cpmGrayRate = rate
|
|
tmp := map[int64]struct{}{}
|
|
for _, w := range white {
|
|
tmp[w] = struct{}{}
|
|
}
|
|
_cpmOn = swt
|
|
_white = tmp
|
|
}
|
|
|
|
// Resources get resource info by pf,ids
|
|
func (s *Service) Resources(c context.Context, arg *rsmdl.ArgRess) (mres map[string][]*rsmdl.Assignment, count int, err error) {
|
|
var (
|
|
aids []int64
|
|
arcs map[int64]*api.Arc
|
|
country, province, city string
|
|
info *locmdl.Info
|
|
)
|
|
arg.IP = metadata.String(c, metadata.RemoteIP)
|
|
if info, err = s.locRPC.Info(c, &locmdl.ArgIP{IP: arg.IP}); err != nil {
|
|
log.Error("Location RPC error %v", err)
|
|
err = nil
|
|
}
|
|
if info != nil {
|
|
country = info.Country
|
|
province = info.Province
|
|
city = info.City
|
|
}
|
|
area := checkAera(country)
|
|
var cpmInfos map[int64]*rsmdl.Assignment
|
|
if _cpmOn {
|
|
cpmInfos = s.cpms(c, arg.Mid, arg.Ids, arg.Sid, arg.IP, country, province, city, arg.Buvid)
|
|
} else if _, ok := _white[arg.Mid]; ok || (arg.Mid%100 < _cpmGrayRate && arg.Mid != 0) {
|
|
cpmInfos = s.cpms(c, arg.Mid, arg.Ids, arg.Sid, arg.IP, country, province, city, arg.Buvid)
|
|
}
|
|
mres = make(map[string][]*rsmdl.Assignment)
|
|
for _, id := range arg.Ids {
|
|
pts := s.posCache[posKey(arg.Pf, int(id))]
|
|
if pts == nil {
|
|
continue
|
|
}
|
|
count = pts.Counter
|
|
// add ads if exists
|
|
res, as := s.res(c, cpmInfos, int(id), area, pts, arg.Mid)
|
|
mres[strconv.FormatInt(id, 10)] = res
|
|
aids = append(aids, as...)
|
|
}
|
|
// fill archive if has video ad
|
|
if len(aids) != 0 {
|
|
argAids := &arcmdl.ArgAids2{
|
|
Aids: aids,
|
|
}
|
|
if arcs, err = s.arcRPC.Archives3(c, argAids); err != nil {
|
|
resource.PromError("arcRPC.Archives3", "s.arcRPC.Archives3(arcAids:(%v), arcs), err(%v)", aids, err)
|
|
return
|
|
}
|
|
for _, tres := range mres {
|
|
for _, rs := range tres {
|
|
if arc, ok := arcs[rs.Aid]; ok {
|
|
rs.Archive = arc
|
|
if rs.Name == "" {
|
|
rs.Name = arc.Title
|
|
}
|
|
if rs.Pic == "" {
|
|
rs.Pic = arc.Pic
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// if id is banner and not content add defult
|
|
for i, rs := range mres {
|
|
if len(rs) == 0 {
|
|
id, _ := strconv.ParseInt(i, 10, 64)
|
|
if _, ok := _bannerID[id]; ok {
|
|
mres[i] = append(mres[i], s.defBannerCache)
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// cpmBanners
|
|
func (s *Service) cpms(c context.Context, mid int64, ids []int64, sid, ip, country, province, city, buvid string) (res map[int64]*rsmdl.Assignment) {
|
|
cpmInfos, err := s.adDao.Cpms(c, mid, ids, sid, ip, country, province, city, buvid)
|
|
if err != nil {
|
|
log.Error("s.adDao.Cpms error(%v)", err)
|
|
return
|
|
}
|
|
res = make(map[int64]*rsmdl.Assignment, len(cpmInfos.AdsInfo))
|
|
for _, id := range ids {
|
|
idStr := strconv.FormatInt(id, 10)
|
|
if adsInfos := cpmInfos.AdsInfo[idStr]; len(adsInfos) > 0 {
|
|
for srcStr, adsInfo := range adsInfos {
|
|
// var url string
|
|
srcIDInt, _ := strconv.ParseInt(srcStr, 10, 64)
|
|
if adInfo := adsInfo.AdInfo; adInfo != nil {
|
|
//switch adInfo.CreativeType {
|
|
// case 0:
|
|
// url = adInfo.CreativeContent.URL
|
|
// case 1:
|
|
// url = "www.bilibili.com/video/av" + adInfo.CreativeContent.VideoID
|
|
// }
|
|
ad := &rsmdl.Assignment{
|
|
CreativeType: adInfo.CreativeType,
|
|
Aid: adInfo.CreativeContent.VideoID,
|
|
RequestID: cpmInfos.RequestID,
|
|
SrcID: srcIDInt,
|
|
IsAdLoc: true,
|
|
IsAd: adsInfo.IsAd,
|
|
CmMark: adsInfo.CmMark,
|
|
CreativeID: adInfo.CreativeID,
|
|
AdCb: adInfo.AdCb,
|
|
ShowURL: adInfo.CreativeContent.ShowURL,
|
|
ClickURL: adInfo.CreativeContent.ClickURL,
|
|
Name: adInfo.CreativeContent.Title,
|
|
Pic: adInfo.CreativeContent.ImageURL,
|
|
LitPic: adInfo.CreativeContent.ThumbnailURL,
|
|
URL: adInfo.CreativeContent.URL,
|
|
PosNum: int(adsInfo.Index),
|
|
Title: adInfo.CreativeContent.Title,
|
|
ServerType: rsmdl.FromCpm,
|
|
IsCpm: true,
|
|
}
|
|
res[srcIDInt] = ad
|
|
} else {
|
|
ad := &rsmdl.Assignment{
|
|
IsAdLoc: true,
|
|
RequestID: cpmInfos.RequestID,
|
|
IsAd: false,
|
|
SrcID: srcIDInt,
|
|
ResID: int(id),
|
|
CmMark: adsInfo.CmMark,
|
|
}
|
|
res[srcIDInt] = ad
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func checkAera(country string) (area int8) {
|
|
switch country {
|
|
case "中国":
|
|
area = 1
|
|
case "香港", "台湾", "澳门":
|
|
area = 2
|
|
case "日本":
|
|
area = 3
|
|
case "美国":
|
|
area = 4
|
|
default:
|
|
if _, ok := rsmdl.OverSeasCountry[country]; ok {
|
|
area = 5
|
|
} else {
|
|
area = 0
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// Relation get relation archives by aid
|
|
func (s *Service) Relation(c context.Context, arg *rsmdl.ArgAid) (rls []*rsmdl.Relation, err error) {
|
|
|
|
var aids []int64
|
|
rls = _emptyRelation
|
|
arg.IP = metadata.String(c, metadata.RemoteIP)
|
|
if aids, err = s.dataDao.Related(c, arg.Aid, arg.IP); err != nil {
|
|
log.Error("s.dataDao.Related aid(%v) error(%v)", arg.Aid, err)
|
|
return
|
|
}
|
|
|
|
if len(aids) == 0 {
|
|
log.Warn("zero_relates")
|
|
return
|
|
}
|
|
argAdis := &arcmdl.ArgAids2{
|
|
Aids: aids,
|
|
RealIP: arg.IP,
|
|
}
|
|
arcs, err := s.arcRPC.Archives3(c, argAdis)
|
|
if err != nil {
|
|
log.Info("s.arcDao.Archives3", err)
|
|
return
|
|
}
|
|
var res []*rsmdl.Relation
|
|
for _, arc := range arcs {
|
|
res = append(res, &rsmdl.Relation{Arc: arc})
|
|
}
|
|
rls = res
|
|
if len(res) < 3 {
|
|
return
|
|
}
|
|
var (
|
|
country, province, city string
|
|
info *locmdl.Info
|
|
)
|
|
if info, err = s.locRPC.Info(c, &locmdl.ArgIP{IP: arg.IP}); err != nil {
|
|
log.Error("Location RPC error %v", err)
|
|
err = nil
|
|
}
|
|
if info != nil {
|
|
country = info.Country
|
|
province = info.Province
|
|
city = info.City
|
|
}
|
|
area := checkAera(country)
|
|
//pts := s.posCache[posKey(0, _RelationResID)]
|
|
cpmInfos := s.cpms(c, arg.Mid, []int64{int64(_RelationResID)}, arg.Sid, arg.IP, country, province, city, arg.Buvid)
|
|
for _, rs := range cpmInfos {
|
|
// just fet one ad
|
|
if rs.IsAd {
|
|
arcAid := &arcmdl.ArgAid2{
|
|
Aid: rs.Aid,
|
|
}
|
|
var arc *api.Arc
|
|
arc, err = s.arcRPC.Archive3(c, arcAid)
|
|
if err != nil {
|
|
resource.PromError("arcRPC.Archive3", "s.arcRPC.Archive3(arcAid:(%v), arcs), err(%v)", rs.Aid, err)
|
|
err = nil
|
|
rls = res
|
|
return
|
|
}
|
|
rl := &rsmdl.Relation{
|
|
Arc: arc,
|
|
Area: area,
|
|
RequestID: rs.RequestID,
|
|
CreativeID: rs.CreativeID,
|
|
AdCb: rs.AdCb,
|
|
SrcID: rs.SrcID,
|
|
ShowURL: rs.ShowURL,
|
|
ClickURL: rs.ClickURL,
|
|
IsAdLoc: rs.IsAdLoc,
|
|
ResID: _RelationResID,
|
|
IsAd: true,
|
|
}
|
|
if rs.Pic != "" {
|
|
rl.Pic = rs.Pic
|
|
}
|
|
if rs.Title != "" {
|
|
rl.Title = rs.Title
|
|
}
|
|
rls = append(res[:2], append([]*rsmdl.Relation{rl}, res[2:]...)...)
|
|
return
|
|
}
|
|
res[2].AdCb = rs.AdCb
|
|
res[2].SrcID = rs.SrcID
|
|
res[2].ShowURL = rs.ShowURL
|
|
res[2].ClickURL = rs.ClickURL
|
|
res[2].IsAdLoc = rs.IsAdLoc
|
|
res[2].RequestID = rs.RequestID
|
|
res[2].CreativeID = rs.CreativeID
|
|
res[2].ResID = _RelationResID
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// Resource get resource info by pf,id
|
|
func (s *Service) Resource(c context.Context, arg *rsmdl.ArgRes) (res []*rsmdl.Assignment, count int, err error) {
|
|
var (
|
|
aids []int64
|
|
arcs map[int64]*api.Arc
|
|
country, province, city string
|
|
info *locmdl.Info
|
|
)
|
|
arg.IP = metadata.String(c, metadata.RemoteIP)
|
|
res = _emptyAsgs
|
|
pts := s.posCache[posKey(arg.Pf, int(arg.ID))]
|
|
if pts == nil {
|
|
return
|
|
}
|
|
count = pts.Counter
|
|
if info, err = s.locRPC.Info(c, &locmdl.ArgIP{IP: arg.IP}); err != nil {
|
|
log.Error("Location RPC error %v", err)
|
|
err = nil
|
|
}
|
|
if info != nil {
|
|
country = info.Country
|
|
province = info.Province
|
|
city = info.City
|
|
}
|
|
area := checkAera(country)
|
|
var cpmInfos map[int64]*rsmdl.Assignment
|
|
if _cpmOn {
|
|
cpmInfos = s.cpms(c, arg.Mid, []int64{arg.ID}, arg.Sid, arg.IP, country, province, city, arg.Buvid)
|
|
} else if _, ok := _white[arg.Mid]; ok || (arg.Mid%100 < _cpmGrayRate && arg.Mid != 0) {
|
|
cpmInfos = s.cpms(c, arg.Mid, []int64{arg.ID}, arg.Sid, arg.IP, country, province, city, arg.Buvid)
|
|
}
|
|
res, aids = s.res(c, cpmInfos, int(arg.ID), area, pts, arg.Mid)
|
|
// fill archive if has video ad
|
|
if len(aids) != 0 {
|
|
argAids := &arcmdl.ArgAids2{
|
|
Aids: aids,
|
|
}
|
|
if arcs, err = s.arcRPC.Archives3(c, argAids); err != nil {
|
|
resource.PromError("arcRPC.Archive3", "s.arcRPC.Archive3(arcAid:(%v), arcs), err(%v)", aids, err)
|
|
return
|
|
}
|
|
for _, rs := range res {
|
|
if arc, ok := arcs[rs.Aid]; ok {
|
|
rs.Archive = arc
|
|
if rs.Name == "" {
|
|
rs.Name = arc.Title
|
|
}
|
|
if rs.Pic == "" {
|
|
rs.Pic = arc.Pic
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// add defBanner if contnent not exits
|
|
if len(res) == 0 {
|
|
if _, ok := _bannerID[int64(arg.ID)]; ok {
|
|
// 142 is index banner
|
|
if rs := s.resByID(142); rs != nil {
|
|
res = append(res, rs)
|
|
} else {
|
|
res = append(res, s.defBannerCache)
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *Service) res(c context.Context, cpmInfos map[int64]*rsmdl.Assignment, id int, area int8, pts *rsmdl.Position, mid int64) (res []*rsmdl.Assignment, aids []int64) {
|
|
// add ads if exists
|
|
var (
|
|
reqID string
|
|
index int
|
|
resIndex int
|
|
ts = strconv.FormatInt(time.Now().Unix(), 10)
|
|
resBs []*rsmdl.Assignment
|
|
)
|
|
for _, pt := range pts.Pos {
|
|
var isAdLoc bool
|
|
if rs, ok := cpmInfos[int64(pt.ID)]; ok && rs.IsCpm {
|
|
rs.Area = area
|
|
if mid != 0 {
|
|
rs.Mid = strconv.FormatInt(mid, 10)
|
|
}
|
|
if rs.CreativeType == rsmdl.CreativeVideo {
|
|
aids = append(aids, rs.Aid)
|
|
}
|
|
rs.ServerType = rsmdl.FromCpm
|
|
res = append(res, rs)
|
|
if rsb := s.resByID(pt.ID); rsb != nil {
|
|
// url mean aid in Asgtypevideo
|
|
resBs = append(resBs, rsb)
|
|
}
|
|
continue
|
|
} else if ok && !rs.IsCpm {
|
|
isAdLoc = true
|
|
reqID = rs.RequestID
|
|
}
|
|
var rs *rsmdl.Assignment
|
|
resBslen := len(resBs)
|
|
if resIndex < resBslen {
|
|
rs = resBs[resIndex]
|
|
resIndex++
|
|
if rsb := s.resByID(pt.ID); rsb != nil {
|
|
resBs = append(resBs, rsb)
|
|
}
|
|
} else if rs = s.resByID(pt.ID); rs != nil {
|
|
|
|
} else {
|
|
rs = s.resByIndex(id, index)
|
|
index++
|
|
}
|
|
if rs != nil {
|
|
if rs.Atype == rsmdl.AsgTypeVideo || rs.Atype == rsmdl.AsgTypeAv {
|
|
aids = append(aids, rs.Aid)
|
|
}
|
|
rs.PosNum = pt.PosNum
|
|
rs.SrcID = int64(pt.ID)
|
|
rs.Area = area
|
|
rs.IsAdLoc = isAdLoc
|
|
if isAdLoc {
|
|
rs.RequestID = reqID
|
|
} else {
|
|
rs.RequestID = ts
|
|
}
|
|
if mid != 0 {
|
|
rs.Mid = strconv.FormatInt(mid, 10)
|
|
}
|
|
res = append(res, rs)
|
|
} else if isAdLoc {
|
|
rs = &rsmdl.Assignment{
|
|
PosNum: pt.PosNum,
|
|
SrcID: int64(pt.ID),
|
|
IsAdLoc: isAdLoc,
|
|
RequestID: reqID,
|
|
Area: area,
|
|
Pic: _nullImage,
|
|
}
|
|
if mid != 0 {
|
|
rs.Mid = strconv.FormatInt(mid, 10)
|
|
}
|
|
res = append(res, rs)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// resByIndex return res of index
|
|
func (s *Service) resByIndex(id, index int) (res *rsmdl.Assignment) {
|
|
ss := s.asgCache[id]
|
|
if index >= len(ss) {
|
|
return
|
|
}
|
|
res = new(rsmdl.Assignment)
|
|
*res = *(ss[index])
|
|
return
|
|
}
|
|
|
|
// resByID return res of id
|
|
func (s *Service) resByID(id int) (res *rsmdl.Assignment) {
|
|
ss := s.asgCache[id]
|
|
l := len(ss)
|
|
if l == 0 {
|
|
return
|
|
}
|
|
res = ss[0]
|
|
for _, s := range ss {
|
|
// ContractId not in contractMap ,it is ad and ad first
|
|
if _, ok := _contractMap[s.ContractID]; !ok {
|
|
res = s
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// rpc resourcesALL
|
|
func (s *Service) resourcesALL() (rscs []*rsmdl.Res, err error) {
|
|
resourcesRPC, err := s.recrpc.ResourceAll(context.Background())
|
|
if err != nil {
|
|
resource.PromError("recRPC.ResourcesALL", "s.recrpc.resourcesRPC error(%v)", err)
|
|
return
|
|
}
|
|
rscs = make([]*rsmdl.Res, 0)
|
|
for _, res := range resourcesRPC {
|
|
rsc := &rsmdl.Res{
|
|
ID: res.ID,
|
|
Platform: res.Platform,
|
|
Name: res.Name,
|
|
Parent: res.Parent,
|
|
Counter: res.Counter,
|
|
Position: res.Position,
|
|
}
|
|
rscs = append(rscs, rsc)
|
|
}
|
|
return
|
|
}
|
|
|
|
// rpc assignmentAll
|
|
func (s *Service) assignmentAll() (asgs []*rsmdl.Assignment, err error) {
|
|
assignRPC, err := s.recrpc.AssignmentAll(context.Background())
|
|
if err != nil {
|
|
resource.PromError("recRPC.AssignmentAll", "s.recrpc.assignRPC error(%v)", err)
|
|
return
|
|
}
|
|
asgs = make([]*rsmdl.Assignment, 0)
|
|
for _, asgr := range assignRPC {
|
|
asg := &rsmdl.Assignment{
|
|
ID: asgr.ID,
|
|
Name: asgr.Name,
|
|
ContractID: asgr.ContractID,
|
|
ResID: asgr.ResID,
|
|
Pic: asgr.Pic,
|
|
LitPic: asgr.LitPic,
|
|
URL: asgr.URL,
|
|
Atype: asgr.Atype,
|
|
Weight: asgr.Weight,
|
|
Rule: asgr.Rule,
|
|
Agency: asgr.Agency,
|
|
STime: asgr.STime,
|
|
}
|
|
asgs = append(asgs, asg)
|
|
}
|
|
return
|
|
}
|
|
|
|
// default banner
|
|
func (s *Service) defBanner() (asg *rsmdl.Assignment, err error) {
|
|
bannerRPC, err := s.recrpc.DefBanner(context.Background())
|
|
if err != nil {
|
|
resource.PromError("recRPC.defBanner", "s.recrpc.defBanner error(%v)", err)
|
|
return
|
|
}
|
|
if bannerRPC != nil {
|
|
asg = &rsmdl.Assignment{
|
|
ID: bannerRPC.ID,
|
|
Name: bannerRPC.Name,
|
|
ContractID: bannerRPC.ContractID,
|
|
ResID: bannerRPC.ResID,
|
|
Pic: bannerRPC.Pic,
|
|
LitPic: bannerRPC.LitPic,
|
|
URL: bannerRPC.URL,
|
|
Atype: bannerRPC.Atype,
|
|
Weight: bannerRPC.Weight,
|
|
Rule: bannerRPC.Rule,
|
|
Agency: bannerRPC.Agency,
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// LoadRes load Res info to cache
|
|
func (s *Service) loadRes() (err error) {
|
|
assign, err := s.assignmentAll()
|
|
if err != nil {
|
|
return
|
|
}
|
|
resources, err := s.resourcesALL()
|
|
if err != nil {
|
|
return
|
|
}
|
|
resMap := make(map[int]*rsmdl.Res)
|
|
posMap := make(map[string]*rsmdl.Position)
|
|
for _, res := range resources {
|
|
resMap[res.ID] = res
|
|
if res.Counter > 0 {
|
|
key := posKey(res.Platform, res.ID)
|
|
pos := &rsmdl.Position{
|
|
Pos: make([]*rsmdl.Loc, 0),
|
|
Counter: res.Counter,
|
|
}
|
|
posMap[key] = pos
|
|
} else {
|
|
key := posKey(res.Platform, res.Parent)
|
|
if pos, ok := posMap[key]; ok {
|
|
loc := &rsmdl.Loc{
|
|
ID: res.ID,
|
|
PosNum: res.Position,
|
|
}
|
|
pos.Pos = append(pos.Pos, loc)
|
|
}
|
|
}
|
|
}
|
|
for _, a := range assign {
|
|
if res, ok := resMap[a.ResID]; ok {
|
|
if err = s.convertURL(a); err != nil {
|
|
return
|
|
}
|
|
var data struct {
|
|
Cover int32 `json:"is_cover"`
|
|
Style int32 `json:"style"`
|
|
Label string `json:"label"`
|
|
Intro string `json:"intro"`
|
|
CreativeType int8 `json:"creative_type"`
|
|
}
|
|
// unmarshal rule for frontpage style
|
|
if a.Rule != "" {
|
|
e := json.Unmarshal([]byte(a.Rule), &data)
|
|
if e != nil {
|
|
log.Error("json.Unmarshal (%s) error(%v)", a.Rule, e)
|
|
} else {
|
|
a.Style = data.Style
|
|
a.CreativeType = data.CreativeType
|
|
if a.ContractID == "rec_video" {
|
|
a.Label = data.Label
|
|
a.Intro = data.Intro
|
|
}
|
|
}
|
|
}
|
|
res.Assignments = append(res.Assignments, a)
|
|
}
|
|
|
|
}
|
|
urlMonitor := make(map[int]map[string]string)
|
|
tmp := make(map[int][]*rsmdl.Assignment, len(resMap))
|
|
for _, res := range resMap {
|
|
tmp[res.ID] = res.Assignments
|
|
urlMap, ok := urlMonitor[res.Platform]
|
|
if !ok {
|
|
urlMap = make(map[string]string)
|
|
urlMonitor[res.Platform] = urlMap
|
|
}
|
|
for _, a := range res.Assignments {
|
|
urlMap[fmt.Sprintf("%d_%s", a.ResID, a.Name)] = a.URL
|
|
}
|
|
}
|
|
s.asgCache = tmp
|
|
s.posCache = posMap
|
|
s.urlMonitor = urlMonitor
|
|
// load default banner
|
|
banner, err := s.defBanner()
|
|
if err != nil {
|
|
return
|
|
} else if banner != nil {
|
|
var data struct {
|
|
Cover int32 `json:"is_cover"`
|
|
Style int32 `json:"style"`
|
|
}
|
|
err := json.Unmarshal([]byte(banner.Rule), &data)
|
|
if err != nil {
|
|
log.Error("json.Unmarshal (%s) error(%v)", banner.Rule, err)
|
|
} else {
|
|
banner.Style = data.Style
|
|
}
|
|
s.defBannerCache = banner
|
|
}
|
|
return
|
|
}
|
|
|
|
func posKey(pf, id int) string {
|
|
return fmt.Sprintf("%d_%d", pf, id)
|
|
}
|
|
|
|
func (s *Service) convertURL(a *rsmdl.Assignment) (err error) {
|
|
switch a.Atype {
|
|
case rsmdl.AsgTypeVideo:
|
|
var aid int64
|
|
if aid, err = strconv.ParseInt(a.URL, 10, 64); err != nil {
|
|
log.Error("strconv.ParseInt(%s) err(%v)", a.URL, err)
|
|
return
|
|
}
|
|
a.Aid = aid
|
|
a.URL = _videoPrefix + a.URL
|
|
case rsmdl.AsgTypeURL:
|
|
case rsmdl.AsgTypeBangumi:
|
|
a.URL = _bangumiPrefix + a.URL
|
|
case rsmdl.AsgTypeLive:
|
|
a.URL = _LivePrefix + a.URL
|
|
case rsmdl.AsgTypeGame:
|
|
a.URL = _GamePrefix + a.URL
|
|
case rsmdl.AsgTypeAv:
|
|
var aid int64
|
|
if aid, err = strconv.ParseInt(a.URL, 10, 64); err != nil {
|
|
log.Error("strconv.ParseInt(%s) err(%v)", a.URL, err)
|
|
return
|
|
}
|
|
a.Aid = aid
|
|
a.URL = _AVprefix + a.URL
|
|
case rsmdl.AsgTypeTopic:
|
|
a.URL = _topicPrefix + a.URL
|
|
}
|
|
return
|
|
}
|