Initial commit

This commit is contained in:
Donny
2019-04-22 20:46:32 +08:00
commit 49ab8aadd1
25441 changed files with 4055000 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/interface/main/web-show/cmd:all-srcs",
"//app/interface/main/web-show/conf:all-srcs",
"//app/interface/main/web-show/dao/ad:all-srcs",
"//app/interface/main/web-show/dao/bangumi:all-srcs",
"//app/interface/main/web-show/dao/data:all-srcs",
"//app/interface/main/web-show/dao/job:all-srcs",
"//app/interface/main/web-show/dao/operation:all-srcs",
"//app/interface/main/web-show/dao/resource:all-srcs",
"//app/interface/main/web-show/http:all-srcs",
"//app/interface/main/web-show/model/job:all-srcs",
"//app/interface/main/web-show/model/operation:all-srcs",
"//app/interface/main/web-show/model/resource:all-srcs",
"//app/interface/main/web-show/service/job:all-srcs",
"//app/interface/main/web-show/service/operation:all-srcs",
"//app/interface/main/web-show/service/resource:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,250 @@
#### Web show 网页端运营及广告类接口
##### Version 2.12.3
> 1.接入location RPC IP查询接口
##### Version 2.12.2
> 1.修复移动端内容运营位无法获取稿件信息的问题
##### Version 2.12.1
> 1.移动端内容运营位增加获取稿件信息逻辑
##### Version 2.12.0
> 1.auth grpc
> 2.bm 启动修改
> 1.ip 传入修改
##### Version 2.11.0
> 1.添加mid
##### Version 2.10.2
> 1.添加相关 creative_type
##### Version 2.10.1
> 1.素材添加 stime
##### Version 2.10.0
> 1.接入话题
##### Version 2.9.2
> 1.使用discovery接入Resource
##### Version 2.9.1
> 1.使用discovery接入archive
##### Version 2.9.0
> 1.使用discovery接入account
##### Version 2.8.0
> 1.move to main
##### Version 2.7.3
> 1.调整固定投放、推荐池、广告优先级的
##### Version 2.7.2
> 1.使用account-service v7
##### Version 2.7.1
> 1.删除 statsd
##### Version 2.7.0
> 1.http参数修改为binging
##### Version 2.6.0
> 1.广告改为插入逻辑
##### Version 2.5.0
> 1.http切换为bm
##### Version 2.4.1
1.add new banner
2.fix pinc
##### Version 2.4.0
> 1.广告接口透传buvid
> 2.相关视频接入大数据接口
> 3.archive3接入
##### Version 2.3.6
> 1.熔断报警 http
##### Version 2.3.5
> 1.全局版头
##### Version 2.3.4
> 1.prom 监控添加
##### Version 2.3.2
> 1.cpm接口改为GET接口dao层
##### Version 2.3.1
> 1.添加广告上报字段
##### Version 2.3.0
> 1.接入新版配置中心
##### Version 2.2.0
> 1.为ad 到添加ping方法检测
> 2.支持根据平台查询后台url配置列表监控
##### Version 2.1.0
> 1.新增接口返回全量运营广告的url
##### Version 1.10.0
> 1.更新vendor
> 2.接入docker
##### Version 1.9.4
> 1.更新vendor
> 1.增加国创区默认版头配置
##### Version 1.9.3
> 1.修改资源位https
##### Version 1.9.2
> 1.更新govendor
##### Version 1.9.1
> 1.更新govendor
##### Version 1.9.0
> 1.接入熔断
> 2.更新vendor依赖
##### Version 1.8.1
> 1.修改静态降级参数
> 2.兼容推荐视频
##### Version 1.8.0
> 1.相关视频推荐接入cpm
> 2.接入引擎cpm&cpt聚合
> 3.升级vendor使用identify
> 4.增加内容运营为agency字段
##### Version 1.7.1
> 1.修复video ad
##### Version 1.7.0
> 1.更新go-common依赖
##### Version 1.6.8
> 1.修复跨域问题
##### Version 1.6.7
> 1.更新govendor依赖
##### Version 1.6.6
> 1.更新govendor 依赖
> 2.删除多余错误日志
##### Version 1.6.5
> 1.修复manage运营内容位置乱序
##### Version 1.6.4
> 1.添加cpm全局开关
##### Version 1.6.3
> 1.修复缓存被修改bug
##### Version 1.6.2
> 1.CPT&CRM 表结构优化
> 2.番剧贴片广告对大会员不展示
##### Version 1.6.1
> 1.判断所有请求area
> 2.设置manager指定内容为广告
##### Version 1.6.0
> 1.增加cpm广告
##### Version 1.5.0
> 1.增加govendor支持
> 2.兼容crm广告数据
##### Version 1.4.0
> 1.公共资源添加文字链及版头
##### Version 1.3.2
> 1.PGC移动端广告数据处理
##### Version 1.3.1
> 1.增加广告id唯一标识
##### Version 1.3.0
> 1.接入trace2
> 2.接入新的router
> 3.批量查询公共资源接口
##### Version 1.2.1
> 1.修复缓存bug
##### Version 1.2.0
> 1.统一公共资源管理
##### Version 1.1.0
> 1.添加广告接口
##### Version 1.0.1
> 1.优化配置
> 2.添加服务发现
##### Version 1.0.0
> 1.初始化完成招聘信息查询接口
> 2.初始化完成通告信息查询接口

View File

@@ -0,0 +1,10 @@
# Owner
liweijia
# Author
liweijia
# Reviewer
zhapuyu
wuhao02
guanyanliang

View File

@@ -0,0 +1,15 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- liweijia
labels:
- interface
- interface/main/web-show
- main
options:
no_parent_owners: true
reviewers:
- guanyanliang
- liweijia
- wuhao02
- zhapuyu

View File

@@ -0,0 +1,15 @@
#### web-show
##### 项目简介
> 1.网页端运营及广告类接口
##### 编译环境
> 请使用golang v1.7.x以上版本编译执行。
##### 依赖包
> 1.公共包go-common
##### 编译执行
> 在主目录执行go build。
> 编译后可执行 ./web-show -conf show-test.toml 使用项目本地配置文件启动服务。
> 也可执行 ./web-show -conf_appid=web-show -conf_version=v2.1.0 -conf_host=172.16.33.134:9011 -conf_path=/data/conf/web-show -conf_env=10 -conf_token=SEHXM8x1vYhIUaZvQUmyWnMYJrF9jHJY 使用配置中心测试环境配置启动服务如无法启动可检查token是否正确。

View File

@@ -0,0 +1,45 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = [
"web-show-example.toml",
"web-show-test.toml",
],
importpath = "go-common/app/interface/main/web-show/cmd",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/http:go_default_library",
"//library/log:go_default_library",
"//library/net/trace: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,46 @@
package main
import (
"flag"
"os"
"os/signal"
"syscall"
"go-common/app/interface/main/web-show/conf"
"go-common/app/interface/main/web-show/http"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
log.Error("conf.Init() error(%v)", err)
panic(err)
}
// init log
log.Init(conf.Conf.XLog)
trace.Init(conf.Conf.Tracer)
defer trace.Close()
defer log.Close()
log.Info("web-show start")
// service init
http.Init(conf.Conf)
// init signal
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("web-show get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
http.CloseService()
log.Info("web-show exit")
return
case syscall.SIGHUP:
// TODO reload
default:
return
}
}
}

View File

@@ -0,0 +1,129 @@
# This is a TOML document. Boom.
version = "1.0.0"
user = "nobody"
pid = "/tmp/web-show.pid"
dir = "./"
perf = "0.0.0.0:6120"
checkFile = "/data/www/web-show.html"
family = "web-show"
address = "172.16.0.148"
bangumiuri = "http://bangumi.bilibili.com/api/bp"
[reload]
jobs ="1h"
notice = "300s"
ad="300s"
[app]
key = "f022126a8a365e20"
secret = "b7b86838145d634b487e67b811b8fab2"
[xlog]
dir = "/data/log/web-show/"
[xlog.elk]
project = "web-show"
addr = "172.18.20.17:8520"
chanSize = 10240
[statsd]
project = "web-show"
addr = "172.18.20.15:8200"
chanSize = 10240
[httpClient]
dial = "500ms"
timeout = "2s"
keepAlive = "60s"
timer = 1000
[httpClient.breaker]
window ="10s"
sleep ="10ms"
bucket = 10
ratio = 0.1
request = 100
[multiHTTP]
[multiHTTP.outer]
addrs = ["0.0.0.0:6121"]
maxListen = 10
[multiHTTP.inner]
addrs = ["0.0.0.0:6122"]
maxListen = 10
[multiHTTP.local]
addrs = ["0.0.0.0:6123"]
maxListen = 10
[identify]
whiteAccessKey = ""
whiteMid = 0
[identify.app]
key = "6a29f8ed87407c11"
secret = "d3c5a85f5b895a03735b5d20a273bc57"
[identify.memcache]
name = "go-business/identify"
proto = "tcp"
addr = "172.16.33.54:11211"
active = 5
idle = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[identify.host]
auth = "http://passport.bilibili.com"
secret = "http://open.bilibili.com"
[identify.authHTTPClient]
dial = "1s"
timeout = "1s"
keepAlive = "60s"
timer = 1000
[identify.secretHTTPClient]
dial = "1s"
timeout = "1s"
keepAlive = "60s"
timer = 1000
[rpcClient2]
[rpcClient2.archive]
pullInterval = "10s"
[rpcClient2.archive.client]
timeout = "1s"
timer = 1000
[[rpcClient2.archive.backup]]
proto = "tcp"
addr = "127.0.0.1:6089"
timeout = "1s"
timer = 1000
[rpcClient2.archive.zookeeper]
root = "/microservice/archive-service/"
addrs = ["127.0.0.1:2181"]
timeout = "30s"
[mysql]
[mysql.operation]
addr = "172.16.0.148:3306"
dsn = "test:test@tcp(172.16.0.148:3306)/bilibili_operation?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
[mysql.ads]
addr = "172.16.0.148:3306"
dsn = "test:test@tcp(172.16.0.148:3306)/bilibili_ads?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
[mysql.res]
addr = "172.16.0.148:3306"
dsn = "test:test@tcp(172.16.0.148:3306)/bilibili_resource?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
[mysql.crm]
addr = "172.16.0.116:3306"
dsn = "test:test@tcp(172.16.0.116:3306)/bilibili_crm?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
[tracer]
proto = "udp"
addr = "172.16.33.46:5140"
tag = "platform/web-show"

View File

