Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@ -0,0 +1,87 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"region_test.go",
"show_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"audit.go",
"banner.go",
"cache.go",
"infoc.go",
"region.go",
"service.go",
"show.go",
],
importpath = "go-common/app/interface/main/app-show/service/region",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/dao/activity:go_default_library",
"//app/interface/main/app-show/dao/ad:go_default_library",
"//app/interface/main/app-show/dao/archive:go_default_library",
"//app/interface/main/app-show/dao/audit:go_default_library",
"//app/interface/main/app-show/dao/bangumi:go_default_library",
"//app/interface/main/app-show/dao/card:go_default_library",
"//app/interface/main/app-show/dao/dynamic:go_default_library",
"//app/interface/main/app-show/dao/location:go_default_library",
"//app/interface/main/app-show/dao/recommend:go_default_library",
"//app/interface/main/app-show/dao/region:go_default_library",
"//app/interface/main/app-show/dao/resource:go_default_library",
"//app/interface/main/app-show/dao/search:go_default_library",
"//app/interface/main/app-show/dao/tag:go_default_library",
"//app/interface/main/app-show/model:go_default_library",
"//app/interface/main/app-show/model/bangumi:go_default_library",
"//app/interface/main/app-show/model/banner:go_default_library",
"//app/interface/main/app-show/model/card:go_default_library",
"//app/interface/main/app-show/model/region:go_default_library",
"//app/interface/main/app-show/model/tag:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//app/service/main/location/model:go_default_library",
"//app/service/main/resource/model:go_default_library",
"//app/service/openplatform/pgc-season/api/grpc/season/v1:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/log/infoc:go_default_library",
"//library/net/metadata:go_default_library",
"//library/stat/prom:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/dgryski/go-farm:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,391 @@
package region
import (
"context"
"strconv"
"time"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/banner"
"go-common/app/interface/main/app-show/model/region"
"go-common/app/service/main/archive/api"
"go-common/library/log"
)
var (
_auditRids = map[int8]map[int]struct{}{
model.PlatIPad: map[int]struct{}{
153: struct{}{},
168: struct{}{},
169: struct{}{},
170: struct{}{},
33: struct{}{},
32: struct{}{},
51: struct{}{},
152: struct{}{},
37: struct{}{},
178: struct{}{},
179: struct{}{},
180: struct{}{},
147: struct{}{},
145: struct{}{},
146: struct{}{},
83: struct{}{},
185: struct{}{},
187: struct{}{},
13: struct{}{},
167: struct{}{},
177: struct{}{},
23: struct{}{},
1: struct{}{},
160: struct{}{},
119: struct{}{},
155: struct{}{},
165: struct{}{},
5: struct{}{},
181: struct{}{},
},
model.PlatIPhone: map[int]struct{}{
153: struct{}{},
168: struct{}{},
169: struct{}{},
170: struct{}{},
33: struct{}{},
32: struct{}{},
51: struct{}{},
152: struct{}{},
37: struct{}{},
178: struct{}{},
179: struct{}{},
180: struct{}{},
147: struct{}{},
145: struct{}{},
146: struct{}{},
83: struct{}{},
185: struct{}{},
187: struct{}{},
1: struct{}{},
160: struct{}{},
119: struct{}{},
155: struct{}{},
165: struct{}{},
5: struct{}{},
181: struct{}{},
},
}
)
// Audit region data list.
func (s *Service) auditRegion(mobiApp string, plat int8, build, rid int) (isAudit bool) {
if plats, ok := s.auditCache[mobiApp]; ok {
if _, ok = plats[build]; ok {
if rids, ok := _auditRids[plat]; ok {
if _, ok = rids[rid]; ok {
return true
}
}
}
}
return false
}
func (s *Service) loadAuditCache() {
as, err := s.adt.Audits(context.TODO())
if err != nil {
log.Error("s.adt.Audits error(%v)", err)
return
}
s.auditCache = as
}
// Audit check audit plat and ip, then return audit data.
func (s *Service) Audit(c context.Context, mobiApp string, plat int8, build, rid int, isShow bool) (res *region.Show, ok bool) {
if plats, ok := s.auditCache[mobiApp]; ok {
if _, ok = plats[build]; ok {
res = s.auditData(c, plat, rid, auditShowAids)
if isShow {
res.Banner = audirRegionBanners[rid]
}
return res, true
}
}
return nil, false
}
// AuditChild check audit plat and ip, then return audit data.
func (s *Service) AuditChild(c context.Context, mobiApp, order string, plat int8, build, rid, tid int) (res *region.Show, ok bool) {
if plats, ok := s.auditCache[mobiApp]; ok {
if _, ok = plats[build]; ok {
res = s.auditData(c, plat, rid, auditChildShowAids)
res.New = s.auditRegionRPCList(c, rid, 1, 8)
return res, true
}
}
return nil, false
}
// AuditChildList check audit plat and ip, then return audit data.
func (s *Service) AuditChildList(c context.Context, mobiApp, order string, plat int8, build, rid, tid, pn, ps int) (res []*region.ShowItem, ok bool) {
if plats, ok := s.auditCache[mobiApp]; ok {
if _, ok = plats[build]; ok {
res = s.auditRegionChildList(c, rid, tid, pn, ps)
return res, true
}
}
return nil, false
}
// auditData some data for audit.
func (s *Service) auditData(c context.Context, p int8, rid int, auditAids map[int][]int64) (res *region.Show) {
aids := auditAids[rid]
// archive
as, err := s.arc.ArchivesPB(c, aids)
if err != nil {
log.Error("s.arc.ArchivesPB error(%v)", err)
as = map[int64]*api.Arc{}
}
res = &region.Show{}
for _, aid := range aids {
if aid == 0 {
continue
}
item := &region.ShowItem{}
item.Goto = model.GotoAv
item.Param = strconv.FormatInt(aid, 10)
item.URI = model.FillURI(item.Goto, item.Param, nil)
if a, ok := as[aid]; ok {
item.Title = a.Title
item.Cover = a.Pic
item.Name = a.Author.Name
item.Play = int(a.Stat.View)
item.Danmaku = int(a.Stat.Danmaku)
item.Reply = int(a.Stat.Reply)
item.Fav = int(a.Stat.Fav)
}
res.Recommend = append(res.Recommend, item)
}
return
}
func (s *Service) auditRegionChildList(c context.Context, rid, tid, pn, ps int) (res []*region.ShowItem) {
if tid == 0 {
arcs, _, err := s.arc.RanksArcs(c, rid, pn, ps)
if err != nil {
log.Error("s.rcmmnd.RegionArcList(%d, %d, %d, %d) error(%v)", rid, pn, ps, err)
return
}
res = s.fromArchivesPBOsea(arcs, false)
} else {
as, err := s.tag.NewArcs(c, rid, tid, pn, ps, time.Now())
if err != nil {
log.Error("s.tag.NewArcs(%d, %d) error(%v)", rid, tid, err)
return
}
res = s.fromAidsOsea(c, as, false, false, 0)
}
return
}
func (s *Service) auditRegionRPCList(c context.Context, rid, pn, ps int) (res []*region.ShowItem) {
arcs, err := s.arc.RankTopArcs(c, rid, pn, ps)
if err != nil {
log.Error("s.arc.RankTopArcs(%d) error(%v)", rid, err)
return
}
res, _ = s.fromArchivesPB(arcs)
return
}
var (
auditShowAids = map[int][]int64{
// rid
1: []int64{575891, 744286, 663583, 666946, 559050, 744299},
3: []int64{881693, 756287, 785484, 402851, 887618, 853895},
4: []int64{861290, 861306, 861410, 861538, 861711, 861945},
5: []int64{791621, 795406, 797933, 800658, 832103, 833520},
11: []int64{1961205, 2028734},
13: []int64{2434272, 7408756, 2222558, 845204, 862063, 845034},
36: []int64{834839, 838077, 872364, 852955, 877423, 881182},
119: []int64{638240, 1959692, 78287, 1979757},
129: []int64{966192, 936016, 1958897, 886841},
}
auditChildShowAids = map[int][]int64{
20: []int64{936016, 886841, 1773160, 1958897, 1406019, 1935680, 1976153, 1985297, 1984555, 1964367, 29013765, 27379226, 25886650, 27684044, 20203945},
21: []int64{689694, 829135, 743922, 876565, 690522, 686220, 286616, 339727, 668054, 288602},
22: []int64{1911041, 1976535, 913421},
24: []int64{258271, 462832, 430248},
25: []int64{190257, 432195},
26: []int64{638240, 1959692, 78287, 1979757},
27: []int64{775898, 199852, 539880, 2469560, 306718, 2460323, 851414, 2471090, 591021, 286678},
28: []int64{221107, 221106, 884789, 364379, 465230, 26437, 29009413, 28965015, 28087847, 27837553, 24691347},
29: []int64{1984330, 1966586, 1984971, 28935962, 28818825, 26514923, 23288906, 18043554},
30: []int64{308040, 850424, 360940, 482844, 887861, 539600, 869576, 400161, 644935, 333069, 28659609, 24929108, 23068834, 26659364, 25386207},
31: []int64{1968681, 1986904, 1986802, 2473751, 2473083, 24910218, 25409335, 25043881, 27384682, 23474776},
37: []int64{1968901, 1969254, 1971484},
47: []int64{364103, 621797, 557774, 620545, 291630, 853831, 627451, 789570, 582598, 666971},
54: []int64{2294239, 2210977, 21297755, 21678914, 22000250, 19929241, 18039794},
59: []int64{1969748, 1966643, 1964781, 1969527, 25814802, 25991412, 26577780, 23922472, 28934467},
71: []int64{1986816, 1985288, 1986516, 1985717},
75: []int64{200595, 721477, 668533, 803294, 708986, 581574, 588820, 718877, 6336, 592586},
76: []int64{800617, 817625, 853774, 808176, 810174, 737783, 792994, 811825, 794302, 817814},
95: []int64{880857, 26317616, 26697725, 24670946, 13562204, 24136940},
96: []int64{2313588, 2314237, 2316089, 28917042, 20177394, 27839524, 25866526, 22021244},
98: []int64{875076, 873174, 580862, 289024, 28868117, 26404621, 17229132, 28810408, 27710623},
122: []int64{1986932, 1985610, 22034719, 19980487, 19841525, 23328696, 29249512},
124: []int64{842756, 875624, 880558, 862316, 876708, 883418, 403120, 855131, 876867, 833785, 29064835, 27464818, 28055879, 18081681, 22968172},
126: []int64{1636345, 1985956, 1975358, 1982533},
127: []int64{1743126, 1625784, 1986533, 1727650},
128: []int64{2031210, 2034983, 1916941, 2030610, 2015734, 2016150, 1982576, 2039658, 1981156, 1964927},
130: []int64{1984887, 1985685, 1985886, 25276379, 17119215, 24949925, 25058065, 2929013},
131: []int64{1980280, 1975409},
137: []int64{2316922, 2318219},
138: []int64{2317125, 2317283, 2315385, 2317914, 2317194},
153: []int64{2429129, 7408756, 2426501, 2425990, 2387429, 2425770, 2219211, 878914, 880182, 2240189},
154: []int64{1960912, 1984928, 29240625, 26192654, 24211477, 23746281, 23871787},
156: []int64{28960012, 26624032, 25520347, 23567968, 23706035},
17: []int64{28989880, 25158325, 23947116, 27052563, 24237900},
171: []int64{29027059, 26486853, 19641793, 26432920, 27107785},
172: []int64{28280704, 28667051, 27462689, 22870782, 17703340},
65: []int64{28386938, 28832756, 27894258, 23401066, 24434703},
173: []int64{28938351, 28945212, 28149415, 17717106, 26227357},
121: []int64{27148774, 24729449, 24544576, 23651344, 21672258},
136: []int64{26033272, 26422598, 26804826, 25773023, 22961192},
19: []int64{28942929, 26325161, 24502096, 22364954, 19289951},
39: []int64{29120624, 26300313, 25504214, 9447066, 20786390},
176: []int64{28811447, 27569816, 11984355, 10788852, 29346662},
}
audirRegionBanners = map[int]map[string][]*banner.Banner{
1: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "四月再见",
Image: "http://i0.hdslb.com/bfs/archive/8bbc82a30720f8c2cdcca1576e25917f7bbdfb96.jpg",
Hash: "db6e4dcc120fcd954a5c2d454b618f09",
URI: "http://www.bilibili.com/video/av2471080/",
},
},
},
3: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "【洛天依原创】夜寂",
Image: "http://i0.hdslb.com/bfs/archive/6fa8a51c9adf6eeda36636ed7fffae5b1888c154.jpg",
Hash: "c925b57dbaa1198e8cdedc84c4781313",
URI: "http://www.bilibili.com/video/av2126431/",
},
},
},
4: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "释放内心中的熊孩子吧",
Image: "http://i0.hdslb.com/bfs/archive/b94d053b289184d498236de100af383bd25cfb13.jpg",
Hash: "f246e2f10d19e30dc7311c9f1ee8385e",
URI: "http://www.bilibili.com/video/av2459834/",
},
},
},
5: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "巅峰料理对决~~~",
Image: "http://i0.hdslb.com/bfs/archive/a91501598fb180f61f234e31f94731b74235b461.jpg",
Hash: "8664c0bd979f62c02cf6711ac0a55219",
URI: "http://www.bilibili.com/video/av2607073/?br",
},
&banner.Banner{
Title: "首轮淘汰赛,谁将会离开",
Image: "http://i0.hdslb.com/bfs/archive/ae6d1ef420a5bfdca969a31ecd7449384cfcd580.jpg",
Hash: "346b456dea567a32a11a9427ebe3246f",
URI: "http://www.bilibili.com/video/av2609994/?br",
},
&banner.Banner{
Title: "孙红雷罗志祥乡村女装秀",
Image: "http://i0.hdslb.com/bfs/archive/3ea355584e26376df6cccbb1a2574f03f7e0a41d.jpg",
Hash: "45e70e0f72dd1fa4621e13986df03b30",
URI: "http://www.bilibili.com/video/av2598211/?br",
},
&banner.Banner{
Title: "帅哥萌妹齐驾到 HK君强势出境",
Image: "http://i0.hdslb.com/bfs/archive/ae6d1ef420a5bfdca969a31ecd7449384cfcd580.jpg",
Hash: "7e7f8fa57dfffa0ca141e12f43088851",
URI: "http://www.bilibili.com/video/av2598658/?br",
},
&banner.Banner{
Title: "林丹谢霆锋上演锅铲大战 容祖儿情绪崩溃大哭",
Image: "http://i0.hdslb.com/bfs/archive/959930c687c172a28d9f24e6a53aceb7fca4f728.jpg",
Hash: "512a11b81e053d52c2ad836c453c18ad",
URI: "http://www.bilibili.com/video/av2588446/?br",
},
&banner.Banner{
Title: "【绅士大概一分钟】尽情舞蹈吧少年",
Image: "http://i0.hdslb.com/bfs/archive/40878881827105f576e0346932cf693c3033e1ca.jpg",
Hash: "147763f8003e6f88385cd438e8b6c7e4",
URI: "http://www.bilibili.com/video/av2614367/?br",
},
},
},
11: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "亚瑟王",
Image: "http://i0.hdslb.com/bfs/archive/60b1339a3eeb8d0de287b7c305e0671082946bfc.jpg",
Hash: "634684fe0fd4fb3b7501daf9a9b4ab5d",
URI: "http://www.bilibili.com/video/av2128802/",
},
},
},
13: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "少女终末旅行",
Image: "http://i0.hdslb.com/bfs/archive/c0c33be60527c377277048c04ee222c9ec76a82c.jpg",
Hash: "2e772627851aa7da8a75f7b5403a5ed3",
URI: "http://bangumi.bilibili.com/anime/6463",
},
},
},
23: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "像素大战",
Image: "http://i0.hdslb.com/bfs/archive/0c8f1e05dfdba3b58fc15159523d0ccceed1e9ac.jpg",
Hash: "f62bbb0578beb4bc63550d5632960480",
URI: "http://www.bilibili.com/video/av2124091/",
},
},
},
36: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "梦回仙剑",
Image: "http://i0.hdslb.com/bfs/archive/76145de97ff917a6e603009376f4ca174dd4ed51.jpg",
Hash: "6334c8c08ffa8eaa6c13f8c14bd0fae0",
URI: "http://www.bilibili.com/video/av2448057/",
},
},
},
119: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "魔都地铁偷走了重要的东西",
Image: "http://i0.hdslb.com/bfs/archive/f84dd391351a00d69cfb44616c1a64419ad4611c.jpg",
Hash: "5de70c2b24a155d7958943b85bf8facc",
URI: "http://www.bilibili.com/video/av2106417/",
},
},
},
129: map[string][]*banner.Banner{
"top": []*banner.Banner{
&banner.Banner{
Title: "元气少女",
Image: "http://i0.hdslb.com/bfs/archive/014c0793bdaf5930e0edca54755da3c25eafcb2e.jpg",
Hash: "46e48cee8d5b344af3a41636e96a60ca",
URI: "http://www.bilibili.com/video/av2448328/",
},
},
},
}
)

