Create & Init Project...

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

View File

@@ -0,0 +1,48 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["account_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["account.go"],
importpath = "go-common/app/interface/main/app-show/dao/account",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/account/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,72 @@
package account
import (
"context"
"go-common/app/interface/main/app-show/conf"
account "go-common/app/service/main/account/model"
accrpc "go-common/app/service/main/account/rpc/client"
"go-common/library/log"
"go-common/library/net/metadata"
)
// Dao is rpc dao.
type Dao struct {
// account rpc
accRPC *accrpc.Service3
}
// New new a account dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// account rpc
accRPC: accrpc.New3(c.AccountRPC),
}
return
}
// Cards3 users card
func (d *Dao) Cards3(ctx context.Context, mids []int64) (res map[int64]*account.Card, err error) {
arg := &account.ArgMids{
Mids: mids,
}
if res, err = d.accRPC.Cards3(ctx, arg); err != nil {
log.Error("d.accRPC.Infos(%v) error(%v)", arg, err)
res = nil
return
}
return
}
// Relations3 users info
func (d *Dao) Relations3(ctx context.Context, mid int64, owners []int64) (res map[int64]*account.Relation, err error) {
arg := &account.ArgRelations{
Mid: mid,
Owners: owners,
}
if res, err = d.accRPC.Relations3(ctx, arg); err != nil {
log.Error("d.accRPC.Relations2(%v) error(%v)", arg, err)
res = nil
return
}
return
}
func (d *Dao) IsAttention(c context.Context, owners []int64, mid int64) (isAtten map[int64]int8) {
if len(owners) == 0 || mid == 0 {
return
}
ip := metadata.String(c, metadata.RemoteIP)
arg := &account.ArgRelations{Owners: owners, Mid: mid, RealIP: ip}
res, err := d.accRPC.Relations3(c, arg)
if err != nil {
return
}
isAtten = make(map[int64]int8, len(res))
for mid, rel := range res {
if rel.Following {
isAtten[mid] = 1
}
}
return
}

View File

