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,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 = ["report_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-view/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = ["report.go"],
importpath = "go-common/app/interface/main/app-view/service/report",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-view/conf:go_default_library",
"//app/interface/main/app-view/dao/archive:go_default_library",
"//app/interface/main/app-view/dao/elec:go_default_library",
"//app/interface/main/app-view/dao/report:go_default_library",
"//app/interface/main/app-view/model:go_default_library",
"//app/interface/main/app-view/model/elec:go_default_library",
"//app/interface/main/app-view/model/report:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//library/ecode: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 report
import (
"bytes"
"context"
"go-common/app/interface/main/app-view/conf"
arcdao "go-common/app/interface/main/app-view/dao/archive"
elcdao "go-common/app/interface/main/app-view/dao/elec"
reportdao "go-common/app/interface/main/app-view/dao/report"
"go-common/app/interface/main/app-view/model"
"go-common/app/interface/main/app-view/model/elec"
"go-common/app/interface/main/app-view/model/report"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
"go-common/library/ecode"
)
const (
_maxContentSize = 400
_maxFileSize = 1048576
)
var (
_elecTypeIds = []int16{
20, 154, 156, // dance
31, 30, 59, 29, 28, // music
26, 22, 126, 127, // guichu
24, 25, 47, 27, // animae
17, 18, 16, 65, 136, 19, 121, 171, 172, 173, // game
37, 124, 122, 39, 96, 95, 98, // tech
71, 137, 131, // yule
157, 158, 159, 164, // fashion
82, 128, // movie and tv
138, 21, 75, 76, 161, 162, 163, 174, // life
153, 168, // guo man
85, 86, 182, 183, 184, // film and television
}
)
// Service is appeal service .
type Service struct {
arcDao *arcdao.Dao
reportDao *reportdao.Dao
elcDao *elcdao.Dao
// elec
allowTypeIds map[int16]struct{}
}
// New init appeal service .
func New(c *conf.Config) (s *Service) {
s = &Service{
reportDao: reportdao.New(c),
arcDao: arcdao.New(c),
elcDao: elcdao.New(c),
}
s.allowTypeIds = map[int16]struct{}{}
for _, id := range _elecTypeIds {
s.allowTypeIds[id] = struct{}{}
}
return
}
// CopyWriter archive appeal copy write .
func (s *Service) CopyWriter(c context.Context, aid int64, plat int8, lang string) (cps []report.CopyWriter, err error) {
var a *api.Arc
if a, err = s.arcDao.Archive(c, aid); err != nil {
return
}
if a == nil {
err = ecode.NothingFound
return
}
// check elec
var info *elec.Info
if _, ok := s.allowTypeIds[int16(a.TypeID)]; ok && a.IsNormal() && a.Copyright == int32(archive.CopyrightOriginal) {
if info, err = s.elcDao.Info(c, a.Author.Mid, 0); err != nil {
return
}
}
if info != nil {
if model.IsOverseas(plat) {
cps = make([]report.CopyWriter, 4)
if lang == model.Hant {
cps[0] = report.CopyWriter{Typ: report.ArchivePVRG, Reason: report.Reason7, Desc: report.Desc7, AllowAdd: true}
cps[1] = report.CopyWriter{Typ: report.ArchiveCopyWriteG, Reason: report.Reason8, Desc: report.Desc8, AllowAdd: false}
cps[2] = report.CopyWriter{Typ: report.ArchiveHarmG, Reason: report.Reason9, Desc: report.Desc9, AllowAdd: true}
cps[3] = report.CopyWriter{Typ: report.OtherG, Reason: report.Reason10, Desc: report.Desc10, AllowAdd: true}
} else {
cps[0] = report.CopyWriter{Typ: report.ArchivePVR, Reason: report.Reason1, Desc: report.Desc1, AllowAdd: true}
cps[1] = report.CopyWriter{Typ: report.ArchiveCopyWrite, Reason: report.Reason2, Desc: report.Desc2, AllowAdd: false}
cps[2] = report.CopyWriter{Typ: report.ArchiveHarmG, Reason: report.Reason11, Desc: report.Desc11, AllowAdd: true}
cps[3] = report.CopyWriter{Typ: report.Other, Reason: report.Reason6, Desc: report.Desc6, AllowAdd: true}
}
} else {
cps = make([]report.CopyWriter, 6)
cps[0] = report.CopyWriter{Typ: report.ArchivePVR, Reason: report.Reason1, Desc: report.Desc1, AllowAdd: true}
cps[1] = report.CopyWriter{Typ: report.ArchiveCopyWrite, Reason: report.Reason2, Desc: report.Desc2, AllowAdd: false}
cps[2] = report.CopyWriter{Typ: report.ArchiveCrash, Reason: report.Reason3, Desc: report.Desc3, AllowAdd: true}
cps[3] = report.CopyWriter{Typ: report.ArchiveNotOwn, Reason: report.Reason4, Desc: report.Desc4, AllowAdd: true}
cps[4] = report.CopyWriter{Typ: report.ArchiveBusiness, Reason: report.Reason5, Desc: report.Desc5, AllowAdd: true}
cps[5] = report.CopyWriter{Typ: report.Other, Reason: report.Reason6, Desc: report.Desc6, AllowAdd: true}
}
} else {
if model.IsOverseas(plat) && lang == model.Hant {
cps = make([]report.CopyWriter, 4)
cps[0] = report.CopyWriter{Typ: report.ArchivePVRG, Reason: report.Reason7, Desc: report.Desc7, AllowAdd: true}
cps[1] = report.CopyWriter{Typ: report.ArchiveCopyWriteG, Reason: report.Reason8, Desc: report.Desc8, AllowAdd: false}
cps[2] = report.CopyWriter{Typ: report.ArchiveHarmG, Reason: report.Reason9, Desc: report.Desc9, AllowAdd: true}
cps[3] = report.CopyWriter{Typ: report.OtherG, Reason: report.Reason10, Desc: report.Desc10, AllowAdd: true}
} else {
cps = make([]report.CopyWriter, 4)
cps[0] = report.CopyWriter{Typ: report.ArchivePVR, Reason: report.Reason1, Desc: report.Desc1, AllowAdd: true}
cps[1] = report.CopyWriter{Typ: report.ArchiveCopyWrite, Reason: report.Reason2, Desc: report.Desc2, AllowAdd: false}
cps[2] = report.CopyWriter{Typ: report.ArchiveCrash, Reason: report.Reason11, Desc: report.Desc11, AllowAdd: true}
cps[3] = report.CopyWriter{Typ: report.Other, Reason: report.Reason6, Desc: report.Desc6, AllowAdd: true}
}
}
return
}
// AddReport add a report .
func (s *Service) AddReport(c context.Context, mid, aid int64, mold int, ak, reason, pics string) (err error) {
if len(reason) > _maxContentSize {
err = ecode.FileTooLarge
return
}
return s.reportDao.AddReport(c, mid, aid, mold, ak, reason, pics)
}
// Upload image upload .
func (s *Service) Upload(c context.Context, fileType string, body []byte) (url string, err error) {
if len(body) == 0 {
err = ecode.FileNotExists
return
}
if len(body) > _maxFileSize {
err = ecode.FileTooLarge
return
}
return s.reportDao.Upload(c, fileType, bytes.NewReader(body))
}

View File

@@ -0,0 +1,43 @@
package report
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-view/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-view-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(5 * time.Second)
}
func Test_CopyWriter(t *testing.T) {
Convey("CopyWriter", t, func() {
s.CopyWriter(context.TODO(), 1, 0, "")
})
}
func Test_AddReport(t *testing.T) {
Convey("AddReport", t, func() {
s.AddReport(context.TODO(), 1684013, 1, 0, "", "", "")
})
}
func Test_Upload(t *testing.T) {
Convey("Upload", t, func() {
s.Upload(context.TODO(), "", []byte{})
})
}

View File