@@ -0,0 +1,205 @@
# This is a TOML document. Boom.
version = "1.0.0"
user = "nobody"
pid = "/tmp/web-show.pid"
dir = "./"
perf = "0.0.0.0:6120"
checkFile = "/data/www/web-show.html"
family = "web-show"
address = "172.16.0.148"
static = "/data/conf/web-show/static"
[Host]
bangumi = "http://bangumi.bilibili.com"
ad = "http://ad.bilibili.co"
[routerconfig]
[routerconfig.degrade]
on = false
args = ["ids"]
[reload]
jobs ="300s"
notice = "300s"
ad="10s"
[app]
key = "f022126a8a365e20"
secret = "b7b86838145d634b487e67b811b8fab2"
[xlog]
dir = "/data/log/web-show/"
[xlog.elk]
project = "web-show"
addr = "172.18.20.17:8520"
chanSize = 10240
[statsd]
project = "web-show"
addr = "172.18.20.15:8200"
chanSize = 10240
[httpClient]
dial = "500ms"
timeout = "100ms"
keepAlive = "60s"
key = "f022126a8a365e20"
secret = "b7b86838145d634b487e67b811b8fab2"
timer = 1000
[httpClient.breaker]
window ="10s"
sleep ="10ms"
bucket = 10
ratio = 0.1
request = 10
[multiHTTP]
[multiHTTP.outer]
addrs = ["0.0.0.0:6121"]
maxListen = 100
[multiHTTP.inner]
addrs = ["0.0.0.0:6122"]
maxListen = 10
[multiHTTP.local]
addrs = ["0.0.0.0:6123"]
maxListen = 10
[bm]
[bm.outer]
addr = "0.0.0.0:6121"
maxListen = 100
timeout = "1s"
[bm.inner]
addr = "0.0.0.0:6122"
maxListen = 10
timeout = "1s"
[bm.local]
addr = "0.0.0.0:6123"
maxListen = 10
timeout = "1s"
[identify]
whiteAccessKey = ""
whiteMid = 0
[identify.app]
key = "f022126a8a365e20"
secret = "b7b86838145d634b487e67b811b8fab2"
[identify.memcache]
name = "go-business/identify"
proto = "tcp"
addr = "172.16.33.54:11211"
active = 5
idle = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[identify.host]
auth = "http://passport.bilibili.com"
secret = "http://open.bilibili.com"
[identify.httpClient]
key = "f022126a8a365e20"
secret = "b7b86838145d634b487e67b811b8fab2"
dial = "30ms"
timeout = "100ms"
keepAlive = "60s"
[identify.httpClient.breaker]
window = "10s"
sleep = "100ms"
bucket = 10
ratio = 0.5
request = 100
[identify.httpClient.url]
"http://passport.bilibili.co/intranet/auth/tokenInfo" = {timeout = "100ms"}
"http://passport.bilibili.co/intranet/auth/cookieInfo" = {timeout = "100ms"}
"http://open.bilibili.co/api/getsecret" = {timeout = "500ms"}
[rpcClient2]
[rpcClient2.archive]
timeout = "30s"
[rpcClient2.account]
timeout = "30s"
[rpcClient2.resource]
timeout = "30s"
[mysql]
[mysql.operation]
addr = "172.16.33.54:3306"
dsn = "test:test@tcp(172.16.33.54:3306)/bilibili_operation?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
idleTimeout ="4h"
queryTimeout = "100ms"
execTimeout = "100ms"
tranTimeout = "200ms"
[mysql.operation.breaker]
window ="3s"
sleep ="100ms"
bucket = 10
ratio = 0.5
request = 100
[mysql.ads]
addr = "172.16.33.54:3306"
dsn = "test:test@tcp(172.16.33.54:3306)/bilibili_ads?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
idleTimeout ="4h"
queryTimeout = "500ms"
execTimeout = "500ms"
tranTimeout = "800ms"
[mysql.ads.breaker]
window ="3s"
sleep ="100ms"
bucket = 10
ratio = 0.5
request = 100
[mysql.res]
addr = "172.16.33.54:3306"
dsn = "test:test@tcp(172.16.33.54:3306)/bilibili_resource?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
idleTimeout ="4h"
queryTimeout = "100ms"
execTimeout = "100ms"
tranTimeout = "200ms"
[mysql.res.breaker]
window ="3s"
sleep ="100ms"
bucket = 10
ratio = 0.5
request = 100
[mysql.cpt]
addr = "172.16.0.116:3306"
dsn = "test:test@tcp(172.16.0.116:3306)/bilibili_solar?timeout=5s&readTimeout=5s&writeTimeout=5s&parseTime=true&loc=Local&charset=utf8,utf8mb4"
active = 5
idle = 2
idleTimeout ="4h"
queryTimeout = "100ms"
execTimeout = "100ms"
tranTimeout = "200ms"
[mysql.cpt.breaker]
window ="3s"
sleep ="100ms"
bucket = 10
ratio = 0.5
request = 100
[degradeConfig]
expire = 86400
[degradeConfig.memcache]
name = "go-common/app/interface/activity/web-show"
proto = "tcp"
addr = "172.16.13.140:11211"
idle = 5
active = 10
dialTimeout = "1s"
readTimeout = "1s"
writeTimeout = "1s"
idleTimeout = "80s"
[tracer]
proto = "udp"
addr = "172.16.33.46:5140"
tag = "platform/web-show"

View File