View File

@ -0,0 +1,254 @@
package region
import (
"context"
"strconv"
"time"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/banner"
resource "go-common/app/service/main/resource/model"
"go-common/library/log"
)
var (
_banners = map[int]map[int8]int{
13: map[int8]int{
model.PlatIPhone: 454,
model.PlatIPad: 788,
model.PlatAndroid: 617,
model.PlatIPhoneI: 1022,
model.PlatAndroidG: 1360,
model.PlatAndroidI: 1791,
model.PlatIPadI: 1192,
},
1: map[int8]int{
model.PlatIPhone: 453,
model.PlatIPad: 787,
model.PlatAndroid: 616,
model.PlatIPhoneI: 1017,
model.PlatAndroidG: 1355,
model.PlatAndroidI: 1785,
model.PlatIPadI: 1187,
},
3: map[int8]int{
model.PlatIPhone: 455,
model.PlatIPad: 789,
model.PlatAndroid: 618,
model.PlatIPhoneI: 1028,
model.PlatAndroidG: 1366,
model.PlatAndroidI: 1798,
model.PlatIPadI: 1198,
},
129: map[int8]int{
model.PlatIPhone: 456,
model.PlatIPad: 790,
model.PlatAndroid: 619,
model.PlatIPhoneI: 1033,
model.PlatAndroidG: 1371,
model.PlatAndroidI: 1804,
model.PlatIPadI: 1203,
},
4: map[int8]int{
model.PlatIPhone: 457,
model.PlatIPad: 791,
model.PlatAndroid: 620,
model.PlatIPhoneI: 1038,
model.PlatAndroidG: 1376,
model.PlatAndroidI: 1810,
model.PlatIPadI: 1208,
},
36: map[int8]int{
model.PlatIPhone: 458,
model.PlatIPad: 792,
model.PlatAndroid: 621,
model.PlatIPhoneI: 1043,
model.PlatAndroidG: 1381,
model.PlatAndroidI: 1816,
model.PlatIPadI: 1213,
},
160: map[int8]int{
model.PlatIPhone: 459,
model.PlatIPad: 793,
model.PlatAndroid: 622,
model.PlatIPhoneI: 1048,
model.PlatAndroidG: 1386,
model.PlatAndroidI: 1822,
model.PlatIPadI: 1218,
},
119: map[int8]int{
model.PlatIPhone: 460,
model.PlatIPad: 794,
model.PlatAndroid: 623,
model.PlatIPhoneI: 1053,
model.PlatAndroidG: 1391,
model.PlatAndroidI: 1828,
model.PlatIPadI: 1223,
},
155: map[int8]int{
model.PlatIPhone: 462,
model.PlatIPad: 795,
model.PlatAndroid: 624,
model.PlatIPhoneI: 1058,
model.PlatAndroidG: 1396,
model.PlatAndroidI: 1834,
model.PlatIPadI: 1228,
},
5: map[int8]int{
model.PlatIPhone: 463,
model.PlatIPad: 796,
model.PlatAndroid: 625,
model.PlatIPhoneI: 1063,
model.PlatAndroidG: 1401,
model.PlatAndroidI: 1840,
model.PlatIPadI: 1233,
},
23: map[int8]int{
model.PlatIPhone: 464,
model.PlatIPad: 797,
model.PlatAndroid: 626,
model.PlatIPhoneI: 1068,
model.PlatAndroidG: 1406,
model.PlatAndroidI: 1846,
model.PlatIPadI: 1238,
},
11: map[int8]int{
model.PlatIPhone: 465,
model.PlatIPad: 798,
model.PlatAndroid: 627,
model.PlatIPhoneI: 1073,
model.PlatAndroidG: 1411,
model.PlatAndroidI: 1852,
model.PlatIPadI: 1243,
},
655: map[int8]int{
model.PlatIPhone: 466,
model.PlatIPad: 799,
model.PlatAndroid: 628,
model.PlatIPhoneI: 1079,
model.PlatAndroidG: 1417,
model.PlatAndroidI: 1859,
model.PlatIPadI: 1249,
},
165: map[int8]int{
model.PlatIPhone: 1473,
model.PlatIPad: 1485,
model.PlatAndroid: 1479,
model.PlatIPhoneI: 1491,
model.PlatAndroidG: 1497,
model.PlatAndroidI: 1873,
model.PlatIPadI: 1503,
},
167: map[int8]int{
model.PlatIPhone: 1934,
model.PlatIPad: 1932,
model.PlatAndroid: 1933,
},
181: map[int8]int{
model.PlatIPhone: 2225,
model.PlatIPad: 2239,
model.PlatAndroid: 2232,
},
177: map[int8]int{
model.PlatIPhone: 2275,
model.PlatIPad: 2289,
model.PlatAndroid: 2282,
},
188: map[int8]int{
model.PlatIPhone: 2996,
model.PlatIPad: 3008,
model.PlatAndroid: 3002,
model.PlatIPhoneI: 3014,
model.PlatAndroidG: 3020,
model.PlatAndroidI: 3032,
model.PlatIPadI: 3026,
},
}
_bannersPlat = map[int8]string{
model.PlatIPhone: "454,453,455,456,457,458,459,460,462,463,464,465,466,1473,1934,2225,2275",
model.PlatIPad: "788,787,789,790,791,792,793,794,795,796,797,798,799,1485,1932,2239,2289",
model.PlatAndroid: "617,616,618,619,620,621,622,623,624,625,626,627,628,1479,1933,2232,2282",
model.PlatIPhoneI: "1022,1017,1028,1033,1038,1043,1048,1053,1058,1063,1068,1073,1079,1491",
model.PlatAndroidG: "1360,1355,1366,1371,1376,1381,1386,1391,1396,1401,1406,1411,1417,1497",
model.PlatAndroidI: "1791,1785,1798,1804,1810,1816,1822,1828,1834,1840,1846,1852,1859,1873",
model.PlatIPadI: "1192,1187,1198,1203,1208,1213,1218,1223,1228,1233,1238,1243,1249,1503",
}
_bannersPGC = map[int8]map[int]int{
model.PlatAndroid: map[int]int{
13: 83,
167: 85,
177: 232,
11: 220,
23: 49,
},
model.PlatIPhone: map[int]int{
13: 97,
167: 98,
177: 233,
11: 221,
23: 50,
},
model.PlatIPad: map[int]int{
13: 332,
167: 333,
177: 334,
11: 336,
23: 335,
},
}
)
// getBanners get banners by plat, build channel, ip.
func (s *Service) getBanners(c context.Context, plat int8, build, rid int, mid int64, channel, ip, buvid, network, mobiApp, device, adExtra string) (res map[string][]*banner.Banner) {
var (
resID = _banners[rid][plat]
bs []*banner.Banner
)
res = map[string][]*banner.Banner{}
if bs = s.bgmBanners(c, plat, rid); len(bs) == 0 {
bs = s.resBanners(c, plat, build, mid, resID, channel, ip, buvid, network, mobiApp, device, adExtra)
}
if len(bs) > 0 {
res["top"] = bs
}
return
}
// resBannersplat
func (s *Service) resBanners(c context.Context, plat int8, build int, mid int64, resID int, channel, ip, buvid, network, mobiApp, device, adExtra string) (res []*banner.Banner) {
var (
plm = s.bannerCache[plat] // operater banner
err error
resbs map[int][]*resource.Banner
tmp []*resource.Banner
)
resIDStr := strconv.Itoa(resID)
if resbs, err = s.res.ResBanner(c, plat, build, mid, resIDStr, channel, ip, buvid, network, mobiApp, device, adExtra, true); err != nil || len(resbs) == 0 {
log.Error("s.res.ResBanner is null or err(%v)", err)
resbs = plm
}
tmp = resbs[resID]
for _, rb := range tmp {
b := &banner.Banner{}
b.ResChangeBanner(rb)
res = append(res, b)
}
return
}
// bgmBanners bangumi banner
func (s *Service) bgmBanners(c context.Context, plat int8, rid int) (bgmBanner []*banner.Banner) {
var (
bgmb = s.bannerBmgCache[plat][rid]
resID = _banners[rid][plat]
)
for i, bb := range bgmb {
b := &banner.Banner{}
b.BgmChangeBanner(bb)
b.RequestId = strconv.FormatInt(time.Now().UnixNano()/1000000, 10)
b.Index = i + 1
b.ResourceID = resID
bgmBanner = append(bgmBanner, b)
}
return
}

