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,21 @@
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//app/interface/main/spread/cmd:all-srcs",
"//app/interface/main/spread/conf:all-srcs",
"//app/interface/main/spread/dao:all-srcs",
"//app/interface/main/spread/http:all-srcs",
"//app/interface/main/spread/model:all-srcs",
"//app/interface/main/spread/service:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,18 @@
# v1.1.1
1. 增加total字段
# v1.1.0
1. 透传番剧数据
# v1.0.3
1. remove identity
2. upgrade http server
# v1.0.2
1. remove net http parse
# v1.0.1
1. 移除无用字段
# v1.0.0
1. 初始化

View File

@@ -0,0 +1,9 @@
# Owner
zhapuyu
renwei
# Author
wangxu01
# Reviewer
zhapuyu

View File

@@ -0,0 +1,15 @@
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- renwei
- wangxu01
- zhapuyu
labels:
- interface
- interface/main/spread
- main
options:
no_parent_owners: true
reviewers:
- wangxu01
- zhapuyu

View File

@@ -0,0 +1,4 @@
# spread
# 项目简介
对外推广通用接口

View File

@@ -0,0 +1,42 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
)
go_binary(
name = "cmd",
embed = [":go_default_library"],
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["main.go"],
data = ["spread-test.toml"],
importpath = "go-common/app/interface/main/spread/cmd",
tags = ["automanaged"],
deps = [
"//app/interface/main/spread/conf:go_default_library",
"//app/interface/main/spread/http:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/trace:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,49 @@
package main
import (
"flag"
"os"
"os/signal"
"syscall"
"go-common/app/interface/main/spread/conf"
"go-common/app/interface/main/spread/http"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
"go-common/library/net/trace"
)
func main() {
flag.Parse()
if err := conf.Init(); err != nil {
log.Error("conf.Init() error(%v)", err)
panic(err)
}
// init log
log.Init(conf.Conf.Log)
defer log.Close()
log.Info("spread start")
// init trace
trace.Init(conf.Conf.Tracer)
defer trace.Close()
// ecode init
ecode.Init(conf.Conf.Ecode)
// service init
http.Init(conf.Conf)
// init pprof conf.Conf.Perf
// init signal
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
s := <-c
log.Info("spread get a signal %s", s.String())
switch s {
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
log.Info("spread exit")
return
case syscall.SIGHUP:
default:
return
}
}
}

View File

@@ -0,0 +1,27 @@
# This is a TOML document. Boom
[log]
dir = "/data/log/spread"
[bm]
addr = "0.0.0.0:7642"
timeout = "1s"
[HTTPClient]
key = "9cfc54570033cd61"
secret = "9d63835fa38fe58a62d9f49ef5da296f"
dial = "100ms"
timeout = "1s"
keepAlive = "60s"
timer = 128
[HTTPClient.breaker]
window ="10s"
sleep ="10ms"
bucket = 10
ratio = 0.5
request = 100
[[Businesses]]
appkey = "douban"
appSecret = "douban"
[Spread]
BangumiContentURL = "http://uat-bangumi.bilibili.co/ext/internal/archive/channel/content"
BangumiOffURL = "http://uat-bangumi.bilibili.co/ext/internal/archive/channel/content/offshelve"

View File

@@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["conf.go"],
importpath = "go-common/app/interface/main/spread/conf",
tags = ["automanaged"],
deps = [
"//library/conf:go_default_library",
"//library/ecode/tip:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/trace:go_default_library",
"//vendor/github.com/BurntSushi/toml:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,101 @@
package conf
import (
"errors"
"flag"
"go-common/library/conf"
ecode "go-common/library/ecode/tip"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/trace"
"github.com/BurntSushi/toml"
)
// global var
var (
confPath string
client *conf.Client
// Conf config
Conf = &Config{}
)
// Config config set
type Config struct {
// elk
Log *log.Config
// http
BM *bm.ServerConfig
// tracer
Tracer *trace.Config
// ecode
Ecode *ecode.Config
// http client
HTTPClient *bm.ClientConfig
Businesses []*Business
Spread *Spread
}
// Spread .
type Spread struct {
BangumiContentURL string
BangumiOffURL string
}
// Business .
type Business struct {
Appkey string
AppSecret string
}
func init() {
flag.StringVar(&confPath, "conf", "", "default config path")
}
// Init init conf
func Init() error {
if confPath != "" {
return local()
}
return remote()
}
func local() (err error) {
_, err = toml.DecodeFile(confPath, &Conf)
return
}
func remote() (err error) {
if client, err = conf.New(); err != nil {
return
}
if err = load(); err != nil {
return
}
go func() {
for range client.Event() {
log.Info("config reload")
if load() != nil {
log.Error("config reload error (%v)", err)
}
}
}()
return
}
func load() (err error) {
var (
s string
ok bool
tmpConf *Config
)
if s, ok = client.Toml2(); !ok {
return errors.New("load config center error")
}
if _, err = toml.Decode(s, &tmpConf); err != nil {
return errors.New("could not decode config")
}
*Conf = *tmpConf
return
}

View File

@@ -0,0 +1,55 @@
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",
"dao_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/spread/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 = [
"bangumi.go",
"dao.go",
],
importpath = "go-common/app/interface/main/spread/dao",
tags = ["automanaged"],
deps = [
"//app/interface/main/spread/conf:go_default_library",
"//app/interface/main/spread/model:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/stat/prom:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,59 @@
package dao
import (
"context"
"fmt"
"net/url"
"strconv"
"go-common/app/interface/main/spread/model"
"go-common/library/ecode"
"go-common/library/log"
)
// BangumiContent .
func (d *Dao) BangumiContent(c context.Context, pn, ps int, typ int8, appkey string) (resp model.BangumiResp, err error) {
params := url.Values{}
params.Set("page_no", strconv.Itoa(pn))
params.Set("page_size", strconv.Itoa(ps))
params.Set("season_type", strconv.Itoa(int(typ)))
params.Set("bsource", appkey)
err = d.httpClient.Get(c, d.c.Spread.BangumiContentURL, "", params, &resp)
u := fmt.Sprintf("%s?%s", d.c.Spread.BangumiContentURL, params.Encode())
if err != nil {
PromError("bangumi:content接口")
log.Errorv(c, log.KV("err", err), log.KV("url", u))
return
}
if resp.Code != 0 {
PromError("bangumi:content接口")
log.Errorv(c, log.KV("res", resp), log.KV("url", u))
err = ecode.Int(resp.Code)
return
}
return
}
// BangumiOff .
func (d *Dao) BangumiOff(c context.Context, pn, ps int, typ int8, appkey string, ts int64) (resp model.BangumiOffResp, err error) {
params := url.Values{}
params.Set("page_no", strconv.Itoa(pn))
params.Set("page_size", strconv.Itoa(ps))
params.Set("timestamp", strconv.FormatInt(ts, 10))
params.Set("season_type", strconv.Itoa(int(typ)))
params.Set("bsource", appkey)
err = d.httpClient.Get(c, d.c.Spread.BangumiOffURL, "", params, &resp)
u := fmt.Sprintf("%s?%s", d.c.Spread.BangumiOffURL, params.Encode())
if err != nil {
PromError("bangumi:off接口")
log.Errorv(c, log.KV("err", err), log.KV("url", u))
return
}
if resp.Code != 0 {
PromError("bangumi:off接口")
log.Errorv(c, log.KV("res", resp), log.KV("url", u))
err = ecode.Int(resp.Code)
return
}
return
}

View File

@@ -0,0 +1,237 @@
package dao
import (
"context"
"net/http"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoBangumiContent(t *testing.T) {
httpMock("GET", "http://uat-bangumi.bilibili.co/ext/internal/archive/channel/content").Reply(http.StatusOK).JSON(`
{
"code": 0,
"message": "success",
"result": [
{
"akira": "11的期望",
"alias": "qwdkhj qwknd,qwjdbhqwdjkbqw,qkjcxsa,jcb,sacb,askjcbscajbsakhc",
"copyright": "bilibili",
"cover_image": "http://i0.hdslb.com/bfs/bangumi/4f84b91e5b90e99d8b96a336385af7d84c308b48.jpg",
"display_address": "https://www.bilibili.com/bangumi/play/ss20017?bsource=baidu_os",
"download_address": "http://app.bilibili.com?bsource=baidu_os",
"duration": 21,
"episodes": [
{
"cover": "http://i0.hdslb.com/bfs/archive/496ea8899680d4a80d163d2edb401b23.jpg",
"duration": 0,
"id": 116664,
"index": 1,
"play_url": "https://www.bilibili.com/bangumi/play/ep116664?bsource=baidu_os",
"pub_real_time": "2018-08-07 00:00:00",
"title": "第二集"
},
{
"cover": "http://i0.hdslb.com/bfs/archive/496ea8899680d4a80d163d2edb401b23.jpg",
"duration": 0,
"id": 116865,
"index": 2,
"play_url": "https://www.bilibili.com/bangumi/play/ep116865?bsource=baidu_os",
"pub_real_time": "2018-09-10 04:00:00",
"title": "9.10zuixin"
},
{
"cover": "http://i0.hdslb.com/bfs/archive/1fda382339317a7f6c918827b261965c24cac831.jpg",
"duration": 0,
"id": 117307,
"index": 3,
"play_url": "https://www.bilibili.com/bangumi/play/ep117307?bsource=baidu_os",
"pub_real_time": "2018-11-07 11:23:00",
"title": "不可播,就不玩了,找邱穗姬"
}
],
"intro": "kate_sponsor_谁都不能动dqw qwd ",
"is_finish": 0,
"media_id": 2130686907,
"name": "免费时承包,转付费后随便看的番",
"play_count": 0,
"premieredate": "2018",
"pub_real_time": 1541560980,
"pub_time": "2018-04-02 00:00:00",
"season": {
"id": 20017,
"index": 1,
"pay_price": 0.0,
"paymentstatus": 1,
"title": "第一季",
"total_count": 6
},
"seasonId": 20017,
"season_series": [
{
"id": 20017,
"index": 1,
"title": "免费时承包,转付费后随便看的番"
},
{
"id": 33409,
"index": 2,
"title": "介绍姜姜的小店的故事"
}
],
"staff": {},
"tag": [],
"type": 1
}
],
"total": 13
}
`)
convey.Convey("BangumiContent", t, func(ctx convey.C) {
var (
c = context.Background()
pn = int(1)
ps = int(10)
typ = int8(1)
appkey = "douban"
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
resp, err := d.BangumiContent(c, pn, ps, typ, appkey)
ctx.Convey("Then err should be nil.resp should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(resp, convey.ShouldNotBeEmpty)
})
})
})
}
func TestDaoBangumiOff(t *testing.T) {
resp := `
{
"code": 0,
"message": "success",
"ttl": 1,
"data": [
{
"name": "中二病也要谈恋爱!恋",
"seasonid": 4349,
"type": 1
},
{
"name": "天空與海洋之間(僅限港澳台地區)",
"seasonid": 25687,
"type": 1
},
{
"name": "只要別西卜大小姐喜歡就好(僅限港澳台地區)",
"seasonid": 25836,
"type": 1
},
{
"name": "嫁给非人类",
"seasonid": 25711,
"type": 1
},
{
"name": "Tokyo Guru: re (Part 2)(僅限港澳台地區)",
"seasonid": 25727,
"type": 1
},
{
"name": "產子救世錄(僅限港澳台地區)",
"seasonid": 25959,
"type": 1
},
{
"name": "精灵宝可梦 日月",
"seasonid": 5707,
"type": 1
},
{
"name": "剧场版「吸血鬼仆人 - Alice in the Garden -」",
"seasonid": 25951,
"type": 1
},
{
"name": "",
"seasonid": 25958,
"type": 1
},
{
"name": "新战神金刚:传奇的保护神 第七季",
"seasonid": 25411,
"type": 1
},
{
"name": "告诉我魔法钟摆~莉露莉露妖精莉露~",
"seasonid": 24579,
"type": 1
},
{
"name": "草莓棉花糖 OVA 第1期",
"seasonid": 4828,
"type": 1
},
{
"name": "NEKOPARA EXTRA 小猫篇(猫娘乐园)",
"seasonid": 25152,
"type": 1
},
{
"name": "新战神金刚:传奇的保护神 第六季",
"seasonid": 25013,
"type": 1
},
{
"name": "闪电十一人 第一季 日语",
"seasonid": 24833,
"type": 1
},
{
"name": "致命紫罗兰编号044",
"seasonid": 24779,
"type": 1
},
{
"name": "灰与幻想的格林姆迦尔 OVA",
"seasonid": 24745,
"type": 1
},
{
"name": "tsetfj",
"seasonid": 24660,
"type": 1
},
{
"name": "未来卡 神搭档对战",
"seasonid": 24416,
"type": 1
},
{
"name": "明日之丈",
"seasonid": 24332,
"type": 1
}
]
}
`
httpMock("GET", "http://uat-bangumi.bilibili.co/ext/internal/archive/channel/content/offshelve").Reply(http.StatusOK).JSON(resp)
convey.Convey("BangumiOff", t, func(ctx convey.C) {
var (
c = context.Background()
pn = int(1)
ps = int(10)
typ = int8(1)
appkey = ""
ts = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
resp, err := d.BangumiOff(c, pn, ps, typ, appkey, ts)
ctx.Convey("Then err should be nil.resp should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(resp, convey.ShouldNotBeEmpty)
})
})
})
}