@@ -0,0 +1,41 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/interface/main/web-show/conf",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/cache/memcache:go_default_library",
"//library/conf:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/auth:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/net/rpc:go_default_library",
"//library/net/trace:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/BurntSushi/toml: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,150 @@
package conf
import (
"errors"
"flag"
"go-common/library/cache/memcache"
"go-common/library/conf"
"go-common/library/database/sql"
xlog "go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/auth"
"go-common/library/net/http/blademaster/middleware/verify"
"go-common/library/net/rpc"
"go-common/library/net/trace"
"go-common/library/time"
"github.com/BurntSushi/toml"
)
var (
confPath string
client *conf.Client
// Conf is global config
Conf = &Config{}
)
// Config service config
type Config struct {
Version string `toml:"version"`
Static string
LocsDegrade bool
// reload
Reload ReloadInterval
// app
App *bm.App
// Auth
Auth *auth.Config
// verify
Verify *verify.Config
// http
BM *HTTPServers
Tracer *trace.Config
// db
MySQL *MySQL
// rpc
RPCClient2 *RPCClient2
// rpc Location
LocationRPC *rpc.ClientConfig
// httpClient
HTTPClient *bm.ClientConfig
// Host
Host *Host
// XLog
XLog *xlog.Config
// DegradeConfig
DegradeConfig *DegradeConfig
}
// Host defeine host info
type Host struct {
Bangumi string
Ad string
}
// HTTPServers Http Servers
type HTTPServers struct {
Outer *bm.ServerConfig
Inner *bm.ServerConfig
Local *bm.ServerConfig
}
// MySQL define MySQL config
type MySQL struct {
Operation *sql.Config
Ads *sql.Config
Res *sql.Config
Cpt *sql.Config
}
// ReloadInterval define reolad config
type ReloadInterval struct {
Jobs time.Duration
Notice time.Duration
Ad time.Duration
}
// RPCClient2 define RPC client config
type RPCClient2 struct {
Archive *rpc.ClientConfig
Account *rpc.ClientConfig
Resource *rpc.ClientConfig
}
// DegradeConfig .
type DegradeConfig struct {
Expire int32
Memcache *memcache.Config
}
func init() {
flag.StringVar(&confPath, "conf", "", "config path")
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
// Init int config
func Init() error {
if confPath != "" {
return local()
}
return remote()
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
xlog.Info("config reload")
if load() != nil {
xlog.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,57 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"cpm_test.go",
"dao_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"cpm.go",
"dao.go",
"mysql.go",
],
importpath = "go-common/app/interface/main/web-show/dao/ad",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/model/resource:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/stat/prom:go_default_library",
"//library/xstr: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,40 @@
package ad
import (
"context"
"fmt"
"net/url"
"strconv"
ad "go-common/app/interface/main/web-show/model/resource"
"go-common/library/log"
"go-common/library/xstr"
)
// Cpms get ads from cpm platform
func (d *Dao) Cpms(c context.Context, mid int64, ids []int64, sid, ip, country, province, city, buvid string) (advert *ad.Ad, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("sid", sid)
params.Set("buvid", buvid)
params.Set("resource", xstr.JoinInts(ids))
params.Set("ip", ip)
params.Set("country", country)
params.Set("province", province)
params.Set("city", city)
var res struct {
Code int `json:"code"`
Data *ad.Ad `json:"data"`
}
if err = d.httpClient.Get(c, d.cpmURL, "", params, &res); err != nil {
log.Error("cpm url(%s) error(%v)", d.cpmURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("cpm api failed(%d)", res.Code)
log.Error("url(%s) res code(%d) or res.data(%v)", d.cpmURL+"?"+params.Encode(), res.Code, res.Data)
return
}
advert = res.Data
return
}

View File

@@ -0,0 +1,18 @@
package ad
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_Cpms(t *testing.T) {
Convey("test Cpms", t, WithDao(func(d *Dao) {
mid := int64(5187977)
ids := []int64{121, 21, 12}
data, err := d.Cpms(context.TODO(), mid, ids, "", "", "", "", "", "")
So(err, ShouldBeNil)
Printf("%+v", data)
}))
}

View File

@@ -0,0 +1,52 @@
package ad
import (
"context"
"go-common/app/interface/main/web-show/conf"
xsql "go-common/library/database/sql"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
"go-common/library/stat/prom"
)
// Dao define db struct
type Dao struct {
cpt *xsql.DB
// sql
selAdsStmt *xsql.Stmt
// cpt
httpClient *httpx.Client
cpmURL string
}
const (
_cpmURL = "/bce/api/bce/pc"
)
// PromError err
func PromError(name string, format string, args ...interface{}) {
prom.BusinessErrCount.Incr(name)
log.Error(format, args...)
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
cpt: xsql.NewMySQL(c.MySQL.Cpt),
httpClient: httpx.NewClient(c.HTTPClient),
cpmURL: c.Host.Ad + _cpmURL,
}
dao.selAdsStmt = dao.cpt.Prepared(_selAds)
return
}
// Close close the resource.
func (dao *Dao) Close() {
dao.cpt.Close()
}
// Ping ping mysql
func (dao *Dao) Ping(c context.Context) error {
return dao.cpt.Ping(c)
}

View File

@@ -0,0 +1,22 @@
package ad
import (
"flag"
"path/filepath"
"go-common/app/interface/main/web-show/conf"
)
var d *Dao
func WithDao(f func(d *Dao)) func() {
return func() {
dir, _ := filepath.Abs("../cmd/web-show-test.toml")
flag.Set("conf", dir)
conf.Init()
if d == nil {
d = New(conf.Conf)
}
f(d)
}
}

View File

@@ -0,0 +1,34 @@
package ad
import (
"context"
"time"
"go-common/app/interface/main/web-show/model/resource"
"go-common/library/log"
)
const (
_selAds = `SELECT sch.id,sch.resource_id,so.title,so.pic,so.spic,so.url,so.atype FROM schedule as sch INNER JOIN order_applied as o ON sch.applied_id = o.id
INNER JOIN material as so ON so.id= o.material_id WHERE sch.stime<? AND sch.etime>? AND o.state =3`
)
// Ads return ads info
func (dao *Dao) Ads(c context.Context) (ads []*resource.Assignment, err error) {
rows, err := dao.selAdsStmt.Query(c, time.Now(), time.Now())
if err != nil {
log.Error("dao.selAdsStmt() err(%v)", err)
return
}
defer rows.Close()
ads = make([]*resource.Assignment, 0)
for rows.Next() {
ad := &resource.Assignment{}
if err = rows.Scan(&ad.ID, &ad.ResID, &ad.Name, &ad.Pic, &ad.LitPic, &ad.URL, &ad.Atype); err != nil {
PromError("mysql.Ads", "rows.scan err(%v)", err)
return
}
ads = append(ads, ad)
}
return
}

View File

@@ -0,0 +1,46 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["bangumi_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["bangumi.go"],
importpath = "go-common/app/interface/main/web-show/dao/bangumi",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster: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,52 @@
package bangumi
import (
"context"
"net/url"
"strconv"
"time"
"go-common/app/interface/main/web-show/conf"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
// Dao struct
type Dao struct {
client *httpx.Client
isbpURL string
}
// New Init
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
client: httpx.NewClient(c.HTTPClient),
isbpURL: c.Host.Bangumi + "/api/bp",
}
return
}
// IsBp check user bp.
func (dao *Dao) IsBp(c context.Context, mid, aid int64, ip string) (is bool) {
params := url.Values{}
params.Set("build", "web-show")
params.Set("platform", "Golang")
params.Set("ts", strconv.FormatInt(time.Now().Unix(), 10))
params.Set("aid", strconv.FormatInt(aid, 10))
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Result bool `json:"result"`
}
if err := dao.client.Get(c, dao.isbpURL, ip, params, &res); err != nil {
log.Error("bangumi url(%s) error(%v) ", dao.isbpURL+"?"+params.Encode(), err)
return
}
// FIXME why two state
if res.Code != 0 && res.Code != 1 {
log.Error("bangumi Isbp api fail(%d)", res.Code)
return
}
is = res.Result
return
}

View File

@@ -0,0 +1,36 @@
package bangumi
import (
"context"
"flag"
"path/filepath"
"testing"
"go-common/app/interface/main/web-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var d *Dao
func WithDao(f func(d *Dao)) func() {
return func() {
dir, _ := filepath.Abs("../cmd/web-show-test.toml")
flag.Set("conf", dir)
conf.Init()
if d == nil {
d = New(conf.Conf)
}
f(d)
}
}
func TestDao_Bangumi(t *testing.T) {
Convey("test Bangumi", t, WithDao(func(d *Dao) {
mid := int64(5187977)
aid := int64(2)
data := d.IsBp(context.TODO(), mid, aid, "")
So(data, ShouldNotBeNil)
Printf("%+v", data)
}))
}

View File

@@ -0,0 +1,47 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["data_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["data.go"],
importpath = "go-common/app/interface/main/web-show/dao/data",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/xstr: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,60 @@
package data
import (
"context"
"fmt"
"net/url"
"strconv"
"go-common/app/interface/main/web-show/conf"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
"go-common/library/xstr"
)
// Dao struct
type Dao struct {
client *httpx.Client
relatedURL string
}
// New Init
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
client: httpx.NewClient(c.HTTPClient),
relatedURL: "http://data.bilibili.co/recsys/related",
}
return
}
// Related check user bp.
func (dao *Dao) Related(c context.Context, aid int64, ip string) (aids []int64, err error) {
params := url.Values{}
params.Set("key", strconv.FormatInt(aid, 10))
var res struct {
Code int `json:"code"`
Data []*struct {
Value string `json:"value"`
} `json:"data"`
}
if err = dao.client.Get(c, dao.relatedURL, ip, params, &res); err != nil {
log.Error("realte url(%s) error(%v) ", dao.relatedURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("relate aids api failed(%d)", res.Code)
log.Error("url(%s) res code(%d) or res.result(%v)", dao.relatedURL+"?"+params.Encode(), res.Code, res.Data)
return
}
if res.Data == nil {
err = nil
return
}
// FIXME why two state
if len(res.Data) > 0 {
if aids, err = xstr.SplitInts(res.Data[0].Value); err != nil {
log.Error("realte aids url(%s) error(%v)", dao.relatedURL+"?"+params.Encode(), err)
}
}
return
}

View File

@@ -0,0 +1,34 @@
package data
import (
"context"
"flag"
"path/filepath"
"testing"
"go-common/app/interface/main/web-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var d *Dao
func WithDao(f func(d *Dao)) func() {
return func() {
dir, _ := filepath.Abs("../cmd/web-show-test.toml")
flag.Set("conf", dir)
conf.Init()
if d == nil {
d = New(conf.Conf)
}
f(d)
}
}
func TestDao_Data(t *testing.T) {
Convey("test Data", t, WithDao(func(d *Dao) {
aid := int64(2)
data, err := d.Related(context.TODO(), aid, "")
So(err, ShouldBeNil)
Printf("%+v", data)
}))
}

View File

@@ -0,0 +1,54 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"jobs_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"jobs.go",
],
importpath = "go-common/app/interface/main/web-show/dao/job",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/model/job:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/stat/prom: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,37 @@
package job
import (
"context"
"go-common/app/interface/main/web-show/conf"
xsql "go-common/library/database/sql"
"go-common/library/log"
"go-common/library/stat/prom"
)
// Dao struct
type Dao struct {
db *xsql.DB
}
// PromError err
func PromError(name string, format string, args ...interface{}) {
prom.BusinessErrCount.Incr(name)
log.Error(format, args...)
}
// New conf
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{db: xsql.NewMySQL(c.MySQL.Operation)}
return
}
// Ping Dao
func (dao *Dao) Ping(c context.Context) error {
return dao.db.Ping(c)
}
// Close Dao
func (dao *Dao) Close() {
dao.db.Close()
}

View File

@@ -0,0 +1,22 @@
package job
import (
"flag"
"path/filepath"
"go-common/app/interface/main/web-show/conf"
)
var d *Dao
func WithDao(f func(d *Dao)) func() {
return func() {
dir, _ := filepath.Abs("../cmd/web-show-test.toml")
flag.Set("conf", dir)
conf.Init()
if d == nil {
d = New(conf.Conf)
}
f(d)
}
}

View File

@@ -0,0 +1,52 @@
package job
import (
"context"
"go-common/app/interface/main/web-show/model/job"
"go-common/library/log"
)
const (
_selCateSQL = "SELECT id,name,type FROM job_category"
_selJobsSQL = "SELECT id,name,cate_id,addr_id,duty,demand FROM jobs WHERE status=1"
)
// Categories Dao
func (dao *Dao) Categories(c context.Context) (cs []*job.Category, err error) {
rows, err := dao.db.Query(c, _selCateSQL)
if err != nil {
log.Error("Job.GetAllCate error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
c := &job.Category{}
if err = rows.Scan(&c.ID, &c.Name, &c.Type); err != nil {
PromError("Categories", "rows.scan err(%v)", err)
return
}
cs = append(cs, c)
}
return
}
// Jobs Dao
func (dao *Dao) Jobs(c context.Context) (js []*job.Job, err error) {
rows, err := dao.db.Query(c, _selJobsSQL)
if err != nil {
log.Error("Job.Jobs error (%v)", err)
return
}
defer rows.Close()
for rows.Next() {
j := &job.Job{}
if err = rows.Scan(&j.ID, &j.Name, &j.CateID, &j.AddrID, &j.Duty, &j.Demand); err != nil {
PromError("Jobs", "rows.scan err(%v)", err)
return
}
js = append(js, j)
}
return
}

View File

@@ -0,0 +1,16 @@
package job
import (
"context"
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_Job(t *testing.T) {
Convey("test job", t, WithDao(func(d *Dao) {
data, err := d.Jobs(context.TODO())
So(err, ShouldBeNil)
Printf("%+v", data)
}))
}

View File

@@ -0,0 +1,52 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["dao_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"operation.go",
],
importpath = "go-common/app/interface/main/web-show/dao/operation",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/model/operation:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/stat/prom:go_default_library",
"//library/time: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,37 @@
package operation
import (
"context"
"go-common/app/interface/main/web-show/conf"
xsql "go-common/library/database/sql"
"go-common/library/log"
"go-common/library/stat/prom"
)
// Dao struct
type Dao struct {
db *xsql.DB
}
// PromError err
func PromError(name string, format string, args ...interface{}) {
prom.BusinessErrCount.Incr(name)
log.Error(format, args...)
}
// New Conf
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{db: xsql.NewMySQL(c.MySQL.Operation)}
return
}
// Close Dao
func (dao *Dao) Close() {
dao.db.Close()
}
// Ping Dao
func (dao *Dao) Ping(c context.Context) error {
return dao.db.Ping(c)
}

View File

@@ -0,0 +1,34 @@
package operation
import (
"context"
"flag"
"path/filepath"
"testing"
"go-common/app/interface/main/web-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var d *Dao
func WithDao(f func(d *Dao)) func() {
return func() {
dir, _ := filepath.Abs("../cmd/web-show-test.toml")
flag.Set("conf", dir)
conf.Init()
if d == nil {
d = New(conf.Conf)
}
f(d)
}
}
func TestDao_Operation(t *testing.T) {
Convey("test operation", t, WithDao(func(d *Dao) {
data, err := d.Operation(context.TODO())
So(err, ShouldBeNil)
Printf("%+v", data)
}))
}

View File

@@ -0,0 +1,34 @@
package operation
import (
"context"
"time"
"go-common/app/interface/main/web-show/model/operation"
"go-common/library/log"
xtime "go-common/library/time"
)
const (
_selNoticeSQL = "SELECT id,type,content,link,ads,pic,rank FROM operations where stime <= ? AND etime > ? ORDER BY stime DESC"
)
//Operation dao
func (dao *Dao) Operation(c context.Context) (ns []*operation.Operation, err error) {
now := xtime.Time(time.Now().Unix())
rows, err := dao.db.Query(c, _selNoticeSQL, now, now)
if err != nil {
log.Error("notice.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
n := &operation.Operation{}
if err = rows.Scan(&n.ID, &n.Type, &n.Message, &n.Link, &n.Ads, &n.Pic, &n.Rank); err != nil {
PromError("Operation", "rows.scan err(%v)", err)
return
}
ns = append(ns, n)
}
return
}

View File

@@ -0,0 +1,54 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["dao_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"res.go",
"vdoactive.go",
"vdoad.go",
],
importpath = "go-common/app/interface/main/web-show/dao/resource",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/model/resource:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/stat/prom:go_default_library",
"//library/time: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,68 @@
package resource
import (
"context"
"go-common/app/interface/main/web-show/conf"
xsql "go-common/library/database/sql"
"go-common/library/log"
"go-common/library/stat/prom"
)
//Dao struct
type Dao struct {
db *xsql.DB
videodb *xsql.DB
// ad_active
selAllVdoActStmt *xsql.Stmt
selVdoActMTCntStmt *xsql.Stmt
delAllVdoActStmt *xsql.Stmt
// ad
selAdVdoActStmt *xsql.Stmt
selAdMtCntVdoStmt *xsql.Stmt
// res
selAllResStmt *xsql.Stmt
selAllAssignStmt *xsql.Stmt
selDefBannerStmt *xsql.Stmt
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
db: xsql.NewMySQL(c.MySQL.Res),
videodb: xsql.NewMySQL(c.MySQL.Ads),
}
dao.initActive()
dao.initRes()
dao.initAd()
return
}
// Close close the resource.
func (dao *Dao) Close() {
dao.db.Close()
}
// PromError err
func PromError(name string, format string, args ...interface{}) {
prom.BusinessErrCount.Incr(name)
log.Error(format, args...)
}
// Ping Dao
func (dao *Dao) Ping(c context.Context) (err error) {
if err = dao.db.Ping(c); err != nil {
log.Error("dao.db.Ping error(%v)", err)
return
}
if err = dao.videodb.Ping(c); err != nil {
log.Error("dao.videodb.Ping error(%v)", err)
}
return
}
//BeginTran Dao
func (dao *Dao) BeginTran(c context.Context) (tx *xsql.Tx, err error) {
tx, err = dao.videodb.Begin(c)
return
}

View File

@@ -0,0 +1,34 @@
package resource
import (
"context"
"flag"
"path/filepath"
"testing"
"go-common/app/interface/main/web-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var d *Dao
func WithDao(f func(d *Dao)) func() {
return func() {
dir, _ := filepath.Abs("../cmd/web-show-test.toml")
flag.Set("conf", dir)
conf.Init()
if d == nil {
d = New(conf.Conf)
}
f(d)
}
}
func TestDao_Operation(t *testing.T) {
Convey("test operation", t, WithDao(func(d *Dao) {
data, err := d.Resources(context.TODO())
So(err, ShouldBeNil)
Printf("%+v", data)
}))
}

View File

@@ -0,0 +1,76 @@
package resource
import (
"context"
"time"
"go-common/app/interface/main/web-show/model/resource"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
_selAllResSQL = `SELECT id,platform,name,parent,counter,position FROM resource WHERE state=0 ORDER BY counter desc`
_selAllAssignSQL = `SELECT id,name,contract_id,resource_id,pic,litpic,url,atype,weight,rule,agency FROM resource_assignment WHERE stime<? AND etime>? AND state=0 ORDER BY weight,stime desc`
_selDefBannerSQL = `SELECT id,name,contract_id,resource_id,pic,litpic,url,atype,weight,rule FROM default_one WHERE state=0`
)
func (dao *Dao) initRes() {
dao.selAllResStmt = dao.db.Prepared(_selAllResSQL)
dao.selAllAssignStmt = dao.db.Prepared(_selAllAssignSQL)
dao.selDefBannerStmt = dao.db.Prepared(_selDefBannerSQL)
}
// Resources get resource infos from db
func (dao *Dao) Resources(c context.Context) (rscs []*resource.Res, err error) {
rows, err := dao.selAllResStmt.Query(c)
if err != nil {
log.Error("dao.selAllResStmt query error (%v)", err)
return
}
defer rows.Close()
rscs = make([]*resource.Res, 0)
for rows.Next() {
rsc := &resource.Res{}
if err = rows.Scan(&rsc.ID, &rsc.Platform, &rsc.Name, &rsc.Parent, &rsc.Counter, &rsc.Position); err != nil {
PromError("Resources", "rows.scan err(%v)", err)
return
}
rscs = append(rscs, rsc)
}
return
}
// Assignment get assigment from db
func (dao *Dao) Assignment(c context.Context) (asgs []*resource.Assignment, err error) {
rows, err := dao.selAllAssignStmt.Query(c, time.Now(), time.Now())
if err != nil {
log.Error("dao.selAllAssignmentStmt query error (%v)", err)
return
}
defer rows.Close()
asgs = make([]*resource.Assignment, 0)
for rows.Next() {
asg := &resource.Assignment{}
if err = rows.Scan(&asg.ID, &asg.Name, &asg.ContractID, &asg.ResID, &asg.Pic, &asg.LitPic, &asg.URL, &asg.Atype, &asg.Weight, &asg.Rule, &asg.Agency); err != nil {
PromError("Assignment", "rows.scan err(%v)", err)
return
}
asgs = append(asgs, asg)
}
return
}
// DefaultBanner set
func (dao *Dao) DefaultBanner(c context.Context) (asg *resource.Assignment, err error) {
row := dao.selDefBannerStmt.QueryRow(c)
asg = &resource.Assignment{}
if err = row.Scan(&asg.ID, &asg.Name, &asg.ContractID, &asg.ResID, &asg.Pic, &asg.LitPic, &asg.URL, &asg.Atype, &asg.Weight, &asg.Rule); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
PromError("DefaultBanner", "dao.DefaultBanner.QueryRow error(%v)", err)
}
}
return
}

View File

@@ -0,0 +1,75 @@
package resource
import (
"context"
"database/sql"
"go-common/app/interface/main/web-show/model/resource"
xsql "go-common/library/database/sql"
"go-common/library/log"
xtime "go-common/library/time"
)
const (
_inVdoActSQL = "INSERT IGNORE INTO video_ads_active (name,aid,cid,url,skipable,strategy,mtime) VALUES(?,?,?,?,?,?,?)"
_selAllVdoActSQL = "SELECT name,aid,cid,url,skipable,strategy FROM video_ads_active ORDER BY id"
_selVdoMTCntActSQL = `SELECT FROM_UNIXTIME(ROUND(AVG(UNIX_TIMESTAMP(mtime)))) FROM video_ads_active`
_delAllVdoActSQL = "DELETE FROM video_ads_active"
)
// initActive init
func (dao *Dao) initActive() {
dao.selAllVdoActStmt = dao.videodb.Prepared(_selAllVdoActSQL)
dao.selVdoActMTCntStmt = dao.videodb.Prepared(_selVdoMTCntActSQL)
dao.delAllVdoActStmt = dao.videodb.Prepared(_delAllVdoActSQL)
}
// TxInsertVideo dao
func (dao *Dao) TxInsertVideo(tx *xsql.Tx, vad resource.VideoAD) (err error) {
if _, err = tx.Exec(_inVdoActSQL, vad.Name, vad.Aid, vad.Cid, vad.URL, vad.Skipable, vad.Strategy, vad.MTime); err != nil {
log.Error("tx.Stmt(dao.inStmt).Exec(), err (%v)", err)
}
return
}
//VideoAds dao
func (dao *Dao) VideoAds(c context.Context) (vads map[int64][]*resource.VideoAD, err error) {
rows, err := dao.selAllVdoActStmt.Query(c)
if err != nil {
log.Error("dao.selAllVdoStmt query error (%v)", err)
return
}
defer rows.Close()
vads = map[int64][]*resource.VideoAD{}
for rows.Next() {
vad := &resource.VideoAD{}
if err = rows.Scan(&vad.Name, &vad.Aid, &vad.Cid, &vad.URL, &vad.Skipable, &vad.Strategy); err != nil {
log.Error("rows.Scan err (%v)", err)
vads = nil
return
}
vads[vad.Aid] = append(vads[vad.Aid], vad)
}
return
}
// ActVideoMTimeCount dao
func (dao *Dao) ActVideoMTimeCount(c context.Context) (mtime xtime.Time, err error) {
row := dao.selVdoActMTCntStmt.QueryRow(c)
if err = row.Scan(&mtime); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan(), err (%v)", err)
}
}
return
}
// DelAllVideo dao
func (dao *Dao) DelAllVideo(c context.Context) (err error) {
if _, err = dao.delAllVdoActStmt.Exec(c); err != nil {
log.Error("mysqlDB.Exec error(%v)", err)
}
return
}