View File

@ -0,0 +1,610 @@
package region
import (
"context"
"fmt"
"strconv"
"time"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/bangumi"
"go-common/app/interface/main/app-show/model/card"
"go-common/app/interface/main/app-show/model/region"
"go-common/app/interface/main/app-show/model/tag"
"go-common/app/service/main/archive/api"
resource "go-common/app/service/main/resource/model"
"go-common/library/log"
)
var (
// 番剧 动画,音乐,舞蹈,游戏,科技,娱乐,鬼畜,电影,时尚, 生活,国漫
_tids = []int{13, 1, 3, 129, 4, 36, 5, 119, 23, 155, 160, 11, 167}
)
// loadBanner1 load banner cache.
func (s *Service) loadBanner() {
var (
resbs = map[int8]map[int][]*resource.Banner{}
)
for plat, resIDStr := range _bannersPlat {
mobiApp := model.MobiApp(plat)
res, err := s.res.ResBanner(context.TODO(), plat, 515007, 0, resIDStr, "master", "", "", "", mobiApp, "", "", false)
if err != nil || len(res) == 0 {
log.Error("s.res.ResBanner is null or err(%v)", err)
return
}
resbs[plat] = res
}
if len(resbs) > 0 {
s.bannerCache = resbs
}
log.Info("loadBannerCahce success")
}
func (s *Service) loadbgmBanner() {
bgmBanners := map[int8]map[int][]*bangumi.Banner{}
for plat, b := range _bannersPGC {
ridBanners := map[int][]*bangumi.Banner{}
for rid, pgcID := range b {
bBanner, err := s.bgm.Banners(context.TODO(), pgcID)
if err != nil {
log.Error("s.bgmdao.Banners is null or err(%v)", err)
return
}
ridBanners[rid] = bBanner
}
bgmBanners[plat] = ridBanners
}
s.bannerBmgCache = bgmBanners
}
// loadRegionShow
func (s *Service) loadShow() {
// default use android regions TODO
regionkey := fmt.Sprintf(_initRegionKey, model.PlatAndroid, _initlanguage)
res := s.cachelist[regionkey]
var (
// region tmp
showTmp = map[int][]*region.ShowItem{} // tmp hotCache
showNTmp = map[int][]*region.ShowItem{} // tmp newCache
showD = map[int][]*region.ShowItem{} // tmp dynamicCache
sTmp = map[int]*region.Show{}
// region tmp overseas
showTmpOsea = map[int][]*region.ShowItem{} // tmp overseas hotCache
showNTmpOsea = map[int][]*region.ShowItem{} // tmp overseas newCache
showDOsea = map[int][]*region.ShowItem{} // tmp overseas dynamicCache
sTmpOsea = map[int]*region.Show{}
// aids
showDynamicAids = map[int][]int64{}
// new region feed
regionFeedTmp = map[int]*region.Show{}
regionFeedTmpOsea = map[int]*region.Show{}
)
for _, v := range res {
if v.Reid == 0 {
if v.Rid == 65537 || v.Rid == 65539 || v.Rid == 65541 || v.Rid == 65543 {
continue
}
var (
tmp, tmpOsea []*region.ShowItem
aidsTmp []int64
)
tmp, tmpOsea = s.loadShowHot(v.Rid)
showTmp[v.Rid], showTmpOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.hotCache[v.Rid], s.hotOseaCache[v.Rid])
tmp, tmpOsea = s.loadShowNewRpc(v.Rid)
showNTmp[v.Rid], showNTmpOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.newCache[v.Rid], s.newOseaCache[v.Rid])
tmp, tmpOsea, aidsTmp = s.loadShowDynamic(v.Rid)
showDynamicAids[v.Rid] = s.upAidsCache(aidsTmp, s.showDynamicAidsCache[v.Rid])
showD[v.Rid], showDOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.dynamicCache[v.Rid], s.dynamicOseaCache[v.Rid])
sTmp[v.Rid] = s.mergeShow(showTmp[v.Rid], showNTmp[v.Rid], showD[v.Rid])
// overseas
sTmpOsea[v.Rid] = s.mergeShow(showTmpOsea[v.Rid], showNTmpOsea[v.Rid], showDOsea[v.Rid])
// new region feed
regionFeedTmp[v.Rid], _ = s.mergeChildShow(showTmp[v.Rid], showNTmp[v.Rid])
regionFeedTmpOsea[v.Rid], _ = s.mergeChildShow(showTmpOsea[v.Rid], showNTmpOsea[v.Rid])
}
}
s.showCache = sTmp
s.hotCache = showTmp
s.newCache = showNTmp
s.dynamicCache = showD
// overseas
s.showOseaCache = sTmpOsea
s.hotOseaCache = showTmpOsea
s.newOseaCache = showNTmpOsea
s.dynamicOseaCache = showDOsea
// new region feed
s.regionFeedCache = regionFeedTmp
s.regionFeedOseaCache = regionFeedTmpOsea
// aids
s.showDynamicAidsCache = showDynamicAids
}
// loadShowChild
func (s *Service) loadShowChild() {
// default use android regions TODO
regionkey := fmt.Sprintf(_initRegionKey, model.PlatAndroid, _initlanguage)
res := s.cachelist[regionkey]
var (
scTmp = map[int]*region.Show{}
showC = map[int][]*region.ShowItem{} // tmp childHotCache
showCN = map[int][]*region.ShowItem{} // tmp childNewCache
// region tmp overseas
scTmpOsea = map[int]*region.Show{}
showCOsea = map[int][]*region.ShowItem{} // tmp overseas childHotCache
showCNOsea = map[int][]*region.ShowItem{} // tmp overseas childNewCache
// aids
showChildAids = map[int][]int64{}
showNewAids = map[int][]int64{}
)
for _, v := range res {
if v.Reid != 0 {
var (
tmp, tmpOsea []*region.ShowItem
aidsTmp []int64
)
tmp, tmpOsea, aidsTmp = s.loadShowChileHot(v.Rid)
showChildAids[v.Rid] = s.upAidsCache(aidsTmp, s.childHotAidsCache[v.Rid])
showC[v.Rid], showCOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.childHotCache[v.Rid], s.childHotOseaCache[v.Rid])
tmp, tmpOsea, aidsTmp = s.loadShowChildNew(v.Rid)
showNewAids[v.Rid] = s.upAidsCache(aidsTmp, s.childNewAidsCache[v.Rid])
showCN[v.Rid], showCNOsea[v.Rid] = s.upCache(tmp, tmpOsea, s.childNewCache[v.Rid], s.childNewOseaCache[v.Rid])
scTmp[v.Rid], showCN[v.Rid] = s.mergeChildShow(showC[v.Rid], showCN[v.Rid])
// overseas
scTmpOsea[v.Rid], showCNOsea[v.Rid] = s.mergeChildShow(showCOsea[v.Rid], showCNOsea[v.Rid])
}
}
s.childShowCache = scTmp
s.childHotCache = showC
s.childNewCache = showCN
// overseas
s.childShowOseaCache = scTmpOsea
s.childHotOseaCache = showCOsea
s.childNewOseaCache = showCNOsea
// region child aids
s.childHotAidsCache = showChildAids
s.childNewAidsCache = showNewAids
}
func (s *Service) loadShowChildTagsInfo() {
// default use android regions TODO
regionkey := fmt.Sprintf(_initRegionKey, model.PlatAndroid, _initlanguage)
res := s.cachelist[regionkey]
reslist := s.regionListCache[regionkey]
var (
// tag tmp
tagsRegionTmp = map[int][]*region.SimilarTag{} // region tags
tagsTmp = map[string]string{} // tagid cache
)
for _, v := range res {
if v.Reid != 0 {
//tag
var rTmp *region.Region
if r, ok := reslist[v.Reid]; ok {
rTmp = r
}
if tids := s.loadShowChildTagIDs(v.Rid); len(tids) > 0 {
for _, tag := range tids {
tagInfo := &region.SimilarTag{
TagId: int(tag.Tid),
TagName: tag.Name,
Rid: v.Rid,
Rname: v.Name,
}
if rTmp != nil {
tagInfo.Reid = rTmp.Rid
tagInfo.Rename = rTmp.Name
}
//tags info
tagsRegionTmp[v.Rid] = append(tagsRegionTmp[v.Rid], tagInfo)
key := fmt.Sprintf(_initRegionTagKey, v.Rid, tag.Tid)
tagsTmp[key] = tag.Name
}
}
}
}
// region child aids
s.regionTagCache = tagsRegionTmp
s.tagsCache = tagsTmp
}
// loadShowHot
func (s *Service) loadShowHot(rid int) (resData, resOseaData []*region.ShowItem) {
res, err := s.rcmmnd.RegionHots(context.TODO(), rid)
if err != nil {
log.Error("s.rcmmnd.RegionHot(%d) error(%v)", rid, err)
return
}
if len(res) > 8 {
res = res[:8]
}
resData, resOseaData = s.fromAids(context.TODO(), res, false, 0)
log.Info("loadShowHot(%d) success", rid)
return
}
// loadShowNewRpc
func (s *Service) loadShowNewRpc(rid int) (resData, resOseaData []*region.ShowItem) {
arcs, err := s.arc.RankTopArcs(context.TODO(), rid, 1, 20)
if err != nil {
log.Error("s.arc.RankTopArcs(%d) error(%v)", rid, err)
return
}
if len(arcs) > 20 {
arcs = arcs[:20]
}
resData, resOseaData = s.fromArchivesPB(arcs)
log.Info("loadShowNewRpc(%d) success", rid)
return
}
// loadShowDynamic
func (s *Service) loadShowDynamic(rid int) (resData, resOseaData []*region.ShowItem, arcAids []int64) {
var (
err error
arcs []*api.Arc
)
arcs, arcAids, err = s.dyn.RegionDynamic(context.TODO(), rid, 1, 100)
if err != nil || len(arcs) < 20 {
log.Error("s.rcmmnd.RegionDynamic(%d) error(%v)", rid, err)
return
}
resData, resOseaData = s.fromArchivesPB(arcs)
log.Info("loadShowRPCDynamic(%d) success", rid)
return
}
// loadShowChileHot
func (s *Service) loadShowChileHot(rid int) (resData, resOseaData []*region.ShowItem, arcAids []int64) {
var err error
arcAids, err = s.rcmmnd.RegionChildHots(context.TODO(), rid)
if err != nil || len(arcAids) < 4 {
log.Error("s.rcmmnd.RegionChildHots(%d) error(%v)", rid, err)
return
}
resData, resOseaData = s.fromAids(context.TODO(), arcAids, false, 0)
log.Info("loadShowChileHot(%d) success", rid)
return
}
// loadShowChildNew
func (s *Service) loadShowChildNew(rid int) (resData, resOseaData []*region.ShowItem, arcAids []int64) {
var (
err error
arcs []*api.Arc
)
arcs, arcAids, err = s.arc.RanksArcs(context.TODO(), rid, 1, 300)
if err != nil || len(arcAids) < 20 {
log.Error("s.arc.RanksArc(%d) error(%v)", rid, err)
return
}
resData, resOseaData = s.fromArchivesPB(arcs)
log.Info("loadShowChildNew(%d) success", rid)
return
}
// loadShowChildTagIDs
func (s *Service) loadShowChildTagIDs(rid int) (tags []*tag.Tag) {
tags, err := s.tag.TagHotsId(context.TODO(), rid, time.Now())
if err != nil || len(tags) == 0 {
log.Error("s.tag.loadShowChildTagIDs(%d) error(%v)", rid, err)
return
}
return
}
// loadRankRegionCache
func (s *Service) loadRankRegionCache() {
var (
tmp = map[int][]*region.ShowItem{}
tmpOsea = map[int][]*region.ShowItem{}
)
for _, rid := range _tids {
aids, others, scores, err := s.rcmmnd.RankAppRegion(context.TODO(), rid)
if err != nil {
log.Error("s.rcmmnd.RankAppRegion rid (%v) error(%v)", rid, err)
return
}
tRank, tOseaRank := s.fromRankAids(context.TODO(), aids, others, scores)
tmp[rid] = tRank
tmpOsea[rid] = tOseaRank
}
if len(tmp) > 0 {
s.rankCache = tmp
}
if len(tmpOsea) > 0 {
s.rankOseaCache = tmpOsea
}
}
// loadRegionListCache
func (s *Service) loadRegionListCache() {
res, err := s.dao.RegionPlat(context.TODO())
if err != nil {
log.Error("s.dao.RegionPlat error(%v)", err)
return
}
tmpRegion := map[int]*region.Region{}
tmp := map[int]*region.Region{}
for _, v := range res {
// region list map
tmpRegion[v.Rid] = v
}
for _, r := range res {
if r.Reid != 0 {
if rerg, ok := tmpRegion[r.Reid]; ok {
tmp[r.Rid] = rerg
}
}
}
s.reRegionCache = tmp
}
func (s *Service) loadColumnListCache(now time.Time) {
var (
tmpChild = map[int]*card.ColumnList{}
)
columns, err := s.cdao.ColumnList(context.TODO(), now)
if err != nil {
log.Error("s.cdao.ColumnList error(%v)", err)
return
}
for _, column := range columns {
tmpChild[column.Cid] = column
}
s.columnListCache = tmpChild
}
// loadCardCache load all card cache
func (s *Service) loadCardCache(now time.Time) {
hdm, err := s.cdao.PosRecs(context.TODO(), now)
if err != nil {
log.Error("s.cdao.PosRecs error(%v)", err)
return
}
itm, aids, err := s.cdao.RecContents(context.TODO(), now)
if err != nil {
log.Error("s.cdao.RecContents error(%v)", err)
return
}
tmpItem := map[int]map[int64]*region.ShowItem{}
for recid, aid := range aids {
tmpItem[recid] = s.fromCardAids(context.TODO(), aid)
}
tmp := s.mergeCard(context.TODO(), hdm, itm, tmpItem, now)
s.cardCache = tmp
}
func (s *Service) mergeCard(c context.Context, hdm map[int8]map[int][]*card.Card, itm map[int][]*card.Content, tmpItems map[int]map[int64]*region.ShowItem, now time.Time) (res map[string][]*region.Head) {
// default use android regions TODO
var (
_topic = 1
_activity = 0
regionkey = fmt.Sprintf(_initRegionKey, model.PlatAndroid, _initlanguage)
regionList = s.cachelist[regionkey]
)
res = map[string][]*region.Head{}
for _, v := range regionList {
if v.Reid != 0 {
continue
}
for plat, phds := range hdm {
hds, ok := phds[v.Rid]
if !ok {
continue
}
for _, hd := range hds {
key := fmt.Sprintf(_initCardKey, plat, v.Rid)
var (
sis []*region.ShowItem
)
its, ok := itm[hd.ID]
if !ok {
its = []*card.Content{}
}
tmpItem, ok := tmpItems[hd.ID]
if !ok {
tmpItem = map[int64]*region.ShowItem{}
}
// 1 daily 2 topic 3 activity 4 rank 5 polymeric_card
switch hd.Type {
case 1:
for _, ci := range its {
si := s.fillCardItem(ci, tmpItem)
if si.Title != "" {
sis = append(sis, si)
}
}
case 2:
if topicID, err := strconv.ParseInt(hd.Rvalue, 10, 64); err == nil {
if actm, err := s.act.Activitys(c, []int64{topicID}, _topic, ""); err != nil {
log.Error("s.act.Activitys topicID error (%v)", topicID, err)
} else {
if act, ok := actm[topicID]; ok && act.H5Cover != "" && act.H5URL != "" {
si := &region.ShowItem{}
si.FromTopic(act)
sis = []*region.ShowItem{si}
}
}
}
case 3:
if topicID, err := strconv.ParseInt(hd.Rvalue, 10, 64); err == nil {
if actm, err := s.act.Activitys(c, []int64{topicID}, _activity, ""); err != nil {
log.Error("s.act.Activitys topicID error (%v)", topicID, err)
} else {
if act, ok := actm[topicID]; ok && act.H5Cover != "" && act.H5URL != "" {
si := &region.ShowItem{}
si.FromActivity(act, now)
sis = []*region.ShowItem{si}
}
}
}
case 4:
if tmpRank, ok := s.rankCache[v.Rid]; ok {
if len(tmpRank) > 3 {
sis = tmpRank[:3]
} else {
sis = tmpRank
}
}
case 5, 6, 8:
for _, ci := range its {
si := s.fillCardItem(ci, tmpItem)
if si.Title != "" {
sis = append(sis, si)
}
}
case 7:
si := &region.ShowItem{
Title: hd.Title,
Cover: hd.Cover,
Desc: hd.Desc,
Goto: hd.Goto,
Param: hd.Param,
}
if hd.Goto == model.GotoColumnStage {
paramInt, _ := strconv.Atoi(hd.Param)
if c, ok := s.columnListCache[paramInt]; ok {
cidStr := strconv.Itoa(c.Ceid)
si.URI = model.FillURICategory(hd.Goto, cidStr, hd.Param)
}
} else {
si.URI = hd.URi
}
sis = append(sis, si)
default:
continue
}
if len(sis) == 0 {
continue
}
sw := &region.Head{
CardID: hd.ID,
Title: hd.Title,
Type: hd.TypeStr,
Build: hd.Build,
Condition: hd.Condition,
Plat: hd.Plat,
}
if hd.Cover != "" {
sw.Cover = hd.Cover
}
switch sw.Type {
case model.GotoDaily:
sw.Date = now.Unix()
sw.Param = hd.Rvalue
sw.URI = hd.URi
sw.Goto = hd.Goto
case model.GotoCard:
sw.URI = hd.URi
sw.Goto = hd.Goto
sw.Param = hd.Param
case model.GotoRank:
sw.Param = strconv.Itoa(v.Rid)
case model.GotoTopic, model.GotoActivity:
if sw.Title == "" {
if len(sis) > 0 {
sw.Title = sis[0].Title
}
}
case model.GotoVeidoCard:
sw.Param = hd.Param
if hd.Goto == model.GotoColumnStage {
paramInt, _ := strconv.Atoi(hd.Param)
if c, ok := s.columnListCache[paramInt]; ok {
cidStr := strconv.Itoa(c.Ceid)
sw.URI = model.FillURICategory(hd.Goto, cidStr, hd.Param)
}
sw.Goto = model.GotoColumn
} else {
sw.Goto = hd.Goto
sw.URI = hd.URi
}
if sisLen := len(sis); sisLen > 1 {
if sisLen%2 != 0 {
sis = sis[:sisLen-1]
}
} else {
continue
}
case model.GotoSpecialCard:
sw.Cover = ""
case model.GotoTagCard:
if hd.TagID > 0 {
var tagIDInt int64
sw.Title, tagIDInt = s.fromTagIDByName(c, hd.TagID, now)
sw.Param = strconv.FormatInt(tagIDInt, 10)
sw.Goto = model.GotoTagID
}
}
sw.Body = sis
res[key] = append(res[key], sw)
}
}
}
return
}
// fillCardItem
func (s *Service) fillCardItem(csi *card.Content, tsi map[int64]*region.ShowItem) (si *region.ShowItem) {
si = &region.ShowItem{}
switch csi.Type {
case model.CardGotoAv:
si.Goto = model.GotoAv
si.Param = csi.Value
}
si.URI = model.FillURI(si.Goto, si.Param, nil)
if si.Goto == model.GotoAv {
aid, err := strconv.ParseInt(si.Param, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", si.Param, err)
} else {
if it, ok := tsi[aid]; ok {
si = it
if csi.Title != "" {
si.Title = csi.Title
}
} else {
si = &region.ShowItem{}
}
}
}
return
}
// fromTagIDByName from tag_id by tag_name
func (s *Service) fromTagIDByName(ctx context.Context, tagID int, now time.Time) (tagName string, tagIDInt int64) {
tag, err := s.tag.TagInfo(ctx, 0, tagID, now)
if err != nil {
log.Error("s.tag.TagInfo(%d) error(%v)", tagID, err)
return
}
tagName = tag.Name
tagIDInt = tag.Tid
return
}
// upCahce update cache
func (s *Service) upCache(new, newOsea, old, oldOsea []*region.ShowItem) (res, resOsea []*region.ShowItem) {
if len(new) > 0 {
res = new
} else {
res = old
}
if len(newOsea) > 0 {
resOsea = newOsea
} else {
resOsea = oldOsea
}
return
}
// upAidsCache update aids cache
func (s *Service) upAidsCache(new, old []int64) (aids []int64) {
if len(new) > 0 {
aids = new
} else {
aids = old
}
return
}

