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,95 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"api_test.go",
"biz_test.go",
"dao_test.go",
"fav_test.go",
"history_test.go",
"memcache_test.go",
"music_test.go",
"netsafe_test.go",
"porder_test.go",
"rpc_test.go",
"staff_test.go",
"viewpoint_test.go",
],
embed = [":go_default_library"],
tags = ["automanaged"],
deps = [
"//app/interface/main/creative/conf:go_default_library",
"//app/interface/main/creative/model/archive:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//vendor/github.com/bouk/monkey: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 = [
"api.go",
"biz.go",
"dao.cache.go",
"dao.go",
"fav.go",
"history.go",
"mc.cache.go",
"memcache.go",
"music.go",
"netsafe.go",
"porder.go",
"rpc.go",
"staff.go",
"viewpoint.go",
],
importpath = "go-common/app/interface/main/creative/dao/archive",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/creative/conf:go_default_library",
"//app/interface/main/creative/dao/tool:go_default_library",
"//app/interface/main/creative/model/archive:go_default_library",
"//app/interface/main/creative/model/music: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/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/net/metadata:go_default_library",
"//library/stat/prom:go_default_library",
"//library/sync/pipeline/fanout:go_default_library",
"//library/xstr:go_default_library",
"//vendor/golang.org/x/sync/singleflight: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,390 @@
package archive
import (
"context"
"fmt"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"time"
"go-common/app/interface/main/creative/conf"
"go-common/app/interface/main/creative/dao/tool"
"go-common/app/interface/main/creative/model/archive"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_view = "/videoup/view"
_views = "/videoup/views"
_del = "/videoup/del"
_video = "/videoup/cid"
_archives = "/videoup/up/archives"
_descFormat = "/videoup/desc/format"
_simpleVideos = "/videoup/simplevideos"
_simpleArchive = "/videoup/simplearchive"
_videoJam = "/videoup/video/jam"
_upSpecial = "/x/internal/uper/special"
_flowjudge = "/videoup/flow/list/judge"
_staffApplies = "/videoup/staff/apply/filter"
_staffApply = "/videoup/staff/apply/submit"
_staffCheck = "/videoup/staff/mid/applys"
)
// SimpleArchive fn
func (d *Dao) SimpleArchive(c context.Context, aid int64, ip string) (sa *archive.SpArchive, err error) {
params := url.Values{}
params.Set("aid", strconv.FormatInt(aid, 10))
var res struct {
Code int `json:"code"`
Data *archive.SpArchive `json:"data"`
}
if err = d.client.Get(c, d.simpleArchive, ip, params, &res); err != nil {
log.Error("archive.simpleArchive url(%s) mid(%d) error(%v)", d.simpleArchive+"?"+params.Encode(), aid, err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("archive.simpleArchive url(%s) mid(%d) res(%v)", d.simpleArchive+"?"+params.Encode(), aid, res)
err = ecode.Int(res.Code)
return
}
if res.Data == nil {
log.Error("archive.simpleArchive url(%s) aid(%d) res(%v)", d.simpleVideos+"?"+params.Encode(), aid, res)
return
}
sa = res.Data
return
}
// SimpleVideos fn
func (d *Dao) SimpleVideos(c context.Context, aid int64, ip string) (vs []*archive.SpVideo, err error) {
params := url.Values{}
params.Set("aid", strconv.FormatInt(aid, 10))
var res struct {
Code int `json:"code"`
Data []*archive.SpVideo `json:"data"`
}
if err = d.client.Get(c, d.simpleVideos, ip, params, &res); err != nil {
log.Error("archive.simpleVideos url(%s) mid(%d) error(%v)", d.simpleVideos+"?"+params.Encode(), aid, err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("archive.simpleVideos url(%s) aid(%d) res(%v)", d.simpleVideos+"?"+params.Encode(), aid, res)
err = ecode.Int(res.Code)
return
}
if res.Data == nil {
log.Error("archive.simpleVideos url(%s) aid(%d) res(%v)", d.simpleVideos+"?"+params.Encode(), aid, res)
return
}
vs = res.Data
sort.Slice(vs, func(i, j int) bool {
return vs[i].Index <= vs[j].Index
})
return
}
// View get archive
func (d *Dao) View(c context.Context, mid, aid int64, ip string, needPOI, needVote int) (av *archive.ArcVideo, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("aid", strconv.FormatInt(aid, 10))
params.Set("need_poi", strconv.Itoa(needPOI))
params.Set("need_vote", strconv.Itoa(needVote))
var res struct {
Code int `json:"code"`
Data *archive.ArcVideo `json:"data"`
}
if err = d.client.Get(c, d.view, ip, params, &res); err != nil {
log.Error("archive.view url(%s) mid(%d) error(%v)", d.view+"?"+params.Encode(), mid, err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("archive.view url(%s) mid(%d) res(%v)", d.view+"?"+params.Encode(), mid, res)
err = ecode.Int(res.Code)
return
}
if res.Data.Archive == nil {
log.Error("archive.view url(%s) mid(%d) res(%v)", d.view+"?"+params.Encode(), mid, res)
return
}
if res.Data.Archive.Staffs == nil {
res.Data.Archive.Staffs = []*archive.StaffView{}
}
res.Data.Archive.StateDesc = d.c.StatDesc(int(res.Data.Archive.State))
res.Data.Archive.StatePanel = archive.StatePanel(res.Data.Archive.State)
av = res.Data
return
}
// Views get archives
func (d *Dao) Views(c context.Context, mid int64, aids []int64, ip string) (avm map[int64]*archive.ArcVideo, err error) {
params := url.Values{}
params.Set("aids", xstr.JoinInts(aids))
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data map[string]*archive.ArcVideo `json:"data"`
}
if err = d.client.Get(c, d.views, ip, params, &res); err != nil {
log.Error("archive.views url(%s) mid(%d) error(%v)", d.views+"?"+params.Encode(), mid, err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("archive.views url(%s) mid(%d) res(%v)", d.views+"?"+params.Encode(), mid, res)
err = ecode.Int(res.Code)
return
}
avm = map[int64]*archive.ArcVideo{}
for aidStr, av := range res.Data {
var err error
aid, err := strconv.ParseInt(aidStr, 10, 64)
if err != nil {
log.Error("strconv.ParseInt(%s) error(%v)", aidStr, err)
continue
}
av.Archive.StateDesc = d.c.StatDesc(int(av.Archive.State))
av.Archive.StatePanel = archive.StatePanel(av.Archive.State)
avm[aid] = av
}
return
}
// Del delete archive.
func (d *Dao) Del(c context.Context, mid, aid int64, ip string) (err error) {
params := url.Values{}
params.Set("appkey", conf.Conf.App.Key)
params.Set("appsecret", conf.Conf.App.Secret)
params.Set("ts", strconv.FormatInt(time.Now().Unix(), 10))
// uri
var (
query, _ = tool.Sign(params)
uri = d.del + "?" + query
)
// new request
req, err := http.NewRequest("POST", uri, strings.NewReader(fmt.Sprintf(`{"mid":%d,"aid":%d}`, mid, aid)))
if err != nil {
log.Error("http.NewRequest(%s) error(%v); mid(%d), aid(%d), ip(%s)", d.del, err, mid, aid, ip)
err = ecode.CreativeArchiveAPIErr
return
}
req.Header.Set("X-BACKEND-BILI-REAL-IP", ip)
var res struct {
Code int `json:"code"`
}
if err = d.client.Do(c, req, &res); err != nil {
log.Error("d.client.Do(%s) error(%v); mid(%d), aid(%d), ip(%s)", d.del, err, mid, aid, ip)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("del archive url(%s) res(%v); mid(%d), aid(%d), ip(%s)", d.del, res, mid, aid, ip)
return
}
return
}
// VideoByCid get videos by cids.
func (d *Dao) VideoByCid(c context.Context, cid int64, ip string) (v *archive.Video, err error) {
params := url.Values{}
params.Set("cid", strconv.FormatInt(cid, 10))
var res struct {
Code int `json:"code"`
Data *archive.Video `json:"data"`
}
if err = d.client.Get(c, d.video, ip, params, &res); err != nil {
log.Error("VideoByCid cidURI(%s) error(%v)", d.video+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
err = ecode.Int(res.Code)
log.Error("VideoByCid cidURI(%s) Code=(%d)", d.video+"?"+params.Encode(), res.Code)
return
}
v = res.Data
return
}
// UpArchives get archives by mid.
func (d *Dao) UpArchives(c context.Context, mid, pn, ps, group int64, ip string) (aids []int64, count int64, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("pn", strconv.FormatInt(pn, 10))
params.Set("ps", strconv.FormatInt(ps, 10))
params.Set("group", strconv.FormatInt(mid, 10)) //0:全部稿件1:开放稿件2:未开放稿件
var res struct {
Code int `json:"code"`
Data struct {
Aids []int64 `json:"aids"`
Count int64 `json:"count"`
} `json:"data"`
}
if err = d.client.Get(c, d.upArchives, ip, params, &res); err != nil {
log.Error("upArchives URI(%s) error(%v)", d.upArchives+"?"+params.Encode(), err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("upArchives URI(%s) Code=(%d)", d.upArchives+"?"+params.Encode(), res.Code)
err = ecode.Int(res.Code)
return
}
aids = res.Data.Aids
count = res.Data.Count
return
}
// DescFormat get desc format by typeid and copyright
func (d *Dao) DescFormat(c context.Context) (descs []*archive.DescFormat, err error) {
params := url.Values{}
var res struct {
Code int `json:"code"`
Message string `json:"message"`
Data []*archive.DescFormat `json:"data"`
}
descs = []*archive.DescFormat{}
if err = d.client.Get(c, d.descFormat, "", params, &res); err != nil {
log.Error("videoup descFormat error(%v) | descFormat(%s) params(%v)", err, d.descFormat+"?"+params.Encode(), params)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("videoup descFormat res.Code(%d) | descFormat(%s)params(%v) res(%v)", res.Code, d.descFormat+"?"+params.Encode(), params, res)
err = ecode.Int(res.Code)
return
}
descs = res.Data
log.Info("res.Code(%d) descFormat(%s) params(%v)", res.Code, d.descFormat+"?"+params.Encode(), params)
return
}
// VideoJam get video-check traffic jam level
func (d *Dao) VideoJam(c context.Context, ip string) (level int8, err error) {
params := url.Values{}
var res struct {
Code int `json:"code"`
Data *struct {
Level int8 `json:"level"`
} `json:"data"`
}
if err = d.client.Get(c, d.videoJam, ip, params, &res); err != nil {
log.Error("archive.VideoJam url(%s) error(%v)", d.videoJam+"?"+params.Encode(), err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("archive.VideoJam url(%s) res(%v)", d.videoJam+"?"+params.Encode(), res)
err = ecode.Int(res.Code)
return
}
if res.Data == nil {
log.Error("archive.VideoJam url(%s) res(%v)", d.videoJam+"?"+params.Encode(), res)
return
}
level = res.Data.Level
return
}
// FlowJudge fn
func (d *Dao) FlowJudge(c context.Context, business, groupID int64, oids []int64) (hitOids []int64, err error) {
params := url.Values{}
params.Set("business", strconv.FormatInt(business, 10))
params.Set("gid", strconv.FormatInt(groupID, 10))
params.Set("oids", xstr.JoinInts(oids))
var res struct {
Code int `json:"code"`
Message string `json:"message"`
Data []int64 `json:"data"`
}
if err = d.client.Get(c, d.flowJudge, "", params, &res); err != nil {
log.Error("archive.FlowJudge url(%s) error(%v)", d.upSpecialURL+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("FlowJudge api url(%s) res(%v) code(%d)", d.upSpecialURL, res, res.Code)
err = ecode.CreativeArchiveAPIErr
return
}
hitOids = res.Data
return
}
// StaffApplies fn
func (d *Dao) StaffApplies(c context.Context, staffMid int64, aids []int64) (apply []*archive.StaffApply, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(staffMid, 10))
params.Set("aids", xstr.JoinInts(aids))
var res struct {
Code int `json:"code"`
Message string `json:"message"`
Data []*archive.StaffApply `json:"data"`
}
if err = d.client.Get(c, d.staffApplies, "", params, &res); err != nil {
log.Error("archive.staffApplies url(%s) error(%v)", d.staffApplies+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("staffApplies api url(%s) res(%v) code(%d)", d.staffApplies, res, res.Code)
err = ecode.CreativeArchiveAPIErr
return
}
apply = res.Data
return
}
// StaffMidValidate fn
func (d *Dao) StaffMidValidate(c context.Context, mid int64) (data int, err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Message string `json:"message"`
Data int `json:"data"`
}
if err = d.client.Get(c, d.staffCheck, "", params, &res); err != nil {
log.Error("archive.StaffMidValidate url(%s) error(%v)", d.staffCheck+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("StaffMidValidate api url(%s) res(%v) code(%d)", d.staffCheck, res, res.Code)
err = ecode.Int(res.Code)
return
}
data = res.Data
return
}
// StaffApplySubmit fn
func (d *Dao) StaffApplySubmit(c context.Context, id, aid, mid, state, atype int64, flagAddBlack, flagRefuse int) (err error) {
params := url.Values{}
params.Set("id", strconv.FormatInt(id, 10))
params.Set("state", strconv.FormatInt(state, 10))
params.Set("type", strconv.FormatInt(atype, 10))
params.Set("apply_aid", strconv.FormatInt(aid, 10))
params.Set("apply_staff_mid", strconv.FormatInt(mid, 10))
params.Set("flag_add_black", strconv.Itoa(flagAddBlack))
params.Set("flag_refuse", strconv.Itoa(flagRefuse))
var res struct {
Code int `json:"code"`
Message string `json:"message"`
}
if err = d.client.Post(c, d.staffApply, "", params, &res); err != nil {
log.Error("archive.StaffApplySubmit url(%s) error(%v)", d.staffApply+"?"+params.Encode(), err)
return
}
if res.Code != 0 {
log.Error("StaffApplySubmit api url(%s) res(%v) code(%d)", d.staffApply, res, res.Code)
err = ecode.Int(res.Code)
return
}
return
}

View File

@@ -0,0 +1,256 @@
package archive
import (
"context"
"encoding/json"
"go-common/app/interface/main/creative/model/archive"
"go-common/library/ecode"
"testing"
"github.com/smartystreets/goconvey/convey"
gock "gopkg.in/h2non/gock.v1"
)
func TestFlowJudge(t *testing.T) {
var (
c = context.TODO()
err error
business = int64(1)
groupID = int64(2)
oids = []int64{1, 2, 3}
hitOids []int64
)
convey.Convey("FlowJudge", t, func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.flowJudge).Reply(200).JSON(`{"code":20001}`)
hitOids, err = d.FlowJudge(c, business, groupID, oids)
ctx.Convey("Then err should be nil.hitOids should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(hitOids, convey.ShouldBeNil)
})
})
}
func TestArchiveSimpleArchive(t *testing.T) {
var (
c = context.TODO()
aid = int64(10110817)
ip = "127.0.0.1"
err error
sa *archive.SpArchive
res struct {
Code int `json:"code"`
Data *archive.SpArchive `json:"data"`
}
)
convey.Convey("4", t, func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.simpleArchive).Reply(-502)
sa, err = d.SimpleArchive(c, aid, ip)
ctx.Convey("Then err should be nil.sa should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(err, convey.ShouldEqual, ecode.CreativeArchiveAPIErr)
ctx.So(sa, convey.ShouldBeNil)
})
})
convey.Convey("1", t, func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.simpleArchive).Reply(200).JSON(`{"code":20001}`)
sa, err = d.SimpleArchive(c, aid, ip)
ctx.Convey("Then err should be nil.sa should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(err, convey.ShouldEqual, ecode.CreativeArchiveAPIErr)
ctx.So(sa, convey.ShouldBeNil)
})
})
convey.Convey("2", t, func(ctx convey.C) {
res.Code = 0
res.Data = &archive.SpArchive{
Aid: aid,
Title: "iamtitle",
Mid: 2089809,
}
js, _ := json.Marshal(res)
defer gock.OffAll()
httpMock("GET", d.simpleArchive).Reply(200).JSON(string(js))
sa, err = d.SimpleArchive(c, aid, ip)
ctx.Convey("Then err should be nil.sa should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(sa, convey.ShouldNotBeNil)
})
})
convey.Convey("3", t, func(ctx convey.C) {
res.Code = 0
res.Data = nil
js, _ := json.Marshal(res)
defer gock.OffAll()
httpMock("GET", d.simpleArchive).Reply(200).JSON(string(js))
sa, err = d.SimpleArchive(c, aid, ip)
ctx.Convey("Then err should be nil.sa should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(sa, convey.ShouldBeNil)
})
})
}
func TestArchiveSimpleVideos(t *testing.T) {
var (
c = context.TODO()
aid = int64(10110817)
ip = "127.0.0.1"
res struct {
Code int `json:"code"`
Data []*archive.SpVideo `json:"data"`
}
)
convey.Convey("1", t, func(ctx convey.C) {
defer gock.OffAll()
js, _ := json.Marshal(res)
httpMock("GET", d.simpleVideos).Reply(200).JSON(string(js))
vs, err := d.SimpleVideos(c, aid, ip)
ctx.Convey("Then err should be nil.vs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(vs, convey.ShouldBeNil)
})
})
convey.Convey("2", t, func(ctx convey.C) {
defer gock.OffAll()
res.Code = 20001
res.Data = nil
js, _ := json.Marshal(res)
httpMock("GET", d.simpleVideos).Reply(200).JSON(string(js))
vs, err := d.SimpleVideos(c, aid, ip)
ctx.Convey("Then err should be nil.vs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(vs, convey.ShouldBeNil)
})
})
convey.Convey("3", t, func(ctx convey.C) {
defer gock.OffAll()
res.Code = 0
res.Data = append(res.Data, &archive.SpVideo{
Cid: 1,
Index: 1,
Title: "1title",
}, &archive.SpVideo{
Cid: 2,
Index: 2,
Title: "2title",
})
js, _ := json.Marshal(res)
httpMock("GET", d.simpleVideos).Reply(200).JSON(string(js))
vs, err := d.SimpleVideos(c, aid, ip)
ctx.Convey("Then err should be nil.vs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(vs, convey.ShouldNotBeNil)
})
})
}
func TestArchiveView(t *testing.T) {
var (
c = context.TODO()
mid = int64(2089809)
aid = int64(10110817)
ip = "127.0.0.1"
)
convey.Convey("View", t, func(ctx convey.C) {
av, err := d.View(c, mid, aid, ip, 0, 0)
ctx.Convey("Then err should be nil.av should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(av, convey.ShouldNotBeNil)
})
})
}
func TestArchiveViews(t *testing.T) {
var (
c = context.TODO()
mid = int64(2089809)
aids = []int64{10110817, 10110816}
ip = "127.0.0.1"
)
convey.Convey("Views", t, func(ctx convey.C) {
avm, err := d.Views(c, mid, aids, ip)
ctx.Convey("Then err should be nil.avm should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(avm, convey.ShouldNotBeNil)
})
})
}
func TestArchiveDel(t *testing.T) {
var (
c = context.TODO()
mid = int64(2089809)
aid = int64(10110817)
ip = "127.0.0.1"
)
convey.Convey("Del", t, func(ctx convey.C) {
err := d.Del(c, mid, aid, ip)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldEqual, ecode.ArchiveAlreadyDel)
})
})
}
func TestArchiveVideoByCid(t *testing.T) {
var (
c = context.TODO()
cid = int64(10134702)
ip = "127.0.0.1"
)
convey.Convey("VideoByCid", t, func(ctx convey.C) {
v, err := d.VideoByCid(c, cid, ip)
ctx.Convey("Then err should be nil.v should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(v, convey.ShouldNotBeNil)
})
})
}
func TestArchiveUpArchives(t *testing.T) {
var (
c = context.TODO()
mid = int64(2089809)
pn = int64(1)
ps = int64(10)
group = int64(0)
ip = "127.0.0.1"
)
convey.Convey("UpArchives", t, func(ctx convey.C) {
aids, count, err := d.UpArchives(c, mid, pn, ps, group, ip)
ctx.Convey("Then err should be nil.aids,count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
ctx.So(aids, convey.ShouldNotBeNil)
})
})
}
func TestArchiveDescFormat(t *testing.T) {
var (
c = context.TODO()
)
convey.Convey("DescFormat", t, func(ctx convey.C) {
descs, err := d.DescFormat(c)
ctx.Convey("Then err should be nil.descs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(descs, convey.ShouldNotBeNil)
})
})
}
func TestArchiveVideoJam(t *testing.T) {
var (
c = context.TODO()
ip = "127.0.0.1"
)
convey.Convey("VideoJam", t, func(ctx convey.C) {
level, err := d.VideoJam(c, ip)
ctx.Convey("Then err should be nil.level should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(level, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,34 @@
package archive
import (
"context"
"time"
model "go-common/app/interface/main/creative/model/archive"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
_bizsByTimeSQL = "SELECT aid,type,ctime FROM archive_biz WHERE mtime >= ? AND mtime < ? AND type = ? ORDER BY mtime"
)
// BIZsByTime list businesses by time and type
func (d *Dao) BIZsByTime(c context.Context, start, end *time.Time, tp int8) (bizs []*model.BIZ, err error) {
var rows *sql.Rows
if rows, err = d.db.Query(c, _bizsByTimeSQL, start, end, tp); err != nil {
log.Error("d.db.Query error(%v)", err)
return
}
defer rows.Close()
bizs = []*model.BIZ{}
for rows.Next() {
var b = new(model.BIZ)
if err = rows.Scan(&b.Aid, &b.Type, &b.Ctime); err != nil {
log.Error("row.Scan error(%v)", err)
return
}
bizs = append(bizs, b)
}
return
}

View File

@@ -0,0 +1,27 @@
package archive
import (
"context"
"testing"
"time"
"github.com/smartystreets/goconvey/convey"
)
func TestArchiveBIZsByTime(t *testing.T) {
convey.Convey("BIZsByTime", t, func(ctx convey.C) {
var (
c = context.Background()
start = &time.Time{}
end = &time.Time{}
tp = int8(0)
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
bizs, err := d.BIZsByTime(c, start, end, tp)
ctx.Convey("Then err should be nil.bizs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(bizs, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,94 @@
// Code generated by $GOPATH/src/go-common/app/tool/cache/gen. DO NOT EDIT.
/*
Package archive is a generated cache proxy package.
It is generated from:
type _cache interface {
// cache: -singleflight=true -nullcache=[]*arcMdl.Staff{{ID:-1}} -check_null_code=len($)==1&&$[0].ID==-1
StaffData(c context.Context, aid int64) ([]*arcMdl.Staff, error)
ViewPoint(c context.Context, aid int64, cid int64) (vp *arcMdl.ViewPointRow, err error)
}
*/
package archive
import (
"context"
arcMdl "go-common/app/interface/main/creative/model/archive"
"go-common/library/net/metadata"
"go-common/library/stat/prom"
"golang.org/x/sync/singleflight"
)
var _ _cache
var cacheSingleFlights = [1]*singleflight.Group{{}}
// StaffData get data from cache if miss will call source method, then add to cache.
func (d *Dao) StaffData(c context.Context, id int64) (res []*arcMdl.Staff, err error) {
addCache := true
res, err = d.CacheStaffData(c, id)
if err != nil {
addCache = false
err = nil
}
defer func() {
if len(res) == 1 && res[0].ID == -1 {
res = nil
}
}()
if len(res) != 0 {
prom.CacheHit.Incr("StaffData")
return
}
var rr interface{}
sf := d.cacheSFStaffData(id)
rr, err, _ = cacheSingleFlights[0].Do(sf, func() (r interface{}, e error) {
prom.CacheMiss.Incr("StaffData")
r, e = d.RawStaffData(c, id)
return
})
res = rr.([]*arcMdl.Staff)
if err != nil {
return
}
miss := res
if len(miss) == 0 {
miss = []*arcMdl.Staff{{ID: -1}}
}
if !addCache {
return
}
d.cache.Do(c, func(c context.Context) {
d.AddCacheStaffData(metadata.WithContext(c), id, miss)
})
return
}
// ViewPoint cache: -singleflight=true -nullcache=[]*arcMdl.Staff{{ID:-1}} -check_null_code=len($)==1&&$[0].ID==-1
func (d *Dao) ViewPoint(c context.Context, id int64, cid int64) (res *arcMdl.ViewPointRow, err error) {
addCache := true
res, err = d.CacheViewPoint(c, id, cid)
if err != nil {
addCache = false
err = nil
}
if res != nil {
prom.CacheHit.Incr("ViewPoint")
return
}
prom.CacheMiss.Incr("ViewPoint")
res, err = d.RawViewPoint(c, id, cid)
if err != nil {
return
}
miss := res
if !addCache {
return
}
d.cache.Do(c, func(c context.Context) {
d.AddCacheViewPoint(metadata.WithContext(c), id, miss, cid)
})
return
}

View File

@@ -0,0 +1,143 @@
package archive
import (
"context"
"time"
"fmt"
"go-common/app/interface/main/creative/conf"
arcMdl "go-common/app/interface/main/creative/model/archive"
archive "go-common/app/service/main/archive/api/gorpc"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/database/sql"
bm "go-common/library/net/http/blademaster"
"go-common/library/sync/pipeline/fanout"
)
// Dao is archive dao.
type Dao struct {
// config
c *conf.Config
// rpc
arc *archive.Service2
// select
client *bm.Client
// db
db *sql.DB
// mc
mc *memcache.Pool
mcExpire int32
//cache tool
cache *fanout.Fanout
// redis
redis *redis.Pool
redisExpire int32
// uri
view string
views string
del string
video string
hList string
hView string
flow string
upArchives string
descFormat string
nsMd5 string
simpleVideos string
simpleArchive string
videoJam string
upSpecialURL string
flowJudge string
staffApplies string
staffApply string
staffCheck string
}
// New init api url
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
arc: archive.New2(c.ArchiveRPC),
// http client
client: bm.NewClient(c.HTTPClient.Normal),
// db
db: sql.NewMySQL(c.DB.Archive),
cache: fanout.New("dao_archive", fanout.Worker(5), fanout.Buffer(10240)),
// mc
mc: memcache.NewPool(c.Memcache.Archive.Config),
mcExpire: 600,
//Fav redis cache
redis: redis.NewPool(c.Redis.Cover.Config),
redisExpire: int32(time.Duration(c.Redis.Cover.Expire) / time.Second),
// uri
view: c.Host.Videoup + _view,
views: c.Host.Videoup + _views,
video: c.Host.Videoup + _video,
del: c.Host.Videoup + _del,
hList: c.Host.Videoup + _hList,
hView: c.Host.Videoup + _hView,
flow: c.Host.Videoup + _flow,
upArchives: c.Host.Videoup + _archives,
descFormat: c.Host.Videoup + _descFormat,
nsMd5: c.Host.Videoup + _nsMd5,
simpleVideos: c.Host.Videoup + _simpleVideos,
simpleArchive: c.Host.Videoup + _simpleArchive,
videoJam: c.Host.Videoup + _videoJam,
upSpecialURL: c.Host.API + _upSpecial,
flowJudge: c.Host.Videoup + _flowjudge,
staffApplies: c.Host.Videoup + _staffApplies,
staffApply: c.Host.Videoup + _staffApply,
staffCheck: c.Host.Videoup + _staffCheck,
}
return
}
// Ping fn
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.pingRedis(c); err != nil {
return
}
return
}
// Close fn
func (d *Dao) Close() (err error) {
if d.redis != nil {
d.redis.Close()
}
if d.mc != nil {
d.mc.Close()
}
return d.db.Close()
}
func staffKey(aid int64) string {
return fmt.Sprintf("staff_aid_%d", aid)
}
func (d *Dao) cacheSFStaffData(aid int64) string {
return fmt.Sprintf("staff_aid_sf_%d", aid)
}
//go:generate $GOPATH/src/go-common/app/tool/cache/gen
type _cache interface {
// cache: -singleflight=true -nullcache=[]*arcMdl.Staff{{ID:-1}} -check_null_code=len($)==1&&$[0].ID==-1
StaffData(c context.Context, aid int64) ([]*arcMdl.Staff, error)
ViewPoint(c context.Context, aid int64, cid int64) (vp *arcMdl.ViewPointRow, err error)
}
//go:generate $GOPATH/src/go-common/app/tool/cache/mc
type _mc interface {
// mc: -key=staffKey
CacheStaffData(c context.Context, key int64) ([]*arcMdl.Staff, error)
// 这里也支持自定义注释 会替换默认的注释
// mc: -key=staffKey -expire=3 -encode=json|gzip
AddCacheStaffData(c context.Context, key int64, value []*arcMdl.Staff) error
// mc: -key=staffKey
DelCacheStaffData(c context.Context, key int64) error
//mc: -key=viewPointCacheKey -expire=_viewPointExp -encode=json
AddCacheViewPoint(c context.Context, aid int64, vp *arcMdl.ViewPointRow, cid int64) (err error)
//mc: -key=viewPointCacheKey
CacheViewPoint(c context.Context, aid int64, cid int64) (vp *arcMdl.ViewPointRow, err error)
}

View File

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

View File

@@ -0,0 +1,34 @@
package archive
import (
"context"
"strconv"
"go-common/library/cache/redis"
"go-common/library/log"
)
const (
_upFavTpsPrefix = "up_fav_tps_"
)
func keyUpFavTpsPrefix(mid int64) string {
return _upFavTpsPrefix + strconv.FormatInt(mid, 10)
}
// FavTypes fn
func (d *Dao) FavTypes(c context.Context, mid int64) (items map[string]int64, err error) {
conn := d.redis.Get(c)
defer conn.Close()
if items, err = redis.Int64Map(conn.Do("ZRANGE", keyUpFavTpsPrefix(mid), "0", "-1", "WITHSCORES")); err != nil {
log.Error("redis.Int64Map(conn.Do(ZRANGE, %s, 0, -1)) error(%v)", keyUpFavTpsPrefix(mid), err)
}
return
}
func (d *Dao) pingRedis(c context.Context) (err error) {
conn := d.redis.Get(c)
_, err = conn.Do("SET", "PING", "PONG")
conn.Close()
return
}

View File

@@ -0,0 +1,59 @@
package archive
import (
"context"
"errors"
"reflect"
"testing"
"go-common/library/cache/redis"
"github.com/bouk/monkey"
"github.com/smartystreets/goconvey/convey"
)
var (
errConnClosed = errors.New("redigo: connection closed")
)
func TestArchivekeyUpFavTpsPrefix(t *testing.T) {
var (
mid = int64(888952460)
)
convey.Convey("keyUpFavTpsPrefix", t, func(ctx convey.C) {
p1 := keyUpFavTpsPrefix(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestArchiveFavTypes(t *testing.T) {
var (
c = context.TODO()
mid = int64(888952460)
)
convey.Convey("FavTypes", t, func(ctx convey.C) {
connGuard := monkey.PatchInstanceMethod(reflect.TypeOf(d.redis), "Get", func(_ *redis.Pool, _ context.Context) redis.Conn {
return redis.MockWith(errConnClosed)
})
defer connGuard.Unpatch()
items, err := d.FavTypes(c, mid)
ctx.Convey("Then err should be nil.items should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(items, convey.ShouldBeNil)
})
})
}
func TestArchivepingRedis(t *testing.T) {
var (
c = context.TODO()
)
convey.Convey("pingRedis", t, func(ctx convey.C) {
err := d.pingRedis(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,62 @@
package archive
import (
"context"
"net/url"
"strconv"
"go-common/app/interface/main/creative/model/archive"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_hList = "/videoup/history/list"
_hView = "/videoup/history/view"
)
// HistoryList get the history of aid
func (d *Dao) HistoryList(c context.Context, mid, aid int64, ip string) (historys []*archive.ArcHistory, err error) {
params := url.Values{}
params.Set("aid", strconv.FormatInt(aid, 10))
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data []*archive.ArcHistory `json:"data"`
}
if err = d.client.Get(c, d.hList, ip, params, &res); err != nil {
log.Error("archive.HistoryList url(%s) mid(%d) error(%v)", d.hList+"?"+params.Encode(), mid, err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("archive.HistoryList url(%s) mid(%d) res(%v)", d.hList+"?"+params.Encode(), mid, res)
err = ecode.CreativeArchiveAPIErr
return
}
historys = res.Data
return
}
// HistoryView get the history of hid
func (d *Dao) HistoryView(c context.Context, mid, hid int64, ip string) (history *archive.ArcHistory, err error) {
params := url.Values{}
params.Set("hid", strconv.FormatInt(hid, 10))
params.Set("mid", strconv.FormatInt(mid, 10))
var res struct {
Code int `json:"code"`
Data *archive.ArcHistory `json:"data"`
}
if err = d.client.Get(c, d.hView, ip, params, &res); err != nil {
log.Error("archive.HistoryView url(%s) mid(%d) error(%v)", d.hView+"?"+params.Encode(), mid, err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("archive.HistoryView url(%s) mid(%d) res(%v)", d.hView+"?"+params.Encode(), mid, res)
err = ecode.CreativeArchiveAPIErr
return
}
history = res.Data
return
}

View File

@@ -0,0 +1,45 @@
package archive
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
gock "gopkg.in/h2non/gock.v1"
)
func TestArchiveHistoryList(t *testing.T) {
var (
c = context.TODO()
mid = int64(888952460)
aid = int64(10110560)
ip = "127.0.0.1"
)
convey.Convey("HistoryList", t, func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.hList).Reply(200).JSON(`{"code":20001}`)
historys, err := d.HistoryList(c, mid, aid, ip)
ctx.Convey("Then err should be nil.historys should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(historys, convey.ShouldBeNil)
})
})
}
func TestArchiveHistoryView(t *testing.T) {
var (
c = context.TODO()
mid = int64(888952460)
hid = int64(0)
ip = "127.0.0.1"
)
convey.Convey("HistoryView", t, func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.hView).Reply(200).JSON(`{"code":20001}`)
history, err := d.HistoryView(c, mid, hid, ip)
ctx.Convey("Then err should be nil.history should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(history, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,134 @@
// Code generated by $GOPATH/src/go-common/app/tool/cache/mc. DO NOT EDIT.
/*
Package archive is a generated mc cache package.
It is generated from:
type _mc interface {
// mc: -key=staffKey
CacheStaffData(c context.Context, key int64) ([]*arcMdl.Staff, error)
// 这里也支持自定义注释 会替换默认的注释
// mc: -key=staffKey -expire=3 -encode=json|gzip
AddCacheStaffData(c context.Context, key int64, value []*arcMdl.Staff) error
// mc: -key=staffKey
DelCacheStaffData(c context.Context, key int64) error
//mc: -key=viewPointCacheKey -expire=_viewPointExp -encode=json
AddCacheViewPoint(c context.Context, aid int64, vp *arcMdl.ViewPointRow, cid int64) (err error)
//mc: -key=viewPointCacheKey
CacheViewPoint(c context.Context, aid int64, cid int64) (vp *arcMdl.ViewPointRow, err error)
}
*/
package archive
import (
"context"
"fmt"
arcMdl "go-common/app/interface/main/creative/model/archive"
"go-common/library/cache/memcache"
"go-common/library/log"
"go-common/library/stat/prom"
)
var _ _mc
// CacheStaffData get data from mc
func (d *Dao) CacheStaffData(c context.Context, id int64) (res []*arcMdl.Staff, err error) {
conn := d.mc.Get(c)
defer conn.Close()
key := staffKey(id)
reply, err := conn.Get(key)
if err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
prom.BusinessErrCount.Incr("mc:CacheStaffData")
log.Errorv(c, log.KV("CacheStaffData", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
res = []*arcMdl.Staff{}
err = conn.Scan(reply, &res)
if err != nil {
prom.BusinessErrCount.Incr("mc:CacheStaffData")
log.Errorv(c, log.KV("CacheStaffData", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
return
}
// AddCacheStaffData 这里也支持自定义注释 会替换默认的注释
func (d *Dao) AddCacheStaffData(c context.Context, id int64, val []*arcMdl.Staff) (err error) {
if len(val) == 0 {
return
}
conn := d.mc.Get(c)
defer conn.Close()
key := staffKey(id)
item := &memcache.Item{Key: key, Object: val, Expiration: 3, Flags: memcache.FlagJSON | memcache.FlagGzip}
if err = conn.Set(item); err != nil {
prom.BusinessErrCount.Incr("mc:AddCacheStaffData")
log.Errorv(c, log.KV("AddCacheStaffData", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
return
}
// DelCacheStaffData delete data from mc
func (d *Dao) DelCacheStaffData(c context.Context, id int64) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
key := staffKey(id)
if err = conn.Delete(key); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
prom.BusinessErrCount.Incr("mc:DelCacheStaffData")
log.Errorv(c, log.KV("DelCacheStaffData", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
return
}
// AddCacheViewPoint Set data to mc
func (d *Dao) AddCacheViewPoint(c context.Context, id int64, val *arcMdl.ViewPointRow, cid int64) (err error) {
if val == nil {
return
}
conn := d.mc.Get(c)
defer conn.Close()
key := viewPointCacheKey(id, cid)
item := &memcache.Item{Key: key, Object: val, Expiration: _viewPointExp, Flags: memcache.FlagJSON}
if err = conn.Set(item); err != nil {
prom.BusinessErrCount.Incr("mc:AddCacheViewPoint")
log.Errorv(c, log.KV("AddCacheViewPoint", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
return
}
// CacheViewPoint get data from mc
func (d *Dao) CacheViewPoint(c context.Context, id int64, cid int64) (res *arcMdl.ViewPointRow, err error) {
conn := d.mc.Get(c)
defer conn.Close()
key := viewPointCacheKey(id, cid)
reply, err := conn.Get(key)
if err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
prom.BusinessErrCount.Incr("mc:CacheViewPoint")
log.Errorv(c, log.KV("CacheViewPoint", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
res = &arcMdl.ViewPointRow{}
err = conn.Scan(reply, res)
if err != nil {
prom.BusinessErrCount.Incr("mc:CacheViewPoint")
log.Errorv(c, log.KV("CacheViewPoint", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
return
}

View File

@@ -0,0 +1,113 @@
package archive
import (
"context"
"crypto/md5"
"encoding/hex"
"strconv"
arcmdl "go-common/app/interface/main/creative/model/archive"
"go-common/library/cache/memcache"
"go-common/library/log"
)
const (
_prefix = "porder_"
_cmPrefix = "arccm_"
_addMidAndTitlePrefix = "add_midtitle_"
)
func limitMidSameTitle(mid int64, title string) string {
ms := md5.Sum([]byte(title))
return _addMidAndTitlePrefix + strconv.FormatInt(mid, 10) + "_" + hex.EncodeToString(ms[:])
}
func keyPorder(aid int64) string {
return _prefix + strconv.FormatInt(aid, 10)
}
func keyArcCM(aid int64) string {
return _cmPrefix + strconv.FormatInt(aid, 10)
}
// POrderCache get stat cache.
func (d *Dao) POrderCache(c context.Context, aid int64) (st *arcmdl.Porder, err error) {
var (
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
r, err = conn.Get(keyPorder(aid))
if err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
log.Error("conn.Get2(%d) error(%v)", aid, err)
}
return
}
if err = conn.Scan(r, &st); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", r.Value, err)
st = nil
}
return
}
// AddPOrderCache add stat cache.
func (d *Dao) AddPOrderCache(c context.Context, aid int64, st *arcmdl.Porder) (err error) {
var (
key = keyPorder(aid)
)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: st, Flags: memcache.FlagJSON, Expiration: d.mcExpire}); err != nil {
log.Error("memcache.Set(%v) error(%v)", key, err)
}
return
}
// ArcCMCache get stat cache.
func (d *Dao) ArcCMCache(c context.Context, aid int64) (st *arcmdl.Commercial, err error) {
var (
conn = d.mc.Get(c)
r *memcache.Item
)
defer conn.Close()
r, err = conn.Get(keyArcCM(aid))
if err != nil {
if err == memcache.ErrNotFound {
err = nil
} else {
log.Error("conn.Get2(%d) error(%v)", aid, err)
}
return
}
if err = conn.Scan(r, &st); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", r.Value, err)
st = nil
}
return
}
// AddArcCMCache add stat cache.
func (d *Dao) AddArcCMCache(c context.Context, aid int64, st *arcmdl.Commercial) (err error) {
var (
key = keyArcCM(aid)
)
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: st, Flags: memcache.FlagJSON, Expiration: d.mcExpire}); err != nil {
log.Error("memcache.Set(%v) error(%v)", key, err)
}
return
}
// DelSubmitCache func
func (d *Dao) DelSubmitCache(c context.Context, mid int64, title string) (err error) {
conn := d.mc.Get(c)
defer conn.Close()
if err = conn.Delete(limitMidSameTitle(mid, title)); err == memcache.ErrNotFound {
err = nil
}
return
}

View File

@@ -0,0 +1,108 @@
package archive
import (
"context"
arcmdl "go-common/app/interface/main/creative/model/archive"
"go-common/library/cache/memcache"
"reflect"
"testing"
"github.com/bouk/monkey"
"github.com/smartystreets/goconvey/convey"
)
func TestArchivekeyPorder(t *testing.T) {
var (
aid = int64(10110560)
)
convey.Convey("keyPorder", t, func(ctx convey.C) {
p1 := keyPorder(aid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestArchivekeyArcCM(t *testing.T) {
var (
aid = int64(10110560)
)
convey.Convey("keyArcCM", t, func(ctx convey.C) {
p1 := keyArcCM(aid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestArchivePOrderCache(t *testing.T) {
var (
c = context.TODO()
aid = int64(10110560)
)
convey.Convey("POrderCache", t, func(ctx convey.C) {
connGuard := monkey.PatchInstanceMethod(reflect.TypeOf(d.mc), "Get", func(_ *memcache.Pool, _ context.Context) memcache.Conn {
return memcache.MockWith(memcache.ErrNotFound)
})
defer connGuard.Unpatch()
st, err := d.POrderCache(c, aid)
ctx.Convey("Then err should be nil.st should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(st, convey.ShouldBeNil)
})
})
}
func TestArchiveAddPOrderCache(t *testing.T) {
var (
c = context.TODO()
aid = int64(10110560)
st = &arcmdl.Porder{}
)
convey.Convey("AddPOrderCache", t, func(ctx convey.C) {
connGuard := monkey.PatchInstanceMethod(reflect.TypeOf(d.mc), "Get", func(_ *memcache.Pool, _ context.Context) memcache.Conn {
return memcache.MockWith(memcache.ErrNotFound)
})
defer connGuard.Unpatch()
err := d.AddPOrderCache(c, aid, st)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
}
func TestArchiveArcCMCache(t *testing.T) {
var (
c = context.TODO()
aid = int64(10110560)
)
convey.Convey("ArcCMCache", t, func(ctx convey.C) {
connGuard := monkey.PatchInstanceMethod(reflect.TypeOf(d.mc), "Get", func(_ *memcache.Pool, _ context.Context) memcache.Conn {
return memcache.MockWith(memcache.ErrNotFound)
})
defer connGuard.Unpatch()
st, err := d.ArcCMCache(c, aid)
ctx.Convey("Then err should be nil.st should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(st, convey.ShouldBeNil)
})
})
}
func TestArchiveAddArcCMCache(t *testing.T) {
var (
c = context.TODO()
aid = int64(10110560)
st = &arcmdl.Commercial{}
)
convey.Convey("AddArcCMCache", t, func(ctx convey.C) {
connGuard := monkey.PatchInstanceMethod(reflect.TypeOf(d.mc), "Get", func(_ *memcache.Pool, _ context.Context) memcache.Conn {
return memcache.MockWith(memcache.ErrNotFound)
})
defer connGuard.Unpatch()
err := d.AddArcCMCache(c, aid, st)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,61 @@
package archive
import (
"context"
"encoding/json"
"sort"
"strings"
"go-common/app/interface/main/creative/model/music"
"go-common/library/log"
)
const (
_AllMusicsSQL = "SELECT cooperate,id,sid,name,frontname,musicians,mid,cover,playurl,state,duration,filesize,ctime,pubtime,tags,timeline FROM music"
)
// AllMusics fn
func (d *Dao) AllMusics(c context.Context) (res map[int64]*music.Music, err error) {
rows, err := d.db.Query(c, _AllMusicsSQL)
if err != nil {
log.Error("mysqlDB.Query error(%v)", err)
return
}
defer rows.Close()
res = make(map[int64]*music.Music)
for rows.Next() {
v := &music.Music{}
var fName string
if err = rows.Scan(&v.Cooperate, &v.ID, &v.SID, &v.Name, &fName, &v.Musicians, &v.UpMID, &v.Cover, &v.Playurl, &v.State, &v.Duration, &v.FileSize, &v.CTime, &v.Pubtime, &v.TagsStr, &v.Timeline); err != nil {
log.Error("row.Scan error(%v)", err)
return
}
if len(fName) > 0 {
v.Name = fName
}
v.Tl = make([]*music.TimePoint, 0)
if len(v.Timeline) > 0 {
if err = json.Unmarshal([]byte(v.Timeline), &v.Tl); err != nil {
log.Error("json.Unmarshal Timeline failed error(%v)", err)
continue
}
sort.Slice(v.Tl, func(i, j int) bool {
return v.Tl[i].Point < v.Tl[j].Point
})
if len(v.Tl) > 0 {
for _, point := range v.Tl {
if point.Recommend == 1 {
v.RecommendPoint = point.Point
break
}
}
}
}
v.Tags = make([]string, 0)
if len(v.TagsStr) > 0 {
v.Tags = strings.Split(v.TagsStr, ",")
}
res[v.SID] = v
}
return
}

View File

@@ -0,0 +1,36 @@
package archive
import (
"context"
"fmt"
xsql "go-common/library/database/sql"
"reflect"
"testing"
"github.com/bouk/monkey"
"github.com/smartystreets/goconvey/convey"
)
func TestMusics(t *testing.T) {
convey.Convey("Musics", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("uat db ok", func(ctx convey.C) {
_, err := d.AllMusics(c)
ctx.Convey("Then err should be nil.bizs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
ctx.Convey("db error", func(ctx convey.C) {
guard := monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Query", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (*xsql.Rows, error) {
return nil, fmt.Errorf("db.Query error")
})
defer guard.Unpatch()
_, err := d.AllMusics(c)
ctx.Convey("Then err should be nil.bizs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,75 @@
package archive
import (
"context"
"crypto/tls"
"fmt"
"go-common/library/ecode"
"go-common/library/log"
"io/ioutil"
"net"
"net/http"
"net/url"
"strconv"
"strings"
"time"
)
const (
_nsMd5 = "/videoup/ns/md5"
_notifyURL = "https://wax.gtloadbalance.cn:38080/InterfaceInfo/GetResult"
)
// AddNetSafeMd5 fn
func (d *Dao) AddNetSafeMd5(c context.Context, nid int64, md5 string) (err error) {
params := url.Values{}
params.Set("nid", strconv.FormatInt(nid, 10))
params.Set("md5", md5)
var res struct {
Code int `json:"code"`
}
if err = d.client.Post(c, d.nsMd5, "", params, &res); err != nil {
log.Error("d.client.Post(%s,%s) err(%v)", d.nsMd5, params.Encode(), err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("d.client.res.Code (%s,%s) err(%v)", d.nsMd5, params.Encode(), res.Code)
err = ecode.Int(res.Code)
return
}
return
}
// NotifyNetSafe fn
func (d *Dao) NotifyNetSafe(c context.Context, nid int64) (err error) {
req, err := http.NewRequest("POST", _notifyURL, strings.NewReader(fmt.Sprintf(`nid=%d&companyId=%d`, nid, 2)))
if err != nil {
log.Error("http.NewRequest error(%v) | uri(%s)", err, _notifyURL)
return
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("cache-control", "no-cache")
httpClient := &http.Client{
Timeout: time.Duration(time.Duration(5) * time.Second),
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Dial: (&net.Dialer{
Timeout: 5 * time.Second,
Deadline: time.Now().Add(5 * time.Second),
KeepAlive: 5 * time.Second,
}).Dial,
TLSHandshakeTimeout: 5 * time.Second,
ResponseHeaderTimeout: time.Second * 2,
},
}
var resp *http.Response
if resp, err = httpClient.Do(req); err != nil {
log.Error("NotifyNetSafe d.client.Do error(%v) | uri(%s)", err, _notifyURL)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
log.Warn("NotifyNetSafe ret body (%+v), nid(%+v)", string(body), nid)
return
}

View File

@@ -0,0 +1,35 @@
package archive
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestArchiveAddNetSafeMd5(t *testing.T) {
var (
c = context.TODO()
nid = int64(0)
md5 = ""
)
convey.Convey("AddNetSafeMd5", t, func(ctx convey.C) {
err := d.AddNetSafeMd5(c, nid, md5)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
}
func TestArchiveNotifyNetSafe(t *testing.T) {
var (
c = context.TODO()
nid = int64(0)
)
convey.Convey("NotifyNetSafe", t, func(ctx convey.C) {
err := d.NotifyNetSafe(c, nid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,56 @@
package archive
import (
"context"
"database/sql"
"net/url"
"go-common/app/interface/main/creative/model/archive"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_flow = "/videoup/flows"
_porderSQL = "SELECT id,aid,industry_id,brand_id,brand_name,official,show_type,advertiser,agent,ctime,mtime FROM archive_porder WHERE aid=? AND show_front = 1"
)
// Flows fn
func (d *Dao) Flows(c context.Context) (flows []*archive.Flow, err error) {
params := url.Values{}
flows = []*archive.Flow{}
var res struct {
Code int `json:"code"`
Data []*archive.Flow `json:"data"`
}
if err = d.client.Get(c, d.flow, "", params, &res); err != nil {
log.Error("archive.Flow url(%s) error(%v)", d.flow+"?"+params.Encode(), err)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Code != 0 {
log.Error("archive.Flow url(%s) res(%v)", d.flow+"?"+params.Encode(), res)
err = ecode.CreativeArchiveAPIErr
return
}
if res.Data == nil || len(res.Data) == 0 {
return
}
flows = res.Data
return
}
// Porder NOTE: move to up service
func (d *Dao) Porder(c context.Context, aid int64) (pd *archive.Porder, err error) {
row := d.db.QueryRow(c, _porderSQL, aid)
pd = &archive.Porder{}
if err = row.Scan(&pd.ID, &pd.AID, &pd.IndustryID, &pd.BrandID, &pd.BrandName, &pd.Official, &pd.ShowType, &pd.Advertiser, &pd.Agent, &pd.Ctime, &pd.Mtime); err != nil {
if err == sql.ErrNoRows {
pd = nil
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}

View File

@@ -0,0 +1,51 @@
package archive
import (
"context"
"go-common/app/interface/main/creative/model/archive"
xsql "go-common/library/database/sql"
"reflect"
"testing"
"github.com/bouk/monkey"
"github.com/smartystreets/goconvey/convey"
gock "gopkg.in/h2non/gock.v1"
)
func TestArchiveFlows(t *testing.T) {
var (
c = context.TODO()
err error
flows []*archive.Flow
)
convey.Convey("Flows", t, func(ctx convey.C) {
defer gock.OffAll()
httpMock("GET", d.simpleArchive).Reply(200).JSON(`{"code":20001}`)
flows, err = d.Flows(c)
ctx.Convey("Then err should be nil.flows should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(flows, convey.ShouldNotBeNil)
})
})
}
func TestArchivePorder(t *testing.T) {
var (
err error
c = context.TODO()
aid = int64(10110560)
res *archive.Porder
)
convey.Convey("Porder", t, func(ctx convey.C) {
ret := &xsql.Row{}
guard := monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "QueryRow", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) *xsql.Row {
return ret
})
defer guard.Unpatch()
res, err = d.Porder(c, aid)
ctx.Convey("Then err should be nil.pd should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,64 @@
package archive
import (
"context"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
"go-common/library/ecode"
"go-common/library/log"
)
// Archive get archive.
func (d *Dao) Archive(c context.Context, aid int64, ip string) (a *api.Arc, err error) {
var arg = &archive.ArgAid2{Aid: aid, RealIP: ip}
if a, err = d.arc.Archive3(c, arg); err != nil {
log.Error("rpc archive (%d) error(%v)", aid, err)
err = ecode.CreativeArcServiceErr
}
return
}
// Archives get archive list.
func (d *Dao) Archives(c context.Context, aids []int64, ip string) (a map[int64]*api.Arc, err error) {
var arg = &archive.ArgAids2{Aids: aids, RealIP: ip}
if a, err = d.arc.Archives3(c, arg); err != nil {
log.Error("rpc archive (%v) error(%v)", aids, err)
err = ecode.CreativeArcServiceErr
}
return
}
// Stats get archives stat.
func (d *Dao) Stats(c context.Context, aids []int64, ip string) (a map[int64]*api.Stat, err error) {
var arg = &archive.ArgAids2{Aids: aids, RealIP: ip}
if a, err = d.arc.Stats3(c, arg); err != nil {
log.Error("rpc Stats (%v) error(%v)", aids, err)
err = ecode.CreativeArcServiceErr
}
return
}
// UpCount get archives count.
func (d *Dao) UpCount(c context.Context, mid int64) (count int, err error) {
var arg = &archive.ArgUpCount2{Mid: mid}
if count, err = d.arc.UpCount2(c, arg); err != nil {
log.Error("rpc UpCount2 (%v) error(%v)", mid, err)
err = ecode.CreativeArcServiceErr
}
return
}
// Video get video.
func (d *Dao) Video(c context.Context, aid, cid int64, ip string) (v *api.Page, err error) {
var arg = &archive.ArgVideo2{Aid: aid, Cid: cid, RealIP: ip}
if v, err = d.arc.Video3(c, arg); err != nil {
if ecode.Cause(err) == ecode.NothingFound {
err = nil
return
}
log.Error("rpc video3 (%d) error(%v)", aid, err)
err = ecode.CreativeArcServiceErr
}
return
}

View File

@@ -0,0 +1,83 @@
package archive
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestArchiveArchive(t *testing.T) {
var (
c = context.TODO()
aid = int64(10110560)
ip = "127.0.0.1"
)
convey.Convey("Archive", t, func(ctx convey.C) {
a, err := d.Archive(c, aid, ip)
ctx.Convey("Then err should be nil.a should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(a, convey.ShouldNotBeNil)
})
})
}
func TestArchiveArchives(t *testing.T) {
var (
c = context.TODO()
aids = []int64{}
ip = ""
)
convey.Convey("Archives", t, func(ctx convey.C) {
a, err := d.Archives(c, aids, ip)
ctx.Convey("Then err should be nil.a should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(a, convey.ShouldNotBeNil)
})
})
}
func TestArchiveStats(t *testing.T) {
var (
c = context.TODO()
aids = []int64{}
ip = ""
)
convey.Convey("Stats", t, func(ctx convey.C) {
a, err := d.Stats(c, aids, ip)
ctx.Convey("Then err should be nil.a should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(a, convey.ShouldNotBeNil)
})
})
}
func TestArchiveUpCount(t *testing.T) {
var (
c = context.TODO()
mid = int64(888952460)
)
convey.Convey("UpCount", t, func(ctx convey.C) {
count, err := d.UpCount(c, mid)
ctx.Convey("Then err should be nil.count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
})
})
}
func TestArchiveVideo(t *testing.T) {
var (
c = context.TODO()
aid = int64(10110816)
cid = int64(10134702)
ip = "127.0.0.1"
)
convey.Convey("Video", t, func(ctx convey.C) {
v, err := d.Video(c, aid, cid, ip)
ctx.Convey("Then err should be nil.v should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(v, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,63 @@
package archive
import (
"context"
"go-common/app/interface/main/creative/model/archive"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
_staffCountSQL = "SELECT count(*) as count FROM archive_staff_apply WHERE apply_staff_mid=? AND deal_state = 1"
_staffSQL = "SELECT id,aid,mid,staff_mid,staff_title FROM archive_staff WHERE aid=? AND state = 1"
)
// RawStaffData get staff data from db
func (d *Dao) RawStaffData(c context.Context, aid int64) (res []*archive.Staff, err error) {
rows, err := d.db.Query(c, _staffSQL, aid)
if err != nil {
log.Error("mysqlDB.Query error(%v)", err)
return
}
defer rows.Close()
res = make([]*archive.Staff, 0)
res = append(res, &archive.Staff{AID: aid})
var mid int64
for rows.Next() {
v := &archive.Staff{}
if err = rows.Scan(&v.ID, &v.AID, &v.MID, &v.StaffMID, &v.StaffTitle); err != nil {
log.Error("row.Scan error(%v)", err)
res = res[0:0]
return
}
res = append(res, v)
mid = v.MID
}
if len(res) == 1 {
return res[0:0], nil
}
for _, v := range res {
if v.MID == 0 {
v.MID = mid
v.StaffMID = mid
v.StaffTitle = "UP"
break
}
}
return
}
// CountByMID .
func (d *Dao) CountByMID(c context.Context, mid int64) (count int, err error) {
row := d.db.QueryRow(c, _staffCountSQL, mid)
if err = row.Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("row.Scan error(%v)", err)
}
}
return
}

View File

@@ -0,0 +1,30 @@
package archive
import (
"context"
"fmt"
xsql "go-common/library/database/sql"
"reflect"
"testing"
"github.com/bouk/monkey"
"github.com/smartystreets/goconvey/convey"
)
func TestStaff(t *testing.T) {
convey.Convey("RawStaff", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
guard := monkey.PatchInstanceMethod(reflect.TypeOf(d.db), "Query", func(_ *xsql.DB, _ context.Context, _ string, _ ...interface{}) (*xsql.Rows, error) {
return nil, fmt.Errorf("db.Query error")
})
defer guard.Unpatch()
_, err := d.RawStaffData(c, 10110195)
ctx.Convey("Then err should be nil.bizs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,84 @@
package archive
import (
"context"
"encoding/json"
"fmt"
"go-common/app/interface/main/creative/model/archive"
"go-common/library/log"
)
const (
_viewPointKey = "viewpoint_%d_%d"
_viewPointExp = 300
_videoViewPoints = "SELECT id,aid,cid,content,state,ctime,mtime FROM video_viewpoint WHERE aid=? AND cid=? AND state=1 ORDER BY mtime DESC LIMIT ?"
)
// viewPointCacheKey 高能看点MC缓存key
func viewPointCacheKey(aid, cid int64) string {
return fmt.Sprintf(_viewPointKey, aid, cid)
}
// RawViewPoint get video highlight viewpoint
func (d *Dao) RawViewPoint(c context.Context, aid, cid int64) (vp *archive.ViewPointRow, err error) {
vps, err := d.RawViewPoints(c, aid, cid, 1)
if err != nil {
return
}
if len(vps) == 0 {
return
}
vp = vps[0]
return
}
// RawViewPoints 获取多个版本的高能看点
func (d *Dao) RawViewPoints(c context.Context, aid, cid int64, count int) (vps []*archive.ViewPointRow, err error) {
rows, err := d.db.Query(c, _videoViewPoints, aid, cid, count)
if err != nil {
log.Error("d.Query() error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
var (
p struct {
ID int64
AID int64
CID int64
Content string
State int32
CTime string
MTime string
}
points struct {
Points []*archive.ViewPoint `json:"points"`
}
)
if err = rows.Scan(&p.ID, &p.AID, &p.CID, &p.Content, &p.State, &p.CTime, &p.MTime); err != nil {
log.Error("row.Scan error(%v)", err)
return
}
if err = json.Unmarshal([]byte(p.Content), &points); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", p.Content, err)
return
}
for i := 0; i < len(points.Points); i++ {
if points.Points[i].State != 1 {
points.Points = append(points.Points[:i], points.Points[i+1:]...)
i--
}
}
vps = append(vps, &archive.ViewPointRow{
ID: p.ID,
AID: p.AID,
CID: p.CID,
Points: points.Points,
State: p.State,
CTime: p.CTime,
MTime: p.MTime,
})
}
return
}

View File

@@ -0,0 +1,21 @@
package archive
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDao_ViewPoints(t *testing.T) {
var (
c = context.TODO()
)
convey.Convey("ViewPoint", t, func(ctx convey.C) {
vp, err := d.ViewPoint(c, 10106351, 10126396)
ctx.Convey("", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(vp, convey.ShouldNotBeNil)
})
})
}