View File

@@ -0,0 +1,56 @@
package resource
import (
"context"
"database/sql"
"time"
"go-common/app/interface/main/web-show/model/resource"
xsql "go-common/library/database/sql"
"go-common/library/log"
xtime "go-common/library/time"
)
const (
_selAdVdoActSQL = `SELECT id,name,aid,ad_cid,ad_url,skipable,ad_strategy,mtime FROM video_ads WHERE platform=0 and type=0 and state=0 AND verified=1 AND starttime<? AND endtime>?`
_selAdMtCntVdoSQL = `SELECT FROM_UNIXTIME(ROUND(AVG(UNIX_TIMESTAMP(mtime)))) FROM video_ads WHERE platform=0 and type=0 and state=0 AND verified=1 AND starttime<? AND endtime>?`
)
func (dao *Dao) initAd() {
dao.selAdVdoActStmt = dao.videodb.Prepared(_selAdVdoActSQL)
dao.selAdMtCntVdoStmt = dao.videodb.Prepared(_selAdMtCntVdoSQL)
}
// AllVideoActive dao
func (dao *Dao) AllVideoActive(c context.Context, now time.Time) (ads []resource.VideoAD, err error) {
var rows *xsql.Rows
if rows, err = dao.selAdVdoActStmt.Query(c, now, now); err != nil {
log.Error("dao..Exec(%v, %v), err (%v)", now, now, err)
return
}
defer rows.Close()
ads = make([]resource.VideoAD, 0, 100)
for rows.Next() {
ad := resource.VideoAD{}
if err = rows.Scan(&ad.ID, &ad.Name, &ad.AidS, &ad.Cid, &ad.URL, &ad.Skipable, &ad.Strategy, &ad.MTime); err != nil {
log.Error("rows.Scan(), err (%v)", err)
ads = nil
return
}
ads = append(ads, ad)
}
return
}
// AdVideoMTimeCount dao
func (dao *Dao) AdVideoMTimeCount(c context.Context, now time.Time) (mtime xtime.Time, err error) {
row := dao.selAdMtCntVdoStmt.QueryRow(c, now, now)
if err = row.Scan(&mtime); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("mysqlDB error(%v)", err)
}
}
return
}