View File

@ -0,0 +1,101 @@
package region
import (
"bytes"
"strconv"
"time"
"go-common/app/interface/main/app-show/conf"
"go-common/library/log"
binfoc "go-common/library/log/infoc"
)
type infoc struct {
mid string
rid string
tid string
pn string
hotavid []int64
newavid []int64
now string
}
// Infoc write data for Hadoop do analytics
func (s *Service) infoc(mid int64, hotavid, newavid []int64, rid, tid int, pull bool, now time.Time) {
var pn string
if pull {
pn = "1"
} else {
pn = "2"
}
select {
case s.logCh <- infoc{strconv.FormatInt(mid, 10), strconv.Itoa(rid), strconv.Itoa(tid), pn, hotavid, newavid, strconv.FormatInt(now.Unix(), 10)}:
default:
log.Warn("infoc log buffer is full")
}
}
// writeInfoc
func (s *Service) infocproc() {
const (
noItem1 = `{"section":{"rid":`
noItem2 = `,"tagid":`
noItem3 = `,"mid":`
noItem4 = `,"pn":`
noItem5 = `,"hot_avids":[],"item_avids":[]}}`
)
var (
msg1 = []byte(`{"section":{"rid":`)
msg2 = []byte(`,"tagid":`)
msg3 = []byte(`,"mid":`)
msg4 = []byte(`,"pn":`)
msg5 = []byte(`,"hot_avids":[`)
msg6 = []byte(`,`)
msg7 = []byte(`],"item_avids":[`)
msg8 = []byte(`,`)
msg9 = []byte(`]}}`)
inf2 = binfoc.New(conf.Conf.FeedInfoc2)
buf bytes.Buffer
list string
)
for {
i, ok := <-s.logCh
if !ok {
log.Warn("infoc proc exit")
return
}
switch v := i.(type) {
case infoc:
if len(v.newavid) > 0 {
buf.Write(msg1)
buf.WriteString(v.rid)
buf.Write(msg2)
buf.WriteString(v.tid)
buf.Write(msg3)
buf.WriteString(v.mid)
buf.Write(msg4)
buf.WriteString(v.pn)
buf.Write(msg5)
for _, v := range v.hotavid {
buf.WriteString(strconv.FormatInt(v, 10))
buf.Write(msg6)
}
if len(v.hotavid) > 0 {
buf.Truncate(buf.Len() - 1)
}
buf.Write(msg7)
for _, v := range v.newavid {
buf.WriteString(strconv.FormatInt(v, 10))
buf.Write(msg8)
}
buf.Truncate(buf.Len() - 1)
buf.Write(msg9)
list = buf.String()
buf.Reset()
} else {
list = noItem1 + v.rid + noItem2 + v.tid + noItem3 + v.mid + noItem4 + v.pn + noItem5
}
inf2.Info(v.now, list)
}
}
}

View File