@@ -0,0 +1,115 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"infoc_test.go",
"service_test.go",
"view_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-view/conf:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"access.go",
"bnj.go",
"contain.go",
"infoc.go",
"search.go",
"service.go",
"view.go",
],
importpath = "go-common/app/interface/main/app-view/service/view",
tags = ["automanaged"],
deps = [
"//app/interface/main/app-card/model:go_default_library",
"//app/interface/main/app-card/model/card:go_default_library",
"//app/interface/main/app-card/model/card/operate:go_default_library",
"//app/interface/main/app-view/conf:go_default_library",
"//app/interface/main/app-view/dao/account:go_default_library",
"//app/interface/main/app-view/dao/act:go_default_library",
"//app/interface/main/app-view/dao/ad:go_default_library",
"//app/interface/main/app-view/dao/ai:go_default_library",
"//app/interface/main/app-view/dao/archive:go_default_library",
"//app/interface/main/app-view/dao/assist:go_default_library",
"//app/interface/main/app-view/dao/audio:go_default_library",
"//app/interface/main/app-view/dao/bangumi:go_default_library",
"//app/interface/main/app-view/dao/coin:go_default_library",
"//app/interface/main/app-view/dao/creative:go_default_library",
"//app/interface/main/app-view/dao/dm:go_default_library",
"//app/interface/main/app-view/dao/elec:go_default_library",
"//app/interface/main/app-view/dao/favorite:go_default_library",
"//app/interface/main/app-view/dao/game:go_default_library",
"//app/interface/main/app-view/dao/live:go_default_library",
"//app/interface/main/app-view/dao/location:go_default_library",
"//app/interface/main/app-view/dao/manager:go_default_library",
"//app/interface/main/app-view/dao/region:go_default_library",
"//app/interface/main/app-view/dao/relation:go_default_library",
"//app/interface/main/app-view/dao/resource:go_default_library",
"//app/interface/main/app-view/dao/search:go_default_library",
"//app/interface/main/app-view/dao/special:go_default_library",
"//app/interface/main/app-view/dao/tag:go_default_library",
"//app/interface/main/app-view/dao/thumbup:go_default_library",
"//app/interface/main/app-view/dao/ugcpay:go_default_library",
"//app/interface/main/app-view/dao/vip:go_default_library",
"//app/interface/main/app-view/model:go_default_library",
"//app/interface/main/app-view/model/ad:go_default_library",
"//app/interface/main/app-view/model/bangumi:go_default_library",
"//app/interface/main/app-view/model/creative:go_default_library",
"//app/interface/main/app-view/model/elec:go_default_library",
"//app/interface/main/app-view/model/game:go_default_library",
"//app/interface/main/app-view/model/live:go_default_library",
"//app/interface/main/app-view/model/manager:go_default_library",
"//app/interface/main/app-view/model/region:go_default_library",
"//app/interface/main/app-view/model/special:go_default_library",
"//app/interface/main/app-view/model/tag:go_default_library",
"//app/interface/main/app-view/model/view:go_default_library",
"//app/service/main/account/model:go_default_library",
"//app/service/main/archive/api:go_default_library",
"//app/service/main/archive/model/archive:go_default_library",
"//app/service/main/location/model:go_default_library",
"//app/service/main/relation/model:go_default_library",
"//app/service/main/resource/model:go_default_library",
"//app/service/main/share/api:go_default_library",
"//app/service/main/thumbup/api:go_default_library",
"//app/service/main/thumbup/model:go_default_library",
"//app/service/openplatform/pgc-season/api/grpc/season/v1:go_default_library",
"//library/conf/env:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/log/infoc:go_default_library",
"//library/net/metadata:go_default_library",
"//library/stat/prom:go_default_library",
"//library/sync/errgroup:go_default_library",
"//library/sync/errgroup.v2: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,117 @@
package view
import (
"context"
"go-common/app/interface/main/app-view/model"
account "go-common/app/service/main/account/model"
"go-common/app/service/main/archive/model/archive"
locmdl "go-common/app/service/main/location/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
)
// ipLimit ip limit
func (s *Service) ipLimit(c context.Context, mid, aid int64, cdnIP string) (down int64, err error) {
var auth *locmdl.Auth
ip := metadata.String(c, metadata.RemoteIP)
if auth, err = s.locDao.Archive(c, aid, mid, ip, cdnIP); err != nil {
log.Error("%v", err)
err = nil // NOTE: return or ignore err???
}
if auth != nil {
down = auth.Down
switch auth.Play {
case locmdl.Forbidden:
err = ecode.AccessDenied
s.prom.Incr("ip_limit_access")
}
}
return
}
// areaLimit area limit
func (s *Service) areaLimit(c context.Context, plat int8, rid int) (err error) {
ip := metadata.String(c, metadata.RemoteIP)
if rm, ok := s.region[plat]; !ok {
return
} else if r, ok := rm[rid]; ok && r != nil && r.Area != "" {
var auths map[string]*locmdl.Auth
if auths, err = s.locDao.AuthPIDs(c, r.Area, ip); err != nil {
log.Error("error(%v) area(%v) ip(%v)", err, r.Area, ip)
err = nil
return
}
if auth, ok := auths[r.Area]; ok && auth.Play == locmdl.Forbidden {
log.Error("zlimit region area(%s) ip(%v) forbid", r.Area, ip)
err = ecode.NothingFound
s.prom.Incr("region_limit_access")
}
}
return
}
// checkAceess check user Aceess
func (s *Service) checkAceess(c context.Context, mid, aid int64, state, access int, ak string) (err error) {
if state >= 0 && access == 0 {
return
}
if state < 0 {
if state == archive.StateForbidFixed {
log.Warn("archive(%d) is fixed", aid)
} else if state == archive.StateForbidUpDelete {
log.Warn("archive(%d) is deleted", aid)
} else {
log.Warn("mid(%d) have not access view not pass archive(%d) ", mid, aid)
}
err = ecode.NothingFound
return
}
if mid == 0 {
log.Warn("not login can not view(%d) state(%d) access(%d)", aid, state, access)
err = ecode.AccessDenied
s.prom.Incr("no_login_access")
return
}
card, err := s.accDao.Card3(c, mid)
if err != nil || card == nil {
if err != nil {
log.Error("s.accDao.Info(%d) error(%v)", mid, err)
}
err = ecode.AccessDenied
log.Warn("s.accDao.Info failed can not view(%d) state(%d) access(%d)", aid, state, access)
s.prom.Incr("err_login_access")
return
}
if access > 0 && int(card.Rank) < access && (card.Vip.Type == 0 || card.Vip.Status == 0 || card.Vip.Status == 2 || card.Vip.Status == 3) {
err = ecode.AccessDenied
log.Warn("mid(%d) rank(%d) vip(tp:%d,status:%d) have not access(%d) view archive(%d) ", mid, card.Rank, card.Vip.Type, card.Vip.Status, access, aid)
s.prom.Incr("login_access")
}
return
}
// checkVIP check user is vip or no .
func (s *Service) checkVIP(c context.Context, mid int64) (vip bool) {
var (
card *account.Card
err error
)
if mid > 0 {
if card, err = s.accDao.Card3(c, mid); err != nil || card == nil {
log.Warn("s.acc.Info(%d) error(%v)", mid, err)
return
}
vip = card.Vip.Type > 0 && card.Vip.Status == 1
}
return
}
func (s *Service) overseaCheck(a *archive.Archive3, plat int8) bool {
if a.AttrVal(archive.AttrBitOverseaLock) == archive.AttrYes && model.IsOverseas(plat) {
s.prom.Incr("oversea_access")
return true
}
return false
}

View File

@@ -0,0 +1,278 @@
package view
import (
"context"
"fmt"
"go-common/app/interface/main/app-view/model/elec"
"go-common/app/interface/main/app-view/model/view"
"go-common/app/service/main/archive/model/archive"
thumbup "go-common/app/service/main/thumbup/model"
"go-common/library/conf/env"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/sync/errgroup"
)
// CheckAccess check
func (s *Service) CheckAccess(mid int64) bool {
if !s.BnjIsGrey {
return true
}
_, ok := s.BnjWhiteMid[mid]
if !ok && env.DeployEnv == env.DeployEnvProd {
log.Error("mid(%d) env(%s) not allow", mid, env.DeployEnv)
return false
}
return true
}
func (s *Service) initBnjPages(c context.Context, ps []*archive.Page3) (pages []*view.Page) {
for _, v := range ps {
page := &view.Page{}
metas := make([]*view.Meta, 0, 4)
for q, r := range _rate {
meta := &view.Meta{
Quality: q,
Size: int64(float64(r*v.Duration) * 1.1 / 8.0),
}
metas = append(metas, meta)
}
page.Page3 = v
page.Metas = metas
page.DMLink = fmt.Sprintf(_dmformat, v.Cid)
pages = append(pages, page)
}
return
}
// initBnjReqUser is
func (s *Service) initBnjReqUser(c context.Context, authorMid, aid, mid int64) (reqUser *view.ReqUser, err error) {
reqUser = &view.ReqUser{Favorite: 0, Attention: -999, Like: 0, Dislike: 0}
if mid == 0 {
return
}
g := errgroup.Group{}
g.Go(func() error {
var is bool
if is, _ = s.favDao.IsFav(context.Background(), mid, aid); is {
reqUser.Favorite = 1
}
return nil
})
g.Go(func() error {
res, err := s.thumbupDao.HasLike(context.Background(), mid, _businessLike, []int64{aid})
if err != nil {
log.Error("s.thumbupDao.HasLike err(%+v)", err)
return nil
}
if res.States == nil {
return nil
}
if typ, ok := res.States[aid]; ok {
if typ.State == thumbup.StateLike {
reqUser.Like = 1
} else if typ.State == thumbup.StateDislike {
reqUser.Dislike = 1
}
}
return nil
})
g.Go(func() (err error) {
res, err := s.coinDao.ArchiveUserCoins(context.Background(), aid, mid, _avTypeAv)
if err != nil {
log.Error("%+v", err)
err = nil
}
if res != nil && res.Multiply > 0 {
reqUser.Coin = 1
}
return
})
if authorMid > 0 {
g.Go(func() error {
fl, err := s.accDao.Following3(context.Background(), mid, authorMid)
if err != nil {
log.Error("%+v", err)
return nil
}
if fl {
reqUser.Attention = 1
}
return nil
})
}
g.Wait()
return
}
// Bnj2019 is
func (s *Service) Bnj2019(c context.Context, mid int64, relateID int64) (bnj *view.BnjMain, err error) {
if s.BnjMainView == nil || !s.BnjMainView.IsNormal() {
err = ecode.NothingFound
return
}
bnj = new(view.BnjMain)
bnj.ElecSmallText = s.c.Bnj2019.ElecSmallText
bnj.ElecBigText = s.c.Bnj2019.ElecBigText
bnj.Archive3 = s.BnjMainView.Archive3
bnj.ReqUser = &view.ReqUser{}
bnj.Elec = s.BnjElecInfo
bnj.Pages = s.initBnjPages(c, s.BnjMainView.Pages)
bnj.ReqUser, _ = s.initBnjReqUser(c, bnj.Author.Mid, bnj.Aid, mid)
bnj.PlayerIcon = s.playerIcon
bnj.Elec = s.BnjElecInfo
for _, a := range s.BnjLists {
relate := &view.BnjItem{
Aid: a.Aid,
Cid: a.FirstCid,
Tid: a.TypeID,
Pic: a.Pic,
Copyright: a.Copyright,
PubDate: a.PubDate,
Title: a.Title,
Desc: a.Desc,
Stat: a.Stat,
Duration: a.Duration,
Author: a.Author,
Dimension: a.Dimension,
Rights: a.Rights,
}
if relate.Aid == s.c.Bnj2019.AdAv {
relate.IsAd = 1
}
if relate.Aid == relateID {
relate.Pages = s.initBnjPages(c, a.Pages)
relate.ReqUser, _ = s.initBnjReqUser(c, a.Author.Mid, a.Aid, mid)
}
bnj.Relates = append(bnj.Relates, relate)
}
return
}
// BnjList is
func (s *Service) BnjList(c context.Context, mid int64) (list *view.BnjList, err error) {
list = new(view.BnjList)
for _, item := range s.BnjLists {
list.Item = append(list.Item, &view.BnjItem{
Aid: item.Aid,
Cid: item.FirstCid,
Pic: item.Pic,
Duration: item.Duration,
IsAd: 0,
Author: item.Author,
})
}
return
}
// BnjItem is
func (s *Service) BnjItem(c context.Context, aid, mid int64) (item *view.BnjItem, err error) {
var v *archive.View3
if aid == s.BnjMainView.Aid {
v = s.BnjMainView
} else {
for _, l := range s.BnjLists {
if aid == l.Aid {
v = l
break
}
}
}
if v == nil || !v.IsNormal() {
err = ecode.NothingFound
return
}
item = &view.BnjItem{
Aid: v.Aid,
Cid: v.FirstCid,
Tid: v.TypeID,
Pic: v.Pic,
Copyright: v.Copyright,
PubDate: v.PubDate,
Title: v.Title,
Desc: v.Desc,
Stat: v.Stat,
Duration: v.Duration,
Author: v.Author,
Dimension: v.Dimension,
Rights: v.Rights,
}
if item.Aid == s.c.Bnj2019.AdAv {
item.IsAd = 1
}
item.ReqUser, _ = s.initBnjReqUser(c, v.Author.Mid, v.Aid, mid)
item.Pages = s.initBnjPages(c, v.Pages)
return
}
func (s *Service) loadBnj2019Infos() (err error) {
var (
aids []int64
avm map[int64]*archive.View3
list []*archive.View3
mainView *archive.View3
elec *elec.Info
whiteMid = make(map[int64]struct{})
liveMids []int64
bnjStatus int
)
if bnjStatus, liveMids, err = s.liveDao.Bnj2019Conf(context.Background()); err != nil {
log.Error("%+v", err)
} else {
log.Info("got live bnj2019 mids(%v)", liveMids)
for _, mid := range liveMids {
whiteMid[mid] = struct{}{}
}
}
if bnjStatus == 1 {
s.BnjIsGrey = true
} else {
s.BnjIsGrey = false
}
// TODO live mids
for _, mid := range s.c.Bnj2019.WhiteMids {
whiteMid[mid] = struct{}{}
}
s.BnjWhiteMid = whiteMid
aids = append(aids, s.c.Bnj2019.MainAid)
aids = append(aids, s.c.Bnj2019.AidList...)
if avm, err = s.arcDao.ViewsRPC(context.Background(), aids); err != nil {
log.Error("bnj s.arcDao.Archives(%v) error(%v)", aids, err)
return
}
mainView, ok := avm[s.c.Bnj2019.MainAid]
if !ok {
log.Error("bnj main archive(%d) not exist", s.c.Bnj2019.MainAid)
return
}
mainView.Rights.Elec = 1
mainView.Rights.Download = 1
s.BnjMainView = mainView
for _, aid := range s.c.Bnj2019.AidList {
a, ok := avm[aid]
if !ok {
log.Error("bnj list has no aid(%d)", aid)
continue
}
if !a.IsNormal() {
log.Error("bnj list aid(%d) not open(%d)", aid, a.State)
continue
}
a.Rights.Elec = 1
a.Rights.Download = 1
list = append(list, a)
}
if len(list) == 0 {
log.Error("list is zero")
return
}
s.BnjLists = list
if elec, err = s.elcDao.TotalInfo(context.Background(), mainView.Author.Mid, mainView.Aid); err == nil {
s.BnjElecInfo = elec
s.BnjElecInfo.Total += s.c.Bnj2019.FakeElec
} else {
log.Error("s.elecDao.TotalInfo(%d,%d) error(%v)", mainView.Author.Mid, mainView.Aid, err)
}
return
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,138 @@
package view
import (
"bytes"
"fmt"
"strconv"
"time"
"go-common/app/interface/main/app-view/conf"
"go-common/app/interface/main/app-view/model/view"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/log/infoc"
)
type viewInfoc struct {
mid string
client string
build string
buvid string
disid string
ip string
api string
now string
aid string
err string
from string
trackid string
autoplay string
fromSpmid string
spmid string
}
type relateInfoc struct {
mid string
aid string
client string
buvid string
disid string
ip string
api string
now string
isRcmmnd int8
rls []*view.Relate
trackid string
build string
returnCode string
userFeature string
from string
}
//ViewInfoc view infoc
func (s *Service) ViewInfoc(mid int64, plat int, trackid, aid, ip, api, build, buvid, disid, from string, now time.Time, err error, autoplay int, spmid, fromSpmid string) {
s.infoc(viewInfoc{strconv.FormatInt(mid, 10), strconv.Itoa(plat), build, buvid, disid, ip, api, strconv.FormatInt(now.Unix(), 10), aid, strconv.Itoa(ecode.Cause(err).Code()), from, trackid, strconv.Itoa(autoplay), fromSpmid, spmid})
}
// RelateInfoc Relate Infoc
func (s *Service) RelateInfoc(mid, aid int64, plat int, trackid, build, buvid, disid, ip, api, returnCode, userFeature, from string, rls []*view.Relate, now time.Time, isRec int8) {
s.infoc(relateInfoc{strconv.FormatInt(mid, 10), strconv.FormatInt(aid, 10), strconv.Itoa(plat), buvid, disid, ip, api, strconv.FormatInt(now.Unix(), 10), isRec, rls, trackid, build, returnCode, userFeature, from})
}
func (s *Service) infoc(i interface{}) {
select {
case s.inCh <- i:
default:
log.Warn("cacheproc chan full")
}
}
// WriteViewInfoc Write View Infoc
func (s *Service) infocproc() {
const (
noItem = `{"section":{"id":"相关视频","pos":1,"from_item":"%s","items":[]}}`
)
var (
msg1 = []byte(`{"section":{"id":"相关视频","pos":1,"from_item":"`)
msg2 = []byte(`","items":[`)
msg3 = []byte(`{"id":`)
msg4 = []byte(`,"pos":`)
msg5 = []byte(`,"goto":"`)
msg6 = []byte(`","from":"`)
msg7 = []byte(`","source":"`)
msg8 = []byte(`","av_feature":`)
msg9 = []byte(`,"type":1,"url":""},`)
infView = infoc.New(conf.Conf.InfocView)
infRelate = infoc.New(conf.Conf.InfocRelate)
buf bytes.Buffer
list string
)
for {
i := <-s.inCh
switch v := i.(type) {
case viewInfoc:
infView.Info(v.ip, v.now, v.api, v.buvid, v.mid, v.client, v.aid, v.disid, v.err, v.from, v.build, v.trackid, v.autoplay, v.fromSpmid, v.spmid)
case relateInfoc:
var trackID string
if len(v.rls) > 0 {
buf.Write(msg1)
buf.WriteString(v.aid)
buf.Write(msg2)
for key, value := range v.rls {
// trackid
if value.TrackID != "" {
trackID = value.TrackID
}
//list
id, _ := strconv.ParseInt(value.Param, 10, 64)
buf.Write(msg3)
buf.WriteString(strconv.FormatInt(id, 10))
buf.Write(msg4)
buf.WriteString(strconv.Itoa(key + 1))
buf.Write(msg5)
buf.WriteString(value.Goto)
buf.Write(msg6)
buf.WriteString(value.From)
buf.Write(msg7)
buf.WriteString(value.Source)
buf.Write(msg8)
if value.AvFeature != nil {
buf.Write(value.AvFeature)
} else {
buf.Write([]byte(`""`))
}
buf.Write(msg9)
}
buf.Truncate(buf.Len() - 1)
buf.WriteString(`]}}`)
list = buf.String()
buf.Reset()
} else {
list = fmt.Sprintf(noItem, v.aid)
}
infRelate.Info(v.ip, v.now, v.api, v.buvid, v.mid, v.client, "2", list, v.disid, v.isRcmmnd, trackID, v.build, v.returnCode, v.userFeature, v.from)
default:
log.Warn("infocproc can't process the type")
}
}
}

View File

@@ -0,0 +1,21 @@
package view
import (
"errors"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
func Test_ViewInfoc(t *testing.T) {
Convey("ViewInfoc", t, func() {
s.ViewInfoc(0, 0, "test", "0", "", "", "", "", "", "", time.Now(), errors.New("test"), 1, "", "")
})
}
func Test_RelateInfoc(t *testing.T) {
Convey("RelateInfoc", t, func() {
s.RelateInfoc(0, 0, 0, "", "", "", "", "", "", "", "", "", nil, time.Now(), 0)
})
}

View File

@@ -0,0 +1,33 @@
package view
import (
"context"
"strconv"
"go-common/app/interface/main/app-card/model"
"go-common/app/interface/main/app-card/model/card/operate"
)
func (s *Service) searchFollow(c context.Context, platform, mobiApp, device, buvid string, build int, mid, vmid int64) (follow *operate.Card, err error) {
const _title = "关注TA的也关注了"
ups, trackID, err := s.search.Follow(c, platform, mobiApp, device, buvid, build, mid, vmid)
if err != nil {
return
}
items := make([]*operate.Card, 0, len(ups))
for _, up := range ups {
if up.Mid != 0 {
item := &operate.Card{ID: up.Mid, Goto: model.GotoMid, Param: strconv.FormatInt(up.Mid, 10), URI: strconv.FormatInt(up.Mid, 10), Desc: up.RecReason}
items = append(items, item)
}
}
if len(items) < 3 {
return
}
id, _ := strconv.ParseInt(trackID, 10, 64)
if id < 1 {
return
}
follow = &operate.Card{ID: id, Param: trackID, Items: items, Title: _title, CardGoto: model.CardGotoSearchUpper}
return
}

View File

@@ -0,0 +1,368 @@
package view
import (
"context"
"fmt"
"time"
"go-common/app/interface/main/app-view/conf"
accdao "go-common/app/interface/main/app-view/dao/account"
actdao "go-common/app/interface/main/app-view/dao/act"
addao "go-common/app/interface/main/app-view/dao/ad"
aidao "go-common/app/interface/main/app-view/dao/ai"
arcdao "go-common/app/interface/main/app-view/dao/archive"
assdao "go-common/app/interface/main/app-view/dao/assist"
audiodao "go-common/app/interface/main/app-view/dao/audio"
bandao "go-common/app/interface/main/app-view/dao/bangumi"
coindao "go-common/app/interface/main/app-view/dao/coin"
creativedao "go-common/app/interface/main/app-view/dao/creative"
dmdao "go-common/app/interface/main/app-view/dao/dm"
elcdao "go-common/app/interface/main/app-view/dao/elec"
favdao "go-common/app/interface/main/app-view/dao/favorite"
gamedao "go-common/app/interface/main/app-view/dao/game"
livedao "go-common/app/interface/main/app-view/dao/live"
locdao "go-common/app/interface/main/app-view/dao/location"
managerdao "go-common/app/interface/main/app-view/dao/manager"
rgndao "go-common/app/interface/main/app-view/dao/region"
reldao "go-common/app/interface/main/app-view/dao/relation"
rscdao "go-common/app/interface/main/app-view/dao/resource"
searchdao "go-common/app/interface/main/app-view/dao/search"
spdao "go-common/app/interface/main/app-view/dao/special"
tagdao "go-common/app/interface/main/app-view/dao/tag"
thumbupdao "go-common/app/interface/main/app-view/dao/thumbup"
ugcpaydao "go-common/app/interface/main/app-view/dao/ugcpay"
vipdao "go-common/app/interface/main/app-view/dao/vip"
"go-common/app/interface/main/app-view/model"
elecmdl "go-common/app/interface/main/app-view/model/elec"
"go-common/app/interface/main/app-view/model/live"
"go-common/app/interface/main/app-view/model/manager"
"go-common/app/interface/main/app-view/model/region"
"go-common/app/interface/main/app-view/model/special"
"go-common/app/interface/main/app-view/model/view"
"go-common/app/service/main/archive/model/archive"
shareclient "go-common/app/service/main/share/api"
"go-common/library/conf/env"
"go-common/library/log"
"go-common/library/stat/prom"
)
var (
_elecTypeIds = []int16{
20, 154, 156, // dance
31, 30, 59, 29, 28, // music
26, 22, 126, 127, // guichu
24, 25, 47, 27, // animae
17, 18, 16, 65, 136, 19, 121, 171, 172, 173, // game
37, 124, 122, 39, 96, 95, 98, // tech
71, 137, 131, // yule
157, 158, 159, 164, // fashion
82, 128, // movie and tv
138, 21, 75, 76, 161, 162, 163, 174, // life
153, 168, // guo man
85, 86, 182, 183, 184, // film and television
}
)
// Service is view service
type Service struct {
c *conf.Config
pHit *prom.Prom
pMiss *prom.Prom
prom *prom.Prom
// dao
accDao *accdao.Dao
arcDao *arcdao.Dao
tagDao *tagdao.Dao
favDao *favdao.Dao
banDao *bandao.Dao
elcDao *elcdao.Dao
rgnDao *rgndao.Dao
liveDao *livedao.Dao
assDao *assdao.Dao
adDao *addao.Dao
rscDao *rscdao.Dao
relDao *reldao.Dao
coinDao *coindao.Dao
audioDao *audiodao.Dao
actDao *actdao.Dao
thumbupDao *thumbupdao.Dao
gameDao *gamedao.Dao
shareClient shareclient.ShareClient
vipDao *vipdao.Dao
mngDao *managerdao.Dao
spDao *spdao.Dao
dmDao *dmdao.Dao
aiDao *aidao.Dao
creativeDao *creativedao.Dao
search *searchdao.Dao
ugcpayDao *ugcpaydao.Dao
locDao *locdao.Dao
// region
tick time.Duration
region map[int8]map[int]*region.Region
// elec
allowTypeIds map[int16]struct{}
// live cache
liveCache map[int64]*live.Live
// chan
inCh chan interface{}
dmRegion map[int16]struct{}
// vip active cache
vipActiveCache map[int]string
vipTick time.Duration
// mamager cache
RelateCache []*manager.Relate
specialCache map[int64]*special.Card
specialMids map[int64]struct{}
// player icon
playerIcon *view.PlayerIcon
// view relate game from AI
RelateGameCache map[int64]int64
// bnj caches
BnjMainView *archive.View3
BnjLists []*archive.View3
BnjElecInfo *elecmdl.Info
BnjWhiteMid map[int64]struct{}
BnjIsGrey bool
}
// New new archive
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
pHit: prom.CacheHit,
pMiss: prom.CacheMiss,
prom: prom.BusinessInfoCount,
// dao
accDao: accdao.New(c),
arcDao: arcdao.New(c),
tagDao: tagdao.New(c),
favDao: favdao.New(c),
banDao: bandao.New(c),
elcDao: elcdao.New(c),
rgnDao: rgndao.New(c),
liveDao: livedao.New(c),
assDao: assdao.New(c),
adDao: addao.New(c),
rscDao: rscdao.New(c),
relDao: reldao.New(c),
coinDao: coindao.New(c),
audioDao: audiodao.New(c),
actDao: actdao.New(c),
thumbupDao: thumbupdao.New(c),
gameDao: gamedao.New(c),
vipDao: vipdao.New(c),
mngDao: managerdao.New(c),
spDao: spdao.New(c),
dmDao: dmdao.New(c),
aiDao: aidao.New(c),
creativeDao: creativedao.New(c),
search: searchdao.New(c),
ugcpayDao: ugcpaydao.New(c),
locDao: locdao.New(c),
// region
tick: time.Duration(c.Tick),
region: map[int8]map[int]*region.Region{},
// live cache
liveCache: map[int64]*live.Live{},
// chan
inCh: make(chan interface{}, 1024),
allowTypeIds: map[int16]struct{}{},
dmRegion: map[int16]struct{}{},
specialMids: map[int64]struct{}{},
// vip
vipActiveCache: make(map[int]string),
vipTick: time.Duration(c.VipTick),
// manager
RelateCache: []*manager.Relate{},
specialCache: map[int64]*special.Card{},
// player icon
playerIcon: &view.PlayerIcon{},
}
for _, id := range _elecTypeIds {
s.allowTypeIds[id] = struct{}{}
}
for _, id := range c.DMRegion {
s.dmRegion[id] = struct{}{}
}
var err error
if s.shareClient, err = shareclient.NewClient(nil); err != nil {
panic(fmt.Sprintf("env:%s no share-service", env.DeployEnv))
}
// load data
s.loadLive()
s.loadRegion()
s.loadPlayerIcon()
s.loadVIPActive()
s.loadManager()
s.loadRelateGame()
s.loadBnj2019Infos()
go s.infocproc()
go s.tickproc()
go s.vipproc()
go s.bnjTickproc()
return s
}
// Ping is dao ping.
func (s *Service) Ping(c context.Context) (err error) {
return s.arcDao.Ping(c)
}
func (s *Service) bnjTickproc() {
for {
time.Sleep(time.Duration(s.c.Bnj2019.Tick))
err := s.loadBnj2019Infos()
if err != nil {
log.Error("bnj load error(%v)", err)
}
}
}
// tickproc tick load cache.
func (s *Service) tickproc() {
for {
time.Sleep(s.tick)
s.loadRegion()
s.loadLive()
s.loadPlayerIcon()
s.loadManager()
s.loadRelateGame()
}
}
// vipproc tick load vip cache.
func (s *Service) vipproc() {
for {
time.Sleep(s.vipTick)
s.loadVIPActive()
}
}
// loadVIPActive tick load vip active cache.
func (s *Service) loadVIPActive() {
var (
va map[int]string
err error
)
va = make(map[int]string)
if va[view.VIPActiveView], err = s.vipDao.VIPActive(context.TODO(), view.VIPActiveView); err != nil {
log.Error("s.vipDao.VIPActinve(%d) error(%v)", view.VIPActiveView, err)
return
}
s.vipActiveCache = va
log.Info("load vip active success")
}
func (s *Service) loadRegion() {
res, err := s.rgnDao.Seconds(context.TODO())
if err != nil {
log.Error("%+v", err)
return
}
s.region = res
}
func (s *Service) loadLive() {
if s.c.Env == model.EnvHK {
return
}
living, err := s.liveDao.Living(context.TODO())
if err != nil {
log.Error("%+v", err)
return
}
tmp := map[int64]*live.Live{}
for _, v := range living {
tmp[v.Mid] = v
}
s.liveCache = tmp
}
func (s *Service) loadManager() {
r, err := s.mngDao.Relate(context.TODO())
if err != nil {
log.Error("%+v", err)
return
}
s.RelateCache = r
sp, err := s.spDao.Card(context.TODO())
if err != nil {
log.Error("%+v", err)
return
}
s.specialCache = sp
midsM, err := s.creativeDao.Special(context.Background())
if err != nil {
log.Error("%+v", err)
return
}
log.Info("load special mids(%+v)", midsM)
s.specialMids = midsM
}
func (s *Service) loadRelateGame() {
g, err := s.aiDao.Av2Game(context.TODO())
if err != nil {
log.Error("%+v", err)
return
}
s.RelateGameCache = g
}
func (s *Service) loadPlayerIcon() {
res, err := s.rscDao.PlayerIcon(context.TODO())
if err != nil {
log.Error("%+v", err)
return
}
if res != nil {
s.playerIcon = &view.PlayerIcon{URL1: res.URL1, Hash1: res.Hash1, URL2: res.URL2, Hash2: res.Hash2, CTime: res.CTime}
} else {
s.playerIcon = nil
}
}
func (s *Service) relateCache(c context.Context, plat int8, build int, now time.Time, aid int64, tids []int64, rid int32) (relate *manager.Relate) {
rs := s.RelateCache
rls := make([]*manager.Relate, 0, len(rs))
if len(rs) != 0 {
LOOP:
for _, r := range rs {
if vs, ok := r.Versions[plat]; ok {
for _, v := range vs {
if model.InvalidBuild(build, v.Build, v.Condition) {
continue LOOP
}
}
if (r.STime == 0 || now.After(r.STime.Time())) && (r.ETime == 0 || now.Before(r.ETime.Time())) {
rls = append(rls, r)
}
}
}
}
for _, r := range rls {
if _, ok := r.Aids[aid]; ok {
relate = r
break
}
if len(tids) != 0 {
for _, tid := range tids {
if _, ok := r.Tids[tid]; ok {
relate = r
break
}
}
}
if _, ok := r.Rids[int64(rid)]; ok {
relate = r
break
}
}
return
}
func (s Service) relateGame(c context.Context, aid int64) (id int64) {
id = s.RelateGameCache[aid]
return
}

View File

@@ -0,0 +1,31 @@
package view
import (
"context"
"flag"
"path/filepath"
"testing"
"time"
"go-common/app/interface/main/app-view/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func init() {
dir, _ := filepath.Abs("../../cmd/app-view-test.toml")
flag.Set("conf", dir)
conf.Init()
s = New(conf.Conf)
time.Sleep(5 * time.Second)
}
func Test_Ping(t *testing.T) {
Convey("Ping", t, func() {
s.Ping(context.TODO())
})
}

View File

@@ -0,0 +1,710 @@
package view
import (
"context"
"crypto/md5"
"encoding/hex"
"net/url"
"strconv"
"strings"
"time"
cdm "go-common/app/interface/main/app-card/model"
"go-common/app/interface/main/app-card/model/card"
"go-common/app/interface/main/app-card/model/card/operate"
"go-common/app/interface/main/app-view/model"
"go-common/app/interface/main/app-view/model/creative"
"go-common/app/interface/main/app-view/model/view"
account "go-common/app/service/main/account/model"
"go-common/app/service/main/archive/api"
"go-common/app/service/main/archive/model/archive"
location "go-common/app/service/main/location/model"
relation "go-common/app/service/main/relation/model"
resource "go-common/app/service/main/resource/model"
sharerpc "go-common/app/service/main/share/api"
thumbuppb "go-common/app/service/main/thumbup/api"
thumbup "go-common/app/service/main/thumbup/model"
"go-common/library/conf/env"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"go-common/library/sync/errgroup"
egV2 "go-common/library/sync/errgroup.v2"
"github.com/pkg/errors"
)
const (
_descLen = 250
_promptCoin = 1
_promptFav = 2
_avTypeAv = 1
_businessLike = "archive"
_coinAv = 1
)
// View all view data.
func (s *Service) View(c context.Context, mid, aid, movieID int64, plat int8, build, qn, fnver, fnval, forceHost, parentMode int, ak, mobiApp, device, buvid, cdnIP, network, adExtra, from string, now time.Time) (v *view.View, err error) {
if v, err = s.ViewPage(c, mid, aid, movieID, plat, build, ak, mobiApp, device, cdnIP, true, now); err != nil {
ip := metadata.String(c, metadata.RemoteIP)
if err == ecode.AccessDenied || err == ecode.NothingFound {
log.Warn("s.ViewPage() mid(%d) aid(%d) movieID(%d) plat(%d) ak(%s) ip(%s) cdn_ip(%s) error(%v)", mid, aid, movieID, plat, ak, ip, cdnIP, err)
} else {
log.Error("s.ViewPage() mid(%d) aid(%d) movieID(%d) plat(%d) ak(%s) ip(%s) cdn_ip(%s) error(%v)", mid, aid, movieID, plat, ak, ip, cdnIP, err)
}
return
}
g, ctx := errgroup.WithContext(c)
g.Go(func() (err error) {
v.VIPActive = s.vipActiveCache[view.VIPActiveView]
return
})
g.Go(func() (err error) {
s.initReqUser(ctx, v, mid, plat, build)
if v.AttrVal(archive.AttrBitIsPGC) != archive.AttrYes {
s.initContributions(ctx, v)
}
return
})
g.Go(func() (err error) {
s.initRelateCMTag(ctx, v, plat, build, qn, fnver, fnval, forceHost, parentMode, mid, buvid, mobiApp, device, network, adExtra, from, now)
return
})
if v.AttrVal(archive.AttrBitIsPGC) != archive.AttrYes {
g.Go(func() (err error) {
s.initDM(ctx, v)
return
})
g.Go(func() (err error) {
s.initAudios(ctx, v)
return
})
g.Go(func() (err error) {
if model.IsIPhoneB(plat) || (model.IsIPhone(plat) && (build >= 7000 && build <= 8000)) {
return
}
s.initElec(ctx, v, mid)
return
})
if len([]rune(v.Desc)) > _descLen {
g.Go(func() (err error) {
if desc, _ := s.arcDao.Description(ctx, v.Aid); desc != "" {
v.Desc = desc
}
return
})
}
}
if v.AttrVal(archive.AttrBitHasBGM) == archive.AttrYes {
g.Go(func() (err error) {
if v.Bgm, err = s.creativeDao.Bgm(ctx, v.Aid, v.FirstCid); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
}
if err = g.Wait(); err != nil {
log.Error("%+v", err)
}
return
}
// ViewPage view page data.
func (s *Service) ViewPage(c context.Context, mid, aid, movieID int64, plat int8, build int, ak, mobiApp, device, cdnIP string, nMovie bool, now time.Time) (v *view.View, err error) {
if aid == 0 && movieID == 0 {
err = ecode.NothingFound
return
}
const (
_androidMovie = 5220000
_iPhoneMovie = 6500
_iPadMovie = 6720
_iPadHDMovie = 12020
)
var (
vs *view.ViewStatic
vp *archive.View3
seasoninfo map[int64]int64
ok bool
)
if movieID != 0 {
if seasoninfo, err = s.banDao.SeasonidAid(c, movieID, now); err != nil {
log.Error("%+v", err)
err = ecode.NothingFound
return
}
if aid, ok = seasoninfo[movieID]; !ok || aid == 0 {
err = ecode.NothingFound
return
}
var a *api.Arc
if a, err = s.arcDao.Archive3(c, aid); err != nil {
log.Error("%+v", err)
err = ecode.NothingFound
return
}
if a == nil {
err = ecode.NothingFound
return
}
vs = &view.ViewStatic{Archive3: archive.BuildArchive3(a)}
s.prom.Incr("from_movieID")
} else {
if vp, err = s.arcDao.ViewCache(c, aid); err != nil {
log.Error("%+v", err)
}
if vp == nil || vp.Archive3 == nil || len(vp.Pages) == 0 || vp.AttrVal(archive.AttrBitIsMovie) == archive.AttrYes {
if vp, err = s.arcDao.View3(c, aid); err != nil {
log.Error("%+v", err)
err = ecode.NothingFound
return
}
}
if vp == nil || vp.Archive3 == nil || len(vp.Pages) == 0 {
err = ecode.NothingFound
return
}
vs = &view.ViewStatic{Archive3: vp.Archive3}
s.initPages(c, vs, vp.Pages)
s.prom.Incr("from_aid")
}
if _, ok := s.specialMids[vs.Author.Mid]; ok && env.DeployEnv == env.DeployEnvProd {
err = ecode.NothingFound
log.Error("aid(%d) mid(%d) can not view on prod", vs.Aid, vs.Author.Mid)
return
}
// TODO 产品最帅了!
vs.Stat.DisLike = 0
if s.overseaCheck(vs.Archive3, plat) {
err = ecode.AreaLimit
return
}
// check region area limit
if err = s.areaLimit(c, plat, int(vs.TypeID)); err != nil {
return
}
v = &view.View{ViewStatic: vs, DMSeg: 1, PlayerIcon: s.playerIcon}
if v.AttrVal(archive.AttrBitIsPGC) != archive.AttrYes {
// check access
if err = s.checkAceess(c, mid, v.Aid, int(v.State), int(v.Access), ak); err != nil {
// archive is ForbitFixed and Transcoding and StateForbitDistributing need analysis history body .
if v.State != archive.StateForbidFixed {
return
}
err = nil
}
if v.Access > 0 {
v.Stat.View = 0
}
}
g, ctx := errgroup.WithContext(c)
if mid != 0 {
g.Go(func() (err error) {
v.History, _ = s.arcDao.Progress(ctx, v.Aid, mid)
return
})
}
if v.AttrVal(archive.AttrBitIsPGC) == archive.AttrYes {
if (v.AttrVal(archive.AttrBitIsMovie) != archive.AttrYes) || (plat == model.PlatAndroid && build >= _androidMovie) || (plat == model.PlatIPhone && build >= _iPhoneMovie) || (plat == model.PlatIPad && build >= _iPadMovie) ||
(plat == model.PlatIpadHD && build > _iPadHDMovie) || plat == model.PlatAndroidTVYST || plat == model.PlatAndroidTV || plat == model.PlatAndroidI || plat == model.PlatIPhoneB {
g.Go(func() error {
return s.initPGC(ctx, v, mid, build, mobiApp, device)
})
} else {
g.Go(func() error {
return s.initMovie(ctx, v, mid, build, mobiApp, device, nMovie)
})
}
} else {
g.Go(func() (err error) {
if err = s.initDownload(ctx, v, mid, cdnIP); err != nil {
ip := metadata.String(ctx, metadata.RemoteIP)
log.Error("aid(%d) mid(%d) ip(%s) cdn_ip(%s) error(%+v)", v.Aid, mid, ip, cdnIP, err)
}
return
})
if v.Rights.UGCPay == 1 && mid != v.Author.Mid {
g.Go(func() (err error) {
if err = s.initUGCPay(ctx, v, plat, mid); err != nil {
log.Error("%+v", err)
err = nil
return
}
return nil
})
}
}
if err = g.Wait(); err != nil {
log.Error("%+v", err)
}
if v.Rights.UGCPay == 1 {
if (v.Asset == nil || v.Asset.Paid == 0) && mid != v.Author.Mid {
v.Rights.Download = int32(location.ForbiddenDown)
}
}
return
}
// AddShare add a share
func (s *Service) AddShare(c context.Context, aid, mid int64, ip string) (share int, isReport bool, upID int64, err error) {
var a *api.Arc
if a, err = s.arcDao.Archive(c, aid); err != nil {
if errors.Cause(err) == ecode.NothingFound {
err = ecode.ArchiveNotExist
}
return
}
if !a.IsNormal() {
err = ecode.ArchiveNotExist
return
}
upID = a.Author.Mid
shareReply, err := s.shareClient.AddShare(context.Background(), &sharerpc.AddShareRequest{
Oid: aid,
Mid: mid,
Type: 3,
Ip: ip,
})
if err != nil {
if ecode.Cause(err).Equal(ecode.ShareAlreadyAdd) {
err = nil
return
}
log.Error("s.shareClient.AddShare(%d, %d, 3) error(%v)", aid, mid, err)
return
}
if shareReply != nil && shareReply.Shares > int64(a.Stat.Share) {
isReport = true
}
return
}
// Shot shot service
func (s *Service) Shot(c context.Context, aid, cid int64) (shot *view.Videoshot, err error) {
var (
arcShot *archive.Videoshot
points []*creative.Points
)
shot = new(view.Videoshot)
if arcShot, err = s.arcDao.Shot(c, aid, cid); err != nil {
log.Error("%+v", err)
return
}
if arcShot == nil {
return
}
shot.Videoshot = arcShot
a := &api.Arc{Attribute: arcShot.Attr}
if a.AttrVal(archive.AttrBitHasViewpoint) == archive.AttrYes {
if points, err = s.creativeDao.Points(c, aid, cid); err != nil {
log.Error("%+v", err)
err = nil
}
shot.Points = points
}
return
}
// Like add a like.
func (s *Service) Like(c context.Context, aid, mid int64, status int8) (upperID int64, toast string, err error) {
var (
a *api.Arc
typ int8
stat *thumbuppb.LikeReply
)
if a, err = s.arcDao.Archive(c, aid); err != nil {
if errors.Cause(err) == ecode.NothingFound {
err = ecode.ArchiveNotExist
}
return
}
if !a.IsNormal() {
err = ecode.ArchiveNotExist
return
}
upperID = a.Author.Mid
if status == 0 {
typ = thumbup.TypeLike
} else if status == 1 {
typ = thumbup.TypeCancelLike
}
if stat, err = s.thumbupDao.Like(c, mid, upperID, _businessLike, a.Aid, typ); err != nil {
if ecode.EqualError(ecode.ThumbupDupLikeErr, err) {
log.Error("%+v", err)
err = nil
toast = "点赞收到!视频可能推荐哦"
}
return
}
if typ == thumbup.TypeLike {
if stat.LikeNumber < 100 {
toast = "点赞收到!视频可能推荐哦"
} else if stat.LikeNumber >= 100 && stat.LikeNumber < 1000 {
toast = "感谢点赞,推荐已收到啦"
} else if stat.LikeNumber >= 1000 && stat.LikeNumber < 10000 {
toast = "get视频也许更多人能看见"
} else {
toast = "点赞爆棚,感谢推荐!"
}
}
return
}
// Dislike add a dislike.
func (s *Service) Dislike(c context.Context, aid, mid int64, status int8) (upperID int64, err error) {
var (
a *api.Arc
typ int8
)
if a, err = s.arcDao.Archive(c, aid); err != nil {
if errors.Cause(err) == ecode.NothingFound {
err = ecode.ArchiveNotExist
}
return
}
if !a.IsNormal() {
err = ecode.ArchiveNotExist
return
}
upperID = a.Author.Mid
if status == 0 {
typ = thumbup.TypeDislike
} else if status == 1 {
typ = thumbup.TypeCancelDislike
}
_, err = s.thumbupDao.Like(c, mid, upperID, _businessLike, a.Aid, typ)
return
}
// AddCoin add a coin
func (s *Service) AddCoin(c context.Context, aid, mid, upID, avtype, multiply int64, ak string, selectLike int) (prompt, like bool, err error) {
var maxCoin int64 = 2
var typeID int16
var pubTime int64
if avtype == _avTypeAv {
var a *api.Arc
if a, err = s.arcDao.Archive(c, aid); err != nil {
if errors.Cause(err) == ecode.NothingFound {
err = ecode.ArchiveNotExist
}
return
}
if !a.IsNormal() {
err = ecode.ArchiveNotExist
return
}
if a.Copyright == int32(archive.CopyrightCopy) {
maxCoin = 1
}
upID = a.Author.Mid
typeID = int16(a.TypeID)
pubTime = int64(a.PubDate)
}
if err = s.coinDao.AddCoins(c, aid, mid, upID, maxCoin, avtype, multiply, typeID, pubTime); err != nil {
return
}
eg, ctx := errgroup.WithContext(c)
eg.Go(func() (err error) {
if avtype == _avTypeAv && selectLike == 1 {
if _, err = s.thumbupDao.Like(ctx, mid, upID, _businessLike, aid, thumbup.TypeLike); err != nil {
log.Error("%+v", err)
err = nil
} else {
like = true
}
}
return
})
eg.Go(func() (err error) {
if prompt, err = s.relDao.Prompt(ctx, mid, upID, _promptCoin); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
eg.Wait()
return
}
// AddFav add a favorite
func (s *Service) AddFav(c context.Context, mid, vmid int64, fids []int64, aid int64, ak string) (prompt bool, err error) {
var a *api.Arc
if a, err = s.arcDao.Archive(c, aid); err != nil {
if errors.Cause(err) == ecode.NothingFound {
err = ecode.ArchiveNotExist
}
return
}
if !a.IsNormal() {
err = ecode.ArchiveNotExist
return
}
if err = s.favDao.AddVideo(c, mid, fids, aid, ak); err != nil {
return
}
if prompt, err = s.relDao.Prompt(c, mid, vmid, _promptFav); err != nil {
log.Error("%+v", err)
err = nil
}
return
}
// Paster get paster if nologin.
func (s *Service) Paster(c context.Context, plat, adType int8, aid, typeID, buvid string) (p *resource.Paster, err error) {
if p, err = s.rscDao.Paster(c, plat, adType, aid, typeID, buvid); err != nil {
log.Error("%+v", err)
}
return
}
// VipPlayURL get playurl token.
func (s *Service) VipPlayURL(c context.Context, aid, cid, mid int64) (res *view.VipPlayURL, err error) {
var (
a *api.Arc
card *account.Card
)
res = &view.VipPlayURL{
From: "app",
Ts: time.Now().Unix(),
Aid: aid,
Cid: cid,
Mid: mid,
}
if card, err = s.accDao.Card3(c, mid); err != nil {
log.Error("%+v", err)
err = ecode.AccessDenied
return
}
if res.VIP = int(card.Level); res.VIP > 6 {
res.VIP = 6
}
if card.Vip.Type != 0 && card.Vip.Status == 1 {
res.SVIP = 1
}
if a, err = s.arcDao.Archive(c, aid); err != nil {
log.Error("%+v", err)
err = ecode.NothingFound
return
}
if mid == a.Author.Mid {
res.Owner = 1
}
params := url.Values{}
params.Set("from", res.From)
params.Set("ts", strconv.FormatInt(res.Ts, 10))
params.Set("aid", strconv.FormatInt(res.Aid, 10))
params.Set("cid", strconv.FormatInt(res.Cid, 10))
params.Set("mid", strconv.FormatInt(res.Mid, 10))
params.Set("vip", strconv.Itoa(res.VIP))
params.Set("svip", strconv.Itoa(res.SVIP))
params.Set("owner", strconv.Itoa(res.Owner))
tmp := params.Encode()
if strings.IndexByte(tmp, '+') > -1 {
tmp = strings.Replace(tmp, "+", "%20", -1)
}
mh := md5.Sum([]byte(strings.ToLower(tmp) + s.c.PlayURL.Secret))
res.Fcs = hex.EncodeToString(mh[:])
return
}
// Follow get auto follow switch from creative and acc.
func (s *Service) Follow(c context.Context, vmid, mid int64) (res *creative.PlayerFollow, err error) {
var (
fl bool
profile *relation.Stat
fs *creative.FollowSwitch
)
g, ctx := errgroup.WithContext(c)
g.Go(func() (err error) {
profile, err = s.relDao.Stat(ctx, vmid)
if err != nil {
log.Error("%+v", err)
}
return
})
if mid > 0 {
g.Go(func() (err error) {
fl, err = s.accDao.Following3(ctx, mid, vmid)
if err != nil {
log.Error("%+v", err)
}
return
})
}
g.Go(func() (err error) {
fs, err = s.creativeDao.FollowSwitch(ctx, vmid)
if err != nil {
log.Error("%+v", err)
}
return
})
if err = g.Wait(); err != nil {
log.Error("%+v", err)
return
}
res = &creative.PlayerFollow{}
if profile.Follower >= s.c.AutoLimit && fs.State == 1 && !fl {
res.Show = true
}
return
}
// UpperRecmd is
func (s *Service) UpperRecmd(c context.Context, plat int8, platform, mobiApp, device, buvid string, build int, mid, vimd int64) (res card.Handler, err error) {
var (
upIDs []int64
follow *operate.Card
cardm map[int64]*account.Card
statm map[int64]*relation.Stat
isAtten map[int64]int8
)
if follow, err = s.searchFollow(c, platform, mobiApp, device, buvid, build, mid, vimd); err != nil {
log.Error("%+v", err)
return
}
if follow == nil {
err = ecode.AppNotData
log.Error("follow is nil")
return
}
for _, item := range follow.Items {
upIDs = append(upIDs, item.ID)
}
g, ctx := errgroup.WithContext(c)
if len(upIDs) != 0 {
g.Go(func() (err error) {
if cardm, err = s.accDao.Cards3(ctx, upIDs); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
g.Go(func() (err error) {
if statm, err = s.relDao.Stats(ctx, upIDs); err != nil {
log.Error("%+v", err)
err = nil
}
return
})
if mid != 0 {
g.Go(func() error {
isAtten = s.accDao.IsAttention(ctx, upIDs, mid)
return nil
})
}
}
g.Wait()
op := &operate.Card{}
op.From(cdm.CardGt(model.GotoSearchUpper), 0, 0, plat, build)
h := card.Handle(plat, cdm.CardGt(model.GotoSearchUpper), "", cdm.ColumnSvrSingle, nil, nil, isAtten, statm, cardm)
if h == nil {
err = ecode.AppNotData
return
}
op = follow
h.From(nil, op)
if h.Get().Right {
res = h
} else {
err = ecode.AppNotData
}
return
}
// LikeTriple like & coin & fav
func (s *Service) LikeTriple(c context.Context, aid, mid int64, ak string) (res *view.TripleRes, err error) {
res = new(view.TripleRes)
maxCoin := int64(1)
multiply := int64(1)
var a *api.Arc
if a, err = s.arcDao.Archive(c, aid); err != nil {
if errors.Cause(err) == ecode.NothingFound {
err = ecode.ArchiveNotExist
}
return
}
if !a.IsNormal() {
err = ecode.ArchiveNotExist
return
}
if a.Copyright == int32(archive.CopyrightOriginal) {
maxCoin = 2
multiply = 2
}
res.UpID = a.Author.Mid
eg := egV2.WithContext(c)
eg.Go(func(ctx context.Context) (err error) {
if multiply == 2 {
userCoins, _ := s.coinDao.UserCoins(ctx, mid)
if userCoins < 1 {
return
}
if userCoins < 2 {
multiply = 1
}
}
err = s.coinDao.AddCoins(ctx, aid, mid, a.Author.Mid, maxCoin, _coinAv, multiply, int16(a.TypeID), int64(a.PubDate))
if err == nil || ecode.EqualError(ecode.CoinOverMax, err) {
res.Multiply = multiply
res.Anticheat = true
res.Coin = true
err = nil
} else {
log.Error("s.coinDao.AddCoins err(%+v) aid(%d) mid(%d)", err, aid, mid)
err = nil
arcUserCoins, _ := s.coinDao.ArchiveUserCoins(ctx, aid, mid, _coinAv)
if arcUserCoins != nil && arcUserCoins.Multiply > 0 {
res.Coin = true
}
}
return
})
eg.Go(func(ctx context.Context) (err error) {
var isFav bool
if isFav, err = s.favDao.IsFavVideo(ctx, mid, aid); err != nil {
log.Error("s.favDao.IsFavVideo err(%+v) aid(%d) mid(%d)", err, aid, mid)
err = nil
} else if isFav {
res.Fav = true
return
}
if err = s.favDao.AddFav(ctx, mid, aid); err != nil {
log.Error("s.favDao.AddFav err(%+v) aid(%d) mid(%d)", err, aid, mid)
if ecode.EqualError(ecode.FavVideoExist, err) || ecode.EqualError(ecode.FavResourceExist, err) {
res.Fav = true
}
err = nil
} else {
res.Fav = true
res.Anticheat = true
}
return
})
eg.Go(func(ctx context.Context) (err error) {
if _, err = s.thumbupDao.Like(ctx, mid, res.UpID, _businessLike, aid, thumbup.TypeLike); err != nil {
log.Error("s.thumbupDao.Like err(%+v) aid(%d) mid(%d)", err, aid, mid)
if ecode.EqualError(ecode.ThumbupDupLikeErr, err) {
res.Like = true
}
err = nil
} else {
res.Like = true
res.Anticheat = true
}
return
})
eg.Go(func(ctx context.Context) (err error) {
if res.Prompt, err = s.relDao.Prompt(ctx, mid, a.Author.Mid, _promptFav); err != nil {
log.Error("s.relDao.Prompt err(%+v)", err)
err = nil
}
return
})
eg.Wait()
if !res.Coin && !res.Fav {
res.Prompt = false
}
return
}

View File

@@ -0,0 +1,69 @@
package view
import (
"context"
"fmt"
"testing"
"time"
. "github.com/smartystreets/goconvey/convey"
)
func Test_View(t *testing.T) {
Convey("View", t, func() {
v, err := s.View(context.TODO(), 1, 10111556, 0, 0, 10000, 0, 0, 0, 0, 0, "", "", "", "", "", "", "", "", time.Now())
Println(v, err)
})
}
func Test_ViewPage(t *testing.T) {
Convey("ViewPage", t, func() {
v, err := s.ViewPage(context.TODO(), 1, 1, 0, 0, 0, "", "", "", "", true, time.Now())
Println(v, err)
})
}
func Test_AddShare(t *testing.T) {
Convey("AddShare", t, func() {
_, _, _, err := s.AddShare(context.TODO(), 1, 1684013, "127.0.0.1")
So(err, ShouldBeNil)
})
}
func Test_Shot(t *testing.T) {
Convey("Shot", t, func() {
shot, _ := s.Shot(context.TODO(), 10106351, 10126396)
fmt.Printf("===%+v===", shot)
})
}
func Test_Like(t *testing.T) {
Convey("Like", t, func() {
s.Like(context.TODO(), 1, 1, 0)
})
}
func Test_AddCoin(t *testing.T) {
Convey("AddCoin", t, func() {
s.AddCoin(context.TODO(), 1, 1684013, 2, 0, 1, "", 0)
})
}
func Test_AddFav(t *testing.T) {
Convey("AddFav", t, func() {
_, err := s.AddFav(context.TODO(), 2, 1684013, []int64{1}, 1, "")
So(err, ShouldBeNil)
})
}
func Test_Paster(t *testing.T) {
Convey("Paster", t, func() {
s.Paster(context.TODO(), 1, 1, "1", "1", "")
})
}
func Test_VipPlayURL(t *testing.T) {
Convey("VipPlayURL", t, func() {
s.VipPlayURL(context.TODO(), 1, 1, 1684013)
})
}