View File

@@ -0,0 +1,50 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"http.go",
"job.go",
"local.go",
"notice.go",
"res.go",
],
importpath = "go-common/app/interface/main/web-show/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/model/operation:go_default_library",
"//app/interface/main/web-show/model/resource:go_default_library",
"//app/interface/main/web-show/service/job:go_default_library",
"//app/interface/main/web-show/service/operation:go_default_library",
"//app/interface/main/web-show/service/resource:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/middleware/auth:go_default_library",
"//library/net/http/blademaster/middleware/cache:go_default_library",
"//library/net/http/blademaster/middleware/cache/store:go_default_library",
"//library/net/http/blademaster/middleware/verify:go_default_library",
"//library/xstr: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,91 @@
package http
import (
"go-common/app/interface/main/web-show/conf"
"go-common/app/interface/main/web-show/service/job"
"go-common/app/interface/main/web-show/service/operation"
res "go-common/app/interface/main/web-show/service/resource"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/auth"
"go-common/library/net/http/blademaster/middleware/cache"
"go-common/library/net/http/blademaster/middleware/cache/store"
"go-common/library/net/http/blademaster/middleware/verify"
)
var (
jobSvc *job.Service
opSvc *operation.Service
vfySvr *verify.Verify
authSvr *auth.Auth
resSvc *res.Service
// cache components
cacheSvr *cache.Cache
deg *cache.Degrader
)
// Init int http service
func Init(c *conf.Config) {
initService(c)
// init external router
cacheSvr = cache.New(store.NewMemcache(c.DegradeConfig.Memcache))
deg = cache.NewDegrader(c.DegradeConfig.Expire)
engineOut := bm.DefaultServer(c.BM.Outer)
outerRouter(engineOut)
// init Outer serve
if err := engineOut.Start(); err != nil {
log.Error("engineOut.Start error(%v)", err)
panic(err)
}
engineLocal := bm.DefaultServer(c.BM.Local)
localRouter(engineLocal)
// init Outlocaler serve
if err := engineLocal.Start(); err != nil {
log.Error("engineLocal.Start error(%v)", err)
panic(err)
}
}
// initService init service
func initService(c *conf.Config) {
authSvr = auth.New(c.Auth)
vfySvr = verify.New(c.Verify)
jobSvc = job.New(c)
opSvc = operation.New(c)
resSvc = res.New(c)
}
//CloseService close all service
func CloseService() {
jobSvc.Close()
opSvc.Close()
}
// outerRouter init outer router api path.
func outerRouter(e *bm.Engine) {
// init api
e.Ping(ping)
group := e.Group("/x/web-show", bm.CORS())
{
group.GET("/join", join)
group.GET("/notice", notice)
group.GET("/promote", promote)
group.GET("/res/loc", authSvr.Guest, cacheSvr.Cache(deg.Args("id", "pf"), nil), resource)
group.GET("/res/locs", authSvr.Guest, cacheSvr.Cache(deg.Args("ids", "pf"), nil), resources)
group.GET("/ad/video", authSvr.Guest, advideo)
group.GET("/archive/relation", relation)
group.GET("/urls", vfySvr.Verify, urlMonitor)
}
e.GET("/x/ad/video", authSvr.Guest, advideo)
}
// innerRouter init local router api path.
func localRouter(e *bm.Engine) {
group := e.Group("/x/web-show", bm.CORS())
{
group.GET("/monitor/ping", ping)
group.GET("/version", version)
group.GET("/gray", grayRate)
}
}

View File

@@ -0,0 +1,10 @@
package http
import (
bm "go-common/library/net/http/blademaster"
)
// join
func join(c *bm.Context) {
c.JSON(jobSvc.Jobs(c), nil)
}

View File

@@ -0,0 +1,46 @@
package http
import (
"net/http"
"strconv"
"go-common/app/interface/main/web-show/conf"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/xstr"
)
// ping check server ok.
func ping(c *bm.Context) {
if jobSvc.Ping(c) != nil || resSvc.Ping(c) != nil || opSvc.Ping(c) != nil {
log.Error("web-show service ping error")
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}
// version check server version.
func version(c *bm.Context) {
c.JSON(map[string]interface{}{
"version": conf.Conf.Version,
}, nil)
}
func grayRate(c *bm.Context) {
params := c.Request.Form
rateStr := params.Get("rate")
whiteStr := params.Get("white")
swtStr := params.Get("swt")
if rateStr == "" && whiteStr == "" {
res := map[string]interface{}{}
res["rate"], res["white"], res["swt"] = resSvc.GrayRate(c)
c.JSON(res, nil)
return
}
rate, _ := strconv.ParseInt(rateStr, 10, 64)
if rate < 0 || rate > 100 {
rate = 0
}
swt, _ := strconv.ParseBool(swtStr)
white, _ := xstr.SplitInts(whiteStr)
resSvc.SetGrayRate(c, swt, rate, white)
}

View File

@@ -0,0 +1,25 @@
package http
import (
opmdl "go-common/app/interface/main/web-show/model/operation"
bm "go-common/library/net/http/blademaster"
)
// notice
func notice(c *bm.Context) {
arg := new(opmdl.ArgOp)
if err := c.Bind(arg); err != nil {
return
}
notice := opSvc.Notice(c, arg)
c.JSON(notice, nil)
}
// promote
func promote(c *bm.Context) {
arg := new(opmdl.ArgPromote)
if err := c.Bind(arg); err != nil {
return
}
c.JSON(opSvc.Promote(c, arg))
}

View File

@@ -0,0 +1,101 @@
package http
import (
"strconv"
rsmdl "go-common/app/interface/main/web-show/model/resource"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
)
const (
_headerBuvid = "Buvid"
_buvid = "buvid3"
)
func resources(c *bm.Context) {
arg := new(rsmdl.ArgRess)
if err := c.Bind(arg); err != nil {
return
}
arg.Mid, arg.Sid, arg.Buvid = device(c)
data, count, err := resSvc.Resources(c, arg)
if err != nil {
log.Error("resSvc.Resource error(%v)", err)
c.JSON(nil, ecode.Degrade)
return
}
c.JSONMap(map[string]interface{}{
"count": count,
"data": data,
}, nil)
}
func resource(c *bm.Context) {
arg := new(rsmdl.ArgRes)
if err := c.Bind(arg); err != nil {
return
}
arg.Mid, arg.Sid, arg.Buvid = device(c)
data, count, err := resSvc.Resource(c, arg)
if err != nil {
log.Error("resSvc.Resource error(%v)", err)
c.JSON(nil, ecode.Degrade)
return
}
c.JSONMap(map[string]interface{}{
"count": count,
"data": data,
}, nil)
}
func relation(c *bm.Context) {
arg := new(rsmdl.ArgAid)
if err := c.Bind(arg); err != nil {
return
}
arg.Mid, arg.Sid, arg.Buvid = device(c)
c.JSON(resSvc.Relation(c, arg))
}
func advideo(c *bm.Context) {
arg := new(rsmdl.ArgAid)
if err := c.Bind(arg); err != nil {
return
}
midTemp, ok := c.Get("mid")
if !ok {
log.Info("mid not exist")
arg.Mid = 0
} else {
arg.Mid = midTemp.(int64)
}
c.JSON(resSvc.VideoAd(c, arg), nil)
}
func urlMonitor(c *bm.Context) {
params := c.Request.Form
pfStr := params.Get("pf")
pf, _ := strconv.Atoi(pfStr)
c.JSON(resSvc.URLMonitor(c, pf), nil)
}
func device(c *bm.Context) (mid int64, sid, buvid string) {
midTemp, ok := c.Get("mid")
buvid = c.Request.Header.Get(_headerBuvid)
if buvid == "" {
cookie, _ := c.Request.Cookie(_buvid)
if cookie != nil {
buvid = cookie.Value
}
}
if !ok {
if sidCookie, err := c.Request.Cookie("sid"); err == nil {
sid = sidCookie.Value
}
} else {
mid = midTemp.(int64)
}
return
}

View File

@@ -0,0 +1,28 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["job.go"],
importpath = "go-common/app/interface/main/web-show/model/job",
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
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,22 @@
package job
// Job struct
type Job struct {
ID int64 `json:"id"`
JobsCla string `json:"jobs_classification"`
Jid int64 `json:"-"`
Name string `json:"name"`
Location string `json:"location"`
Slogan string `json:"slogan,omitempty"`
CateID int `json:"-"`
AddrID int `json:"-"`
Duty string `json:"duty"`
Demand string `json:"demand"`
}
// Category struct
type Category struct {
ID int `json:"id"`
Name string `json:"name"`
Type int8 `json:"type"`
}

View File

@@ -0,0 +1,32 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"operation.go",
"promote.go",
],
importpath = "go-common/app/interface/main/web-show/model/operation",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = ["//app/service/main/archive/api: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,28 @@
package operation
// Types
var (
Types = []string{
"uptool",
"promote",
}
)
// Operation struct
type Operation struct {
ID int64 `json:"-"`
Type string `json:"-"`
Message string `json:"message"`
Link string `json:"link"`
Pic string `json:"pic,omitempty"`
Ads int `json:"ads,omitempty"`
Rank int `json:"rank"`
Aid int64 `json:"-"`
}
// ArgOp ArgOp
type ArgOp struct {
Tp string `form:"tp"`
Count int `form:"count" validate:"min=0"`
Rank int `form:"rank" validate:"min=0"`
}

View File

@@ -0,0 +1,16 @@
package operation
import "go-common/app/service/main/archive/api"
// Promote strcuct
type Promote struct {
IsAd int8 `json:"is_ad"`
Archive *api.Arc `json:"archive"`
}
// ArgPromote strcuct
type ArgPromote struct {
Tp string `form:"tp" validate:"required"`
Count int `form:"count" validate:"min=0"`
Rank int `form:"rank" validate:"min=0"`
}

View File

@@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"ad.go",
"res.go",
],
importpath = "go-common/app/interface/main/web-show/model/resource",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/archive/api:go_default_library",
"//library/time: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,64 @@
package resource
import xtime "go-common/library/time"
// StrategyOnly int8
const (
StrategyOnly = int8(0) // only
StrategyShare = int8(1) // share
StrategyRank = int8(2) // rank
)
// VideoAD is Ads of videos
type VideoAD struct {
ID int `json:"-"`
Name string `json:"name"`
AidS string `json:"-"`
Aid int64 `json:"aid"`
Cid int64 `json:"cid"`
URL string `json:"url"`
Skipable int8 `json:"skipable"`
Strategy int8 `json:"strategy"`
MTime xtime.Time `json:"-"`
}
// Ad struct
type Ad struct {
RequestID string `json:"request_id"`
AdsInfo map[string]map[string]*AdsInfo `json:"ads_info"`
}
// AdsInfo struct
type AdsInfo struct {
Index int64 `json:"index"`
IsAd bool `json:"is_ad"`
CmMark int8 `json:"cm_mark"`
AdInfo *AdInfo `json:"ad_info"`
}
// CreativeImage type
const (
CreativeImage = int8(0)
CreativeVideo = int8(1)
)
// AdInfo struct
type AdInfo struct {
CreativeID int64 `json:"creative_id"`
CreativeType int8 `json:"creative_type"`
CreativeContent struct {
Title string `json:"title"`
Desc string `json:"description"`
VideoID int64 `json:"video_id"`
UserName string `json:"username"`
ImageURL string `json:"image_url"`
ImageMD5 string `json:"image_md5"`
LogURL string `json:"log_url"`
LogMD5 string `json:"log_md5"`
URL string `json:"url"`
ClickURL string `json:"click_url"`
ShowURL string `json:"show_url"`
ThumbnailURL string `json:"thumbnail_url"`
} `json:"creative_content"`
AdCb string `json:"ad_cb"`
}