@ -0,0 +1,362 @@
package region
import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/region"
locmdl "go-common/app/service/main/location/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
farm "github.com/dgryski/go-farm"
)
const (
_initRegionKey = "region_key_%d_%v"
_initlanguage = "hans"
_initVersion = "region_version"
_regionAll = int8(0)
_isRegion = int8(1)
_isRank = int8(2)
_initRegionlimit = "%d_%v"
_regionRepeat = "r_%d_%d"
)
var (
_emptyRegions = []*region.Region{}
_isBangumi = map[int]struct{}{
13: struct{}{},
177: struct{}{},
23: struct{}{},
11: struct{}{},
}
_isBangumiIndex = map[int]struct{}{
13: struct{}{},
23: struct{}{},
11: struct{}{},
167: struct{}{},
}
_regionlimit = map[int8]map[string]map[int]string{
model.PlatIPhone: map[string]map[int]string{
"65542_bilibili://cliparea": map[int]string{
5960: "gt",
6570: "lt",
},
"65541_bilibili://category/65541": map[int]string{
5960: "gt",
6570: "lt",
},
"65544_bilibili://albumarea": map[int]string{
6090: "gt",
6570: "lt",
},
},
}
)
// Regions get regions.
func (s *Service) Regions(c context.Context, plat int8, build int, ver, mobiApp, device, language string) (rs []*region.Region, version string, err error) {
ip := metadata.String(c, metadata.RemoteIP)
rs, version, err = s.getCache(c, plat, build, ver, ip, mobiApp, device, language, "", false)
return
}
// Regions get regions.
func (s *Service) RegionsList(c context.Context, plat int8, build int, ver, mobiApp, device, language, entrance string) (rs []*region.Region, version string, err error) {
ip := metadata.String(c, metadata.RemoteIP)
rs, version, err = s.getCache(c, plat, build, ver, ip, mobiApp, device, language, entrance, true)
return
}
// getCache get region from cache.
func (s *Service) getCache(c context.Context, plat int8, build int, ver, ip, mobiApp, device, language, entrance string, isNew bool) (res []*region.Region, version string, err error) {
if language == "" {
language = _initlanguage
}
var (
rs = s.cache[fmt.Sprintf(_initRegionKey, plat, language)]
child = map[int][]*region.Region{}
entranceShow = _isRegion
ridlimit = _regionlimit[plat]
ridtmp = map[string]struct{}{}
pids []string
auths map[string]*locmdl.Auth
)
switch entrance {
case "region":
entranceShow = _isRegion
case "rank":
entranceShow = _isRank
}
for _, rtmp := range rs {
if rtmp.Area != "" {
pids = append(pids, rtmp.Area)
}
}
if len(pids) > 0 {
auths, _ = s.loc.AuthPIDs(c, strings.Join(pids, ","), ip)
}
Retry:
for _, rtmp := range rs {
r := &region.Region{}
*r = *rtmp
if _, isgbm := _isBangumi[r.Rid]; isgbm {
r.IsBangumi = 1
}
if isNew {
if r.Entrance != _regionAll && entranceShow != r.Entrance {
continue
}
} else {
switch r.Rid {
case 65545, 65542, 65541, 65543, 65544, 65546:
if mobiApp == "android" {
continue
}
}
}
if r.Rid != 165 || ((mobiApp != "iphone" || device != "pad") || build <= 3590) {
if model.InvalidBuild(build, r.Build, r.Condition) {
continue
}
}
key := fmt.Sprintf(_initRegionlimit, r.Rid, r.URI)
if rlimit, ok := ridlimit[key]; ok {
for blimit, climit := range rlimit {
if model.InvalidBuild(build, blimit, climit) {
continue Retry
}
}
}
if r.Rid == 65541 && (plat == model.PlatIPhone && build == 7040) {
continue
}
if r.Rid == 65543 && ((plat == model.PlatIPhone && (build == 7070 || build == 7040 || build == 7030)) ||
(plat == model.PlatAndroid && (build == 591182 || build == 591181 || build == 591178 || build == 591177))) {
continue
}
if auth, ok := auths[r.Area]; ok && auth.Play == locmdl.Forbidden {
log.Warn("s.invalid area(%v) ip(%v) error(%v)", r.Area, ip, err)
continue
}
if isAudit := s.auditRegion(mobiApp, plat, build, r.Rid); isAudit {
continue
}
rkey := fmt.Sprintf(_regionRepeat, r.Rid, r.Reid)
if _, ok := ridtmp[rkey]; !ok {
ridtmp[rkey] = struct{}{}
} else {
continue
}
if r.Reid != 0 {
cl, ok := child[r.Reid]
if !ok {
cl = []*region.Region{}
}
cl = append(cl, r)
child[r.Reid] = cl
} else {
res = append(res, r)
}
}
if len(res) == 0 {
res = _emptyRegions
} else {
for _, r := range res {
r.Children = child[r.Rid]
}
}
if version = s.hash(res); version == ver {
err = ecode.NotModified
res = nil
}
return
}
// NewRegionList get region from cache.
func (s *Service) NewRegionList(c context.Context, plat int8, build int, ver, mobiApp, device, language string) (res []*region.Region, version string, err error) {
ip := metadata.String(c, metadata.RemoteIP)
var (
hantlanguage = "hant"
)
if ok := model.IsOverseas(plat); ok && language != _initlanguage && language != hantlanguage {
language = hantlanguage
} else if language == "" {
language = _initlanguage
}
var (
rs = s.cachelist[fmt.Sprintf(_initRegionKey, plat, language)]
child = map[int][]*region.Region{}
ridtmp = map[string]struct{}{}
pids []string
auths map[string]*locmdl.Auth
)
for _, rtmp := range rs {
if rtmp.Area != "" {
pids = append(pids, rtmp.Area)
}
}
if len(pids) > 0 {
auths, _ = s.loc.AuthPIDs(c, strings.Join(pids, ","), ip)
}
LOOP:
for _, rtmp := range rs {
r := &region.Region{}
*r = *rtmp
if _, isgbm := _isBangumiIndex[r.Rid]; isgbm {
r.IsBangumi = 1
}
var tmpl, limitshow bool
if limit, ok := s.limitCache[r.ID]; ok {
for i, l := range limit {
if i+1 <= len(limit)-1 {
if ((l.Condition == "gt" && limit[i+1].Condition == "lt") && (l.Build < limit[i+1].Build)) ||
((l.Condition == "lt" && limit[i+1].Condition == "gt") && (l.Build > limit[i+1].Build)) {
if (l.Condition == "gt" && limit[i+1].Condition == "lt") &&
(build > l.Build && build < limit[i+1].Build) {
break
} else if (l.Condition == "lt" && limit[i+1].Condition == "gt") &&
(build < l.Build && build > limit[i+1].Build) {
break
} else {
tmpl = true
continue
}
}
}
if tmpl {
if i == len(limit)-1 {
limitshow = true
// continue LOOP
break
}
tmpl = false
continue
}
if model.InvalidBuild(build, l.Build, l.Condition) {
limitshow = true
continue
// continue LOOP
} else {
limitshow = false
break
}
}
}
if limitshow {
continue LOOP
}
if auth, ok := auths[r.Area]; ok && auth.Play == locmdl.Forbidden {
log.Warn("s.invalid area(%v) ip(%v) error(%v)", r.Area, ip, err)
continue
}
if isAudit := s.auditRegion(mobiApp, plat, build, r.Rid); isAudit {
continue
}
if config, ok := s.configCache[r.ID]; ok {
r.Config = config
}
key := fmt.Sprintf(_regionRepeat, r.Rid, r.Reid)
if _, ok := ridtmp[key]; !ok {
ridtmp[key] = struct{}{}
} else {
continue
}
if r.Reid != 0 {
cl, ok := child[r.Reid]
if !ok {
cl = []*region.Region{}
}
cl = append(cl, r)
child[r.Reid] = cl
} else {
res = append(res, r)
}
}
if len(res) == 0 {
res = _emptyRegions
} else {
for _, r := range res {
r.Children = child[r.Rid]
}
}
if version = s.hash(res); version == ver {
err = ecode.NotModified
res = nil
}
return
}
func (s *Service) hash(v []*region.Region) string {
bs, err := json.Marshal(v)
if err != nil {
log.Error("json.Marshal error(%v)", err)
return _initVersion
}
return strconv.FormatUint(farm.Hash64(bs), 10)
}
// loadRegion regions cache.
func (s *Service) loadRegion() {
res, err := s.dao.All(context.TODO())
if err != nil {
log.Error("s.dao.All error(%v)", err)
return
}
tmp := map[string][]*region.Region{}
for _, v := range res {
key := fmt.Sprintf(_initRegionKey, v.Plat, v.Language)
tmp[key] = append(tmp[key], v)
}
if len(tmp) > 0 {
s.cache = tmp
}
log.Info("region cacheproc success")
}
func (s *Service) loadRegionlist() {
res, err := s.dao.AllList(context.TODO())
if err != nil {
log.Error("s.dao.All error(%v)", err)
return
}
tmp := map[string][]*region.Region{}
tmpRegion := map[string]map[int]*region.Region{}
for _, v := range res {
key := fmt.Sprintf(_initRegionKey, v.Plat, v.Language)
tmp[key] = append(tmp[key], v)
// region list map
if r, ok := tmpRegion[key]; ok {
r[v.Rid] = v
} else {
tmpRegion[key] = map[int]*region.Region{
v.Rid: v,
}
}
}
if len(tmp) > 0 && len(tmpRegion) > 0 {
s.cachelist = tmp
s.regionListCache = tmpRegion
}
log.Info("region list cacheproc success")
limit, err := s.dao.Limit(context.TODO())
if err != nil {
log.Error("s.dao.limit error(%v)", err)
return
}
s.limitCache = limit
log.Info("region limit cacheproc success")
config, err := s.dao.Config(context.TODO())
if err != nil {
log.Error("s.dao.Config error(%v)", err)
return
}
s.configCache = config
log.Info("region config cacheproc success")
}

View File

