res.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. package resource
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. "strconv"
  7. "time"
  8. "go-common/app/interface/main/web-show/dao/resource"
  9. rsmdl "go-common/app/interface/main/web-show/model/resource"
  10. "go-common/app/service/main/archive/api"
  11. arcmdl "go-common/app/service/main/archive/model/archive"
  12. locmdl "go-common/app/service/main/location/model"
  13. "go-common/library/log"
  14. "go-common/library/net/metadata"
  15. )
  16. const (
  17. _nullImage = "https://static.hdslb.com/images/transparent.gif"
  18. _videoPrefix = "http://www.bilibili.com/video/av"
  19. _bangumiPrefix = "bilibili://bangumi/season/"
  20. _GamePrefix = "bilibili://game/"
  21. _LivePrefix = "bilibili://live/"
  22. _AVprefix = "bilibili://video/"
  23. _topicPrefix = "//www.bilibili.com/tag/"
  24. )
  25. var (
  26. _emptyRelation = []*rsmdl.Relation{}
  27. _emptyAsgs = []*rsmdl.Assignment{}
  28. _contractMap = map[string]struct{}{
  29. "banner": struct{}{},
  30. "focus": struct{}{},
  31. "promote": struct{}{},
  32. "app_banner": struct{}{},
  33. "text_link": struct{}{},
  34. "frontpage": struct{}{},
  35. }
  36. _bannerID = map[int64]struct{}{
  37. 142: struct{}{},
  38. 1576: struct{}{},
  39. 1580: struct{}{},
  40. 1584: struct{}{},
  41. 1588: struct{}{},
  42. 1592: struct{}{},
  43. 1596: struct{}{},
  44. 1600: struct{}{},
  45. 1604: struct{}{},
  46. 1608: struct{}{},
  47. 1612: struct{}{},
  48. 1616: struct{}{},
  49. 1620: struct{}{},
  50. 1622: struct{}{},
  51. 1634: struct{}{},
  52. 1920: struct{}{},
  53. 2260: struct{}{},
  54. 2210: struct{}{},
  55. }
  56. _cpmGrayRate = int64(0)
  57. _white = map[int64]struct{}{}
  58. _cpmOn = true
  59. _RelationResID = 162
  60. )
  61. // URLMonitor return all urls configured
  62. func (s *Service) URLMonitor(c context.Context, pf int) (urls map[string]string) {
  63. return s.urlMonitor[pf]
  64. }
  65. // GrayRate return gray percent
  66. func (s *Service) GrayRate(c context.Context) (r int64, ws []int64, swt bool) {
  67. r = _cpmGrayRate
  68. for w := range _white {
  69. ws = append(ws, w)
  70. }
  71. swt = _cpmOn
  72. return
  73. }
  74. // SetGrayRate set gray percent
  75. func (s *Service) SetGrayRate(c context.Context, swt bool, rate int64, white []int64) {
  76. _cpmGrayRate = rate
  77. tmp := map[int64]struct{}{}
  78. for _, w := range white {
  79. tmp[w] = struct{}{}
  80. }
  81. _cpmOn = swt
  82. _white = tmp
  83. }
  84. // Resources get resource info by pf,ids
  85. func (s *Service) Resources(c context.Context, arg *rsmdl.ArgRess) (mres map[string][]*rsmdl.Assignment, count int, err error) {
  86. var (
  87. aids []int64
  88. arcs map[int64]*api.Arc
  89. country, province, city string
  90. info *locmdl.Info
  91. )
  92. arg.IP = metadata.String(c, metadata.RemoteIP)
  93. if info, err = s.locRPC.Info(c, &locmdl.ArgIP{IP: arg.IP}); err != nil {
  94. log.Error("Location RPC error %v", err)
  95. err = nil
  96. }
  97. if info != nil {
  98. country = info.Country
  99. province = info.Province
  100. city = info.City
  101. }
  102. area := checkAera(country)
  103. var cpmInfos map[int64]*rsmdl.Assignment
  104. if _cpmOn {
  105. cpmInfos = s.cpms(c, arg.Mid, arg.Ids, arg.Sid, arg.IP, country, province, city, arg.Buvid)
  106. } else if _, ok := _white[arg.Mid]; ok || (arg.Mid%100 < _cpmGrayRate && arg.Mid != 0) {
  107. cpmInfos = s.cpms(c, arg.Mid, arg.Ids, arg.Sid, arg.IP, country, province, city, arg.Buvid)
  108. }
  109. mres = make(map[string][]*rsmdl.Assignment)
  110. for _, id := range arg.Ids {
  111. pts := s.posCache[posKey(arg.Pf, int(id))]
  112. if pts == nil {
  113. continue
  114. }
  115. count = pts.Counter
  116. // add ads if exists
  117. res, as := s.res(c, cpmInfos, int(id), area, pts, arg.Mid)
  118. mres[strconv.FormatInt(id, 10)] = res
  119. aids = append(aids, as...)
  120. }
  121. // fill archive if has video ad
  122. if len(aids) != 0 {
  123. argAids := &arcmdl.ArgAids2{
  124. Aids: aids,
  125. }
  126. if arcs, err = s.arcRPC.Archives3(c, argAids); err != nil {
  127. resource.PromError("arcRPC.Archives3", "s.arcRPC.Archives3(arcAids:(%v), arcs), err(%v)", aids, err)
  128. return
  129. }
  130. for _, tres := range mres {
  131. for _, rs := range tres {
  132. if arc, ok := arcs[rs.Aid]; ok {
  133. rs.Archive = arc
  134. if rs.Name == "" {
  135. rs.Name = arc.Title
  136. }
  137. if rs.Pic == "" {
  138. rs.Pic = arc.Pic
  139. }
  140. }
  141. }
  142. }
  143. }
  144. // if id is banner and not content add defult
  145. for i, rs := range mres {
  146. if len(rs) == 0 {
  147. id, _ := strconv.ParseInt(i, 10, 64)
  148. if _, ok := _bannerID[id]; ok {
  149. mres[i] = append(mres[i], s.defBannerCache)
  150. }
  151. }
  152. }
  153. return
  154. }
  155. // cpmBanners
  156. func (s *Service) cpms(c context.Context, mid int64, ids []int64, sid, ip, country, province, city, buvid string) (res map[int64]*rsmdl.Assignment) {
  157. cpmInfos, err := s.adDao.Cpms(c, mid, ids, sid, ip, country, province, city, buvid)
  158. if err != nil {
  159. log.Error("s.adDao.Cpms error(%v)", err)
  160. return
  161. }
  162. res = make(map[int64]*rsmdl.Assignment, len(cpmInfos.AdsInfo))
  163. for _, id := range ids {
  164. idStr := strconv.FormatInt(id, 10)
  165. if adsInfos := cpmInfos.AdsInfo[idStr]; len(adsInfos) > 0 {
  166. for srcStr, adsInfo := range adsInfos {
  167. // var url string
  168. srcIDInt, _ := strconv.ParseInt(srcStr, 10, 64)
  169. if adInfo := adsInfo.AdInfo; adInfo != nil {
  170. //switch adInfo.CreativeType {
  171. // case 0:
  172. // url = adInfo.CreativeContent.URL
  173. // case 1:
  174. // url = "www.bilibili.com/video/av" + adInfo.CreativeContent.VideoID
  175. // }
  176. ad := &rsmdl.Assignment{
  177. CreativeType: adInfo.CreativeType,
  178. Aid: adInfo.CreativeContent.VideoID,
  179. RequestID: cpmInfos.RequestID,
  180. SrcID: srcIDInt,
  181. IsAdLoc: true,
  182. IsAd: adsInfo.IsAd,
  183. CmMark: adsInfo.CmMark,
  184. CreativeID: adInfo.CreativeID,
  185. AdCb: adInfo.AdCb,
  186. ShowURL: adInfo.CreativeContent.ShowURL,
  187. ClickURL: adInfo.CreativeContent.ClickURL,
  188. Name: adInfo.CreativeContent.Title,
  189. Pic: adInfo.CreativeContent.ImageURL,
  190. LitPic: adInfo.CreativeContent.ThumbnailURL,
  191. URL: adInfo.CreativeContent.URL,
  192. PosNum: int(adsInfo.Index),
  193. Title: adInfo.CreativeContent.Title,
  194. ServerType: rsmdl.FromCpm,
  195. IsCpm: true,
  196. }
  197. res[srcIDInt] = ad
  198. } else {
  199. ad := &rsmdl.Assignment{
  200. IsAdLoc: true,
  201. RequestID: cpmInfos.RequestID,
  202. IsAd: false,
  203. SrcID: srcIDInt,
  204. ResID: int(id),
  205. CmMark: adsInfo.CmMark,
  206. }
  207. res[srcIDInt] = ad
  208. }
  209. }
  210. }
  211. }
  212. return
  213. }
  214. func checkAera(country string) (area int8) {
  215. switch country {
  216. case "中国":
  217. area = 1
  218. case "香港", "台湾", "澳门":
  219. area = 2
  220. case "日本":
  221. area = 3
  222. case "美国":
  223. area = 4
  224. default:
  225. if _, ok := rsmdl.OverSeasCountry[country]; ok {
  226. area = 5
  227. } else {
  228. area = 0
  229. }
  230. }
  231. return
  232. }
  233. // Relation get relation archives by aid
  234. func (s *Service) Relation(c context.Context, arg *rsmdl.ArgAid) (rls []*rsmdl.Relation, err error) {
  235. var aids []int64
  236. rls = _emptyRelation
  237. arg.IP = metadata.String(c, metadata.RemoteIP)
  238. if aids, err = s.dataDao.Related(c, arg.Aid, arg.IP); err != nil {
  239. log.Error("s.dataDao.Related aid(%v) error(%v)", arg.Aid, err)
  240. return
  241. }
  242. if len(aids) == 0 {
  243. log.Warn("zero_relates")
  244. return
  245. }
  246. argAdis := &arcmdl.ArgAids2{
  247. Aids: aids,
  248. RealIP: arg.IP,
  249. }
  250. arcs, err := s.arcRPC.Archives3(c, argAdis)
  251. if err != nil {
  252. log.Info("s.arcDao.Archives3", err)
  253. return
  254. }
  255. var res []*rsmdl.Relation
  256. for _, arc := range arcs {
  257. res = append(res, &rsmdl.Relation{Arc: arc})
  258. }
  259. rls = res
  260. if len(res) < 3 {
  261. return
  262. }
  263. var (
  264. country, province, city string
  265. info *locmdl.Info
  266. )
  267. if info, err = s.locRPC.Info(c, &locmdl.ArgIP{IP: arg.IP}); err != nil {
  268. log.Error("Location RPC error %v", err)
  269. err = nil
  270. }
  271. if info != nil {
  272. country = info.Country
  273. province = info.Province
  274. city = info.City
  275. }
  276. area := checkAera(country)
  277. //pts := s.posCache[posKey(0, _RelationResID)]
  278. cpmInfos := s.cpms(c, arg.Mid, []int64{int64(_RelationResID)}, arg.Sid, arg.IP, country, province, city, arg.Buvid)
  279. for _, rs := range cpmInfos {
  280. // just fet one ad
  281. if rs.IsAd {
  282. arcAid := &arcmdl.ArgAid2{
  283. Aid: rs.Aid,
  284. }
  285. var arc *api.Arc
  286. arc, err = s.arcRPC.Archive3(c, arcAid)
  287. if err != nil {
  288. resource.PromError("arcRPC.Archive3", "s.arcRPC.Archive3(arcAid:(%v), arcs), err(%v)", rs.Aid, err)
  289. err = nil
  290. rls = res
  291. return
  292. }
  293. rl := &rsmdl.Relation{
  294. Arc: arc,
  295. Area: area,
  296. RequestID: rs.RequestID,
  297. CreativeID: rs.CreativeID,
  298. AdCb: rs.AdCb,
  299. SrcID: rs.SrcID,
  300. ShowURL: rs.ShowURL,
  301. ClickURL: rs.ClickURL,
  302. IsAdLoc: rs.IsAdLoc,
  303. ResID: _RelationResID,
  304. IsAd: true,
  305. }
  306. if rs.Pic != "" {
  307. rl.Pic = rs.Pic
  308. }
  309. if rs.Title != "" {
  310. rl.Title = rs.Title
  311. }
  312. rls = append(res[:2], append([]*rsmdl.Relation{rl}, res[2:]...)...)
  313. return
  314. }
  315. res[2].AdCb = rs.AdCb
  316. res[2].SrcID = rs.SrcID
  317. res[2].ShowURL = rs.ShowURL
  318. res[2].ClickURL = rs.ClickURL
  319. res[2].IsAdLoc = rs.IsAdLoc
  320. res[2].RequestID = rs.RequestID
  321. res[2].CreativeID = rs.CreativeID
  322. res[2].ResID = _RelationResID
  323. return
  324. }
  325. return
  326. }
  327. // Resource get resource info by pf,id
  328. func (s *Service) Resource(c context.Context, arg *rsmdl.ArgRes) (res []*rsmdl.Assignment, count int, err error) {
  329. var (
  330. aids []int64
  331. arcs map[int64]*api.Arc
  332. country, province, city string
  333. info *locmdl.Info
  334. )
  335. arg.IP = metadata.String(c, metadata.RemoteIP)
  336. res = _emptyAsgs
  337. pts := s.posCache[posKey(arg.Pf, int(arg.ID))]
  338. if pts == nil {
  339. return
  340. }
  341. count = pts.Counter
  342. if info, err = s.locRPC.Info(c, &locmdl.ArgIP{IP: arg.IP}); err != nil {
  343. log.Error("Location RPC error %v", err)
  344. err = nil
  345. }
  346. if info != nil {
  347. country = info.Country
  348. province = info.Province
  349. city = info.City
  350. }
  351. area := checkAera(country)
  352. var cpmInfos map[int64]*rsmdl.Assignment
  353. if _cpmOn {
  354. cpmInfos = s.cpms(c, arg.Mid, []int64{arg.ID}, arg.Sid, arg.IP, country, province, city, arg.Buvid)
  355. } else if _, ok := _white[arg.Mid]; ok || (arg.Mid%100 < _cpmGrayRate && arg.Mid != 0) {
  356. cpmInfos = s.cpms(c, arg.Mid, []int64{arg.ID}, arg.Sid, arg.IP, country, province, city, arg.Buvid)
  357. }
  358. res, aids = s.res(c, cpmInfos, int(arg.ID), area, pts, arg.Mid)
  359. // fill archive if has video ad
  360. if len(aids) != 0 {
  361. argAids := &arcmdl.ArgAids2{
  362. Aids: aids,
  363. }
  364. if arcs, err = s.arcRPC.Archives3(c, argAids); err != nil {
  365. resource.PromError("arcRPC.Archive3", "s.arcRPC.Archive3(arcAid:(%v), arcs), err(%v)", aids, err)
  366. return
  367. }
  368. for _, rs := range res {
  369. if arc, ok := arcs[rs.Aid]; ok {
  370. rs.Archive = arc
  371. if rs.Name == "" {
  372. rs.Name = arc.Title
  373. }
  374. if rs.Pic == "" {
  375. rs.Pic = arc.Pic
  376. }
  377. }
  378. }
  379. }
  380. // add defBanner if contnent not exits
  381. if len(res) == 0 {
  382. if _, ok := _bannerID[int64(arg.ID)]; ok {
  383. // 142 is index banner
  384. if rs := s.resByID(142); rs != nil {
  385. res = append(res, rs)
  386. } else {
  387. res = append(res, s.defBannerCache)
  388. }
  389. }
  390. }
  391. return
  392. }
  393. 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) {
  394. // add ads if exists
  395. var (
  396. reqID string
  397. index int
  398. resIndex int
  399. ts = strconv.FormatInt(time.Now().Unix(), 10)
  400. resBs []*rsmdl.Assignment
  401. )
  402. for _, pt := range pts.Pos {
  403. var isAdLoc bool
  404. if rs, ok := cpmInfos[int64(pt.ID)]; ok && rs.IsCpm {
  405. rs.Area = area
  406. if mid != 0 {
  407. rs.Mid = strconv.FormatInt(mid, 10)
  408. }
  409. if rs.CreativeType == rsmdl.CreativeVideo {
  410. aids = append(aids, rs.Aid)
  411. }
  412. rs.ServerType = rsmdl.FromCpm
  413. res = append(res, rs)
  414. if rsb := s.resByID(pt.ID); rsb != nil {
  415. // url mean aid in Asgtypevideo
  416. resBs = append(resBs, rsb)
  417. }
  418. continue
  419. } else if ok && !rs.IsCpm {
  420. isAdLoc = true
  421. reqID = rs.RequestID
  422. }
  423. var rs *rsmdl.Assignment
  424. resBslen := len(resBs)
  425. if resIndex < resBslen {
  426. rs = resBs[resIndex]
  427. resIndex++
  428. if rsb := s.resByID(pt.ID); rsb != nil {
  429. resBs = append(resBs, rsb)
  430. }
  431. } else if rs = s.resByID(pt.ID); rs != nil {
  432. } else {
  433. rs = s.resByIndex(id, index)
  434. index++
  435. }
  436. if rs != nil {
  437. if rs.Atype == rsmdl.AsgTypeVideo || rs.Atype == rsmdl.AsgTypeAv {
  438. aids = append(aids, rs.Aid)
  439. }
  440. rs.PosNum = pt.PosNum
  441. rs.SrcID = int64(pt.ID)
  442. rs.Area = area
  443. rs.IsAdLoc = isAdLoc
  444. if isAdLoc {
  445. rs.RequestID = reqID
  446. } else {
  447. rs.RequestID = ts
  448. }
  449. if mid != 0 {
  450. rs.Mid = strconv.FormatInt(mid, 10)
  451. }
  452. res = append(res, rs)
  453. } else if isAdLoc {
  454. rs = &rsmdl.Assignment{
  455. PosNum: pt.PosNum,
  456. SrcID: int64(pt.ID),
  457. IsAdLoc: isAdLoc,
  458. RequestID: reqID,
  459. Area: area,
  460. Pic: _nullImage,
  461. }
  462. if mid != 0 {
  463. rs.Mid = strconv.FormatInt(mid, 10)
  464. }
  465. res = append(res, rs)
  466. }
  467. }
  468. return
  469. }
  470. // resByIndex return res of index
  471. func (s *Service) resByIndex(id, index int) (res *rsmdl.Assignment) {
  472. ss := s.asgCache[id]
  473. if index >= len(ss) {
  474. return
  475. }
  476. res = new(rsmdl.Assignment)
  477. *res = *(ss[index])
  478. return
  479. }
  480. // resByID return res of id
  481. func (s *Service) resByID(id int) (res *rsmdl.Assignment) {
  482. ss := s.asgCache[id]
  483. l := len(ss)
  484. if l == 0 {
  485. return
  486. }
  487. res = ss[0]
  488. for _, s := range ss {
  489. // ContractId not in contractMap ,it is ad and ad first
  490. if _, ok := _contractMap[s.ContractID]; !ok {
  491. res = s
  492. return
  493. }
  494. }
  495. return
  496. }
  497. // rpc resourcesALL
  498. func (s *Service) resourcesALL() (rscs []*rsmdl.Res, err error) {
  499. resourcesRPC, err := s.recrpc.ResourceAll(context.Background())
  500. if err != nil {
  501. resource.PromError("recRPC.ResourcesALL", "s.recrpc.resourcesRPC error(%v)", err)
  502. return
  503. }
  504. rscs = make([]*rsmdl.Res, 0)
  505. for _, res := range resourcesRPC {
  506. rsc := &rsmdl.Res{
  507. ID: res.ID,
  508. Platform: res.Platform,
  509. Name: res.Name,
  510. Parent: res.Parent,
  511. Counter: res.Counter,
  512. Position: res.Position,
  513. }
  514. rscs = append(rscs, rsc)
  515. }
  516. return
  517. }
  518. // rpc assignmentAll
  519. func (s *Service) assignmentAll() (asgs []*rsmdl.Assignment, err error) {
  520. assignRPC, err := s.recrpc.AssignmentAll(context.Background())
  521. if err != nil {
  522. resource.PromError("recRPC.AssignmentAll", "s.recrpc.assignRPC error(%v)", err)
  523. return
  524. }
  525. asgs = make([]*rsmdl.Assignment, 0)
  526. for _, asgr := range assignRPC {
  527. asg := &rsmdl.Assignment{
  528. ID: asgr.ID,
  529. Name: asgr.Name,
  530. ContractID: asgr.ContractID,
  531. ResID: asgr.ResID,
  532. Pic: asgr.Pic,
  533. LitPic: asgr.LitPic,
  534. URL: asgr.URL,
  535. Atype: asgr.Atype,
  536. Weight: asgr.Weight,
  537. Rule: asgr.Rule,
  538. Agency: asgr.Agency,
  539. STime: asgr.STime,
  540. }
  541. asgs = append(asgs, asg)
  542. }
  543. return
  544. }
  545. // default banner
  546. func (s *Service) defBanner() (asg *rsmdl.Assignment, err error) {
  547. bannerRPC, err := s.recrpc.DefBanner(context.Background())
  548. if err != nil {
  549. resource.PromError("recRPC.defBanner", "s.recrpc.defBanner error(%v)", err)
  550. return
  551. }
  552. if bannerRPC != nil {
  553. asg = &rsmdl.Assignment{
  554. ID: bannerRPC.ID,
  555. Name: bannerRPC.Name,
  556. ContractID: bannerRPC.ContractID,
  557. ResID: bannerRPC.ResID,
  558. Pic: bannerRPC.Pic,
  559. LitPic: bannerRPC.LitPic,
  560. URL: bannerRPC.URL,
  561. Atype: bannerRPC.Atype,
  562. Weight: bannerRPC.Weight,
  563. Rule: bannerRPC.Rule,
  564. Agency: bannerRPC.Agency,
  565. }
  566. }
  567. return
  568. }
  569. // LoadRes load Res info to cache
  570. func (s *Service) loadRes() (err error) {
  571. assign, err := s.assignmentAll()
  572. if err != nil {
  573. return
  574. }
  575. resources, err := s.resourcesALL()
  576. if err != nil {
  577. return
  578. }
  579. resMap := make(map[int]*rsmdl.Res)
  580. posMap := make(map[string]*rsmdl.Position)
  581. for _, res := range resources {
  582. resMap[res.ID] = res
  583. if res.Counter > 0 {
  584. key := posKey(res.Platform, res.ID)
  585. pos := &rsmdl.Position{
  586. Pos: make([]*rsmdl.Loc, 0),
  587. Counter: res.Counter,
  588. }
  589. posMap[key] = pos
  590. } else {
  591. key := posKey(res.Platform, res.Parent)
  592. if pos, ok := posMap[key]; ok {
  593. loc := &rsmdl.Loc{
  594. ID: res.ID,
  595. PosNum: res.Position,
  596. }
  597. pos.Pos = append(pos.Pos, loc)
  598. }
  599. }
  600. }
  601. for _, a := range assign {
  602. if res, ok := resMap[a.ResID]; ok {
  603. if err = s.convertURL(a); err != nil {
  604. return
  605. }
  606. var data struct {
  607. Cover int32 `json:"is_cover"`
  608. Style int32 `json:"style"`
  609. Label string `json:"label"`
  610. Intro string `json:"intro"`
  611. CreativeType int8 `json:"creative_type"`
  612. }
  613. // unmarshal rule for frontpage style
  614. if a.Rule != "" {
  615. e := json.Unmarshal([]byte(a.Rule), &data)
  616. if e != nil {
  617. log.Error("json.Unmarshal (%s) error(%v)", a.Rule, e)
  618. } else {
  619. a.Style = data.Style
  620. a.CreativeType = data.CreativeType
  621. if a.ContractID == "rec_video" {
  622. a.Label = data.Label
  623. a.Intro = data.Intro
  624. }
  625. }
  626. }
  627. res.Assignments = append(res.Assignments, a)
  628. }
  629. }
  630. urlMonitor := make(map[int]map[string]string)
  631. tmp := make(map[int][]*rsmdl.Assignment, len(resMap))
  632. for _, res := range resMap {
  633. tmp[res.ID] = res.Assignments
  634. urlMap, ok := urlMonitor[res.Platform]
  635. if !ok {
  636. urlMap = make(map[string]string)
  637. urlMonitor[res.Platform] = urlMap
  638. }
  639. for _, a := range res.Assignments {
  640. urlMap[fmt.Sprintf("%d_%s", a.ResID, a.Name)] = a.URL
  641. }
  642. }
  643. s.asgCache = tmp
  644. s.posCache = posMap
  645. s.urlMonitor = urlMonitor
  646. // load default banner
  647. banner, err := s.defBanner()
  648. if err != nil {
  649. return
  650. } else if banner != nil {
  651. var data struct {
  652. Cover int32 `json:"is_cover"`
  653. Style int32 `json:"style"`
  654. }
  655. err := json.Unmarshal([]byte(banner.Rule), &data)
  656. if err != nil {
  657. log.Error("json.Unmarshal (%s) error(%v)", banner.Rule, err)
  658. } else {
  659. banner.Style = data.Style
  660. }
  661. s.defBannerCache = banner
  662. }
  663. return
  664. }
  665. func posKey(pf, id int) string {
  666. return fmt.Sprintf("%d_%d", pf, id)
  667. }
  668. func (s *Service) convertURL(a *rsmdl.Assignment) (err error) {
  669. switch a.Atype {
  670. case rsmdl.AsgTypeVideo:
  671. var aid int64
  672. if aid, err = strconv.ParseInt(a.URL, 10, 64); err != nil {
  673. log.Error("strconv.ParseInt(%s) err(%v)", a.URL, err)
  674. return
  675. }
  676. a.Aid = aid
  677. a.URL = _videoPrefix + a.URL
  678. case rsmdl.AsgTypeURL:
  679. case rsmdl.AsgTypeBangumi:
  680. a.URL = _bangumiPrefix + a.URL
  681. case rsmdl.AsgTypeLive:
  682. a.URL = _LivePrefix + a.URL
  683. case rsmdl.AsgTypeGame:
  684. a.URL = _GamePrefix + a.URL
  685. case rsmdl.AsgTypeAv:
  686. var aid int64
  687. if aid, err = strconv.ParseInt(a.URL, 10, 64); err != nil {
  688. log.Error("strconv.ParseInt(%s) err(%v)", a.URL, err)
  689. return
  690. }
  691. a.Aid = aid
  692. a.URL = _AVprefix + a.URL
  693. case rsmdl.AsgTypeTopic:
  694. a.URL = _topicPrefix + a.URL
  695. }
  696. return
  697. }