View File

@@ -0,0 +1,376 @@
package resource
import (
"go-common/app/service/main/archive/api"
xtime "go-common/library/time"
)
// OverSeasCountry OverSeas Country
var OverSeasCountry = map[string]int64{
"澳大利亚": 2,
"泰国": 4,
"印度": 5,
"英国": 6,
"马来西亚": 8,
"安哥拉": 9,
"韩国": 10,
"俄罗斯": 11,
"新加坡": 12,
"菲律宾": 13,
"越南": 14,
"法国": 15,
"波兰": 16,
"荷兰": 17,
"德国": 18,
"西班牙": 19,
"瑞士": 20,
"欧盟": 21,
"丹麦": 22,
"瑞典": 23,
"意大利": 24,
"比利时": 25,
"爱尔兰": 26,
"芬兰": 27,
"匈牙利": 28,
"希腊": 29,
"保加利亚": 30,
"奥地利": 31,
"阿联酋": 32,
"捷克": 33,
"南非": 34,
"以色列": 35,
"卡塔尔": 36,
"乌克兰": 37,
"哈萨克斯坦": 38,
"葡萄牙": 39,
"沙特阿拉伯": 40,
"伊朗": 41,
"挪威": 42,
"加拿大": 43,
"北美地区": 44,
"叙利亚": 45,
"科威特": 46,
"巴林": 47,
"黎巴嫩": 48,
"阿曼": 49,
"约旦": 50,
"伊拉克": 51,
"土耳其": 52,
"罗马尼亚": 53,
"印度尼西亚": 54,
"格鲁吉亚": 55,
"阿塞拜疆": 56,
"布隆迪": 57,
"津巴布韦": 58,
"赞比亚": 59,
"刚果(金)": 60,
"巴勒斯坦": 61,
"立陶宛": 62,
"斯洛伐克": 63,
"塞尔维亚": 64,
"冰岛": 65,
"斯洛文尼亚": 66,
"摩尔多瓦": 67,
"马其顿": 68,
"列支敦士登": 69,
"泽西岛": 70,
"克罗地亚": 71,
"根西岛": 72,
"波斯尼亚和黑塞哥维那": 73,
"爱沙尼亚": 74,
"拉脱维亚": 75,
"智利": 76,
"秘鲁": 77,
"巴西": 78,
"吉尔吉斯斯坦": 79,
"留尼汪岛": 80,
"马恩岛": 81,
"直布罗陀": 82,
"利比亚": 83,
"亚美尼亚": 84,
"也门": 85,
"白俄罗斯": 86,
"瓜德罗普": 87,
"卢森堡": 88,
"马提尼克岛": 89,
"圭亚那": 90,
"科索沃": 91,
"关岛": 92,
"多米尼加": 93,
"墨西哥": 94,
"委内瑞拉": 95,
"波多黎各": 97,
"格林纳达": 98,
"蒙古": 99,
"新西兰": 100,
"孟加拉": 101,
"巴基斯坦": 102,
"亚太地区": 103,
"尼泊尔": 104,
"巴布亚新几内亚": 105,
"特立尼达和多巴哥": 106,
"哥伦比亚": 107,
"阿根廷": 108,
"斯里兰卡": 109,
"埃及": 110,
"厄瓜多尔": 111,
"哥斯达黎加": 112,
"乌拉圭": 113,
"巴巴多斯": 114,
"巴哈马": 115,
"圣卢西亚": 116,
"拉美地区": 117,
"托克劳群岛": 118,
"柬埔寨": 119,
"马尔代夫": 120,
"阿富汗": 121,
"新喀里多尼亚": 122,
"斐济": 123,
"瓦利斯和富图纳群岛": 124,
"尼日利亚": 125,
"阿尔巴尼亚": 126,
"乌兹别克斯坦": 127,
"塞浦路斯": 128,
"圣马力诺": 129,
"黑山": 130,
"塔吉克斯坦": 131,
"马耳他": 132,
"百慕大": 133,
"圣文森特和格林纳丁斯": 134,
"牙买加": 135,
"多哥": 136,
"危地马拉": 137,
"玻利维亚": 138,
"几内亚": 139,
"苏里南": 140,
"利比里亚": 141,
"肯尼亚": 142,
"加纳": 143,
"坦桑尼亚": 144,
"塞内加尔": 145,
"马达加斯加": 146,
"纳米比亚": 147,
"科特迪瓦": 148,
"苏丹": 149,
"喀麦隆": 150,
"马拉维": 151,
"加蓬": 152,
"马里": 153,
"贝宁": 154,
"乍得": 155,
"博茨瓦纳": 156,
"佛得角": 157,
"卢旺达": 158,
"刚果(布)": 159,
"乌干达": 160,
"莫桑比克": 161,
"冈比亚": 162,
"莱索托": 163,
"毛里求斯": 164,
"非洲地区": 165,
"阿尔及利亚": 166,
"斯威士兰": 167,
"布基纳法索": 168,
"塞拉利昂": 169,
"索马里": 170,
"尼日尔": 171,
"中非": 172,
"南苏丹": 173,
"赤道几内亚": 174,
"塞舌尔": 175,
"吉布提": 176,
"摩洛哥": 177,
"毛里塔尼亚": 178,
"科摩罗": 179,
"英属印度洋领地": 180,
"开曼群岛": 181,
"突尼斯": 182,
"马约特": 183,
"老挝": 184,
"缅甸": 185,
"文莱": 186,
"瑙鲁": 187,
"瓦努阿图": 188,
"不丹": 189,
"密克罗尼西亚联邦": 190,
"法属波利尼西亚": 191,
"东帝汶": 192,
"汤加": 193,
"北马里亚纳群岛": 194,
"格陵兰": 195,
"英属维尔京群岛": 196,
"法罗群岛": 197,
"纽埃岛": 198,
"福克兰群岛": 199,
"特克斯和凯科斯群岛": 200,
"洪都拉斯": 201,
"库拉索": 202,
"荷兰加勒比": 203,
"马绍尔群岛": 204,
"库克群岛": 205,
"巴拿马": 206,
"法属圣马丁": 207,
"美属维尔京群岛": 208,
"美属萨摩亚": 209,
"萨尔瓦多": 210,
"荷属圣马丁": 211,
"阿鲁巴": 212,
"巴拉圭": 213,
"多米尼克": 214,
"安提瓜和巴布达": 215,
"安圭拉": 216,
"圣基茨和尼维斯": 217,
"圣皮埃尔和密克隆群岛": 218,
"土库曼斯坦": 219,
"奥兰群岛": 220,
"摩纳哥": 221,
"法属圭亚那": 222,
"安道尔": 223,
"梵蒂冈": 224,
"海地": 225,
"共享地址": 226,
"所罗门群岛": 227,
"基里巴斯": 228,
"帕劳": 229,
"诺福克岛": 230,
"萨摩亚": 231,
"阿里云骨干网": 232,
"本机地址": 233,
"伯利兹": 234,
"尼加拉瓜": 235,
"古巴": 236,
"圣多美和普林西比": 237,
"几内亚比绍": 238,
"本地链路": 239,
"朝鲜": 240,
"埃塞俄比亚": 241,
"厄立特里亚": 242,
"蒙塞拉特岛": 243,
"图瓦卢": 244,
"圣诞岛": 245,
"圣巴泰勒米岛": 246,
}
// AsgTypePic AsgTypeVideo
const (
AsgTypePic = int8(0)
AsgTypeVideo = int8(1)
// pgc mobile
AsgTypeURL = int8(2)
AsgTypeBangumi = int8(3)
AsgTypeLive = int8(4)
AsgTypeGame = int8(5)
AsgTypeAv = int8(6)
AsgTypeTopic = int8(7)
// content type
FromManager = int8(0)
FromCpm = int8(1)
)
// Assignment struct
type Assignment struct {
ID int `json:"id"`
ContractID string `json:"contract_id"`
ResID int `json:"-"`
PosNum int `json:"pos_num"`
Name string `json:"name"`
Pic string `json:"pic"`
LitPic string `json:"litpic"`
URL string `json:"url"`
Rule string `json:"-"`
Style int32 `json:"style"`
IsAd bool `json:"is_ad,omitempty"`
Archive *api.Arc `json:"archive,omitempty"`
Aid int64 `json:"-"`
Weight int `json:"-"`
Atype int8 `json:"-"`
MTime xtime.Time `json:"-"`
Agency string `json:"agency"`
Label string `json:"label"`
Intro string `json:"intro"`
// cpm
CreativeType int8 `json:"creative_type"`
RequestID string `json:"request_id,omitempty"`
CreativeID int64 `json:"creative_id,omitempty"`
SrcID int64 `json:"src_id,omitempty"`
ShowURL string `json:"show_url,omitempty"`
ClickURL string `json:"click_url,omitempty"`
Area int8 `json:"area"`
IsAdLoc bool `json:"is_ad_loc"`
AdCb string `json:"ad_cb"`
Title string `json:"title"`
ServerType int8 `json:"server_type"`
CmMark int8 `json:"cm_mark"`
IsCpm bool `json:"-"`
STime xtime.Time `json:"stime"`
Mid string `json:"mid"`
}
// Relation struct
type Relation struct {
*api.Arc
// cpm
RequestID string `json:"request_id,omitempty"`
CreativeID int64 `json:"creative_id,omitempty"`
SrcID int64 `json:"src_id,omitempty"`
ShowURL string `json:"show_url,omitempty"`
ClickURL string `json:"click_url,omitempty"`
Area int8 `json:"area"`
IsAdLoc bool `json:"is_ad_loc"`
AdCb string `json:"ad_cb"`
ResID int `json:"resource_id"`
IsAd bool `json:"is_ad"`
}
// Position struct
type Position struct {
Pos []*Loc
Counter int `json:"-"`
}
// Res struct
type Res struct {
ID int `json:"-"`
Platform int `json:"-"`
Name string `json:"-"`
Parent int `json:"-"`
Counter int `json:"-"`
Position int `json:"-"`
// ass
Assignments []*Assignment `json:"-"`
}
// Loc struct
type Loc struct {
ID int `json:"-"`
PosNum int `json:"-"`
}
// ArgRess ArgRess
type ArgRess struct {
Pf int `form:"pf" validate:"min=0"`
Ids []int64 `form:"ids,split" validate:"min=1,dive,gte=1"`
Mid int64
Sid string
IP string
Buvid string
}
// ArgRes ArgRes
type ArgRes struct {
Pf int `form:"pf" validate:"min=0"`
ID int64 `form:"id" validate:"min=1"`
Mid int64
Sid string
IP string
Buvid string
}
// ArgAid ArgAid
type ArgAid struct {
Aid int64 `form:"aid" validate:"min=1"`
Mid int64
Sid string
IP string
Buvid string
}