View File

@@ -0,0 +1,38 @@
package dao
import (
"context"
"go-common/app/interface/main/spread/conf"
bm "go-common/library/net/http/blademaster"
"go-common/library/stat/prom"
)
// Dao dao
type Dao struct {
c *conf.Config
httpClient *bm.Client
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
httpClient: bm.NewClient(c.HTTPClient),
}
return
}
// Close close the resource.
func (d *Dao) Close() {
}
// Ping dao ping
func (d *Dao) Ping(c context.Context) error {
return nil
}
// PromError .
func PromError(name string) {
prom.BusinessErrCount.Incr(name)
}

View File

@@ -0,0 +1,45 @@
package dao
import (
"flag"
"os"
"strings"
"testing"
"go-common/app/interface/main/spread/conf"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.web-svr.spread-interface")
flag.Set("conf_token", "4e987fd4fa064115a1b0207ee298a6e1")
flag.Set("tree_id", "22531")
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/spread-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
d.httpClient.SetTransport(gock.DefaultTransport)
os.Exit(m.Run())
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
r.Method = strings.ToUpper(method)
return r
}

View File

@@ -0,0 +1,38 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"bangumi.go",
"http.go",
],
importpath = "go-common/app/interface/main/spread/http",
tags = ["automanaged"],
deps = [
"//app/interface/main/spread/conf:go_default_library",
"//app/interface/main/spread/service:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/http/blademaster/render:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,40 @@
package http
import (
"go-common/library/ecode"
bm "go-common/library/net/http/blademaster"
)
func bangumiContent(c *bm.Context) {
v := new(struct {
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" validate:"min=1,max=1000" default:"20"`
Type int8 `form:"type" validate:"required"`
Appkey string `form:"appkey" validate:"required"`
})
if err := c.Bind(v); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
data, err := svc.BangumiContent(c, v.Pn, v.Ps, v.Type, v.Appkey)
Render(c, data.Code, data.Message, data.Result, data.Total, err)
}
func bangumiOff(c *bm.Context) {
v := new(struct {
Pn int `form:"pn" default:"1"`
Ps int `form:"ps" validate:"min=1,max=1000" default:"20"`
Type int8 `form:"type" validate:"required"`
Timestamp int64 `form:"timestamp"`
Appkey string `form:"appkey" validate:"required"`
})
if err := c.Bind(v); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
if v.Pn == 0 {
v.Pn = 1
}
data, err := svc.BangumiOff(c, v.Pn, v.Ps, v.Type, v.Timestamp, v.Appkey)
Render(c, data.Code, data.Message, data.Result, data.Total, err)
}

View File

@@ -0,0 +1,138 @@
package http
import (
"crypto/md5"
"encoding/hex"
"net/http"
"net/url"
"strings"
"go-common/app/interface/main/spread/conf"
"go-common/app/interface/main/spread/service"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/render"
)
var (
svc *service.Service
business = make(map[string]string)
)
// Init init
func Init(c *conf.Config) {
initService(c)
// init router
engine := bm.DefaultServer(c.BM)
outerRouter(engine)
if err := engine.Start(); err != nil {
log.Error("xhttp.Serve error(%v)", err)
panic(err)
}
for _, b := range c.Businesses {
business[b.Appkey] = b.AppSecret
}
}
// initService init services.
func initService(c *conf.Config) {
svc = service.New(c)
}
// outerRouter init outer router api path.
func outerRouter(e *bm.Engine) {
//init api
e.Ping(ping)
group := e.Group("/x/spread", Verify)
{
bangumi := group.Group("/bangumi")
{
bangumi.GET("/content", bangumiContent)
bangumi.GET("/offshelve", bangumiOff)
}
}
}
// ping check server ok.
func ping(c *bm.Context) {
}
// Verify will inject into handler func as verify required
func Verify(ctx *bm.Context) {
var (
secret string
ok bool
)
req := ctx.Request
params := req.Form
if req.Method == "POST" {
// Give priority to sign in url query, otherwise check sign in post form.
q := req.URL.Query()
if q.Get("sign") != "" {
params = q
}
}
// check timestamp is not empty (TODO : Check if out of some seconds.., like 100s)
if params.Get("ts") == "" {
log.Error("ts is empty")
ctx.JSON(nil, ecode.RequestErr)
ctx.Abort()
return
}
sign := params.Get("sign")
params.Del("sign")
sappkey := params.Get("appkey")
secret, ok = business[sappkey]
if !ok {
ctx.JSON(nil, ecode.AppKeyInvalid)
ctx.Abort()
return
}
if hsign := paramsSign(params, sappkey, secret, true); hsign != sign {
if hsign1 := paramsSign(params, sappkey, secret, false); hsign1 != sign {
log.Error("Get sign: %s, expect %s", sign, hsign)
ctx.JSON(nil, ecode.SignCheckErr)
ctx.Abort()
return
}
}
}
// Render .
func Render(c *bm.Context, code int, msg string, data interface{}, total int64, err error) {
c.Error = err
bcode := ecode.Cause(err)
if err != nil {
c.Render(http.StatusOK, render.JSON{
Code: bcode.Code(),
Message: bcode.Message(),
Data: data,
})
return
}
c.Render(http.StatusOK, render.MapJSON{
"code": code,
"message": msg,
"data": data,
"total": total,
})
}
// sign is used to sign form params by given condition.
func paramsSign(params url.Values, appkey string, secret string, lower bool) (hexdigest string) {
data := params.Encode()
if strings.IndexByte(data, '+') > -1 {
data = strings.Replace(data, "+", "%20", -1)
}
if lower {
data = strings.ToLower(data)
}
digest := md5.Sum([]byte(data + secret))
hexdigest = hex.EncodeToString(digest[:])
return
}

View File

@@ -0,0 +1,27 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["bangumi.go"],
importpath = "go-common/app/interface/main/spread/model",
tags = ["automanaged"],
)
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,85 @@
package model
import "encoding/json"
// Bangumi struct
type Bangumi struct {
Actors string `json:"actors,omitempty"`
Akira string `json:"akira,omitempty"`
Alias string `json:"alias,omitempty"`
Country string `json:"country,omitempty"`
CoverImage string `json:"cover_image,omitempty"`
DisplayAddress string `json:"display_address,omitempty"`
DownloadAddress string `json:"download_address,omitempty"`
Duration int64 `json:"duration"`
Episodes []struct {
Index int64 `json:"index"`
PlayURL string `json:"play_url"`
} `json:"episodes"`
Intro string `json:"intro,omitempty"`
Name string `json:"name,omitempty"`
PlayCount int64 `json:"play_count"`
Premieredate string `json:"premieredate,omitempty"`
Season struct {
ID int64 `json:"id"`
Index int64 `json:"index"`
Paymentstatus int64 `json:"paymentstatus"`
Title string `json:"title"`
} `json:"season"`
Staff struct {
AnimationProduction string `json:"animation_production,omitempty"`
AnimationScript string `json:"animation_script,omitempty"`
ArtSupervisor string `json:"art_supervisor,omitempty"`
CharacterDisign string `json:"character_disign,omitempty"`
ChiefContributor string `json:"chief_contributor,omitempty"`
ChiefDirector string `json:"chief_director,omitempty"`
ChiefExecutiveProducer string `json:"chief_executive_producer,omitempty"`
ChiefProducer string `json:"chief_producer,omitempty"`
ChiefProductionManager string `json:"chief_production_manager,omitempty"`
ChiefScenarist string `json:"chief_scenarist,omitempty"`
ColorDesign string `json:"color_design,omitempty"`
Director string `json:"director,omitempty"`
DocumentaryProduction string `json:"documentary_production,omitempty"`
ExecutiveProducer string `json:"executive_producer,omitempty"`
JointProduction string `json:"joint_production,omitempty"`
Music string `json:"music,omitempty"`
OriginalAutor string `json:"original_autor,omitempty"`
OriginalCharacter string `json:"original_character,omitempty"`
PaintingSupervisor string `json:"painting_supervisor,omitempty"`
Performer string `json:"performer,omitempty"`
Produce string `json:"produce,omitempty"`
Producer string `json:"producer,omitempty"`
Production string `json:"production,omitempty"`
ProductionManager string `json:"production_manager,omitempty"`
Publisher string `json:"publisher,omitempty"`
Screenwriter string `json:"screenwriter,omitempty"`
SeriesComposition string `json:"series_composition,omitempty"`
Star string `json:"star,omitempty"`
Storyboard string `json:"storyboard,omitempty"`
Supervisor string `json:"supervisor,omitempty"`
} `json:"staff"`
Type int64 `json:"type"`
}
// BangumiResp .
type BangumiResp struct {
Code int `json:"code"`
Message string `json:"message"`
Result json.RawMessage `json:"result"`
Total int64 `json:"total"`
}
// BangumiOffResp .
type BangumiOffResp struct {
Code int `json:"code"`
Message string `json:"message"`
Total int64 `json:"total"`
Result []*BangumiOff `json:"result"`
}
// BangumiOff .
type BangumiOff struct {
Name string `json:"name"`
Seasonid int64 `json:"seasonid"`
Type int64 `json:"type"`
}

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 = [
"bangumi_test.go",
"service_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/spread/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"bangumi.go",
"service.go",
],
importpath = "go-common/app/interface/main/spread/service",
tags = ["automanaged"],
deps = [
"//app/interface/main/spread/conf:go_default_library",
"//app/interface/main/spread/dao:go_default_library",
"//app/interface/main/spread/model: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,19 @@
package service
import (
"context"
"go-common/app/interface/main/spread/model"
)
// BangumiContent .
func (s *Service) BangumiContent(c context.Context, pn, ps int, typ int8, appkey string) (res model.BangumiResp, err error) {
res, err = s.dao.BangumiContent(c, pn, ps, typ, appkey)
return
}
// BangumiOff .
func (s *Service) BangumiOff(c context.Context, pn, ps int, typ int8, ts int64, appkey string) (res model.BangumiOffResp, err error) {
res, err = s.dao.BangumiOff(c, pn, ps, typ, appkey, ts)
return
}

View File

@@ -0,0 +1,23 @@
package service
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func Test_Bangumi(t *testing.T) {
Convey("bangumi", t, func() {
res, err := s.BangumiContent(c, 1, 10, 1, "douban")
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}
func Test_BangumiOff(t *testing.T) {
Convey("bangumi", t, func() {
res, err := s.BangumiOff(c, 1, 10, 1, 1, "douban")
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
})
}

View File

@@ -0,0 +1,33 @@
package service
import (
"context"
"go-common/app/interface/main/spread/conf"
"go-common/app/interface/main/spread/dao"
)
// Service struct
type Service struct {
c *conf.Config
dao *dao.Dao
}
// New init
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: dao.New(c),
}
return s
}
// Ping Service
func (s *Service) Ping(c context.Context) (err error) {
return s.dao.Ping(c)
}
// Close Service
func (s *Service) Close() {
s.dao.Close()
}

View File

@@ -0,0 +1,23 @@
package service
import (
"context"
"flag"
"path/filepath"
"time"
"go-common/app/interface/main/spread/conf"
)
var (
s *Service
c = context.TODO()
)
func init() {
dir, _ := filepath.Abs("../cmd/convey-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(time.Second)
}