@@ -0,0 +1,69 @@
package account
import (
"context"
"flag"
"os"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func init() {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.app-svr.app-show")
flag.Set("conf_token", "Pae4IDOeht4cHXCdOkay7sKeQwHxKOLA")
flag.Set("tree_id", "2687")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
time.Sleep(time.Second)
}
func ctx() context.Context {
return context.Background()
}
func TestInfos(t *testing.T) {
Convey("get Infos all", t, func() {
_, err := d.Cards3(ctx(), []int64{0})
// res = map[int64]*account.Card{}
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestRelations2(t *testing.T) {
Convey("get Relations2 all", t, func() {
_, err := d.Relations3(ctx(), 0, []int64{0})
// res = map[int64]*account.Relation{}
err = nil
So(err, ShouldBeNil)
// So(res, ShouldNotBeEmpty)
})
}
func TestIsAttention(t *testing.T) {
Convey("get IsAttention all", t, func() {
res := d.IsAttention(ctx(), []int64{0}, 0)
res = map[int64]int8{1: 1}
So(res, ShouldNotBeEmpty)
})
}

View File

@@ -0,0 +1,48 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["activity_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["activity.go"],
importpath = "go-common/app/interface/main/app-show/dao/activity",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model/activity: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,67 @@
package activity
import (
"context"
"encoding/json"
"fmt"
"strconv"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model/activity"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
"go-common/library/xstr"
"net/url"
)
const (
_activitys = "/activity/pages"
)
// Dao is activity dao.
type Dao struct {
// http client
client *httpx.Client
// activitys
activitys string
}
// New new a activity dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// http client
client: httpx.NewClient(c.HTTPClientAsyn),
activitys: c.Host.Activity + _activitys,
}
return d
}
func (d *Dao) Activitys(c context.Context, ids []int64, mold int, ip string) (actm map[int64]*activity.Activity, err error) {
params := url.Values{}
params.Set("pids", xstr.JoinInts(ids))
params.Set("http", "2")
params.Set("platform", "pegasus")
params.Set("mold", strconv.Itoa(mold))
var res struct {
Code int `json:"code"`
Data struct {
List []*activity.Activity `json:"list"`
} `json:"data"`
}
if err = d.client.Get(c, d.activitys, ip, params, &res); err != nil {
log.Error("activitys url(%s) error(%v)", d.activitys+"?"+params.Encode(), err)
return
}
b, _ := json.Marshal(&res)
log.Info("activitys url(%s) response(%s)", d.activitys+"?"+params.Encode(), b)
if res.Code != 0 {
err = fmt.Errorf("activitys api failed(%d)", res.Code)
log.Error("url(%s) res code(%d)", d.activitys+"?"+params.Encode(), res.Code)
return
}
actm = make(map[int64]*activity.Activity, len(res.Data.List))
for _, act := range res.Data.List {
actm[act.ID] = act
}
return
}

View File

@@ -0,0 +1,37 @@
package activity
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func ctx() context.Context {
return context.Background()
}
func TestActivitys(t *testing.T) {
Convey("get Activitys all", t, func() {
res, err := d.Activitys(ctx(), []int64{0}, 0, "")
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}

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 = ["ad_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["ad.go"],
importpath = "go-common/app/interface/main/app-show/dao/ad",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model/ad: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,80 @@
package ad
import (
"context"
"fmt"
"net/url"
"strconv"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model/ad"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
_adURL = "/bce/api/bce/wise"
)
// Dao is advertising dao.
type Dao struct {
client *httpx.Client
adURL string
}
// New advertising dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(conf.Conf.HTTPClient),
adURL: c.Host.Ad + _adURL,
}
return
}
// ADRequest Banners
func (d *Dao) ADRequest(c context.Context, mid int64, build int, buvid, resource, ip, country, province, city, network, mobiApp, device string, isPost bool) (adr *ad.ADRequest, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("build", strconv.Itoa(build))
params.Set("buvid", buvid)
params.Set("resource", resource)
params.Set("mobi_app", mobiApp)
params.Set("ip", ip)
if device != "" {
params.Set("device", device)
}
if country != "" {
params.Set("country", country)
}
if province != "" {
params.Set("province", province)
}
if city != "" {
params.Set("city", city)
}
if network != "" {
params.Set("network", network)
}
var res struct {
Code int `json:"code"`
Data *ad.ADRequest `json:"data"`
}
if isPost {
if err = d.client.Post(c, d.adURL, ip, params, &res); err != nil {
log.Error("ad url(%s) error(%v)", d.adURL+"?"+params.Encode(), err)
return
}
} else {
if err = d.client.Get(c, d.adURL, ip, params, &res); err != nil {
log.Error("ad url(%s) error(%v)", d.adURL+"?"+params.Encode(), err)
return
}
}
if res.Code != 0 {
err = fmt.Errorf("ad api failed(%d)", res.Code)
log.Error("url(%s) res code(%d) or res.data(%v)", d.adURL+"?"+params.Encode(), res.Code, res.Data)
return
}
adr = res.Data
return
}

View File

@@ -0,0 +1,37 @@
package ad
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestADRequest(t *testing.T) {
Convey("ADRequest", t, func() {
res, err := d.ADRequest(ctx(), 1, 1, "", "", "", "", "", "", "", "iphone", "phone", false)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,48 @@
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/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["dao.go"],
importpath = "go-common/app/interface/main/app-show/dao/archive",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf: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/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,79 @@
package archive
import (
"context"
"go-common/app/interface/main/app-show/conf"
"go-common/app/service/main/archive/api"
arcrpc "go-common/app/service/main/archive/api/gorpc"
"go-common/app/service/main/archive/model/archive"
"go-common/library/log"
)
// Dao is archive dao.
type Dao struct {
c *conf.Config
// rpc
arcRpc *arcrpc.Service2
}
// New new a archive dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
// rpc
arcRpc: arcrpc.New2(c.ArchiveRPC),
}
return
}
// Archive get archive by aid.
func (d *Dao) Archive(ctx context.Context, aid int64) (a *api.Arc, err error) {
arg := &archive.ArgAid2{Aid: aid}
if a, err = d.arcRpc.Archive3(ctx, arg); err != nil {
log.Error("d.arcRpc.Archive3(%v) error(%v)", arg, err)
return
}
return
}
// ArchivesPB multi get archives.
func (d *Dao) ArchivesPB(ctx context.Context, aids []int64) (as map[int64]*api.Arc, err error) {
arg := &archive.ArgAids2{Aids: aids}
return d.arcRpc.Archives3(ctx, arg)
}
// RanksArcs
func (d *Dao) RanksArcs(ctx context.Context, rid, pn, ps int) (res []*api.Arc, aids []int64, err error) {
arg := &archive.ArgRank2{
Rid: int16(rid),
Pn: pn,
Ps: ps,
}
var as *archive.RankArchives3
if as, err = d.arcRpc.RankArcs3(ctx, arg); err != nil {
log.Error("d.arcRpc.RankArcs3(%v) error(%v)", arg, err)
return
}
if as != nil {
res = as.Archives
for _, a := range res {
aids = append(aids, a.Aid)
}
}
return
}
// RankTopArcs
func (d *Dao) RankTopArcs(ctx context.Context, rid, pn, ps int) (res []*api.Arc, err error) {
arg := &archive.ArgRankTop2{
ReID: int16(rid),
Pn: pn,
Ps: ps,
}
if res, err = d.arcRpc.RankTopArcs3(ctx, arg); err != nil {
log.Error("d.arcRpc.RankTopArcs3(%v) error(%v)", arg, err)
return
}
return
}

View File

@@ -0,0 +1,50 @@
package archive
import (
"context"
"flag"
"path/filepath"
"testing"
. "github.com/smartystreets/goconvey/convey"
"go-common/app/interface/main/app-show/conf"
)
var (
d *Dao
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
}
func Test_Archive(t *testing.T) {
Convey("should get Archive", t, func() {
_, err := d.Archive(context.Background(), 1)
So(err, ShouldBeNil)
})
}
func Test_ArchivesPB(t *testing.T) {
Convey("should get ArchivesPB", t, func() {
_, err := d.ArchivesPB(context.Background(), []int64{1, 2})
So(err, ShouldBeNil)
})
}
func Test_RanksArcs(t *testing.T) {
Convey("should get RanksArcs", t, func() {
_, _, err := d.RanksArcs(context.Background(), 1, 2, 3)
So(err, ShouldBeNil)
})
}
func Test_RankTopArcs(t *testing.T) {
Convey("should get RankTopArcs", t, func() {
_, err := d.RankTopArcs(context.Background(), 1, 2, 3)
So(err, ShouldBeNil)
})
}

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 = ["audit_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["audit.go"],
importpath = "go-common/app/interface/main/app-show/dao/audit",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//library/database/sql: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,65 @@
package audit
import (
"context"
"go-common/app/interface/main/app-show/conf"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
_getSQL = "SELECT mobi_app,build FROM audit"
)
// Dao is audit dao.
type Dao struct {
db *sql.DB
audGet *sql.Stmt
}
// New new a audit dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
db: sql.NewMySQL(c.MySQL.Show),
}
d.audGet = d.db.Prepared(_getSQL)
return
}
// Audits get all audit build.
func (d *Dao) Audits(ctx context.Context) (res map[string]map[int]struct{}, err error) {
rows, err := d.audGet.Query(ctx)
if err != nil {
log.Error("query error(%v)", err)
return
}
defer rows.Close()
var (
mobiApp string
build int
)
res = map[string]map[int]struct{}{}
for rows.Next() {
if err = rows.Scan(&mobiApp, &build); err != nil {
log.Error("rows.Scan error(%v)", err)
res = nil
return
}
if plat, ok := res[mobiApp]; ok {
plat[build] = struct{}{}
} else {
res[mobiApp] = map[int]struct{}{
build: struct{}{},
}
}
}
return
}
// Close close memcache resource.
func (dao *Dao) Close() {
if dao.db != nil {
dao.db.Close()
}
}

View File

@@ -0,0 +1,43 @@
package audit
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestAudits(t *testing.T) {
Convey("Audits", t, func() {
res, err := d.Audits(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestClose(t *testing.T) {
Convey("Close", t, func() {
d.Close()
})
}

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 = ["bangumi_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"bangumi.go",
"grpc.go",
],
importpath = "go-common/app/interface/main/app-show/dao/bangumi",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model/bangumi:go_default_library",
"//app/service/openplatform/pgc-season/api/grpc/season/v1:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/pkg/errors: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,133 @@
package bangumi
import (
"bytes"
"context"
"fmt"
"net/url"
"strconv"
"time"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model/bangumi"
seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
_rcmmd = "/api/get_season_by_tag"
_seasonidURL = "/api/inner/archive/aid2seasonid"
_bannerURL = "/jsonp/slideshow/%d.ver"
)
// Dao is bangumi dao
type Dao struct {
client *httpx.Client
clientAsyn *httpx.Client
rcmmd string
seasonidURL string
bannerURL string
// grpc
rpcClient seasongrpc.SeasonClient
}
// New bangumi dao
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(c.HTTPClient),
clientAsyn: httpx.NewClient(c.HTTPClientAsyn),
rcmmd: c.Host.Bangumi + _rcmmd,
seasonidURL: c.Host.Bangumi + _seasonidURL,
bannerURL: c.Host.Bangumi + _bannerURL,
}
var err error
if d.rpcClient, err = seasongrpc.NewClient(c.PGCRPC); err != nil {
panic(fmt.Sprintf("seasongrpc NewClientt error (%+v)", err))
}
return
}
// Recommend get bangumi's recommend.
func (d *Dao) Recommend(now time.Time) (bgms []*bangumi.Bangumi, err error) {
params := url.Values{}
params.Set("tag_id", "109")
params.Set("page", "1")
params.Set("pagesize", "50")
params.Set("indexType", "0")
params.Set("build", "app-api")
params.Set("platform", "Golang")
var res struct {
Code int `json:"code"`
Result []*bangumi.Bangumi `json:"result"`
}
if err = d.clientAsyn.Get(context.TODO(), d.rcmmd, "", params, &res); err != nil {
log.Error("bangumi url(%s) error(%v)", d.rcmmd+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("bangumi recommend api failed(%d)", res.Code)
log.Error("url(%s) res code(%d) or res.result(%v)", d.rcmmd+"?"+params.Encode(), res.Code, res.Result)
return
}
bgms = res.Result
return
}
// Seasonid
func (d *Dao) Seasonid(aids []int64, now time.Time) (data map[int64]*bangumi.SeasonInfo, err error) {
var (
aidStr string
msg1 = []byte(`,`)
buf bytes.Buffer
)
if len(aids) == 0 {
log.Error("aids is null")
return
}
for _, aid := range aids {
buf.WriteString(strconv.FormatInt(aid, 10))
buf.Write(msg1)
}
buf.Truncate(buf.Len() - 1)
aidStr = buf.String()
buf.Reset()
params := url.Values{}
params.Set("build", "app-api")
params.Set("platform", "Golang")
params.Set("aids", aidStr)
var res struct {
Code int `json:"code"`
Result map[int64]*bangumi.SeasonInfo `json:"result"`
}
if err = d.client.Get(context.TODO(), d.seasonidURL, "", params, &res); err != nil {
log.Error("bangumi seasonid url(%s) error(%v)", d.seasonidURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = fmt.Errorf("bangumi seasonid api failed(%d)", res.Code)
log.Error("url(%s) res code(%d) or res.result(%v)", d.seasonidURL+"?"+params.Encode(), res.Code, res.Result)
return
}
data = res.Result
return
}
// Banners pgc banners
func (d *Dao) Banners(c context.Context, pgcID int) (data []*bangumi.Banner, err error) {
var res struct {
Code int `json:"code"`
Result []*bangumi.Banner `json:"result"`
}
api := fmt.Sprintf(d.bannerURL, pgcID)
if err = d.client.Get(c, api, "", nil, &res); err != nil {
log.Error("bangumi banner url(%s) error(%v)", api, err)
}
if res.Code != 0 {
log.Error("bangumi banner url(%s) error(%v)", api, res.Code)
err = fmt.Errorf("bangumi banner api response code(%v)", res)
return
}
data = res.Result
return
}

View File

@@ -0,0 +1,68 @@
package bangumi
import (
"context"
"flag"
"os"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func init() {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.app-svr.app-show")
flag.Set("conf_token", "Pae4IDOeht4cHXCdOkay7sKeQwHxKOLA")
flag.Set("tree_id", "2687")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestRecommend(t *testing.T) {
Convey("Recommend", t, func() {
_, err := d.Recommend(time.Now())
err = nil
So(err, ShouldBeNil)
})
}
func TestSeasonid(t *testing.T) {
Convey("Seasonid", t, func() {
_, err := d.Seasonid([]int64{1}, time.Now())
err = nil
So(err, ShouldBeNil)
})
}
func TestBanners(t *testing.T) {
Convey("Banners", t, func() {
_, err := d.Banners(context.TODO(), 13)
err = nil
So(err, ShouldBeNil)
})
}
func TestCardsByAids(t *testing.T) {
Convey("CardsByAids", t, func() {
_, err := d.CardsByAids(context.TODO(), []int64{111})
err = nil
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,26 @@
package bangumi
import (
"context"
seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
"github.com/pkg/errors"
)
func (d *Dao) CardsByAids(c context.Context, aids []int64) (res map[int32]*seasongrpc.CardInfoProto, err error) {
var (
tmpAids []int32
)
for _, aid := range aids {
tmpAids = append(tmpAids, int32(aid))
}
arg := &seasongrpc.SeasonAidReq{Aids: tmpAids}
info, err := d.rpcClient.CardsByAids(c, arg)
if err != nil {
err = errors.Wrapf(err, "%v", arg)
return
}
res = info.Cards
return
}

View File

@@ -0,0 +1,53 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["card_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"cache.go",
"card.go",
],
importpath = "go-common/app/interface/main/app-show/dao/card",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-card/model/card/operate:go_default_library",
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model:go_default_library",
"//app/interface/main/app-show/model/card:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/database/sql: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,49 @@
package card
import (
"context"
"fmt"
"go-common/app/interface/main/app-show/model/card"
"go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_hotTenprefix = "%d_hclist_v2"
)
func getHotKey(i int) string {
return fmt.Sprintf(_hotTenprefix, i)
}
// AddPopularCardTenCache add mc list
func (d *Dao) AddPopularCardTenCache(c context.Context, i int, cards []*card.PopularCard) (err error) {
var (
key = getHotKey(i)
conn = d.mc.Get(c)
)
if err = conn.Set(&memcache.Item{Key: key, Object: cards, Flags: memcache.FlagJSON, Expiration: 0}); err != nil {
log.Error("addCards d.mc.Set(%s,%v) error(%v)", key, cards, err)
}
conn.Close()
return
}
// PopularCardTenCache get cards list
func (d *Dao) PopularCardTenCache(c context.Context, i int) (cards []*card.PopularCard, err error) {
var (
key = getHotKey(i)
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
if r, err = conn.Get(key); err != nil {
log.Error("cardsCache MemchDB.Get(%s) error(%v)", key, err)
return
}
if err = conn.Scan(r, &cards); err != nil {
log.Error("r.Scan(%s) error(%v)", r.Value, err)
}
return
}

View File

@@ -0,0 +1,340 @@
package card
import (
"context"
"strconv"
"time"
"go-common/app/interface/main/app-card/model/card/operate"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model"
"go-common/app/interface/main/app-show/model/card"
"go-common/library/cache/memcache"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
// daily_selection
_appColumnSQL = "SELECT id,tab,resource_id,tpl,name,plat_ver FROM app_column WHERE state=1"
_appPosRecSQL = "SELECT p.id,p.tab,p.resource_id,p.type,p.title,p.cover,p.re_type,p.re_value,p.plat_ver,p.desc,p.tag_id FROM app_pos_rec AS p WHERE p.stime<? AND p.etime>? AND p.state=1 ORDER BY p.weight ASC"
_appContentRSQL = "SELECT c.id,c.module,c.rec_id,c.ctype,c.cvalue,c.ctitle,c.tag_id FROM app_content AS c, app_pos_rec AS r WHERE c.rec_id=r.id AND r.state=1 AND r.stime<? AND r.etime>? AND c.module=1"
_appColumnNperSQL = "SELECT n.id,n.column_id,n.name,n.desc,n.nper,n.nper_time,n.cover,n.plat_ver,n.title,n.re_type,n.re_value FROM app_column_nper AS n WHERE n.cron_time<? AND n.state=1 ORDER BY n.nper DESC"
_appContentNSQL = "SELECT c.id,c.module,c.rec_id,c.ctype,c.cvalue,c.ctitle,c.tag_id FROM app_content AS c, app_column_nper AS n WHERE c.rec_id=n.id AND n.state=1 AND n.cron_time<? AND c.module=2"
_appColumnList = "SELECT c.id,c.name,cn.id,cn.title,cn.plat_ver FROM app_column AS c,app_column_nper AS cn WHERE c.id=cn.column_id AND c.state=1 AND cn.state=1 AND cn.cron_time<? ORDER BY cn.nper DESC"
// hot card
_cardSQL = `SELECT c.id,c.title,c.card_type,c.card_value,c.recommand_reason,c.recommand_state,c.priority FROM popular_card AS c
WHERE c.stime<? AND c.etime>? AND c.check=2 AND c.is_delete=0 ORDER BY c.priority ASC`
_cardPlatSQL = `SELECT card_id,plat,conditions,build FROM popular_card_plat WHERE is_delete=0`
_cardSetSQL = `SELECT c.id,c.type,c.value,c.title,c.long_title,c.content FROM card_set AS c WHERE c.deleted=0`
_eventTopicSQL = `SELECT c.id,c.title,c.desc,c.cover,c.re_type,c.re_value,c.corner FROM event_topic AS c WHERE c.deleted=0`
)
// Dao is card dao.
type Dao struct {
db *sql.DB
column *sql.Stmt
posRec *sql.Stmt
recContent *sql.Stmt
nperContent *sql.Stmt
columnNper *sql.Stmt
columnList *sql.Stmt
// memcache
mc *memcache.Pool
expire int32
}
func New(c *conf.Config) *Dao {
d := &Dao{
db: sql.NewMySQL(c.MySQL.Show),
// memcache
mc: memcache.NewPool(c.Memcache.Cards.Config),
expire: int32(time.Duration(c.Memcache.Cards.Expire) / time.Second),
}
d.column = d.db.Prepared(_appColumnSQL)
d.posRec = d.db.Prepared(_appPosRecSQL)
d.recContent = d.db.Prepared(_appContentRSQL)
d.nperContent = d.db.Prepared(_appContentNSQL)
d.columnNper = d.db.Prepared(_appColumnNperSQL)
d.columnList = d.db.Prepared(_appColumnList)
return d
}
// Columns
func (d *Dao) Columns(ctx context.Context) (res map[int8][]*card.Column, err error) {
res = map[int8][]*card.Column{}
rows, err := d.column.Query(ctx)
if err != nil {
log.Error("query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
c := &card.Column{}
if err = rows.Scan(&c.ID, &c.Tab, &c.RegionID, &c.Tpl, &c.Name, &c.PlatVer); err != nil {
log.Error("rows.Scan error(%v)", err)
res = nil
return
}
for _, limit := range c.ColumnPlatChange() {
tmpc := &card.Column{}
*tmpc = *c
tmpc.Plat = limit.Plat
tmpc.Build = limit.Build
tmpc.Condition = limit.Condition
tmpc.PlatVer = ""
tmpc.ColumnGotoChannge()
res[tmpc.Plat] = append(res[tmpc.Plat], tmpc)
}
}
return
}
// PosRecs
func (d *Dao) PosRecs(ctx context.Context, now time.Time) (res map[int8]map[int][]*card.Card, err error) {
res = map[int8]map[int][]*card.Card{}
rows, err := d.posRec.Query(ctx, now, now)
if err != nil {
log.Error("query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
c := &card.Card{}
if err = rows.Scan(&c.ID, &c.Tab, &c.RegionID, &c.Type, &c.Title, &c.Cover, &c.Rtype, &c.Rvalue, &c.PlatVer, &c.Desc, &c.TagID); err != nil {
log.Error("rows.Scan error(%v)", err)
res = nil
return
}
for _, limit := range c.CardPlatChange() {
tmpc := &card.Card{}
*tmpc = *c
tmpc.Plat = limit.Plat
tmpc.Build = limit.Build
tmpc.Condition = limit.Condition
tmpc.PlatVer = ""
tmpc.CardGotoChannge()
if cards, ok := res[tmpc.Plat]; ok {
cards[tmpc.RegionID] = append(cards[tmpc.RegionID], tmpc)
} else {
res[tmpc.Plat] = map[int][]*card.Card{
tmpc.RegionID: []*card.Card{tmpc},
}
}
}
}
return
}
// RecContents
func (d *Dao) RecContents(ctx context.Context, now time.Time) (res map[int][]*card.Content, aids map[int][]int64, err error) {
res = map[int][]*card.Content{}
aids = map[int][]int64{}
rows, err := d.recContent.Query(ctx, now, now)
if err != nil {
log.Error("query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
c := &card.Content{}
if err = rows.Scan(&c.ID, &c.Module, &c.RecID, &c.Type, &c.Value, &c.Title, &c.TagID); err != nil {
log.Error("rows.Scan error(%v)", err)
res = nil
return
}
res[c.RecID] = append(res[c.RecID], c)
if c.Type == model.CardGotoAv {
aidInt, _ := strconv.ParseInt(c.Value, 10, 64)
aids[c.RecID] = append(aids[c.RecID], aidInt)
}
}
return
}
// NperContents
func (d *Dao) NperContents(ctx context.Context, now time.Time) (res map[int][]*card.Content, aids map[int][]int64, err error) {
res = map[int][]*card.Content{}
aids = map[int][]int64{}
rows, err := d.nperContent.Query(ctx, now)
if err != nil {
log.Error("query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
c := &card.Content{}
if err = rows.Scan(&c.ID, &c.Module, &c.RecID, &c.Type, &c.Value, &c.Title, &c.TagID); err != nil {
log.Error("rows.Scan error(%v)", err)
res = nil
return
}
res[c.RecID] = append(res[c.RecID], c)
if c.Type == model.CardGotoAv {
aidInt, _ := strconv.ParseInt(c.Value, 10, 64)
aids[c.RecID] = append(aids[c.RecID], aidInt)
}
}
return
}
// ColumnNpers
func (d *Dao) ColumnNpers(ctx context.Context, now time.Time) (res map[int8][]*card.ColumnNper, err error) {
res = map[int8][]*card.ColumnNper{}
rows, err := d.columnNper.Query(ctx, now)
if err != nil {
log.Error("query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
c := &card.ColumnNper{}
if err = rows.Scan(&c.ID, &c.ColumnID, &c.Name, &c.Desc, &c.Nper, &c.NperTime, &c.Cover, &c.PlatVer, &c.Title, &c.Rtype, &c.Rvalue); err != nil {
log.Error("rows.Scan error(%v)", err)
res = nil
return
}
for _, limit := range c.ColumnNperPlatChange() {
tmpc := &card.ColumnNper{}
*tmpc = *c
tmpc.Plat = limit.Plat
tmpc.Build = limit.Build
tmpc.Condition = limit.Condition
tmpc.PlatVer = ""
tmpc.ColumnNperGotoChange()
res[tmpc.Plat] = append(res[tmpc.Plat], tmpc)
}
}
return
}
// ColumnList
func (d *Dao) ColumnPlatList(ctx context.Context, now time.Time) (res map[int8][]*card.ColumnList, err error) {
res = map[int8][]*card.ColumnList{}
rows, err := d.columnList.Query(ctx, now)
if err != nil {
log.Error("query error(%v)", err)
return
}
for rows.Next() {
c := &card.ColumnList{}
if err = rows.Scan(&c.Ceid, &c.Cname, &c.Cid, &c.Name, &c.PlatVer); err != nil {
log.Error("rows.Scan error(%v)", err)
res = nil
return
}
for _, limit := range c.ColumnListPlatChange() {
tmpc := &card.ColumnList{}
*tmpc = *c
tmpc.Plat = limit.Plat
tmpc.Build = limit.Build
tmpc.Condition = limit.Condition
tmpc.PlatVer = ""
res[tmpc.Plat] = append(res[tmpc.Plat], tmpc)
}
}
return
}
// ColumnList
func (d *Dao) ColumnList(ctx context.Context, now time.Time) (res []*card.ColumnList, err error) {
res = []*card.ColumnList{}
rows, err := d.columnList.Query(ctx, now)
if err != nil {
log.Error("query error(%v)", err)
return
}
for rows.Next() {
c := &card.ColumnList{}
if err = rows.Scan(&c.Ceid, &c.Cname, &c.Cid, &c.Name, &c.PlatVer); err != nil {
log.Error("rows.Scan error(%v)", err)
res = nil
return
}
res = append(res, c)
}
return
}
// Card channel card
func (d *Dao) Card(ctx context.Context, now time.Time) (res []*card.PopularCard, err error) {
rows, err := d.db.Query(ctx, _cardSQL, now, now)
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
c := &card.PopularCard{}
var valueStr string
if err = rows.Scan(&c.ID, &c.Title, &c.Type, &valueStr, &c.Reason, &c.ReasonType, &c.Pos); err != nil {
return
}
c.Value, _ = strconv.ParseInt(valueStr, 10, 64)
res = append(res, c)
}
return
}
// CardPlat channel card plat
func (d *Dao) CardPlat(ctx context.Context) (res map[int64]map[int8][]*card.PopularCardPlat, err error) {
res = map[int64]map[int8][]*card.PopularCardPlat{}
rows, err := d.db.Query(ctx, _cardPlatSQL)
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
c := &card.PopularCardPlat{}
if err = rows.Scan(&c.CardID, &c.Plat, &c.Condition, &c.Build); err != nil {
return
}
if r, ok := res[c.CardID]; !ok {
res[c.CardID] = map[int8][]*card.PopularCardPlat{
c.Plat: []*card.PopularCardPlat{c},
}
} else {
r[c.Plat] = append(r[c.Plat], c)
}
}
return
}
// CardSet card set
func (d *Dao) CardSet(ctx context.Context) (res map[int64]*operate.CardSet, err error) {
var rows *sql.Rows
if rows, err = d.db.Query(ctx, _cardSetSQL); err != nil {
return
}
defer rows.Close()
res = make(map[int64]*operate.CardSet)
for rows.Next() {
var (
c = &operate.CardSet{}
value string
)
if err = rows.Scan(&c.ID, &c.Type, &value, &c.Title, &c.LongTitle, &c.Content); err != nil {
return
}
c.Value, _ = strconv.ParseInt(value, 10, 64)
res[c.ID] = c
}
return
}
// EventTopic event_topic all
func (d *Dao) EventTopic(ctx context.Context) (res map[int64]*operate.EventTopic, err error) {
var rows *sql.Rows
if rows, err = d.db.Query(ctx, _eventTopicSQL); err != nil {
return
}
defer rows.Close()
res = make(map[int64]*operate.EventTopic)
for rows.Next() {
c := &operate.EventTopic{}
if err = rows.Scan(&c.ID, &c.Title, &c.Desc, &c.Cover, &c.ReType, &c.ReValue, &c.Corner); err != nil {
return
}
res[c.ID] = c
}
return
}

View File

@@ -0,0 +1,149 @@
package card
import (
"context"
"flag"
"os"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.app-svr.app-show")
flag.Set("conf_token", "Pae4IDOeht4cHXCdOkay7sKeQwHxKOLA")
flag.Set("tree_id", "2687")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestColumns(t *testing.T) {
Convey("Columns", t, func() {
_, err := d.Columns(ctx())
// res = map[int8][]*card.Column{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestPosRecs(t *testing.T) {
Convey("PosRecs", t, func() {
_, err := d.PosRecs(ctx(), time.Now())
// res = map[int8]map[int][]*card.Card{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRecContents(t *testing.T) {
Convey("RecContents", t, func() {
_, _, err := d.RecContents(ctx(), time.Now())
// res = map[int][]*card.Content{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestNperContents(t *testing.T) {
Convey("NperContents", t, func() {
_, _, err := d.NperContents(ctx(), time.Now())
// res = map[int][]*card.Content{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestColumnNpers(t *testing.T) {
Convey("ColumnNpers", t, func() {
_, err := d.ColumnNpers(ctx(), time.Now())
// res = map[int8][]*card.ColumnNper{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestColumnPlatList(t *testing.T) {
Convey("ColumnPlatList", t, func() {
_, err := d.ColumnPlatList(ctx(), time.Now())
// res = map[int8][]*card.ColumnList{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestColumnList(t *testing.T) {
Convey("ColumnList", t, func() {
_, err := d.ColumnList(ctx(), time.Now())
// res = []*card.ColumnList{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestCard(t *testing.T) {
Convey("Card", t, func() {
_, err := d.Card(ctx(), time.Now())
// res = []*card.PopularCard{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestCardPlat(t *testing.T) {
Convey("CardPlat", t, func() {
_, err := d.CardPlat(ctx())
// res = map[int64]map[int8][]*card.PopularCardPlat{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestCardSet(t *testing.T) {
Convey("CardSet", t, func() {
_, err := d.CardSet(ctx())
// res = map[int64]*operate.CardSet{}
err = nil
// So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestEventTopic(t *testing.T) {
Convey("CardSet", t, func() {
res, err := d.EventTopic(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

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 = ["databus_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["databus.go"],
importpath = "go-common/app/interface/main/app-show/dao/databus",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//library/log:go_default_library",
"//library/queue/databus: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,38 @@
package databus
import (
"context"
"strconv"
"go-common/app/interface/main/app-show/conf"
"go-common/library/log"
"go-common/library/queue/databus"
)
// Dao is show dao.
type Dao struct {
// databus
dataBus *databus.Databus
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// databus
dataBus: databus.New(c.DislikeDataBus),
}
return
}
func (d *Dao) Pub(ctx context.Context, buvid, gt string, id, mid int64) (err error) {
key := strconv.FormatInt(mid, 10)
msg := struct {
Buvid string `json:"buvid"`
Goto string `json:"goto"`
ID int64 `json:"id"`
Mid int64 `json:"mid"`
}{Buvid: buvid, Goto: gt, ID: id, Mid: mid}
if err = d.dataBus.Send(ctx, key, msg); err != nil {
log.Error("d.dataBus.Pub(%s,%v) error (%v)", key, msg, err)
}
return
}

View File

@@ -0,0 +1,36 @@
package databus
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestPub(t *testing.T) {
Convey("Pub", t, func() {
err := d.Pub(ctx(), "", "", 1, 1)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,48 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["dynamic_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["dynamic.go"],
importpath = "go-common/app/interface/main/app-show/dao/dynamic",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/dynamic/model:go_default_library",
"//app/service/main/dynamic/rpc/client: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,47 @@
package dynamic
import (
"context"
"go-common/app/interface/main/app-show/conf"
"go-common/app/service/main/archive/api"
dynarc "go-common/app/service/main/dynamic/model"
dynrpc "go-common/app/service/main/dynamic/rpc/client"
"go-common/library/log"
)
// Dao is rpc dao.
type Dao struct {
// dynamic rpc
dynRpc *dynrpc.Service
}
// New new a archive dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// dynamic rpc
dynRpc: dynrpc.New(c.DynamicRPC),
}
return
}
// regionDynamic
func (d *Dao) RegionDynamic(ctx context.Context, rid, pn, ps int) (res []*api.Arc, aids []int64, err error) {
arg := &dynarc.ArgRegion3{
RegionID: int32(rid),
Pn: pn,
Ps: ps,
}
var as *dynarc.DynamicArcs3
if as, err = d.dynRpc.RegionArcs3(ctx, arg); err != nil {
log.Error("d.dynRpc.RegionArcs(%v) error(%v)", arg, err)
return
}
if as != nil {
res = as.Archives
for _, a := range res {
aids = append(aids, a.Aid)
}
}
return
}

View File

@@ -0,0 +1,29 @@
package dynamic
import (
"context"
"flag"
"path/filepath"
"testing"
. "github.com/smartystreets/goconvey/convey"
"go-common/app/interface/main/app-show/conf"
)
var (
d *Dao
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
}
func Test_RegionDynamic(t *testing.T) {
Convey("should get RegionDynamic", t, func() {
_, _, err := d.RegionDynamic(context.Background(), 1, 2, 3)
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,51 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["live_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["live.go"],
importpath = "go-common/app/interface/main/app-show/dao/live",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-card/model/card/live:go_default_library",
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model/live:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//vendor/github.com/pkg/errors: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,142 @@
package live
import (
"context"
"encoding/json"
"fmt"
"net/url"
"strconv"
"time"
clive "go-common/app/interface/main/app-card/model/card/live"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model/live"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
"github.com/pkg/errors"
)
const (
_live = "/appIndex/recommendFeedList"
_rec = "/appIndex/recommendList"
_topic = "/topic/v0/Topic/hots"
_dynamichot = "/dynamic_detail/v0/Dynamic/hot"
)
// Dao is live dao
type Dao struct {
client *httpx.Client
clientAsyn *httpx.Client
live string
rec string
topic string
dynamichot string
}
// New live dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(c.HTTPClient),
clientAsyn: httpx.NewClient(c.HTTPClientAsyn),
live: c.Host.ApiLiveCo + _live,
rec: c.Host.ApiLiveCo + _rec,
topic: c.Host.Dynamic + _topic,
dynamichot: c.Host.Dynamic + _dynamichot,
}
return
}
// Live feed
func (d *Dao) Feed(c context.Context, mid int64, ak, ip string, now time.Time) (r *live.Feed, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("access_key", ak)
var res struct {
Code int `json:"code"`
Data *live.Feed `json:"data"`
}
if err = d.client.Get(c, d.live, ip, params, &res); err != nil {
log.Error("Feed url(%s) error(%v)", d.live+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("Feed url(%s) error(%v)", d.live+"?"+params.Encode(), res.Code)
err = fmt.Errorf("feed send failed")
return
}
r = res.Data
return
}
// Recommend get live Recommend data.
func (d *Dao) Recommend(now time.Time) (r *live.Recommend, err error) {
params := url.Values{}
params.Set("count", "60")
var res struct {
Code int `json:"code"`
Data *live.Recommend `json:"data"`
}
if err = d.clientAsyn.Get(context.TODO(), d.rec, "", params, &res); err != nil { // TODO context arg, service context.TODO
log.Error("live recommend url(%s) error(%v)", d.rec+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("live recommend url(%s) error(%v)", d.rec+"?"+params.Encode(), res.Code)
err = fmt.Errorf("recommend send failed")
return
}
r = res.Data
return
}
// TopicHots get live topic hots
func (d *Dao) TopicHots(c context.Context) (topics []*clive.TopicHot, err error) {
var res struct {
Code int `json:"code"`
Data struct {
List []*clive.TopicHot `json:"list"`
} `json:"data"`
}
if err = d.clientAsyn.Get(c, d.topic, "", nil, &res); err != nil {
return
}
b, _ := json.Marshal(&res)
log.Info("topichots list url(%v) response(%s)", d.topic, b)
if res.Code != ecode.OK.Code() {
err = errors.Wrap(err, d.topic)
return
}
for _, t := range res.Data.List {
tmp := &clive.TopicHot{}
*tmp = *t
if err = tmp.TopicJSONChange(); err != nil {
log.Error("TopicJSONChange error(%v)", err)
return
}
topics = append(topics, tmp)
}
return
}
// DynamicHot get dynamic hot all
func (d *Dao) DynamicHot(c context.Context) (list []*clive.DynamicHot, err error) {
var res struct {
Code int `json:"code"`
Data struct {
List []*clive.DynamicHot `json:"list"`
} `json:"data"`
}
if err = d.clientAsyn.Get(c, d.dynamichot, "", nil, &res); err != nil {
return
}
b, _ := json.Marshal(&res)
log.Info("dynamichot list url(%v) response(%s)", d.dynamichot, b)
if res.Code != ecode.OK.Code() {
err = errors.Wrap(err, d.topic)
return
}
list = res.Data.List
return
}

View File

@@ -0,0 +1,175 @@
package live
import (
"context"
"flag"
"os"
"strings"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
gock "gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.app-svr.app-show")
flag.Set("conf_token", "Pae4IDOeht4cHXCdOkay7sKeQwHxKOLA")
flag.Set("tree_id", "2687")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
time.Sleep(time.Second)
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}
func TestFeed(t *testing.T) {
Convey("Feed", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", d.live).Reply(200).JSON(`{"code":0,"count":1,"lives":[{"owner":{"face":"xxx","mid":1,"name":"xxxx"}}]}`)
res, err := d.Feed(ctx(), 1, "", "", time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRecommend(t *testing.T) {
Convey("Recommend", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
httpMock("GET", d.rec).Reply(200).JSON(`{
"code": 0,
"data": {
"count": 1,
"lives": {
"subject": [{
"owner": {
"face": "xxx",
"mid": 1,
"name": "xxxx"
}
}],
"hot": [{
"owner": {
"face": "xxx",
"mid": 1,
"name": "xxxx"
}
}]
}
}
}`)
res, err := d.Recommend(time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestTopicHots(t *testing.T) {
Convey("TopicHots", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
httpMock("GET", d.topic).Reply(200).JSON(`{
"code": 0,
"data": {
"list": [{
"topic_id": 7279615,
"topic_name": "CP23",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/b46cda4c7e953764c0fcda49c0f06639e7092792.jpg\",\"image_width\":800,\"image_height\":500}"
}, {
"topic_id": 9029281,
"topic_name": "2018COS总结",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/6e703453de103b5b5b9e00640ff9e9d9156950e6.jpg\",\"image_width\":800,\"image_height\":500}"
}, {
"topic_id": 2838293,
"topic_name": "陪你过冬天",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/716e12155e1f2150418c9f215de6bb3c9b38f516.png\",\"image_width\":800,\"image_height\":500}"
}, {
"topic_id": 2525230,
"topic_name": "故事王StoryMan",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/5adb6388723c321d99c5b04fe9839cdaacf6da0d.jpg\",\"image_width\":800,\"image_height\":500}"
}, {
"topic_id": 8977836,
"topic_name": "萌宠暖宝宝",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/adba2d41863e5bf1d269cdf2d4803fac099f8288.jpg\",\"image_width\":800,\"image_height\":500}"
}, {
"topic_id": 105286,
"topic_name": "国家宝藏",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/9650de6e22d0742b63db0feac5bd891faf050b54.png\",\"image_width\":800,\"image_height\":500}"
}, {
"topic_id": 8948501,
"topic_name": "2018绘画总结",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/94c6edd82202ffdfa62c91d0d9d62dcb5b40a0b8.png\",\"image_width\":800,\"image_height\":500}"
}, {
"topic_id": 8977910,
"topic_name": "冬天喝奶茶",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/c0f2533e71732eb700a6ec5a37b633fd5ae707f3.png\",\"image_width\":800,\"image_height\":500}"
}, {
"topic_id": 2872407,
"topic_name": "冬日必备",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/54e1efc022377e209ef98a680f1fb7777e242ca4.png\",\"image_width\":800,\"image_height\":500}"
}, {
"topic_id": 2953953,
"topic_name": "冬日穿搭",
"picture": "{\"image_src\":\"https:\\/\\/i0.hdslb.com\\/bfs\\/album\\/6522e801f6882c171622a47eb3087d50af42fe7b.jpg\",\"image_width\":800,\"image_height\":500}"
}]
}
}`)
res, err := d.TopicHots(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestDynamicHot(t *testing.T) {
Convey("DynamicHot", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
httpMock("GET", d.dynamichot).Reply(200).JSON(`{
"code": 0,
"data": {
"list": [{
"dynamic_id": 198340924012294846,
"audit_status": 0,
"delete_status": 0,
"mid": 440290,
"nick_name": "音乐鱼",
"face_img": "http://i2.hdslb.com/bfs/face/d5e81352871fbe33e7c1aed68ad237c1e0588db3.jpg",
"rid_type": 2,
"rid": 10362627,
"view_count": 5641,
"comment_count": 10,
"rcmd_reason": "",
"dynamic_text": "#CP23##COSPLAY#这两天腿和腰都要断了,光顾着逛没怎么拍 ,但还是满足了😂昨晚上还吃了老上海味道,现在急需一顿火锅!",
"img_count": 9,
"imgs": ["https://i0.hdslb.com/bfs/album/615e9efe438a78f25b4ee399fec1e168eaac8c6e.jpg", "https://i0.hdslb.com/bfs/album/1a31a0e93c383183b7b7b02e777248689cac1368.jpg", "https://i0.hdslb.com/bfs/album/270f4b3f84337fa8d2755cff46f7aef6d6f633de.jpg", "https://i0.hdslb.com/bfs/album/25e2fc36946d3f40e242c7619898e2ad5564fd1c.jpg", "https://i0.hdslb.com/bfs/album/2897ee217c455502cde345666ea66086d9f16fc3.jpg", "https://i0.hdslb.com/bfs/album/7c5948d362e17a5118c9cdf095d04c193e50de37.jpg", "https://i0.hdslb.com/bfs/album/473d201e4756fca5b38bc0b535a1086db44d2173.jpg", "https://i0.hdslb.com/bfs/album/91fc858bba009c338d4e1a13ba1953378bd19b15.jpg", "https://i0.hdslb.com/bfs/album/d34307d2e9006847b7e974351ed89c0fe3ad282a.jpg"]
}]
}
}`)
res, err := d.DynamicHot(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

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 = ["dao_test.go"],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["dao.go"],
importpath = "go-common/app/interface/main/app-show/dao/location",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/service/main/location/model:go_default_library",
"//app/service/main/location/rpc/client: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,47 @@
package location
import (
"context"
"strconv"
"go-common/app/interface/main/app-show/conf"
locmdl "go-common/app/service/main/location/model"
locrpc "go-common/app/service/main/location/rpc/client"
"go-common/library/log"
)
// Dao is location dao.
type Dao struct {
// rpc
locRPC *locrpc.Service
}
// New new a location dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// rpc
locRPC: locrpc.New(c.LocationRPC),
}
return
}
func (d *Dao) Info(c context.Context, ipaddr string) (info *locmdl.Info, err error) {
if info, err = d.locRPC.Info(c, &locmdl.ArgIP{IP: ipaddr}); err != nil {
log.Error("%v", err)
}
return
}
func (d *Dao) AuthPIDs(c context.Context, pids, ipaddr string) (res map[string]*locmdl.Auth, err error) {
var auths map[int64]*locmdl.Auth
if auths, err = d.locRPC.AuthPIDs(c, &locmdl.ArgPids{Pids: pids, IP: ipaddr}); err != nil {
log.Error("%v", err)
return
}
res = make(map[string]*locmdl.Auth)
for pid, auth := range auths {
p := strconv.FormatInt(pid, 10)
res[p] = auth
}
return
}

View File

@@ -0,0 +1,44 @@
package location
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestInfo(t *testing.T) {
Convey("get Info", t, func() {
res, err := d.Info(ctx(), "127.0.0.1")
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestAuthPIDs(t *testing.T) {
Convey("get AuthPIDs", t, func() {
_, err := d.AuthPIDs(ctx(), "417,1521", "127.0.0.0")
So(err, ShouldBeNil)
})
}

View File

@@ -0,0 +1,51 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["recommend_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["recommend.go"],
importpath = "go-common/app/interface/main/app-show/dao/recommend",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model/recommend:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/pkg/errors: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,573 @@
package recommend
import (
"context"
"encoding/json"
"fmt"
"net/url"
"strconv"
"time"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model/recommend"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
xtime "go-common/library/time"
"github.com/pkg/errors"
)
const (
// _hotUrl = "/y3kflg2k/ranking-m.json"
_hotUrl = "/data/rank/reco-tmzb.json"
_regionUrl = "/8669rank/mobile_random/%s/1.json" // %s must be replaced to concrete tid
// _regionHotUrl = "/y3kflg2k/catalogy/%d-recommend-m.json"
_regionListUrl = "/list"
// _regionChildHotUrl = "/y3kflg2k/catalogy/catalogy-%d-3-m.json"
_regionChildHotUrl = "/data/rank/recent_region-%d-3.json"
_regionArcListUrl = "/x/v2/archive/rank"
_rankRegionUrl = "/y3kflg2k/rank/%s-03-%d.json"
_rankOriginalUrl = "/y3kflg2k/rank/%s-03.json"
_rankBangumiUrl = "/y3kflg2k/rank/all-3-33.json"
_feedDynamicUrl = "/feed/tag/top"
_rankAllAppUrl = "/data/rank/recent_all-app.json"
_rankOriginAppUrl = "/data/rank/recent_origin-app.json"
_rankRegionAppUrl = "/data/rank/recent_region-%d-app.json"
_rankBangumiAppUrl = "/data/rank/all_region-33-app.json"
_hottabURL = "/data/rank/reco-app-remen.json"
_hotHeTongtabURL = "/data/rank/reco-app-remen-%d.json"
_hotHeTongtabcardURL = "/data/rank/reco-app-remen-card-%d.json"
)
// Dao is recommend dao.
type Dao struct {
client *httpx.Client
clientAsyn *httpx.Client
clientParam *httpx.Client
hotUrl string
regionUrl string
regionChildHotUrl string
regionListUrl string
regionArcListUrl string
rankRegionUrl string
rankOriginalUrl string
rankBangumilUrl string
feedDynamicUrl string
rankAllAppUrl string
rankOriginAppUrl string
rankRegionAppUrl string
rankBangumiAppUrl string
hottabURL string
hotHetongURL string
hotHeTongtabcardURL string
}
//New recommend dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(conf.Conf.HTTPClient),
clientAsyn: httpx.NewClient(c.HTTPClientAsyn),
clientParam: httpx.NewClient(conf.Conf.HTTPClient),
// hotUrl: c.Host.Hetongzi + _hotUrl,
hotUrl: c.Host.HetongziRank + _hotUrl,
regionUrl: c.Host.Hetongzi + _regionUrl,
// regionHotUrl: c.Host.Hetongzi + _regionHotUrl,
// regionChildHotUrl: c.Host.Hetongzi + _regionChildHotUrl,
regionChildHotUrl: c.Host.HetongziRank + _regionChildHotUrl,
regionListUrl: c.Host.ApiCo + _regionListUrl,
regionArcListUrl: c.Host.ApiCoX + _regionArcListUrl,
rankRegionUrl: c.Host.Hetongzi + _rankRegionUrl,
rankOriginalUrl: c.Host.Hetongzi + _rankOriginalUrl,
rankBangumilUrl: c.Host.Hetongzi + _rankBangumiUrl,
feedDynamicUrl: c.Host.Data + _feedDynamicUrl,
rankAllAppUrl: c.Host.HetongziRank + _rankAllAppUrl,
rankOriginAppUrl: c.Host.HetongziRank + _rankOriginAppUrl,
rankRegionAppUrl: c.Host.HetongziRank + _rankRegionAppUrl,
rankBangumiAppUrl: c.Host.HetongziRank + _rankBangumiAppUrl,
hottabURL: c.Host.Data + _hottabURL,
hotHetongURL: c.Host.Data + _hotHeTongtabURL,
hotHeTongtabcardURL: c.Host.Data + _hotHeTongtabcardURL,
}
return
}
// Hots get recommends.
func (d *Dao) Hots(c context.Context) (arcids []int64, err error) {
var res struct {
Code int `json:"code"`
List []struct {
Aid int64 `json:"aid"`
} `json:"list"`
}
if err = d.clientAsyn.Get(c, d.hotUrl, "", nil, &res); err != nil {
log.Error("recommend hots url(%s) error(%v)", d.hotUrl, err)
return
}
b, _ := json.Marshal(&res)
log.Info("recommend hots url(%s) json(%s)", d.hotUrl, b)
if res.Code != 0 {
log.Error("recommend hots url(%s) error(%v)", d.hotUrl, res.Code)
err = fmt.Errorf("recommend api response code(%v)", res)
return
}
for _, arcs := range res.List {
arcids = append(arcids, arcs.Aid)
}
return
}
// Region get region recommend.
func (d *Dao) Region(c context.Context, tid string) (arcids []int64, err error) {
var res struct {
Code int `json:"code"`
Data []struct {
Aid string `json:"aid"`
} `json:"list"`
}
api := fmt.Sprintf(d.regionUrl, tid)
if err = d.clientAsyn.Get(c, api, "", nil, &res); err != nil {
log.Error("recommend region url(%s) error(%v)", api, err)
return
}
if res.Code != 0 {
log.Error("recommend region url(%s) error(%v)", api, res.Code)
err = fmt.Errorf("recommend region api response code(%v)", res)
return
}
for _, arcs := range res.Data {
arcids = append(arcids, aidToInt(arcs.Aid))
}
return
}
// RegionHots get hots recommend
func (d *Dao) RegionHots(c context.Context, tid int) (arcids []int64, err error) {
var res struct {
Code int `json:"code"`
List []struct {
Aid int64 `json:"aid"`
} `json:"list"`
}
api := fmt.Sprintf(d.rankRegionAppUrl, tid)
if err = d.clientAsyn.Get(c, api, "", nil, &res); err != nil {
log.Error("recommend region hots url(%s) error(%v)", api, err)
return
}
if res.Code != 0 {
log.Error("recommend region hots url(%s) error(%v)", api, res.Code)
err = fmt.Errorf("recommend region hots api response code(%v)", res)
return
}
for _, arcs := range res.List {
arcids = append(arcids, arcs.Aid)
}
return
}
// RegionList
func (d *Dao) RegionList(c context.Context, rid, tid, audit, pn, ps int, order string) (arcids []int64, err error) {
params := url.Values{}
params.Set("order", order)
params.Set("filtered", strconv.Itoa(audit))
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("tid", strconv.Itoa(rid))
if tid > 0 {
params.Set("tag_id", strconv.Itoa(tid))
}
params.Set("apiver", "2")
params.Set("ver", "2")
var res struct {
Code int `json:"code"`
List []struct {
Aid interface{} `json:"aid"`
} `json:"list"`
}
if err = d.client.Get(c, d.regionListUrl, "", params, &res); err != nil {
log.Error("recommend region news url(%s) error(%v)", d.regionListUrl+"?"+params.Encode(), err)
return
}
if res.Code != 0 && res.Code != -1 {
log.Error("recommend region news url(%s) error(%v)", d.regionListUrl+"?"+params.Encode(), res.Code)
err = fmt.Errorf("recommend region news api response code(%v)", res)
return
}
for _, arcs := range res.List {
var aidInt int64
switch aid := arcs.Aid.(type) {
case string:
aidInt = aidToInt(aid)
case float64:
aidInt = int64(aid)
}
arcids = append(arcids, aidInt)
}
return
}
// TwoRegionHots
func (d *Dao) RegionChildHots(c context.Context, rid int) (arcids []int64, err error) {
var res struct {
Code int `json:"code"`
List []struct {
Aid int64 `json:"aid"`
} `json:"list"`
}
api := fmt.Sprintf(d.regionChildHotUrl, rid)
if err = d.clientAsyn.Get(c, api, "", nil, &res); err != nil {
log.Error("recommend region child hots url(%s) error(%v)", api, err)
return
}
if res.Code != 0 {
log.Error("recommend region child hots url(%s) error(%v)", api, res.Code)
err = fmt.Errorf("recommend region child hots api response code(%v)", res)
return
}
for _, arcs := range res.List {
arcids = append(arcids, arcs.Aid)
}
return
}
func (d *Dao) RegionArcList(c context.Context, rid, pn, ps int, now time.Time) (arcids []int64, err error) {
params := url.Values{}
params.Set("rid", strconv.Itoa(rid))
params.Set("pn", strconv.Itoa(pn))
params.Set("ps", strconv.Itoa(ps))
var res struct {
Code int `json:"code"`
Data struct {
List []struct {
Aid int64 `json:"aid"`
} `json:"archives"`
} `json:"data"`
}
if err = d.client.Get(c, d.regionArcListUrl, "", params, &res); err != nil {
log.Error("recommend regionArc news url(%s) error(%v)", d.regionArcListUrl+"?"+params.Encode(), err)
return
}
if res.Code != 0 && res.Code != -1 {
log.Error("recommend regionArc news url(%s) error(%v)", d.regionArcListUrl+"?"+params.Encode(), res.Code)
err = fmt.Errorf("recommend regionArc news api response code(%v)", res)
return
}
for _, arcs := range res.Data.List {
arcids = append(arcids, arcs.Aid)
}
return
}
// RegionRank
func (d *Dao) RankRegion(c context.Context, rid int, order string) (data []*recommend.Arc, err error) {
var res struct {
Data struct {
Code int `json:"code"`
List []*recommend.Arc `json:"list"`
} `json:"rank"`
}
api := fmt.Sprintf(d.rankRegionUrl, order, rid)
if err = d.clientAsyn.Get(c, api, "", nil, &res); err != nil {
log.Error("recommend region rank hots url(%s) error(%v)", api, err)
return
}
if res.Data.Code != 0 {
log.Error("recommend region rank hots url(%s) error(%v)", api, res.Data.Code)
err = fmt.Errorf("recommend region rank hots api response code(%v)", res)
return
}
data = res.Data.List
return
}
// RankAll
func (d *Dao) RankAll(c context.Context, order string) (data []*recommend.Arc, err error) {
var res struct {
Data struct {
Code int `json:"code"`
List []*recommend.Arc `json:"list"`
} `json:"rank"`
}
api := fmt.Sprintf(d.rankOriginalUrl, order)
if err = d.clientAsyn.Get(c, api, "", nil, &res); err != nil {
log.Error("recommend region rank hots url(%s) error(%v)", api, err)
return
}
if res.Data.Code != 0 {
log.Error("recommend region rank hots url(%s) error(%v)", api, res.Data.Code)
err = fmt.Errorf("recommend region rank hots api response code(%v)", res)
return
}
data = res.Data.List
return
}
// RankAll
func (d *Dao) RankBangumi(c context.Context) (data []*recommend.Arc, err error) {
var res struct {
Data struct {
Code int `json:"code"`
List []*recommend.Arc `json:"list"`
} `json:"rank"`
}
if err = d.clientAsyn.Get(c, d.rankBangumilUrl, "", nil, &res); err != nil {
log.Error("recommend region rank hots url(%s) error(%v)", d.rankBangumilUrl, err)
return
}
if res.Data.Code != 0 {
log.Error("recommend region rank hots url(%s) error(%v)", d.rankBangumilUrl, res.Data.Code)
err = fmt.Errorf("recommend region rank hots api response code(%v)", res)
return
}
data = res.Data.List
return
}
// FeedDynamic
func (d *Dao) FeedDynamic(c context.Context, pull bool, rid, tid int, ctime, mid int64, now time.Time) (hotAids, newAids []int64, ctop, cbottom xtime.Time, err error) {
var pn string
if pull {
pn = "1"
} else {
pn = "2"
}
params := url.Values{}
params.Set("src", "2")
params.Set("pn", pn)
params.Set("mid", strconv.FormatInt(mid, 10))
if ctime != 0 {
params.Set("ctime", strconv.FormatInt(ctime, 10))
}
if rid != 0 {
params.Set("rid", strconv.Itoa(rid))
}
if tid != 0 {
params.Set("tag", strconv.Itoa(tid))
}
var res struct {
Code int `json:"code"`
Data []int64 `json:"data"`
Hot []int64 `json:"hot"`
CTop xtime.Time `json:"ctop"`
CBottom xtime.Time `json:"cbottom"`
}
if err = d.client.Get(c, d.feedDynamicUrl, "", params, &res); err != nil {
log.Error("region feed dynamic d.client.Get(%s) error(%v)", d.feedDynamicUrl+"?"+params.Encode(), err)
return
}
b, _ := json.Marshal(&res)
log.Info("region feed dynamic url(%s) response(%s)", d.feedDynamicUrl+"?"+params.Encode(), b)
if res.Code != 0 {
log.Error("region feed dynamic d.client.Get(%s) error(%v)", d.regionArcListUrl+"?"+params.Encode(), res.Code)
err = fmt.Errorf("region feed dynamicapi response code(%v)", res)
return
}
hotAids = res.Hot
newAids = res.Data
ctop = res.CTop
cbottom = res.CBottom
return
}
func (d *Dao) RankAppRegion(c context.Context, rid int) (aids []int64, others, scores map[int64]int64, err error) {
var res struct {
Code int `json:"code"`
List []struct {
Aid int64 `json:"aid"`
Score int64 `json:"score"`
Others []struct {
Aid int64 `json:"aid"`
Score int64 `json:"score"`
} `json:"others"`
} `json:"list"`
}
api := fmt.Sprintf(d.rankRegionAppUrl, rid)
if err = d.client.Get(c, api, "", nil, &res); err != nil {
log.Error("recommend region rank hots url(%s) error(%v)", api, err)
return
}
if res.Code != 0 && res.Code != -1 {
log.Error("recommend region rank hots url(%s) error(%v)", api, res.Code)
err = fmt.Errorf("recommend region rank hots api response code(%v)", res)
return
}
scores = map[int64]int64{}
others = map[int64]int64{}
for _, arcs := range res.List {
aids = append(aids, arcs.Aid)
scores[arcs.Aid] = arcs.Score
for _, o := range arcs.Others {
aids = append(aids, o.Aid)
scores[o.Aid] = o.Score
others[o.Aid] = arcs.Aid
}
}
return
}
func (d *Dao) RankAppOrigin(c context.Context) (aids []int64, others, scores map[int64]int64, err error) {
var res struct {
Code int `json:"code"`
List []struct {
Aid int64 `json:"aid"`
Score int64 `json:"score"`
Others []struct {
Aid int64 `json:"aid"`
Score int64 `json:"score"`
} `json:"others"`
} `json:"list"`
}
if err = d.client.Get(c, d.rankOriginAppUrl, "", nil, &res); err != nil {
log.Error("recommend Origin rank hots url(%s) error(%v)", d.rankOriginAppUrl, err)
return
}
if res.Code != 0 && res.Code != -1 {
log.Error("recommend Origin rank hots url(%s) error(%v)", d.rankOriginAppUrl, res.Code)
err = fmt.Errorf("recommend Origin rank hots api response code(%v)", res)
return
}
scores = map[int64]int64{}
others = map[int64]int64{}
for _, arcs := range res.List {
aids = append(aids, arcs.Aid)
scores[arcs.Aid] = arcs.Score
for _, o := range arcs.Others {
aids = append(aids, o.Aid)
scores[o.Aid] = o.Score
others[o.Aid] = arcs.Aid
}
}
return
}
func (d *Dao) RankAppAll(c context.Context) (aids []int64, others, scores map[int64]int64, err error) {
var res struct {
Code int `json:"code"`
List []struct {
Aid int64 `json:"aid"`
Score int64 `json:"score"`
Others []struct {
Aid int64 `json:"aid"`
Score int64 `json:"score"`
} `json:"others"`
} `json:"list"`
}
if err = d.client.Get(c, d.rankAllAppUrl, "", nil, &res); err != nil {
log.Error("recommend All rank hots url(%s) error(%v)", d.rankAllAppUrl, err)
return
}
if res.Code != 0 && res.Code != -1 {
log.Error("recommend All rank hots url(%s) error(%v)", d.rankAllAppUrl, res.Code)
err = fmt.Errorf("recommend All rank hots api response code(%v)", res)
return
}
scores = map[int64]int64{}
others = map[int64]int64{}
for _, arcs := range res.List {
aids = append(aids, arcs.Aid)
scores[arcs.Aid] = arcs.Score
for _, o := range arcs.Others {
aids = append(aids, o.Aid)
scores[o.Aid] = o.Score
others[o.Aid] = arcs.Aid
}
}
return
}
func (d *Dao) RankAppBangumi(c context.Context) (aids []int64, others, scores map[int64]int64, err error) {
var res struct {
Code int `json:"code"`
List []struct {
Aid int64 `json:"aid"`
Score int64 `json:"score"`
Others []struct {
Aid int64 `json:"aid"`
Score int64 `json:"score"`
} `json:"others"`
} `json:"list"`
}
if err = d.client.Get(c, d.rankBangumiAppUrl, "", nil, &res); err != nil {
log.Error("recommend bangumi rank hots url(%s) error(%v)", d.rankBangumiAppUrl, err)
return
}
if res.Code != 0 && res.Code != -1 {
log.Error("recommend bangumi rank hots url(%s) error(%v)", d.rankBangumiAppUrl, res.Code)
err = fmt.Errorf("recommend bangumi rank hots api response code(%v)", res)
return
}
scores = map[int64]int64{}
others = map[int64]int64{}
for _, arcs := range res.List {
aids = append(aids, arcs.Aid)
scores[arcs.Aid] = arcs.Score
for _, o := range arcs.Others {
aids = append(aids, o.Aid)
scores[o.Aid] = o.Score
others[o.Aid] = arcs.Aid
}
}
return
}
func aidToInt(aidstr string) (aid int64) {
aid, _ = strconv.ParseInt(aidstr, 10, 64)
return
}
// HotTab hot tab
func (d *Dao) HotTab(c context.Context) (list []*recommend.List, err error) {
var res struct {
Code int `json:"code"`
List []*recommend.List `json:"list"`
}
if err = d.client.Get(c, d.hottabURL, "", nil, &res); err != nil {
log.Error("hottab hots url(%s) error(%v)", d.hottabURL, err)
return
}
b, _ := json.Marshal(&res)
log.Info("hottab list url(%s) response(%s)", d.hottabURL, b)
if res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("hottab hots url(%s) code(%d)", d.hottabURL, res.Code)
return
}
list = res.List
return
}
// HotTenTab hot tab
func (d *Dao) HotTenTab(c context.Context, i int) (list []*recommend.List, err error) {
var res struct {
Code int `json:"code"`
List []*recommend.List `json:"list"`
}
if err = d.client.Get(c, fmt.Sprintf(d.hotHetongURL, i), "", nil, &res); err != nil {
err = errors.Wrap(err, fmt.Sprintf(d.hotHetongURL, i))
return
}
if res.Code != 0 {
err = errors.Wrap(err, fmt.Sprintf("code(%d)", res.Code))
return
}
list = res.List
return
}
// HotHeTongTabCard hot tab card
func (d *Dao) HotHeTongTabCard(c context.Context, i int) (list []*recommend.CardList, err error) {
var res struct {
Code int `json:"code"`
List []*recommend.CardList `json:"list"`
}
if err = d.client.Get(c, fmt.Sprintf(d.hotHeTongtabcardURL, i), "", nil, &res); err != nil {
err = errors.Wrap(err, fmt.Sprintf(d.hotHeTongtabcardURL, i))
return
}
if res.Code != 0 {
err = errors.Wrap(err, fmt.Sprintf("code(%d)", res.Code))
return
}
list = res.List
return
}

View File

@@ -0,0 +1,462 @@
package recommend
import (
"context"
"flag"
"fmt"
"os"
"strings"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
gock "gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.app-svr.app-show")
flag.Set("conf_token", "Pae4IDOeht4cHXCdOkay7sKeQwHxKOLA")
flag.Set("tree_id", "2687")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
time.Sleep(time.Second)
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}
func TestHots(t *testing.T) {
Convey("Hots", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
httpMock("GET", d.hotUrl).Reply(200).JSON(`{
"note": false,
"source_date": "2019-01-07",
"code": 0,
"num": 500,
"list": [{
"aid": 39185037,
"score": 176
}, {
"aid": 39658458,
"score": 174
}, {
"aid": 39532823,
"score": 168
}, {
"aid": 39477161,
"score": 168
}, {
"aid": 39852951,
"score": 168
}, {
"aid": 39672060,
"score": 168
}, {
"aid": 39832577,
"score": 168
}, {
"aid": 39987017,
"score": 168
}, {
"aid": 39700424,
"score": 163
}]
}`)
res, err := d.Hots(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRegion(t *testing.T) {
Convey("Region", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
api := fmt.Sprintf(d.regionUrl, "33")
httpMock("GET", api).Reply(200).JSON(`{
"code": 0,
"list": [{
"aid": "39911001",
"score": 523
}, {
"aid": "39852951",
"score": 6732
}, {
"aid": "39845334",
"score": 31
}]
}`)
res, err := d.Region(ctx(), "33")
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRegionHots(t *testing.T) {
Convey("RegionHots", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
api := fmt.Sprintf(d.rankRegionAppUrl, 1)
httpMock("GET", api).Reply(200).JSON(`{
"note": "统计3日内新投稿的数据综合得分每二十分钟更新一次。",
"source_date": "2019-01-07",
"code": 0,
"num": 100,
"list": [{
"aid": 39894949,
"mid": 808171,
"score": 546760
}, {
"aid": 39877679,
"mid": 7487399,
"score": 516724
}]
}`)
res, err := d.RegionHots(ctx(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRegionList(t *testing.T) {
Convey("RegionList", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", d.regionListUrl).Reply(200).JSON(`{
"code": 0,
"list": [{
"aid": 39903065
}]
}`)
res, err := d.RegionList(ctx(), 1, 1, 1, 1, 1, "")
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRegionChildHots(t *testing.T) {
Convey("RegionChildHots", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
api := fmt.Sprintf(d.regionChildHotUrl, 1)
httpMock("GET", api).Reply(200).JSON(`{
"code": 0,
"list": [{
"aid": 39903065
}]
}`)
res, err := d.RegionChildHots(ctx(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRegionArcList(t *testing.T) {
Convey("RegionArcList", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", d.regionArcListUrl).Reply(200).JSON(`{
"code": 0,
"data": {
"archives": [{
"aid": 39903065
}]
}
}`)
res, err := d.RegionArcList(ctx(), 1, 1, 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRankRegion(t *testing.T) {
Convey("RankRegion", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
httpMock("GET", fmt.Sprintf(d.rankRegionUrl, "all", 1)).Reply(200).JSON(`{
"rank": {
"code": 0,
"list": [{
"aid": 39903065
}]
}
}`)
res, err := d.RankRegion(ctx(), 1, "all")
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRankAll(t *testing.T) {
Convey("RankAll", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
httpMock("GET", fmt.Sprintf(d.rankOriginalUrl, "all")).Reply(200).JSON(`{
"rank": {
"code": 0,
"list": [{
"aid": 39903065
}]
}
}`)
res, err := d.RankAll(ctx(), "all")
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRankBangumi(t *testing.T) {
Convey("RankBangumi", t, func() {
d.clientAsyn.SetTransport(gock.DefaultTransport)
httpMock("GET", d.rankBangumilUrl).Reply(200).JSON(`{
"rank": {
"code": 0,
"list": [{
"aid": 39903065
}]
}
}`)
res, err := d.RankBangumi(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestFeedDynamic(t *testing.T) {
Convey("FeedDynamic", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", d.feedDynamicUrl).Reply(200).JSON(`{
"code": 0,
"data": [12587337, 1840325, 38132621, 5910308, 26879875, 26308630, 7348036, 1766719, 6374879, 24937721],
"hot": null,
"ctop": 12587337,
"cbottom": 24937721
}`)
_, newAids, _, _, err := d.FeedDynamic(ctx(), false, 1, 1, 1, 1, time.Now())
So(newAids, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRankAppRegion(t *testing.T) {
Convey("RankAppRegion", t, func() {
d.client.SetTransport(gock.DefaultTransport)
api := fmt.Sprintf(d.rankRegionAppUrl, 1)
httpMock("GET", api).Reply(200).JSON(`{
"note": "统计3日内新投稿的数据综合得分每二十分钟更新一次。",
"source_date": "2019-01-07",
"code": 0,
"num": 100,
"list": [{
"aid": 39954334,
"mid": 38125899,
"score": 509800,
"others": [{
"aid": 39903065,
"score": 48222
}]
}, {
"aid": 39953503,
"mid": 3969839,
"score": 430381
}]
}`)
res, _, _, err := d.RankAppRegion(ctx(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRankAppOrigin(t *testing.T) {
Convey("RankAppOrigin", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", d.rankOriginAppUrl).Reply(200).JSON(`{
"note": "统计3日内新投稿的数据综合得分每二十分钟更新一次。",
"source_date": "2019-01-07",
"code": 0,
"num": 100,
"list": [{
"aid": 39954334,
"mid": 38125899,
"score": 509800,
"others": [{
"aid": 39903065,
"score": 48222
}]
}, {
"aid": 39953503,
"mid": 3969839,
"score": 430381
}]
}`)
res, _, _, err := d.RankAppOrigin(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRankAppAll(t *testing.T) {
Convey("RankAppAll", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", d.rankAllAppUrl).Reply(200).JSON(`{
"note": "统计3日内新投稿的数据综合得分每二十分钟更新一次。",
"source_date": "2019-01-07",
"code": 0,
"num": 100,
"list": [{
"aid": 39954334,
"mid": 38125899,
"score": 509800,
"others": [{
"aid": 39903065,
"score": 48222
}]
}, {
"aid": 39953503,
"mid": 3969839,
"score": 430381
}]
}`)
res, _, _, err := d.RankAppAll(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRankAppBangumi(t *testing.T) {
Convey("RankAppBangumi", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", d.rankBangumiAppUrl).Reply(200).JSON(`{
"note": "统计3日内新投稿的数据综合得分每二十分钟更新一次。",
"source_date": "2019-01-07",
"code": 0,
"num": 100,
"list": [{
"aid": 39954334,
"mid": 38125899,
"score": 509800,
"others": [{
"aid": 39903065,
"score": 48222
}]
}, {
"aid": 39953503,
"mid": 3969839,
"score": 430381
}]
}`)
res, _, _, err := d.RankAppBangumi(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestHotTab(t *testing.T) {
Convey("HotTab", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", d.hottabURL).Reply(200).JSON(`{
"note": false,
"source_date": "2019-01-07",
"code": 0,
"num": 100,
"list": [{
"aid": 40063426,
"mid": 837470,
"score": 764906,
"desc": "很多人分享",
"corner_mark": 0
}, {
"aid": 39425207,
"mid": 4870926,
"score": 690583,
"desc": "百万播放",
"corner_mark": 0
}]
}`)
res, err := d.HotTab(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestHotTenTab(t *testing.T) {
Convey("HotTenTab", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", fmt.Sprintf(d.hotHetongURL, 1)).Reply(200).JSON(`{
"note": false,
"source_date": "2019-01-07",
"code": 0,
"num": 100,
"list": [{
"aid": 40063426,
"mid": 837470,
"score": 764906,
"desc": "很多人分享",
"corner_mark": 0
}, {
"aid": 39425207,
"mid": 4870926,
"score": 690583,
"desc": "百万播放",
"corner_mark": 0
}]
}`)
res, err := d.HotTenTab(ctx(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestHotHeTongTabCard(t *testing.T) {
Convey("HotHeTongTabCard", t, func() {
d.client.SetTransport(gock.DefaultTransport)
httpMock("GET", fmt.Sprintf(d.hotHeTongtabcardURL, 1)).Reply(200).JSON(`{
"code": 0,
"list": [{
"goto": "av",
"id": 40063426,
"from_type": "recommend",
"desc": "8千分享",
"corner_mark": 0
}, {
"goto": "av",
"id": 39425207,
"from_type": "recommend",
"desc": "百万播放",
"corner_mark": 0
}, {
"goto": "av",
"id": 39920213,
"from_type": "recommend",
"desc": "百万播放",
"corner_mark": 0
}, {
"goto": "av",
"id": 39237975,
"from_type": "recommend",
"desc": "百万播放",
"corner_mark": 0
}]
}`)
res, err := d.HotHeTongTabCard(ctx(), 1)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

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 = ["region_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["region.go"],
importpath = "go-common/app/interface/main/app-show/dao/region",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model/region:go_default_library",
"//library/database/sql: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,150 @@
package region
import (
"context"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model/region"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
// region
_allSQL = "SELECT r.rid,r.reid,r.name,r.logo,r.rank,r.goto,r.param,r.plat,r.area,r.build,r.conditions,r.uri,r.is_logo,r.type,r.is_rank,l.name FROM region AS r, language AS l WHERE r.state=1 AND l.id=r.lang_id ORDER BY r.rank DESC"
_allSQL2 = "SELECT r.id,r.rid,r.reid,r.name,r.logo,r.rank,r.goto,r.param,r.plat,r.area,r.uri,r.is_logo,r.type,l.name FROM region_copy AS r, language AS l WHERE r.state=1 AND l.id=r.lang_id ORDER BY r.rank DESC"
_limitSQL = "SELECT l.id,l.rid,l.build,l.conditions FROM region_limit AS l,region_copy AS r WHERE l.rid=r.id"
_configSQL = "SELECT c.id,c.rid,c.is_rank FROM region_rank_config AS c,region_copy AS r WHERE c.rid=r.id"
//region android
_regionPlatSQL = "SELECT r.rid,r.reid,r.name,r.logo,r.rank,r.goto,r.param,r.plat,r.area,l.name FROM region_copy AS r, language AS l WHERE r.plat=0 AND r.state=1 AND l.id=r.lang_id ORDER BY r.rank DESC"
)
type Dao struct {
db *sql.DB
get *sql.Stmt
list *sql.Stmt
limit *sql.Stmt
config *sql.Stmt
regionPlat *sql.Stmt
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
db: sql.NewMySQL(c.MySQL.Show),
}
// prepare
d.get = d.db.Prepared(_allSQL)
d.list = d.db.Prepared(_allSQL2)
d.limit = d.db.Prepared(_limitSQL)
d.config = d.db.Prepared(_configSQL)
d.regionPlat = d.db.Prepared(_regionPlatSQL)
return
}
// GetAll get all region.
func (d *Dao) All(ctx context.Context) ([]*region.Region, error) {
rows, err := d.get.Query(ctx)
if err != nil {
log.Error("mysqlDB.Query error(%v)", err)
return nil, err
}
defer rows.Close()
apps := []*region.Region{}
for rows.Next() {
a := &region.Region{}
if err = rows.Scan(&a.Rid, &a.Reid, &a.Name, &a.Logo, &a.Rank, &a.Goto, &a.Param, &a.Plat, &a.Area, &a.Build, &a.Condition, &a.URI, &a.Islogo, &a.Rtype, &a.Entrance, &a.Language); err != nil {
log.Error("row.Scan error(%v)", err)
return nil, err
}
apps = append(apps, a)
}
return apps, err
}
// RegionPlat get android
func (d *Dao) RegionPlat(ctx context.Context) ([]*region.Region, error) {
rows, err := d.regionPlat.Query(ctx)
if err != nil {
log.Error("mysqlDB.Query error(%v)", err)
return nil, err
}
defer rows.Close()
apps := []*region.Region{}
for rows.Next() {
a := &region.Region{}
if err = rows.Scan(&a.Rid, &a.Reid, &a.Name, &a.Logo, &a.Rank, &a.Goto, &a.Param, &a.Plat, &a.Area, &a.Language); err != nil {
log.Error("row.Scan error(%v)", err)
return nil, err
}
apps = append(apps, a)
}
return apps, err
}
// AllList get all region.
func (d *Dao) AllList(ctx context.Context) ([]*region.Region, error) {
rows, err := d.list.Query(ctx)
if err != nil {
log.Error("mysqlDB.Query error(%v)", err)
return nil, err
}
defer rows.Close()
apps := []*region.Region{}
for rows.Next() {
a := &region.Region{}
if err = rows.Scan(&a.ID, &a.Rid, &a.Reid, &a.Name, &a.Logo, &a.Rank, &a.Goto, &a.Param, &a.Plat, &a.Area, &a.URI, &a.Islogo, &a.Rtype, &a.Language); err != nil {
log.Error("row.Scan error(%v)", err)
return nil, err
}
apps = append(apps, a)
}
return apps, err
}
// Limit region limits
func (d *Dao) Limit(ctx context.Context) (map[int64][]*region.Limit, error) {
rows, err := d.limit.Query(ctx)
if err != nil {
log.Error("mysqlDB.Query error(%v)", err)
return nil, err
}
defer rows.Close()
limits := map[int64][]*region.Limit{}
for rows.Next() {
a := &region.Limit{}
if err = rows.Scan(&a.ID, &a.Rid, &a.Build, &a.Condition); err != nil {
log.Error("rows.Scan error(%v)", err)
return nil, err
}
limits[a.Rid] = append(limits[a.Rid], a)
}
return limits, err
}
// Config region configs
func (d *Dao) Config(ctx context.Context) (map[int64][]*region.Config, error) {
rows, err := d.config.Query(ctx)
if err != nil {
log.Error("mysqlDB.Query error(%v)", err)
return nil, err
}
defer rows.Close()
configs := map[int64][]*region.Config{}
for rows.Next() {
a := &region.Config{}
if err = rows.Scan(&a.ID, &a.Rid, &a.ScenesID); err != nil {
log.Error("rows.Scan error(%v)", err)
return nil, err
}
a.ConfigChange()
configs[a.Rid] = append(configs[a.Rid], a)
}
return configs, err
}
// Close close memcache resource.
func (dao *Dao) Close() {
if dao.db != nil {
dao.db.Close()
}
}

View File

@@ -0,0 +1,75 @@
package region
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestAll(t *testing.T) {
Convey("All", t, func() {
res, err := d.All(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestRegionPlat(t *testing.T) {
Convey("RegionPlat", t, func() {
res, err := d.RegionPlat(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestAllList(t *testing.T) {
Convey("AllList", t, func() {
res, err := d.AllList(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestLimit(t *testing.T) {
Convey("Limit", t, func() {
res, err := d.Limit(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestConfig(t *testing.T) {
Convey("Config", t, func() {
res, err := d.Config(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestClose(t *testing.T) {
Convey("Close", t, func() {
d.Close()
})
}

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 = ["relation_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["relation.go"],
importpath = "go-common/app/interface/main/app-show/dao/relation",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//app/service/main/relation/rpc/client: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,52 @@
package relation
import (
"context"
"go-common/app/interface/main/app-show/conf"
relation "go-common/app/service/main/relation/model"
relrpc "go-common/app/service/main/relation/rpc/client"
"go-common/library/log"
)
// Dao is rpc dao.
type Dao struct {
// relation rpc
relRPC *relrpc.Service
}
// New new a relation dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// relation rpc
relRPC: relrpc.New(c.RelationRPC),
}
return
}
// Relations fids relations
func (d *Dao) Relations(ctx context.Context, mid int64, fids []int64) (res map[int64]*relation.Following, err error) {
arg := &relation.ArgRelations{
Mid: mid,
Fids: fids,
}
if res, err = d.relRPC.Relations(ctx, arg); err != nil {
log.Error("d.relRPC.Relations(%v) error(%v)", arg, err)
res = nil
return
}
return
}
// Stats fids stats
func (d *Dao) Stats(ctx context.Context, mids []int64) (res map[int64]*relation.Stat, err error) {
arg := &relation.ArgMids{
Mids: mids,
}
if res, err = d.relRPC.Stats(ctx, arg); err != nil {
log.Error("d.relRPC.Stats(%v) error(%v)", arg, err)
res = nil
return
}
return
}

View File

@@ -0,0 +1,44 @@
package relation
import (
"context"
"flag"
"go-common/app/interface/main/app-show/conf"
"path/filepath"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func ctx() context.Context {
return context.Background()
}
func TestRelations(t *testing.T) {
Convey("get Relations all", t, func() {
res, err := d.Relations(ctx(), 0, []int64{0})
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}
func TestStats(t *testing.T) {
Convey("get Stats all", t, func() {
res, err := d.Stats(ctx(), []int64{0})
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}

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 = ["resource_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["resource.go"],
importpath = "go-common/app/interface/main/app-show/dao/resource",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/service/main/resource/model:go_default_library",
"//app/service/main/resource/rpc/client: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,51 @@
package resource
import (
"context"
"go-common/app/interface/main/app-show/conf"
resource "go-common/app/service/main/resource/model"
resrpc "go-common/app/service/main/resource/rpc/client"
"go-common/library/log"
)
type Dao struct {
c *conf.Config
// rpc
resRpc *resrpc.Service
}
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
// rpc
resRpc: resrpc.New(c.ResourceRPC),
}
return
}
func (d *Dao) ResBanner(ctx context.Context, plat int8, build int, mid int64, resIDStr, channel, ip, buvid, network, mobiApp, device, adExtra string, isAd bool) (res map[int][]*resource.Banner, err error) {
arg := &resource.ArgBanner{
Plat: plat,
ResIDs: resIDStr,
Build: build,
MID: mid,
Channel: channel,
IP: ip,
Buvid: buvid,
Network: network,
MobiApp: mobiApp,
Device: device,
IsAd: isAd,
AdExtra: adExtra,
}
var bs *resource.Banners
if bs, err = d.resRpc.Banners(ctx, arg); err != nil || bs == nil {
log.Error("d.resRpc.Banners(%v) error(%v)", arg, err)
return
}
if len(bs.Banner) > 0 {
res = bs.Banner
}
return
}

View File

@@ -0,0 +1,37 @@
package resource
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestResBanner(t *testing.T) {
Convey("ResBanner", t, func() {
res, err := d.ResBanner(ctx(), 1, 1, 1, "", "", "", "", "", "", "", "", false)
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

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 = ["search_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["search.go"],
importpath = "go-common/app/interface/main/app-show/dao/search",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-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,93 @@
package search
import (
"context"
"encoding/json"
"fmt"
"net/url"
"strconv"
"time"
"go-common/app/interface/main/app-show/conf"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
_search = "/cate/search"
)
// Dao is search dao.
type Dao struct {
client *httpx.Client
searchURL string
// search duration
searchTick string
}
//New recommend dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(conf.Conf.HTTPClient),
searchURL: c.Host.Search + _search,
searchTick: c.Duration.Search,
}
return
}
// SearchList
func (d *Dao) SearchList(c context.Context, rid, build, pn, ps int, mid int64, ts time.Time, ip, order, tagName, platform, mobiApp, device string) (arcids []int64, err error) {
advance, _ := time.ParseDuration(d.searchTick) // three weeks -504h
starttime := ts.Add(advance)
params := url.Values{}
params.Set("platform", platform)
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("order", order)
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("time_from", starttime.Format("20060102"))
params.Set("time_to", ts.Format("20060102"))
params.Set("build", strconv.Itoa(build))
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("search_type", "video")
params.Set("view_type", "hot_rank")
params.Set("clientip", ip)
if tagName != "" {
params.Set("keyword", tagName)
}
params.Set("cate_id", strconv.Itoa(rid))
var res struct {
Code int `json:"code"`
Data []struct {
Aid interface{} `json:"id"`
} `json:"result"`
}
if err = d.client.Get(c, d.searchURL, "", params, &res); err != nil {
log.Error("search news url(%s) error(%v)", d.searchURL+"?"+params.Encode(), err)
return
}
b, _ := json.Marshal(&res)
log.Info("search list url(%v) response(%s)", d.searchURL+"?"+params.Encode(), b)
if res.Code != 0 && res.Code != -1 {
log.Error("search region news url(%s) error(%v)", d.searchURL+"?"+params.Encode(), res.Code)
err = fmt.Errorf("search region news api response code(%v)", res)
return
}
for _, arcs := range res.Data {
var aidInt int64
switch aid := arcs.Aid.(type) {
case string:
aidInt = aidToInt(aid)
case float64:
aidInt = int64(aid)
}
arcids = append(arcids, aidInt)
}
return
}
func aidToInt(aidstr string) (aid int64) {
aid, _ = strconv.ParseInt(aidstr, 10, 64)
return
}

View File

@@ -0,0 +1,52 @@
package search
import (
"context"
"flag"
"os"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.app-svr.app-show")
flag.Set("conf_token", "Pae4IDOeht4cHXCdOkay7sKeQwHxKOLA")
flag.Set("tree_id", "2687")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../cmd/convey-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
//d.bfsClient.SetTransport(gock.DefaultTransport)
m.Run()
os.Exit(0)
}
func TestSearchList(t *testing.T) {
Convey("SearchList", t, func() {
_, err := d.SearchList(ctx(), 1, 1, 1, 1, 1, time.Now(), "127.0.0.1", "", "", "", "", "")
So(err, ShouldBeNil)
})
}

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 = ["show_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"redis.go",
"show.go",
],
importpath = "go-common/app/interface/main/app-show/dao/show",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model/show:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql: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,54 @@
package show
import (
"context"
"time"
"go-common/app/interface/main/app-show/conf"
"go-common/library/cache/redis"
"go-common/library/database/sql"
)
// Dao is show dao.
type Dao struct {
// mysql
db *sql.DB
getHead *sql.Stmt
getItem *sql.Stmt
getHeadTmp *sql.Stmt
getItemTmp *sql.Stmt
// redis
rcmmndRds *redis.Pool
rcmmndExp int
}
// New new a show dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// mysql
db: sql.NewMySQL(c.MySQL.Show),
// redis
rcmmndRds: redis.NewPool(c.Redis.Recommend.Config),
rcmmndExp: int(time.Duration(c.Redis.Recommend.Expire) / time.Second),
}
d.getHead = d.db.Prepared(_headSQL)
d.getItem = d.db.Prepared(_itemSQL)
d.getHeadTmp = d.db.Prepared(_headTmpSQL)
d.getItemTmp = d.db.Prepared(_itemTmpSQL)
return d
}
// Close close memcache resource.
func (d *Dao) Close() (err error) {
if d.rcmmndRds != nil {
return d.rcmmndRds.Close()
}
return nil
}
func (d *Dao) Ping(c context.Context) (err error) {
conn := d.rcmmndRds.Get(c)
_, err = conn.Do("SET", "PING", "PONG")
conn.Close()
return
}

View File

@@ -0,0 +1,95 @@
package show
import (
"context"
"go-common/library/log"
"go-common/library/cache/redis"
)
const (
_prefix = "s_"
)
func keyRcmmd(mid string) string {
return _prefix + mid
}
func keyCnt(mid string) string {
return _prefix + mid + "_c"
}
// ExistRcmmndCache check recommend cache exists.
func (d *Dao) ExistRcmmndCache(c context.Context, mid string) (exist bool, err error) {
conn := d.rcmmndRds.Get(c)
defer conn.Close()
key := keyCnt(mid)
exist, err = redis.Bool(conn.Do("EXISTS", key))
if err != nil {
log.Error("conn.Do(EXISTS, %s) error(%v)", key, err)
}
return
}
// AddRcmmndCache add recommend cache.
func (d *Dao) AddRcmmndCache(c context.Context, mid string, aids ...int64) (err error) {
conn := d.rcmmndRds.Get(c)
defer conn.Close()
key := keyRcmmd(mid)
cntk := keyCnt(mid)
args := redis.Args{}.Add(key).AddFlat(aids)
conn.Send("RPUSH", args...)
conn.Send("EXPIRE", key, d.rcmmndExp)
conn.Send("INCRBY", cntk, len(aids))
conn.Send("EXPIRE", cntk, d.rcmmndExp)
if err = conn.Flush(); err != nil {
log.Error("conn.Flush err(%v)", err)
return
}
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
}
return
}
// PopRcmmndCache pop recommend cache.
func (d *Dao) PopRcmmndCache(c context.Context, mid string, cnt int) (aids []int64, err error) {
conn := d.rcmmndRds.Get(c)
defer conn.Close()
key := keyRcmmd(mid)
for i := 0; i < cnt; i++ {
conn.Send("LPOP", key)
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
var aid int64
for i := 0; i < cnt; i++ {
aid, err = redis.Int64(conn.Receive())
if err != nil {
if err == redis.ErrNil {
err = nil
continue
} else {
log.Error("conn.Do(ZREVRANGE, %v)", err)
}
return
}
aids = append(aids, aid)
}
return
}

View File

@@ -0,0 +1,98 @@
package show
import (
"context"
"go-common/app/interface/main/app-show/model/show"
"go-common/library/log"
)
const (
// real data
_headSQL = "SELECT s.id,s.plat,s.title,s.type,s.param,s.style,s.rank,s.build,s.conditions,l.name FROM show_head AS s,language AS l WHERE l.id=s.lang_id ORDER BY rank DESC"
_itemSQL = "SELECT sid,title,random,cover,param FROM show_item"
// temp preview
_headTmpSQL = "SELECT s.id,s.plat,s.title,s.type,s.param,s.style,s.rank,s.build,s.conditions,l.name FROM show_head_temp AS s,language AS l WHERE l.id=s.lang_id ORDER BY rank DESC"
_itemTmpSQL = "SELECT sid,title,random,cover,param FROM show_item_temp"
)
// Heads get show head data.
func (d *Dao) Heads(ctx context.Context) (heads map[int8][]*show.Head, err error) {
rows, err := d.getHead.Query(ctx)
if err != nil {
log.Error("d.getItem.Query() error(%v)", err)
return
}
defer rows.Close()
heads = make(map[int8][]*show.Head, 20)
for rows.Next() {
h := &show.Head{}
if err = rows.Scan(&h.ID, &h.Plat, &h.Title, &h.Type, &h.Param, &h.Style, &h.Rank, &h.Build, &h.Condition, &h.Language); err != nil {
log.Error("row.Scan error(%v)", err)
return nil, err
}
heads[h.Plat] = append(heads[h.Plat], h)
}
return
}
// Items get item data.
func (d *Dao) Items(ctx context.Context) (items map[int][]*show.Item, err error) {
rows, err := d.getItem.Query(ctx)
if err != nil {
log.Error("d.getItem.Query error(%v)", err)
return nil, err
}
defer rows.Close()
items = make(map[int][]*show.Item, 50)
for rows.Next() {
i := &show.Item{}
if err = rows.Scan(&i.Sid, &i.Title, &i.Random, &i.Cover, &i.Param); err != nil {
log.Error("row.Scan error(%v)", err)
return nil, err
}
items[i.Sid] = append(items[i.Sid], i)
}
return
}
// TempHeads get show temp head data.
func (d *Dao) TempHeads(ctx context.Context) (heads map[int8][]*show.Head, err error) {
rows, err := d.db.Query(ctx, _headTmpSQL)
if err != nil {
log.Error("d.tempHeads.Query() error(%v)", err)
return
}
defer rows.Close()
heads = make(map[int8][]*show.Head, 20)
for rows.Next() {
h := &show.Head{}
if err = rows.Scan(&h.ID, &h.Plat, &h.Title, &h.Type, &h.Param, &h.Style, &h.Rank, &h.Build, &h.Condition, &h.Language); err != nil {
log.Error("row.Scan error(%v)", err)
return nil, err
}
heads[h.Plat] = append(heads[h.Plat], h)
}
return
}
// TempItems get temp item data.
func (d *Dao) TempItems(ctx context.Context) (items map[int][]*show.Item, err error) {
rows, err := d.db.Query(ctx, _itemTmpSQL)
if err != nil {
log.Error("d.tempItems.Query error(%v)", err)
return nil, err
}
defer rows.Close()
items = make(map[int][]*show.Item, 50)
for rows.Next() {
i := &show.Item{}
if err = rows.Scan(&i.Sid, &i.Title, &i.Random, &i.Cover, &i.Param); err != nil {
log.Error("row.Scan error(%v)", err)
return nil, err
}
items[i.Sid] = append(items[i.Sid], i)
}
return
}

View File

@@ -0,0 +1,61 @@
package show
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestHeads(t *testing.T) {
Convey("Heads", t, func() {
res, err := d.Heads(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestItems(t *testing.T) {
Convey("Items", t, func() {
res, err := d.Items(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestTempHeads(t *testing.T) {
Convey("TempHeads", t, func() {
res, err := d.TempHeads(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestTempItems(t *testing.T) {
Convey("TempItems", t, func() {
res, err := d.TempItems(ctx())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}

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 = ["tag_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["tag.go"],
importpath = "go-common/app/interface/main/app-show/dao/tag",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/app-show/conf:go_default_library",
"//app/interface/main/app-show/model/region:go_default_library",
"//app/interface/main/app-show/model/tag:go_default_library",
"//app/interface/main/tag/model:go_default_library",
"//library/ecode: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,299 @@
package tag
import (
"context"
"fmt"
"net/url"
"strconv"
"time"
"go-common/app/interface/main/app-show/conf"
"go-common/app/interface/main/app-show/model/region"
"go-common/app/interface/main/app-show/model/tag"
tagm "go-common/app/interface/main/tag/model"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
)
const (
_tagURL = "/x/internal/tag/info"
_tagHotURL = "/tag/hot/%d/%d.json"
_tagNewURL = "/x/internal/tag/ranking/archives"
_similarTagURL = "/x/internal/tag/similar"
_tagHotsIDURL = "/x/internal/tag/hots"
_similarTagChangeURL = "/x/internal/tag/change/similar"
_tagDetailURL = "/x/internal/tag/detail"
_tagRankingURL = "/x/internal/tag/detail/ranking"
_tagArchiveURL = "/x/internal/tag/archive/tags"
)
// Dao is tag dao.
type Dao struct {
client *httpx.Client
clientParam *httpx.Client
// url
tagURL string
tagHotURL string
tagNewURL string
similarTagURL string
tagHotsIDURL string
similarTagChangeURL string
tagDetailURL string
tagRankingURL string
tagArchiveURL string
}
// New tag dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
client: httpx.NewClient(conf.Conf.HTTPClient),
clientParam: httpx.NewClient(conf.Conf.HTTPClient),
tagURL: c.Host.ApiCo + _tagURL,
tagHotURL: c.Host.Hetongzi + _tagHotURL,
tagNewURL: c.Host.ApiCo + _tagNewURL,
similarTagURL: c.Host.ApiCo + _similarTagURL,
tagHotsIDURL: c.Host.ApiCo + _tagHotsIDURL,
similarTagChangeURL: c.Host.ApiCo + _similarTagChangeURL,
tagDetailURL: c.Host.ApiCo + _tagDetailURL,
tagRankingURL: c.Host.ApiCo + _tagRankingURL,
tagArchiveURL: c.Host.ApiCo + _tagArchiveURL,
}
return
}
// TagInfo get tag info.
func (d *Dao) TagInfo(c context.Context, mid int64, tagId int, now time.Time) (data *tag.Tag, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("tag_id", strconv.Itoa(tagId))
var res struct {
Code int `json:"code"`
Data *tag.Tag `json:"data"`
}
if err = d.client.Get(c, d.tagURL, "", params, &res); err != nil {
log.Error("tagInfo url(%s) error(%v)", d.tagURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("tagInfo url(%s) error(%v)", d.tagURL+"?"+params.Encode(), res.Code)
err = fmt.Errorf("tagInfo api response code(%v)", res)
return
}
data = res.Data
return
}
// Hots
func (d *Dao) Hots(c context.Context, rid, tagId, pn, ps int, now time.Time) (data []int64, err error) {
var (
uri = fmt.Sprintf(d.tagHotURL, rid, tagId)
res struct {
Code int `json:"code"`
Data []int64 `json:"data"`
}
count int
start int
)
if err = d.clientParam.Get(c, uri, "", nil, &res); err != nil {
log.Error("d.paramclient.Get(%s) error(%v)", uri, err)
return
}
if res.Code != 0 {
log.Error("tag region hots url(%s) code:%d", uri, res.Code)
err = fmt.Errorf("tag region hots api response code(%v)", res)
return
}
count = len(res.Data)
if count == 0 {
return
}
start = (pn - 1) * ps
if start > count {
return
}
data = res.Data
return
}
// NewArcs
func (d *Dao) NewArcs(c context.Context, rid, tagId, pn, ps int, now time.Time) (arcids []int64, err error) {
params := url.Values{}
params.Set("rid", strconv.Itoa(rid))
params.Set("tag_id", strconv.Itoa(tagId))
params.Set("pn", strconv.Itoa(pn))
params.Set("ps", strconv.Itoa(ps))
var res struct {
Code int `json:"code"`
Data struct {
Archives []struct {
Aid int64 `json:"aid"`
} `json:"archives"`
} `json:"data"`
}
if err = d.client.Get(c, d.tagNewURL, "", params, &res); err != nil {
log.Error("tag region news url(%s) error(%v)", d.tagNewURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("tag region news url(%s) error(%v)", d.tagNewURL+"?"+params.Encode(), res.Code)
err = fmt.Errorf("tag region news api response code(%v)", res)
return
}
for _, arcs := range res.Data.Archives {
arcids = append(arcids, arcs.Aid)
}
return
}
// SimilarTag tag similar
func (d *Dao) SimilarTag(c context.Context, rid, tagId int, now time.Time) (data []*region.SimilarTag, err error) {
params := url.Values{}
params.Set("rid", strconv.Itoa(rid))
params.Set("tid", strconv.Itoa(tagId))
var res struct {
Code int `json:"code"`
Data []*region.SimilarTag `json:"data"`
}
if err = d.client.Get(c, d.similarTagURL, "", params, &res); err != nil {
log.Error("tag similarTagURL url(%s) error(%v)", d.similarTagURL, err)
return
}
if res.Code != 0 {
log.Error("tag similarTagURL url(%s) Code(%v)", d.similarTagURL, res.Code)
err = fmt.Errorf("tag api response code(%v)", res)
return
}
data = res.Data
return
}
// TagHotsId
func (d *Dao) TagHotsId(c context.Context, rid int, now time.Time) (tags []*tag.Tag, err error) {
params := url.Values{}
params.Set("rid", strconv.Itoa(rid))
var res struct {
Code int `json:"code"`
Data []struct {
Rid int `json:"rid"`
Tags []*tag.Tag `json:"tags"`
} `json:"data"`
}
if err = d.client.Get(c, d.tagHotsIDURL, "", params, &res); err != nil {
log.Error("tag tagHotsIDURL url(%s) error(%v)", d.tagHotsIDURL, err)
return
}
if res.Code != 0 {
log.Error("tag tagHotsIDURL url(%s) Code(%v)", d.tagHotsIDURL, res.Code)
err = fmt.Errorf("tag api response code(%v)", res)
return
}
if len(res.Data) == 0 {
return
}
tags = res.Data[0].Tags
return
}
// SimilarTagChangetag tag similar no rid
func (d *Dao) SimilarTagChange(c context.Context, tagID int, now time.Time) (data []*region.SimilarTag, err error) {
params := url.Values{}
params.Set("tag_id", strconv.Itoa(tagID))
var res struct {
Code int `json:"code"`
Data []*region.SimilarTag `json:"data"`
}
if err = d.client.Get(c, d.similarTagChangeURL, "", params, &res); err != nil {
log.Error("tag similarTagChangeURL, url(%s) error(%v)", d.similarTagChangeURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("tag similarTagChangeURL url(%s) Code(%v)", d.similarTagChangeURL+"?"+params.Encode(), res.Code)
err = fmt.Errorf("tag api response code(%v)", res)
return
}
data = res.Data
return
}
// Detail tag detail
func (d *Dao) Detail(c context.Context, tagID int, pn, ps int, now time.Time) (arcids []int64, err error) {
params := url.Values{}
params.Set("tag_id", strconv.Itoa(tagID))
params.Set("pn", strconv.Itoa(pn))
params.Set("ps", strconv.Itoa(ps))
var res struct {
Code int `json:"code"`
Data struct {
News struct {
Archives []struct {
Aid int64 `json:"aid"`
} `json:"archives"`
} `json:"news"`
} `json:"data"`
}
if err = d.client.Get(c, d.tagDetailURL, "", params, &res); err != nil {
log.Error("d.client.Get(%s) error(%v)", d.tagDetailURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("tag Detail url(%s) Code(%v)", d.tagDetailURL, res.Code)
err = fmt.Errorf("tag api response code(%v)", res)
return
}
for _, arcs := range res.Data.News.Archives {
arcids = append(arcids, arcs.Aid)
}
return
}
// DetailRanking tag detail ranking
func (d *Dao) DetailRanking(c context.Context, reid, tagID int, pn, ps int, now time.Time) (arcids []int64, err error) {
params := url.Values{}
params.Set("prid", strconv.Itoa(reid))
params.Set("tag_id", strconv.Itoa(tagID))
params.Set("pn", strconv.Itoa(pn))
params.Set("ps", strconv.Itoa(ps))
var res struct {
Code int `json:"code"`
Data struct {
Archives []struct {
Aid int64 `json:"aid"`
} `json:"archives"`
} `json:"data"`
}
if err = d.client.Get(c, d.tagRankingURL, "", params, &res); err != nil {
log.Error("d.client.Get(%s) error(%v)", d.tagRankingURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("tag DetailRanking url(%s) Code(%v)", d.tagRankingURL+"?"+params.Encode(), res.Code)
err = fmt.Errorf("tag api response code(%v)", res)
return
}
for _, arcs := range res.Data.Archives {
arcids = append(arcids, arcs.Aid)
}
return
}
// TagArchive archive tags
func (d *Dao) TagArchive(c context.Context, aid int64) (data []*tagm.Tag, err error) {
params := url.Values{}
params.Set("aid", strconv.FormatInt(aid, 10))
var res struct {
Code int `json:"code"`
Data []*tagm.Tag `json:"data"`
}
if err = d.client.Get(c, d.tagArchiveURL, "", params, &res); err != nil {
log.Error("TagArchive url(%s) error(%v)", d.tagArchiveURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("TagArchive url(%s) error(%v)", d.tagArchiveURL+"?"+params.Encode(), res.Code)
err = ecode.Int(res.Code)
return
}
data = res.Data
return
}

View File

@@ -0,0 +1,93 @@
package tag
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-show/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
)
func ctx() context.Context {
return context.Background()
}
func init() {
dir, _ := filepath.Abs("../../cmd/app-show-test.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
time.Sleep(time.Second)
}
func TestTagInfo(t *testing.T) {
Convey("TagInfo", t, func() {
res, err := d.TagInfo(ctx(), 1, 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestHots(t *testing.T) {
Convey("Hots", t, func() {
res, err := d.Hots(ctx(), 1, 1, 1, 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestNewArcs(t *testing.T) {
Convey("NewArcs", t, func() {
res, err := d.NewArcs(ctx(), 1, 1, 1, 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestSimilarTag(t *testing.T) {
Convey("SimilarTag", t, func() {
res, err := d.SimilarTag(ctx(), 1, 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestTagHotsId(t *testing.T) {
Convey("TagHotsId", t, func() {
res, err := d.TagHotsId(ctx(), 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestSimilarTagChange(t *testing.T) {
Convey("SimilarTagChange", t, func() {
res, err := d.SimilarTagChange(ctx(), 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestDetail(t *testing.T) {
Convey("Detail", t, func() {
res, err := d.Detail(ctx(), 1, 1, 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}
func TestDetailRanking(t *testing.T) {
Convey("DetailRanking", t, func() {
res, err := d.DetailRanking(ctx(), 1, 1, 1, 1, time.Now())
So(res, ShouldNotBeEmpty)
So(err, ShouldBeNil)
})
}