View File

@@ -0,0 +1,50 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["service_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"jobs.go",
"service.go",
],
importpath = "go-common/app/interface/main/web-show/service/job",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/dao/job:go_default_library",
"//app/interface/main/web-show/model/job:go_default_library",
"//library/log: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,13 @@
package job
import (
"context"
jobmdl "go-common/app/interface/main/web-show/model/job"
)
// Jobs get job infos
func (s *Service) Jobs(c context.Context) (js []*jobmdl.Job) {
js = s.cache
return
}

View File

@@ -0,0 +1,75 @@
package job
import (
"context"
"time"
"go-common/app/interface/main/web-show/conf"
"go-common/app/interface/main/web-show/dao/job"
jobmdl "go-common/app/interface/main/web-show/model/job"
"go-common/library/log"
)
var (
_emptyJobs = make([]*jobmdl.Job, 0)
)
// Service struct
type Service struct {
dao *job.Dao
cache []*jobmdl.Job
}
// New init
func New(c *conf.Config) (s *Service) {
s = &Service{}
s.dao = job.New(c)
s.cache = _emptyJobs
s.reload()
go s.loadproc()
return
}
// jobproc load job infos to cache
func (s *Service) loadproc() {
for {
s.reload()
time.Sleep(time.Duration(conf.Conf.Reload.Jobs))
}
}
// reload
func (s *Service) reload() {
js, err := s.dao.Jobs(context.Background())
if err != nil {
log.Error("s.job.Jobs error(%v)", err)
return
} else if len(js) == 0 {
s.cache = _emptyJobs
}
cates, err := s.dao.Categories(context.Background())
if err != nil {
log.Error("job.Categories error(%v)", err)
return
}
cs := make(map[int]string, len(cates))
for _, cate := range cates {
cs[cate.ID] = cate.Name
}
for _, j := range js {
j.JobsCla = cs[j.CateID]
j.Location = cs[j.AddrID]
}
s.cache = js
}
// Ping Service
func (s *Service) Ping(c context.Context) (err error) {
err = s.dao.Ping(c)
return
}
// Close Service
func (s *Service) Close() {
s.dao.Close()
}

View File

@@ -0,0 +1,40 @@
package job
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/web-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var svf *Service
func init() {
dir, _ := filepath.Abs("../../cmd/web-show-test.toml")
flag.Set("conf", dir)
if err := conf.Init(); err != nil {
panic(err)
}
if svf == nil {
svf = New(conf.Conf)
}
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
f(svf)
}
}
func TestService_Jobs(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
res := svf.Jobs(context.TODO())
So(res, ShouldNotBeNil)
Printf("%+v", res)
}))
}

View File

@@ -0,0 +1,56 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["promote_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/model/operation:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"notice.go",
"promote.go",
"service.go",
],
importpath = "go-common/app/interface/main/web-show/service/operation",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/dao/operation:go_default_library",
"//app/interface/main/web-show/model/operation:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/archive/api/gorpc:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//library/ecode:go_default_library",
"//library/log: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,13 @@
package operation
import (
"context"
opmdl "go-common/app/interface/main/web-show/model/operation"
)
// Notice Service
func (s *Service) Notice(c context.Context, arg *opmdl.ArgOp) (res map[string][]*opmdl.Operation) {
res = s.operation(arg.Tp, arg.Rank, arg.Count)
return
}

View File

@@ -0,0 +1,79 @@
package operation
import (
"context"
"regexp"
"strconv"
opmdl "go-common/app/interface/main/web-show/model/operation"
"go-common/app/service/main/archive/api"
comarcmdl "go-common/app/service/main/archive/model/archive"
"go-common/library/ecode"
"go-common/library/log"
)
var (
_emptyPromoteMap = make(map[string][]*opmdl.Promote)
_avReg = regexp.MustCompile(`video\/av[0-9]+`)
)
// Promote Service
func (s *Service) Promote(c context.Context, arg *opmdl.ArgPromote) (res map[string][]*opmdl.Promote, err error) {
var (
ok bool
arcs map[int64]*api.Arc
arc *api.Arc
aid int64
aids []int64
)
opMap := s.operation(arg.Tp, arg.Rank, arg.Count)
for _, ops := range opMap {
for _, op := range ops {
if aid, err = s.regAid(op.Link); err != nil {
log.Error("service.regAid error(%v)", err)
continue
}
op.Aid = aid
aids = append(aids, aid)
}
}
argAids := &comarcmdl.ArgAids2{
Aids: aids,
}
if arcs, err = s.arcRPC.Archives3(c, argAids); err != nil {
log.Error("s.arcRPC.Archives2(arcAids:(%v), arcs), err(%v)", aids, err)
res = _emptyPromoteMap
return
}
res = make(map[string][]*opmdl.Promote)
for rk, ops := range opMap {
promotes := make([]*opmdl.Promote, 0, len(ops))
for _, op := range ops {
if arc, ok = arcs[op.Aid]; !ok {
continue
}
promote := &opmdl.Promote{
IsAd: int8(op.Ads),
Archive: arc,
}
promotes = append(promotes, promote)
}
res[rk] = promotes
}
return
}
// regAid Service
func (s *Service) regAid(link string) (aid int64, err error) {
avStr := _avReg.FindString(link)
if avStr != "" {
aidStr := avStr[8:]
if aid, err = strconv.ParseInt(aidStr, 10, 64); err != nil {
log.Error("strconv.ParseInt error(%v)", err)
return
}
} else {
err = ecode.ArchiveNotExist
}
return
}

View File

@@ -0,0 +1,46 @@
package operation
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/web-show/conf"
rsmdl "go-common/app/interface/main/web-show/model/operation"
. "github.com/smartystreets/goconvey/convey"
)
var svf *Service
func init() {
dir, _ := filepath.Abs("../../cmd/web-show-test.toml")
flag.Set("conf", dir)
if err := conf.Init(); err != nil {
panic(err)
}
if svf == nil {
svf = New(conf.Conf)
}
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
f(svf)
}
}
func TestService_Resource(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
arg := &rsmdl.ArgPromote{
Tp: "test",
Count: 1,
Rank: 1,
}
res, err := svf.Promote(context.TODO(), arg)
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan, 0)
}))
}

View File

@@ -0,0 +1,109 @@
package operation
import (
"context"
"strconv"
"time"
"go-common/app/interface/main/web-show/conf"
"go-common/app/interface/main/web-show/dao/operation"
opdml "go-common/app/interface/main/web-show/model/operation"
arcrpc "go-common/app/service/main/archive/api/gorpc"
"go-common/library/log"
)
const (
_rankCacheLen = 20
)
// Service struct
type Service struct {
dao *operation.Dao
arcRPC *arcrpc.Service2
cache map[string]map[int][]*opdml.Operation
}
// New init
func New(c *conf.Config) (s *Service) {
s = &Service{
cache: make(map[string]map[int][]*opdml.Operation, len(opdml.Types)),
}
s.arcRPC = arcrpc.New2(c.RPCClient2.Archive)
s.dao = operation.New(c)
s.reload()
go s.loadproc()
return
}
// Notice return notice info
func (s *Service) operation(tp string, rank, num int) (res map[string][]*opdml.Operation) {
res = make(map[string][]*opdml.Operation)
tmp, ok := s.cache[tp]
if ok {
if rank != 0 {
if ns := tmp[rank]; ns != nil {
if len(ns) < num || num < 0 {
num = len(ns)
}
ns = ns[:num]
res[strconv.FormatInt(int64(rank), 10)] = ns
}
} else {
for rk, ns := range tmp {
if ns != nil {
if len(ns) < num || num < 0 {
num = len(ns)
}
ns = ns[:num]
res[strconv.FormatInt(int64(rk), 10)] = ns
}
}
}
}
return
}
// reload Service
func (s *Service) reload() {
var (
tmpT = make(map[string]map[int][]*opdml.Operation)
)
ops, err := s.dao.Operation(context.Background())
if err != nil {
log.Error("s.reloadNotice error(%v)", err)
return
}
for _, op := range ops {
tmp, ok := tmpT[op.Type]
if !ok {
tmp = make(map[int][]*opdml.Operation)
}
if len(tmp) > _rankCacheLen {
continue
}
tmp[op.Rank] = append(tmp[op.Rank], op)
tmpT[op.Type] = tmp
}
s.cache = tmpT
}
// loadproc Service
func (s *Service) loadproc() {
for {
s.reload()
time.Sleep(time.Duration(conf.Conf.Reload.Notice))
}
}
// Close Service
func (s *Service) Close() {
s.dao.Close()
}
// Ping Service
func (s *Service) Ping(c context.Context) (err error) {
err = s.dao.Ping(c)
return
}

View File