@ -0,0 +1,38 @@
package region
import (
"context"
"flag"
"go-common/app/interface/main/app-show/conf"
"path/filepath"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func TestRegions(t *testing.T) {
Convey("get Regions data", t, WithService(func(s *Service) {
res, ver, err := s.Regions(context.TODO(), 0, 11111, "", "android", "", _initlanguage)
So(res, ShouldNotBeEmpty)
So(ver, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}
func TestRegionsList(t *testing.T) {
Convey("get RegionsList data", t, WithService(func(s *Service) {
res, ver, err := s.RegionsList(context.TODO(), 0, 11111, "", "android", "", _initlanguage, "region")
So(res, ShouldNotBeEmpty)
So(ver, ShouldNotBeEmpty)
So(err, ShouldBeNil)
}))
}

View File

@ -0,0 +1,338 @@
package region
import (
"time"
"go-common/app/interface/main/app-show/conf"
actdao "go-common/app/interface/main/app-show/dao/activity"
addao "go-common/app/interface/main/app-show/dao/ad"
arcdao "go-common/app/interface/main/app-show/dao/archive"
adtdao "go-common/app/interface/main/app-show/dao/audit"
bgmdao "go-common/app/interface/main/app-show/dao/bangumi"
carddao "go-common/app/interface/main/app-show/dao/card"
dyndao "go-common/app/interface/main/app-show/dao/dynamic"
locdao "go-common/app/interface/main/app-show/dao/location"
rcmmndao "go-common/app/interface/main/app-show/dao/recommend"
rgdao "go-common/app/interface/main/app-show/dao/region"
resdao "go-common/app/interface/main/app-show/dao/resource"
searchdao "go-common/app/interface/main/app-show/dao/search"
tagdao "go-common/app/interface/main/app-show/dao/tag"
"go-common/app/interface/main/app-show/model/bangumi"
"go-common/app/interface/main/app-show/model/card"
"go-common/app/interface/main/app-show/model/region"
resource "go-common/app/service/main/resource/model"
"go-common/library/stat/prom"
)
const (
_initRegionTagKey = "region_tag_%d_%d"
)
// Service is region service.
type Service struct {
c *conf.Config
// prom
pHit *prom.Prom
pMiss *prom.Prom
prmobi *prom.Prom
// dao
dao *rgdao.Dao
// bnnr *bnnrdao.Dao
rcmmnd *rcmmndao.Dao
ad *addao.Dao // cptbanner
tag *tagdao.Dao
adt *adtdao.Dao
arc *arcdao.Dao
dyn *dyndao.Dao
search *searchdao.Dao
cdao *carddao.Dao
act *actdao.Dao
bgm *bgmdao.Dao
res *resdao.Dao
loc *locdao.Dao
// tick
tick time.Duration
// regions cache
cache map[string][]*region.Region
// new region list cache
cachelist map[string][]*region.Region
limitCache map[int64][]*region.Limit
configCache map[int64][]*region.Config
regionListCache map[string]map[int]*region.Region
verCache map[string]string
// audit cache
auditCache map[string]map[int]struct{} // audit mobi_app builds
// region show item cache
bannerCache map[int8]map[int][]*resource.Banner
bannerBmgCache map[int8]map[int][]*bangumi.Banner
hotCache map[int][]*region.ShowItem
newCache map[int][]*region.ShowItem
dynamicCache map[int][]*region.ShowItem
// overseas
hotOseaCache map[int][]*region.ShowItem
newOseaCache map[int][]*region.ShowItem
dynamicOseaCache map[int][]*region.ShowItem
// region child show item cache
childHotCache map[int][]*region.ShowItem
childNewCache map[int][]*region.ShowItem
childHotAidsCache map[int][]int64
childNewAidsCache map[int][]int64
showDynamicAidsCache map[int][]int64
// overseas region child show item cache
childHotOseaCache map[int][]*region.ShowItem
childNewOseaCache map[int][]*region.ShowItem
// region tag show item cache
tagHotCache map[string][]*region.ShowItem
tagNewCache map[string][]*region.ShowItem
tagHotAidsCache map[string][]int64
tagNewAidsCache map[string][]int64
// overseas region tag show item cache
tagHotOseaCache map[string][]*region.ShowItem
tagNewOseaCache map[string][]*region.ShowItem
// new region feed
regionFeedCache map[int]*region.Show
regionFeedOseaCache map[int]*region.Show
// tags cache
tagsCache map[string]string
// region show
showCache map[int]*region.Show
childShowCache map[int]*region.Show
// overseas region show
showOseaCache map[int]*region.Show
childShowOseaCache map[int]*region.Show
// region dynamic show
showDynamicCache map[int]*region.Show
childShowDynamicCache map[int]*region.Show
// overseas region dynamic show
showDynamicOseaCache map[int]*region.Show
childShowDynamicOseaCache map[int]*region.Show
// similar tag
similarTagCache map[string][]*region.SimilarTag
// similar tag
regionTagCache map[int][]*region.SimilarTag
// ranking
rankCache map[int][]*region.ShowItem
rankOseaCache map[int][]*region.ShowItem
// card
cardCache map[string][]*region.Head
columnListCache map[int]*card.ColumnList
// region
reRegionCache map[int]*region.Region
// json tick
jsonOn bool
jsonCh chan int64
jsonIdsCache map[int64]struct{} // rid<<32 | tid
// cpm percentage 0~100
cpmNum int
cpmMid map[int64]struct{}
cpmAll bool
adIsPost bool
// infoc
logCh chan interface{}
}
// New new a region service.
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
pHit: prom.CacheHit,
pMiss: prom.CacheMiss,
prmobi: prom.BusinessInfoCount,
// dao
dao: rgdao.New(c),
// bnnr: bnnrdao.New(c),
rcmmnd: rcmmndao.New(c),
ad: addao.New(c),
adt: adtdao.New(c),
arc: arcdao.New(c),
tag: tagdao.New(c),
dyn: dyndao.New(c),
search: searchdao.New(c),
cdao: carddao.New(c),
act: actdao.New(c),
bgm: bgmdao.New(c),
res: resdao.New(c),
loc: locdao.New(c),
// tick
tick: time.Duration(c.Tick),
// audit cache
auditCache: map[string]map[int]struct{}{},
// regions cache
cache: map[string][]*region.Region{},
// new region list cache
cachelist: map[string][]*region.Region{},
limitCache: map[int64][]*region.Limit{},
configCache: map[int64][]*region.Config{},
regionListCache: map[string]map[int]*region.Region{},
verCache: map[string]string{},
// region show item cache
bannerCache: map[int8]map[int][]*resource.Banner{},
bannerBmgCache: map[int8]map[int][]*bangumi.Banner{},
hotCache: map[int][]*region.ShowItem{},
newCache: map[int][]*region.ShowItem{},
dynamicCache: map[int][]*region.ShowItem{},
// overseas
hotOseaCache: map[int][]*region.ShowItem{},
newOseaCache: map[int][]*region.ShowItem{},
dynamicOseaCache: map[int][]*region.ShowItem{},
// region child show item cache
childHotCache: map[int][]*region.ShowItem{},
childNewCache: map[int][]*region.ShowItem{},
childHotAidsCache: map[int][]int64{},
childNewAidsCache: map[int][]int64{},
showDynamicAidsCache: map[int][]int64{},
// overseas region child show item cache
childHotOseaCache: map[int][]*region.ShowItem{},
childNewOseaCache: map[int][]*region.ShowItem{},
// region tag show item cache
tagHotCache: map[string][]*region.ShowItem{},
tagNewCache: map[string][]*region.ShowItem{},
tagHotAidsCache: map[string][]int64{},
tagNewAidsCache: map[string][]int64{},
// overseas region tag show item cache
tagHotOseaCache: map[string][]*region.ShowItem{},
tagNewOseaCache: map[string][]*region.ShowItem{},
// new region feed
regionFeedCache: map[int]*region.Show{},
regionFeedOseaCache: map[int]*region.Show{},
// tags cache
tagsCache: map[string]string{},
// region show
showCache: map[int]*region.Show{},
childShowCache: map[int]*region.Show{},
// overseas region show
showOseaCache: map[int]*region.Show{},
childShowOseaCache: map[int]*region.Show{},
// region dynamic show
showDynamicCache: map[int]*region.Show{},
childShowDynamicCache: map[int]*region.Show{},
// overseas region dynamic show
showDynamicOseaCache: map[int]*region.Show{},
childShowDynamicOseaCache: map[int]*region.Show{},
// similar tag
similarTagCache: map[string][]*region.SimilarTag{},
// similar tag
regionTagCache: map[int][]*region.SimilarTag{},
// ranking
rankCache: map[int][]*region.ShowItem{},
rankOseaCache: map[int][]*region.ShowItem{},
// card
cardCache: map[string][]*region.Head{},
columnListCache: map[int]*card.ColumnList{},
// region
reRegionCache: map[int]*region.Region{},
// json tick
jsonOn: false,
jsonCh: make(chan int64, 128),
jsonIdsCache: map[int64]struct{}{},
// cpm percentage 0~100
cpmNum: 0,
cpmMid: map[int64]struct{}{},
cpmAll: true,
adIsPost: false,
// infoc
logCh: make(chan interface{}, 1024),
}
now := time.Now()
s.loadRegionlist()
s.loadRegion()
s.loadShow()
s.loadShowChild()
s.loadShowChildTagsInfo()
s.loadBanner()
s.loadbgmBanner()
s.loadAuditCache()
s.loadRegionListCache()
s.loadRankRegionCache()
s.loadColumnListCache(now)
s.loadCardCache(now)
go s.loadproc()
go s.infocproc()
return
}
func (s *Service) loadproc() {
for {
time.Sleep(s.tick)
now := time.Now()
s.loadRegionlist()
s.loadRegion()
s.loadShow()
s.loadShowChild()
s.loadShowChildTagsInfo()
s.loadBanner()
s.loadbgmBanner()
s.loadAuditCache()
s.loadRegionListCache()
s.loadRankRegionCache()
s.loadColumnListCache(now)
s.loadCardCache(now)
}
}
// Close dao
func (s *Service) Close() {
s.dao.Close()
}
// SetCpm percentage 0~100
func (s *Service) SetCpmNum(num int) {
s.cpmNum = num
if s.cpmNum < 0 {
s.cpmNum = 0
} else if s.cpmNum > 100 {
s.cpmNum = 100
}
}
// GetCpm percentage
func (s *Service) CpmNum() int {
return s.cpmNum
}
// SetCpm percentage 0~100
func (s *Service) SetCpmMid(mid int64) {
var mids = map[int64]struct{}{}
mids[mid] = struct{}{}
for mid, _ := range s.cpmMid {
if _, ok := mids[mid]; !ok {
mids[mid] = struct{}{}
}
}
s.cpmMid = mids
}
// GetCpm percentage
func (s *Service) CpmMid() []int {
var mids []int
for mid, _ := range s.cpmMid {
mids = append(mids, int(mid))
}
return mids
}
// SetCpm All
func (s *Service) SetCpmAll(isAll bool) {
s.cpmAll = isAll
}
// GetCpm All
func (s *Service) CpmAll() int {
if s.cpmAll {
return 1
}
return 0
}
// SetIsPost Get or Post
func (s *Service) SetAdIsPost(isPost bool) {
s.adIsPost = isPost
}
// IsPost Get or Post
func (s *Service) AdIsPost() int {
if s.adIsPost {
return 1
}
return 0
}

View File

@ -0,0 +1,926 @@
package region
import (
"context"
"fmt"
"time"
"go-common/app/interface/main/app-show/model"
seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
"go-common/app/interface/main/app-show/model/region"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
"go-common/library/log"
"go-common/library/net/metadata"
xtime "go-common/library/time"
)
const (
_initCardKey = "card_key_%d_%d"
_bangumiSeasonID = 1
_bangumiEpisodeID = 2
)
var (
_emptyShow = &region.Show{}
_emptyShowItems = []*region.ShowItem{}
_bangumiRids = map[int]struct{}{
33: struct{}{},
32: struct{}{},
153: struct{}{},
51: struct{}{},
152: struct{}{},
168: struct{}{},
169: struct{}{},
170: struct{}{},
}
_bangumiReids = map[int]struct{}{
13: struct{}{},
167: struct{}{},
}
)
// Show region show
func (s *Service) Show(c context.Context, plat int8, rid, build int, mid int64, channel, buvid, network, mobiApp, device, adExtra string) (res *region.Show) {
ip := metadata.String(c, metadata.RemoteIP)
if model.IsOverseas(plat) {
res = s.showOseaCache[rid]
} else {
res = s.showCache[rid]
}
if res == nil {
res = _emptyShow
return
}
if !model.IsIPad(plat) && len(res.Recommend) >= 4 {
res = &region.Show{
Recommend: res.Recommend[:4],
New: res.New,
Dynamic: res.Dynamic,
}
} else if model.IsIPad(plat) && len(res.Recommend) < 8 {
var (
max = 8
hotlen = len(res.Recommend)
)
if last := max - hotlen; last < len(res.New) {
res.Recommend = append(res.Recommend, res.New[:last]...)
} else if len(res.New) > 0 {
res.Recommend = append(res.Recommend, res.New...)
} else {
if last < len(res.Dynamic) {
res.Recommend = append(res.Recommend, res.Dynamic[:last]...)
} else if len(res.Dynamic) > 0 {
res.Recommend = append(res.Recommend, res.Dynamic...)
}
}
}
res.Banner = s.getBanners(c, plat, build, rid, mid, channel, ip, buvid, network, mobiApp, device, adExtra)
return
}
// ShowDynamic show dynamic page
func (s *Service) ShowDynamic(c context.Context, plat int8, build, rid, pn, ps int) (res []*region.ShowItem) {
var (
isOsea = model.IsOverseas(plat) //is overseas
bangumiType = 0
)
if _, isBangumi := _bangumiReids[rid]; isBangumi {
if (plat == model.PlatIPhone && build > 6090) || (plat == model.PlatAndroid && build > 514000) {
bangumiType = _bangumiEpisodeID
}
}
start := (pn - 1) * ps
end := start + ps
if bangumiType != 0 {
if end < len(s.showDynamicAidsCache[rid]) {
aids := s.showDynamicAidsCache[rid][start:end]
res = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
if len(res) > 0 {
return
}
}
}
if !isOsea {
if end < len(s.dynamicCache[rid]) {
res = s.dynamicCache[rid][start:end]
return
}
} else {
if end < len(s.dynamicOseaCache[rid]) {
res = s.dynamicOseaCache[rid][start:end]
return
}
}
as, aids, err := s.dyn.RegionDynamic(c, rid, pn, ps)
if err != nil {
log.Error("s.rcmmnd.RegionDynamic(%d, %d, %d) error(%v)", rid, pn, ps, err)
return
}
if bangumiType != 0 {
res = s.fromArchivesPBBangumiOsea(c, as, aids, isOsea, bangumiType)
} else {
res = s.fromArchivesPBOsea(as, isOsea)
}
return
}
// ChildShow region child show
func (s *Service) ChildShow(c context.Context, plat int8, mid int64, rid, tid, build int, channel, mobiApp string, now time.Time) (res *region.Show) {
var (
isOsea = model.IsOverseas(plat) //is overseas
bangumiType = 0
max = 20
)
if _, isBangumi := _bangumiRids[rid]; isBangumi {
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
bangumiType = _bangumiEpisodeID
} else {
bangumiType = _bangumiSeasonID
}
}
if (mobiApp == "iphone" && build <= 4280) || (mobiApp == "ipad" && build <= 10400) || (mobiApp == "white" && build <= 101320) ||
(mobiApp == "android" && build <= 501020) || (mobiApp == "android_tv" && build <= 1310) || mobiApp == "android_G" || mobiApp == "win" {
bangumiType = 0
}
if tid == 0 {
if bangumiType != 0 {
var (
hotTmp, newTmp []*region.ShowItem
aids []int64
hotOk, newOk bool
)
if aids, hotOk = s.childHotAidsCache[rid]; hotOk {
if len(aids) > max {
aids = aids[:max]
}
hotTmp = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
}
if aids, newOk = s.childNewAidsCache[rid]; newOk {
if len(aids) > max {
aids = aids[:max]
}
newTmp = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
}
if hotOk && newOk && len(hotTmp) > 0 && len(newTmp) > 0 {
res, _ = s.mergeChildShow(hotTmp, newTmp)
return
}
}
if !isOsea {
if res = s.childShowCache[rid]; res == nil {
res = _emptyShow
return
}
} else {
if res = s.childShowOseaCache[rid]; res == nil {
res = _emptyShow
return
}
}
return
}
res = s.mergeTagShow(c, rid, tid, bangumiType, isOsea, now)
if mid > 0 {
var err error
if res.Tag, err = s.tag.TagInfo(c, mid, tid, now); err != nil {
log.Error("s.tag.TagInfo(%d, %d) error(%v)", mid, tid, err)
}
}
return
}
// ChildListShow region childList show
func (s *Service) ChildListShow(c context.Context, plat int8, rid, tid, pn, ps, build int, mid int64, order, platform, mobiApp, device string) (res []*region.ShowItem) {
ip := metadata.String(c, metadata.RemoteIP)
var (
isOsea = model.IsOverseas(plat) //is overseas
bangumiType = 0
)
start := (pn - 1) * ps
end := start + ps
key := fmt.Sprintf(_initRegionTagKey, rid, tid)
if _, isBangumi := _bangumiRids[rid]; isBangumi {
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
bangumiType = _bangumiEpisodeID
} else {
bangumiType = _bangumiSeasonID
}
}
if (mobiApp == "iphone" && build <= 4280) || (mobiApp == "ipad" && build <= 10400) || (mobiApp == "white" && build <= 101320) ||
(mobiApp == "android" && build <= 501020) || (mobiApp == "android_tv" && build <= 1310) || mobiApp == "android_G" || mobiApp == "win" {
bangumiType = 0
}
if bangumiType != 0 {
if tid == 0 && (order == "" || order == "new") && end < len(s.childNewAidsCache[rid]) {
aids := s.childNewAidsCache[rid][start:end]
res = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
if len(res) > 0 {
return
}
}
if tid > 0 && (order == "" || order == "new") && end < len(s.tagNewAidsCache[key]) {
aids := s.tagNewAidsCache[key][start:end]
res = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
if len(res) > 0 {
return
}
}
}
if !isOsea {
if tid == 0 && (order == "" || order == "new") && end < len(s.childNewCache[rid]) {
res = s.childNewCache[rid][start:end]
return
}
if tid > 0 && (order == "" || order == "new") && end < len(s.tagNewCache[key]) {
res = s.tagNewCache[key][start:end]
return
}
} else {
if tid == 0 && (order == "" || order == "new") && end < len(s.childNewOseaCache[rid]) {
res = s.childNewOseaCache[rid][start:end]
return
}
if tid > 0 && (order == "" || order == "new") && end < len(s.tagNewOseaCache[key]) {
res = s.tagNewOseaCache[key][start:end]
return
}
}
if (order == "" || order == "new") && tid == 0 {
arcs, aids, err := s.arc.RanksArcs(c, rid, pn, ps)
if err != nil {
log.Error("s.rcmmnd.RegionArcList(%d, %d, %d, %d) error(%v)", rid, pn, ps, err)
}
if bangumiType != 0 {
res = s.fromArchivesPBBangumiOsea(c, arcs, aids, isOsea, bangumiType)
} else {
res = s.fromArchivesPBOsea(arcs, isOsea)
}
return
} else if (order == "" || order == "new") && tid > 0 {
as, err := s.tag.NewArcs(c, rid, tid, pn, ps, time.Now())
if err != nil {
log.Error("s.tag.NewArcs(%d, %d) error(%v)", rid, tid, err)
return
}
res = s.fromAidsOsea(c, as, false, isOsea, bangumiType)
return
}
var (
tname string
ok bool
)
if tid > 0 {
if tname, ok = s.tagsCache[key]; !ok {
return
}
}
as, err := s.search.SearchList(c, rid, build, pn, ps, mid, time.Now(), ip, order, tname, platform, mobiApp, device)
if err != nil {
log.Error("s.search.SearchList(%d, %d, %v, %d, %d) error(%v)", rid, tid, tname, pn, ps, err)
}
res = s.fromAidsOsea(c, as, false, isOsea, bangumiType)
return
}
// Dynamic region dynamic
func (s *Service) Dynamic(c context.Context, plat int8, rid, build int, mid int64, channel, buvid, network, mobiApp, device, adExtra string, now time.Time) (res *region.Show) {
ip := metadata.String(c, metadata.RemoteIP)
var (
isOsea = model.IsOverseas(plat) //is overseas
resCache *region.Show
)
s.prmobi.Incr("region_dynamic_plat_" + mobiApp)
if isOsea {
if resCache = s.regionFeedOseaCache[rid]; resCache == nil {
resCache = _emptyShow
}
} else {
if resCache = s.regionFeedCache[rid]; resCache == nil {
resCache = _emptyShow
}
}
if dyn, err := s.feedRegionDynamic(c, plat, rid, 0, 0, false, true, 0, mid, resCache.Recommend, now); err == nil && dyn != nil {
res = dyn
} else {
res = resCache
}
if res != nil {
res.Banner = s.getBanners(c, plat, build, rid, mid, channel, ip, buvid, network, mobiApp, device, adExtra)
res.Card = s.regionCardDisplay(plat, build, rid)
}
return
}
// regionCardDisplay
func (s *Service) regionCardDisplay(plat int8, build, rid int) (res []*region.Head) {
var ss []*region.Head
key := fmt.Sprintf(_initCardKey, plat, rid)
ss = s.cardCache[key]
if len(ss) == 0 {
res = []*region.Head{}
return
}
res = []*region.Head{}
for _, sw := range ss {
if model.InvalidBuild(build, sw.Build, sw.Condition) {
continue
}
tmp := &region.Head{}
*tmp = *sw
tmp.FillBuildURI(plat, build)
res = append(res, tmp)
}
return
}
// DynamicList show dynamic list
func (s *Service) DynamicList(c context.Context, plat int8, rid int, pull bool, ctime, mid int64, now time.Time) (res *region.Show) {
var (
err error
)
if res, err = s.feedRegionDynamic(c, plat, rid, 0, 0, pull, false, ctime, mid, nil, now); err != nil || res == nil {
res = _emptyShow
return
}
return
}
// DynamicChild region show dynamic
func (s *Service) DynamicChild(c context.Context, plat int8, rid, tid, build int, mid int64, mobiApp string, now time.Time) (res *region.Show) {
var (
isOsea = model.IsOverseas(plat) //is overseas
bangumiType = 0
resCache *region.Show
max = 20
)
s.prmobi.Incr("region_dynamic_child_plat_" + mobiApp)
if _, isBangumi := _bangumiRids[rid]; isBangumi {
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
bangumiType = _bangumiEpisodeID
} else {
bangumiType = _bangumiSeasonID
}
}
if tid == 0 {
if bangumiType != 0 {
var (
hotTmp, newTmp []*region.ShowItem
aids []int64
hotOk, newOk bool
)
if aids, hotOk = s.childHotAidsCache[rid]; hotOk {
if len(aids) > max {
aids = aids[:max]
}
hotTmp = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
}
if aids, newOk = s.childNewAidsCache[rid]; newOk {
if len(aids) > max {
aids = aids[:max]
}
newTmp = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
}
if len(hotTmp) > 0 && len(newTmp) > 0 {
resCache, _ = s.mergeChildShow(hotTmp, newTmp)
}
}
if resCache == nil {
if !isOsea {
if resCache = s.childShowCache[rid]; resCache == nil {
resCache = _emptyShow
}
} else {
if resCache = s.childShowOseaCache[rid]; resCache == nil {
resCache = _emptyShow
}
}
}
} else {
resCache = s.mergeTagShow(c, rid, tid, bangumiType, isOsea, now)
}
if resCache == nil {
resCache = _emptyShow
}
if dyn, err := s.feedRegionDynamic(c, plat, rid, tid, bangumiType, false, true, 0, mid, nil, now); err == nil && dyn != nil {
res = dyn
s.pHit.Incr("feed_region_dynamic")
} else {
res = resCache
s.pMiss.Incr("feed_region_dynamic")
}
if res != nil {
if tid == 0 {
if tags, ok := s.regionTagCache[rid]; ok {
res.TopTag = tags
}
} else if mid > 0 {
var err error
if res.Tag, err = s.tag.TagInfo(c, mid, tid, now); err != nil {
log.Error("s.tag.TagInfo(%d, %d) error(%v)", mid, tid, err)
}
}
}
return
}
// DynamicListChild dynamic childList show
func (s *Service) DynamicListChild(c context.Context, plat int8, rid, tid, build int, pull bool, ctime, mid int64, now time.Time) (res *region.Show) {
var (
err error
bangumiType = 0
)
if _, isBangumi := _bangumiRids[rid]; isBangumi {
if (plat == model.PlatIPhone && build > 6050) || (plat == model.PlatAndroid && build > 512007) {
bangumiType = _bangumiEpisodeID
} else {
bangumiType = _bangumiSeasonID
}
}
if res, err = s.feedRegionDynamic(c, plat, rid, tid, bangumiType, pull, false, ctime, mid, nil, now); err != nil || res == nil {
res = _emptyShow
return
}
return
}
// feedRegionDynamic
func (s *Service) feedRegionDynamic(c context.Context, plat int8, rid, tid, bangumiType int, pull, isRecommend bool, ctime, mid int64, items []*region.ShowItem, now time.Time) (res *region.Show, err error) {
var (
smTagNum = 10
smTagPos = 4
)
if res, err = s.feedDynamic(c, plat, rid, tid, bangumiType, pull, isRecommend, ctime, mid, items, now); err != nil || res == nil {
log.Error("s.feedDynamic is null rid:%v tid:%v", rid, tid)
} else {
if isRecommend && tid > 0 {
if st := s.similarTags(c, rid, tid, now); st != nil {
if len(st) > smTagNum {
res.TopTag = st[:smTagNum]
res.NewTag = &region.NewTag{
Position: smTagPos,
Tag: st[smTagNum:],
}
} else {
res.TopTag = st
}
}
}
}
return
}
// feedRegionDynamic
func (s *Service) feedDynamic(c context.Context, plat int8, rid, tid, bangumiType int, pull, isRecommend bool, ctime, mid int64, items []*region.ShowItem, now time.Time) (res *region.Show, err error) {
var (
isOsea = model.IsOverseas(plat) //is overseas
newAids = []int64{}
hotAids = []int64{}
ctop, cbottom xtime.Time
)
if hotAids, newAids, ctop, cbottom, err = s.rcmmnd.FeedDynamic(c, pull, rid, tid, ctime, mid, now); err != nil || len(newAids) == 0 {
log.Error("s.rcmmnd.FeedDynamic(%v) error(%v)", rid, err)
return
}
newItems := s.fromAidsOsea(c, newAids, false, isOsea, bangumiType)
hotItems := s.fromAidsOsea(c, hotAids, false, isOsea, bangumiType)
if isRecommend && (len(newItems) > 0 || len(hotItems) > 4) && len(newItems) > 0 {
if len(hotItems) >= 4 {
res = s.mergeDynamicShow(hotItems, newItems, ctop, cbottom)
} else {
log.Error("feedDynamic_hot is null rid:%v tid:%v", rid, tid)
res = s.mergeDynamicShow(items, newItems, ctop, cbottom)
}
} else if !isRecommend && len(newItems) > 0 {
res = s.mergeDynamicShow(_emptyShowItems, newItems, ctop, cbottom)
} else {
log.Error("feedDynamic_newItems is null rid:%v tid:%v", rid, tid)
}
s.infoc(mid, hotAids, newAids, rid, tid, pull, now)
return
}
// fromArchives return region show items from archive archives.
func (s *Service) fromArchivesPB(as []*api.Arc) (is, isOsea []*region.ShowItem) {
var asLen = len(as)
if asLen == 0 {
is = _emptyShowItems
return
}
is = make([]*region.ShowItem, 0, asLen)
for _, a := range as {
i := &region.ShowItem{}
i.FromArchivePB(a)
if a.AttrVal(archive.AttrBitOverseaLock) == 0 {
isOsea = append(isOsea, i)
}
is = append(is, i)
}
return
}
// fromArchivesPBBangumi aid to sid
func (s *Service) fromArchivesPBBangumi(c context.Context, as []*api.Arc, aids []int64, bangumiType int) (is, isOsea []*region.ShowItem) {
var (
asLen = len(as)
err error
// bangumi
// sids map[int64]int64
sids map[int32]*seasongrpc.CardInfoProto
)
if asLen == 0 {
is = _emptyShowItems
return
}
if sids, err = s.fromSeasonID(c, aids); err != nil {
log.Error("s.fromSeasonID error(%v)", err)
return
}
is = make([]*region.ShowItem, 0, asLen)
for _, a := range as {
if sid, ok := sids[int32(a.Aid)]; ok && sid.SeasonId != 0 {
i := &region.ShowItem{}
i.FromBangumiArchivePB(a, sid, bangumiType)
if a.AttrVal(archive.AttrBitOverseaLock) == 0 {
isOsea = append(isOsea, i)
}
is = append(is, i)
}
}
return
}
// mergeShow merge show
func (s *Service) mergeShow(hotTmp, newTmp, dynTmp []*region.ShowItem) (rs *region.Show) {
rs = &region.Show{}
if len(hotTmp) >= 4 {
rs.Recommend = hotTmp
} else {
rs.Recommend = _emptyShowItems
}
if len(newTmp) >= 4 {
rs.New = newTmp[:4]
} else {
rs.New = _emptyShowItems
}
if len(dynTmp) > 20 {
rs.Dynamic = dynTmp[:20]
} else if len(dynTmp) > 0 {
rs.Dynamic = dynTmp
} else {
rs.Dynamic = _emptyShowItems
}
return
}
// mergeChildShow merge child show
func (s *Service) mergeChildShow(recTmp, newTmp []*region.ShowItem) (rs *region.Show, new []*region.ShowItem) {
var (
last int
)
rs = &region.Show{}
if len(recTmp) >= 4 {
rs.Recommend = recTmp[:4]
} else if len(newTmp) >= 4 {
var (
max = 4
hotlen = len(recTmp)
)
rs.Recommend = recTmp
if last = max - hotlen; last < len(newTmp) {
rs.Recommend = append(rs.Recommend, newTmp[:last]...)
} else {
rs.Recommend = append(rs.Recommend, newTmp...)
}
} else {
rs.Recommend = _emptyShowItems
}
new = newTmp
if last > 0 {
if len(new) > last {
new = new[last:]
}
}
if len(new) >= 20 {
rs.New = new[:20]
} else if len(new) > 0 {
rs.New = new
} else {
rs.New = _emptyShowItems
}
return
}
// mergeDynamicShow
func (s *Service) mergeDynamicShow(recTmp, dynTmp []*region.ShowItem, ctop, cbottom xtime.Time) (rs *region.Show) {
if ctop == 0 || cbottom == 0 {
rs = &region.Show{}
} else {
rs = &region.Show{
Ctop: ctop,
Cbottom: cbottom,
}
}
if len(recTmp) >= 4 {
rs.Recommend = recTmp[:4]
} else {
rs.Recommend = _emptyShowItems
}
if len(dynTmp) > 0 {
rs.New = dynTmp
} else {
rs.New = _emptyShowItems
}
return
}
// mergeTagShow merge tag show
func (s *Service) mergeTagShow(c context.Context, rid, tid, bangumiType int, isOsea bool, now time.Time) (rs *region.Show) {
const (
strtNum = 1
hotNum = 4
newNum = 20
maxNum = 50
smTagNum = 10
smTagPos = 4
)
rs = &region.Show{}
// hots
key := fmt.Sprintf(_initRegionTagKey, rid, tid)
var (
is []*region.ShowItem
ok = false
)
if bangumiType != 0 {
var aids []int64
if aids, ok = s.tagHotAidsCache[key]; ok {
is = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
}
} else if bangumiType == 0 || !ok {
is, ok = s.tagHotCache[key]
if isOsea {
is, ok = s.tagHotOseaCache[key]
}
}
if !ok {
arcAids, err := s.tag.Hots(c, rid, tid, strtNum, hotNum, now)
if err != nil {
log.Error("s.tag.Hots(%d, %d) error(%v)", rid, tid, err)
} else if is = s.fromAidsOsea(c, arcAids, true, isOsea, bangumiType); len(is) > 0 {
if len(is) > hotNum {
is = is[:hotNum]
}
}
}
rs.Recommend = is
// news
if bangumiType != 0 {
var aids []int64
if aids, ok = s.tagNewAidsCache[key]; ok {
is = s.fromAidsOsea(c, aids, false, isOsea, bangumiType)
}
} else if bangumiType == 0 || !ok {
is, ok = s.tagNewCache[key]
if isOsea {
is, ok = s.tagNewOseaCache[key]
}
}
if !ok {
as, err := s.tag.NewArcs(c, rid, tid, strtNum, maxNum, now)
if err != nil {
log.Error("s.tag.NewArcs(%d, %d) error(%v)", rid, tid, err)
return
}
is = s.fromAidsOsea(c, as, false, isOsea, bangumiType)
}
var (
hotlen = len(rs.Recommend)
last int
)
if hotlen < hotNum {
if last = hotNum - hotlen; last < len(is) {
rs.Recommend = append(rs.Recommend, is[:last]...)
} else {
rs.Recommend = append(rs.Recommend, is...)
}
}
if last > 0 {
if len(is) > last {
is = is[last:]
}
}
if len(is) >= newNum {
is = is[:newNum]
}
rs.New = is
// similar tags
if st := s.similarTags(c, rid, tid, now); st != nil {
if len(st) > smTagNum {
rs.TopTag = st[:smTagNum]
rs.NewTag = &region.NewTag{
Position: smTagPos,
Tag: st[smTagNum+1:],
}
} else {
rs.TopTag = st
}
}
return
}
// fromAids get Aids. bangumiType 1 seasonid 2 epid
func (s *Service) fromAids(c context.Context, arcAids []int64, isCheck bool, bangumiType int) (data, dataOsea []*region.ShowItem) {
if len(arcAids) == 0 {
return
}
var (
ok bool
aid int64
arc *api.Arc
as map[int64]*api.Arc
err error
// bangumi
sids map[int32]*seasongrpc.CardInfoProto
)
if as, err = s.arc.ArchivesPB(c, arcAids); err != nil {
log.Error("s.arc.ArchivesPB aids(%v) error(%v)", arcAids, err)
return
}
data = make([]*region.ShowItem, 0, len(arcAids))
if bangumiType != 0 {
if sids, err = s.fromSeasonID(c, arcAids); err != nil {
log.Error("s.fromSeasonID error(%v)", err)
return
}
}
for _, aid = range arcAids {
if arc, ok = as[aid]; ok {
if isCheck && !arc.IsNormal() {
continue
}
i := &region.ShowItem{}
if sid, ok := sids[int32(aid)]; ok && bangumiType != 0 && sid.SeasonId != 0 {
i.FromBangumiArchivePB(arc, sid, bangumiType)
} else {
i.FromArchivePB(arc)
}
data = append(data, i)
if arc.AttrVal(archive.AttrBitOverseaLock) == 0 {
dataOsea = append(dataOsea, i)
}
}
}
return
}
// fromSeasonID
func (s *Service) fromSeasonID(c context.Context, arcAids []int64) (seasonID map[int32]*seasongrpc.CardInfoProto, err error) {
if seasonID, err = s.bgm.CardsByAids(c, arcAids); err != nil {
log.Error("s.bmg.CardsByAids error %v", err)
}
return
}
// similarTags similar tags
func (s *Service) similarTags(c context.Context, rid, tid int, now time.Time) (res []*region.SimilarTag) {
key := fmt.Sprintf(_initRegionTagKey, rid, tid)
res, ok := s.similarTagCache[key]
if !ok {
sts, err := s.tag.SimilarTag(c, rid, tid, now)
if err != nil {
log.Error("s.tag.SimilarTag error(%v)", err)
return
}
res = sts
}
return
}
// isOverseas
func (s *Service) fromAidsOsea(ctx context.Context, aids []int64, isCheck, isOsea bool, bangumiType int) (data []*region.ShowItem) {
tmp, tmpOsea := s.fromAids(ctx, aids, isCheck, bangumiType)
if isOsea {
data = tmpOsea
} else {
data = tmp
}
if data == nil {
data = _emptyShowItems
}
return
}
// fromArchivesOsea isOverseas
func (s *Service) fromArchivesPBOsea(as []*api.Arc, isOsea bool) (data []*region.ShowItem) {
tmp, tmpOsea := s.fromArchivesPB(as)
if isOsea {
data = tmpOsea
} else {
data = tmp
}
if data == nil {
data = _emptyShowItems
}
return
}
// fromArchivesOsea isOverseas
func (s *Service) fromArchivesPBBangumiOsea(c context.Context, as []*api.Arc, aids []int64, isOsea bool, bangumiType int) (data []*region.ShowItem) {
tmp, tmpOsea := s.fromArchivesPBBangumi(c, as, aids, bangumiType)
if isOsea {
data = tmpOsea
} else {
data = tmp
}
if data == nil {
data = _emptyShowItems
}
return
}
// fromRankAids
func (s *Service) fromRankAids(ctx context.Context, aids []int64, others, scores map[int64]int64) (sis, sisOsea []*region.ShowItem) {
var (
aid int64
as map[int64]*api.Arc
arc *api.Arc
ok bool
err error
paid int64
)
if as, err = s.arc.ArchivesPB(ctx, aids); err != nil {
log.Error("s.arc.ArchivesPB aids(%v) error(%v)", aids, err)
return
}
if len(as) == 0 {
log.Warn("s.arc.ArchivesPB aids(%v) length is 0", aids)
return
}
child := map[int64][]*region.ShowItem{}
childOsea := map[int64][]*region.ShowItem{}
for _, aid = range aids {
if arc, ok = as[aid]; ok {
if paid, ok = others[arc.Aid]; ok {
i := &region.ShowItem{}
i.FromArchivePBRank(arc, scores)
child[paid] = append(child[paid], i)
if arc.AttrVal(archive.AttrBitOverseaLock) == 0 {
childOsea[paid] = append(childOsea[paid], i)
}
}
}
}
for _, aid = range aids {
if arc, ok = as[aid]; ok {
if _, ok = others[arc.Aid]; !ok {
i := &region.ShowItem{}
i.FromArchivePBRank(arc, scores)
if arc.AttrVal(archive.AttrBitOverseaLock) == 0 {
if tmpchild, ok := childOsea[arc.Aid]; ok {
i.Children = tmpchild
}
sisOsea = append(sisOsea, i)
}
if tmpchild, ok := child[arc.Aid]; ok {
i.Children = tmpchild
}
sis = append(sis, i)
}
}
}
return
}
// fromCardAids get Aids.
func (s *Service) fromCardAids(ctx context.Context, aids []int64) (data map[int64]*region.ShowItem) {
var (
arc *api.Arc
ok bool
)
as, err := s.arc.ArchivesPB(ctx, aids)
if err != nil {
log.Error("s.arc.ArchivesPB error(%v)", err)
return
}
if len(as) == 0 {
log.Warn("s.arc.ArchivesPB(%v) length is 0", aids)
return
}
data = map[int64]*region.ShowItem{}
for _, aid := range aids {
if arc, ok = as[aid]; ok {
if !arc.IsNormal() {
continue
}
i := &region.ShowItem{}
i.FromArchivePB(arc)
if region, ok := s.reRegionCache[int(arc.TypeID)]; ok {
i.Reid = region.Rid
}
i.Desc = i.Rname
data[aid] = i
}
}
return
}

View File

@ -0,0 +1,108 @@
package region
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func WithService(f func(s *Service)) func() {
return func() {
f(s)
}
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}
func TestChildShow(t *testing.T) {
Convey("get ChildShow data", t, WithService(func(s *Service) {
res := s.ChildShow(context.TODO(), model.PlatIPhone, 0, 1, 0, 111, "", "iphone", time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestShow(t *testing.T) {
Convey("get Show data", t, WithService(func(s *Service) {
res := s.Show(context.TODO(), model.PlatIPhone, 1, 0, 0, "channel", "", "", "iphone", "phone", "")
So(res, ShouldNotBeEmpty)
}))
}
func TestShowDynamic(t *testing.T) {
Convey("get ShowDynamic data", t, WithService(func(s *Service) {
res := s.ShowDynamic(context.TODO(), model.PlatIPhone, 0, 1, 1, 20)
So(res, ShouldNotBeEmpty)
}))
}
func TestChildListShow(t *testing.T) {
Convey("get ChildListShow data", t, WithService(func(s *Service) {
res := s.ChildListShow(context.TODO(), model.PlatIPhone, 1, 0, 1, 20, 0, 0, "new", "ios", "iphone", "phone")
So(res, ShouldNotBeEmpty)
}))
}
func TestDynamic(t *testing.T) {
Convey("get Dynamic data", t, WithService(func(s *Service) {
res := s.Dynamic(context.TODO(), model.PlatIPhone, 1, 0, 0, "channel", "", "", "iphone", "phone", "", time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestDynamicList(t *testing.T) {
Convey("get DynamicList data", t, WithService(func(s *Service) {
res := s.DynamicList(context.TODO(), model.PlatIPhone, 1, true, 0, 0, time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestDynamicChild(t *testing.T) {
Convey("get DynamicChild data", t, WithService(func(s *Service) {
res := s.DynamicChild(context.TODO(), model.PlatIPhone, 1, 0, 0, 0, "iphone", time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestDynamicListChild(t *testing.T) {
Convey("get DynamicListChild data", t, WithService(func(s *Service) {
res := s.DynamicListChild(context.TODO(), model.PlatIPhone, 1, 0, 0, true, 0, 0, time.Now())
So(res, ShouldNotBeEmpty)
}))
}
func TestAudit(t *testing.T) {
Convey("get Audit data", t, WithService(func(s *Service) {
res, _ := s.Audit(context.TODO(), "iphone", model.PlatIPhone, 1, 1, false)
So(res, ShouldNotBeEmpty)
}))
}
func TestAuditChild(t *testing.T) {
Convey("get AuditChild data", t, WithService(func(s *Service) {
res, _ := s.AuditChild(context.TODO(), "iphone", "", model.PlatIPhone, 1, 1, 0)
So(res, ShouldNotBeEmpty)
}))
}
func TestAuditChildList(t *testing.T) {
Convey("get AuditChildList data", t, WithService(func(s *Service) {
res, _ := s.AuditChildList(context.TODO(), "iphone", "", model.PlatIPhone, 1, 1, 0, 1, 1)
So(res, ShouldNotBeEmpty)
}))
}