@@ -0,0 +1,65 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["res_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/model/resource:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"ad.go",
"refresh.go",
"res.go",
"service.go",
],
importpath = "go-common/app/interface/main/web-show/service/resource",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/web-show/conf:go_default_library",
"//app/interface/main/web-show/dao/ad:go_default_library",
"//app/interface/main/web-show/dao/bangumi:go_default_library",
"//app/interface/main/web-show/dao/data:go_default_library",
"//app/interface/main/web-show/dao/resource:go_default_library",
"//app/interface/main/web-show/model/resource:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/account/rpc/client:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/archive/api/gorpc:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//app/service/main/location/model:go_default_library",
"//app/service/main/location/rpc/client:go_default_library",
"//app/service/main/resource/rpc/client:go_default_library",
"//library/log:go_default_library",
"//library/net/metadata: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,103 @@
package resource
import (
"context"
"math/rand"
"go-common/app/interface/main/web-show/dao/ad"
resmdl "go-common/app/interface/main/web-show/model/resource"
account "go-common/app/service/main/account/model"
"go-common/library/log"
"go-common/library/net/metadata"
)
var (
_emptyVideoAds = []*resmdl.VideoAD{}
)
// VideoAd get videoad by aid
func (s *Service) VideoAd(c context.Context, arg *resmdl.ArgAid) (res []*resmdl.VideoAD) {
arg.IP = metadata.String(c, metadata.RemoteIP)
if arg.Mid > 0 {
// ignore error
var (
resPro *account.Card
err error
)
if resPro, err = s.user(c, arg.Mid, arg.IP); err == nil {
if s.normalVip(c, resPro) {
return
}
}
// NOTE cache?
if isBp := s.bangumiDao.IsBp(c, arg.Mid, arg.Aid, arg.IP); isBp {
log.Info("mid(%d) aid(%d) is bp", arg.Mid, arg.IP)
res = _emptyVideoAds
return
}
}
if res = s.videoAdByAid(arg.Aid); len(res) == 0 {
res = _emptyVideoAds
}
return
}
func (s *Service) user(c context.Context, mid int64, ip string) (resPro *account.Card, err error) {
arg := &account.ArgMid{
Mid: mid,
}
resPro, err = s.accRPC.Card3(c, arg)
if err != nil {
ad.PromError("accRPC.Info2", "s.accRPC.Info2() err(%v)", err)
log.Error("s.accRPC.Info2() err(%v)", err)
}
return
}
// checkVip check normal vip
func (s *Service) normalVip(c context.Context, pro *account.Card) bool {
if pro.Vip.Type != 0 && pro.Vip.Status == 1 {
return true
}
return false
}
func (s *Service) videoAdByAid(aid int64) (res []*resmdl.VideoAD) {
ss := s.videoCache[aid]
l := len(ss)
if l == 0 {
return
}
// NOTE this means StrategyOnly
if l == 1 {
res = ss[0]
return
}
// NOTE this means StrategyShare
res = ss[rand.Intn(l)]
return
}
// loadVideoAd load videoad to cache
func (s *Service) loadVideoAd() (err error) {
ads, err := s.resdao.VideoAds(context.Background())
if err != nil {
log.Error("s.resdao.VideoAds error(%v)", err)
return
}
tmp := make(map[int64][][]*resmdl.VideoAD)
for aid, vads := range ads {
if len(vads) < 1 {
continue
}
if vads[0].Strategy == resmdl.StrategyOnly || vads[0].Strategy == resmdl.StrategyRank {
tmp[aid] = append(tmp[aid], vads)
} else if vads[0].Strategy == resmdl.StrategyShare {
for _, vad := range vads {
tmp[aid] = append(tmp[aid], []*resmdl.VideoAD{vad})
}
}
}
s.videoCache = tmp
return
}

View File

@@ -0,0 +1,71 @@
package resource
import (
"context"
"strconv"
"strings"
"time"
"go-common/library/log"
)
// checkDiff check diff between ads and ads_active
func (s *Service) checkDiff() {
now := time.Now()
s.activeVideos(context.Background(), now)
}
// activeVideos check if VideoAds active need to update
func (s *Service) activeVideos(c context.Context, now time.Time) {
amtime, err := s.resdao.ActVideoMTimeCount(c)
if err != nil {
log.Error("resdao.ActVideoMTimeCount error(%v)", err)
return
}
dmtime, err := s.resdao.AdVideoMTimeCount(c, now)
if err != nil {
log.Error("resdao.AdVideoMTimeCount error(%v)", err)
return
}
if amtime == dmtime {
log.Info("all video active ad are same")
return
}
log.Info("video active avg mtime(%d), ads avg mtime(%d)", amtime, dmtime)
if err = s.resdao.DelAllVideo(c); err != nil {
log.Error("sdDao.DelAllVideo(), err (%v)", err)
return
}
ads, err := s.resdao.AllVideoActive(c, now)
if err != nil {
log.Error("resdao.AllVideoActive(%v), err (%v)", now, err)
return
}
tx, err := s.resdao.BeginTran(c)
if err != nil {
log.Error("BeginTran(), err (%v)", err)
return
}
for _, ad := range ads {
aids := strings.Split(ad.AidS, ",")
for _, aid := range aids {
i, e := strconv.ParseInt(aid, 10, 64)
if e != nil {
log.Error("strconv.ParseInt() error(%v)", e)
continue
}
ad.Aid = i
ad.MTime = dmtime
if err = s.resdao.TxInsertVideo(tx, ad); err != nil {
if err = tx.Rollback(); err != nil {
log.Error("tx.Rollback(), err (%v)", err)
}
log.Error("resdao.TxInsertVideo(tx, %v), err(%v)", ad, err)
return
}
}
}
if err = tx.Commit(); err != nil {
log.Error("tx.Commit(), error(%v)", err)
}
}

View File

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

View File

@@ -0,0 +1,72 @@
package resource
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/web-show/conf"
rsmdl "go-common/app/interface/main/web-show/model/resource"
. "github.com/smartystreets/goconvey/convey"
)
const (
_ip = "172.0.0.1"
)
var svf *Service
func init() {
dir, _ := filepath.Abs("../../cmd/web-show-test.toml")
flag.Set("conf", dir)
if err := conf.Init(); err != nil {
panic(err)
}
if svf == nil {
svf = New(conf.Conf)
}
time.Sleep(time.Second)
}
func WithService(f func(s *Service)) func() {
return func() {
f(svf)
}
}
func TestService_Resource(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
arg := &rsmdl.ArgRes{
Mid: 1,
ID: 0,
Pf: 0,
Sid: "test",
IP: _ip,
Buvid: "test",
}
res, count, err := svf.Resource(context.TODO(), arg)
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan, 0)
So(count, ShouldBeGreaterThan, 0)
}))
}
func TestService_Resources(t *testing.T) {
Convey("should return without err", t, WithService(func(svf *Service) {
arg := &rsmdl.ArgRess{
Mid: 1,
Ids: []int64{1, 2, 3},
Pf: 0,
Sid: "test",
IP: _ip,
Buvid: "test",
}
res, count, err := svf.Resources(context.TODO(), arg)
So(err, ShouldBeNil)
So(len(res), ShouldBeGreaterThan, 0)
So(count, ShouldBeGreaterThan, 0)
}))
}

View File

@@ -0,0 +1,108 @@
package resource
import (
"context"
"time"
"go-common/app/interface/main/web-show/conf"
"go-common/app/interface/main/web-show/dao/ad"
"go-common/app/interface/main/web-show/dao/bangumi"
"go-common/app/interface/main/web-show/dao/data"
resdao "go-common/app/interface/main/web-show/dao/resource"
rsmdl "go-common/app/interface/main/web-show/model/resource"
accrc "go-common/app/service/main/account/rpc/client"
arcrpc "go-common/app/service/main/archive/api/gorpc"
locrpc "go-common/app/service/main/location/rpc/client"
recrpc "go-common/app/service/main/resource/rpc/client"
"go-common/library/log"
)
// Service define web-show service
type Service struct {
resdao *resdao.Dao
bangumiDao *bangumi.Dao
accRPC *accrc.Service3
arcRPC *arcrpc.Service2
recrpc *recrpc.Service
adDao *ad.Dao
dataDao *data.Dao
locRPC *locrpc.Service
// cache
asgCache map[int][]*rsmdl.Assignment // resID => assignments
urlMonitor map[int]map[string]string // pf=>map[rs.name=>url]
videoCache map[int64][][]*rsmdl.VideoAD
posCache map[string]*rsmdl.Position // resID=>srcIDs
defBannerCache *rsmdl.Assignment
adsCache map[int]*rsmdl.Assignment
}
// New return service object
func New(c *conf.Config) *Service {
s := &Service{
adDao: ad.New(c),
resdao: resdao.New(c),
bangumiDao: bangumi.New(c),
dataDao: data.New(c),
asgCache: make(map[int][]*rsmdl.Assignment),
videoCache: make(map[int64][][]*rsmdl.VideoAD),
posCache: make(map[string]*rsmdl.Position),
// crm
adsCache: make(map[int]*rsmdl.Assignment),
}
s.arcRPC = arcrpc.New2(c.RPCClient2.Archive)
s.accRPC = accrc.New3(c.RPCClient2.Account)
s.recrpc = recrpc.New(c.RPCClient2.Resource)
s.locRPC = locrpc.New(c.LocationRPC)
s.init()
return s
}
func (s *Service) init() (err error) {
if err = s.loadRes(); err != nil {
log.Error("adService.Load, err (%v)", err)
}
if err = s.loadVideoAd(); err != nil {
log.Error("adService.LoadVideo, err (%v)", err)
}
// if err = s.loadAds(); err != nil {
// log.Error("s.loadAds err(%v)", err)
// }
go s.checkproc()
go s.loadproc()
return
}
// loadproc is a routine load ads to cache
func (s *Service) loadproc() {
for {
s.loadRes()
s.loadVideoAd()
//s.loadAds()
time.Sleep(time.Duration(conf.Conf.Reload.Ad))
}
}
// checkpro a routine check diff
func (s *Service) checkproc() {
for {
s.checkDiff()
time.Sleep(time.Duration(conf.Conf.Reload.Ad))
}
}
// Close close service
func (s *Service) Close() {
s.resdao.Close()
}
// Ping ping service
func (s *Service) Ping(c context.Context) (err error) {
if err = s.resdao.Ping(c); err != nil {
log.Error("s.resDap.Ping err(%v)", err)
return
}
if err = s.adDao.Ping(c); err != nil {
log.Error("s.adDao.Ping err(%v)", err)
}
return
}