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,55 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = ["service_test.go"],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/job/main/answer/conf:go_default_library",
"//app/job/main/answer/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"img.go",
"question.go",
"service.go",
],
importpath = "go-common/app/job/main/answer/service",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/job/main/answer/conf:go_default_library",
"//app/job/main/answer/dao:go_default_library",
"//app/job/main/answer/model:go_default_library",
"//library/log:go_default_library",
"//library/queue/databus:go_default_library",
"//library/text/translate/chinese:go_default_library",
"//vendor/github.com/golang/freetype: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,62 @@
package service
import (
"bufio"
"bytes"
"context"
"crypto/md5"
"encoding/hex"
"fmt"
"image/jpeg"
"strconv"
"go-common/app/job/main/answer/model"
"go-common/library/log"
"go-common/library/text/translate/chinese"
"github.com/golang/freetype"
)
var (
platform = map[string]bool{"H5": true, "PC": false}
fileFormat = "%s_A-%s_B-%s_%s"
language = []string{"zh-CN", "zh-TW"}
)
// createBFSImg create bfs img.
func (s *Service) createBFSImg(c context.Context, que *model.LabourQs) (err error) {
log.Info("createBFSImg(%v)", que)
as := [2]string{model.ExtraAnsA, model.ExtraAnsB}
for _, langv := range language {
if langv == "zh-TW" {
que.Question = chinese.Convert(c, que.Question)
as = [2]string{chinese.Convert(c, model.ExtraAnsA), chinese.Convert(c, model.ExtraAnsB)}
}
for ps, pb := range platform {
quec := s.dao.QueConf(pb)
imgh := s.dao.Height(quec, que.Question, 2)
r := s.dao.Board(imgh)
imgc := s.dao.Context(r, s.c.Properties.FontFilePath)
pt := freetype.Pt(0, int(quec.Fontsize))
s.dao.DrawQue(imgc, que.Question, quec, &pt)
s.dao.DrawAns(imgc, quec, as, &pt)
buf := new(bytes.Buffer)
jpeg.Encode(buf, r, nil)
bufReader := bufio.NewReader(buf)
m := md5.New()
m.Write([]byte(fmt.Sprintf(fileFormat, strconv.FormatInt(que.ID, 10), as[0], as[1], ps)))
fname := hex.EncodeToString(m.Sum(nil)) + ".jpg"
location, err := s.dao.Upload(c, "image/jpeg", fname, bufReader)
if err != nil {
log.Error("question (%v) bfs upload failed error(%s)", que, err)
continue
}
log.Info("upload img success.fname:%s,location:%s,lang:%s", fname, location, langv)
}
}
return
}

View File

@@ -0,0 +1,60 @@
package service
import (
"context"
"encoding/json"
"go-common/app/job/main/answer/model"
"go-common/library/log"
)
// AddLabourQuestion add labour question.
func (s *Service) AddLabourQuestion(c context.Context, msg *model.MsgCanal) (err error) {
var que = &model.LabourQs{}
if err = json.Unmarshal(msg.New, que); err != nil {
log.Error("json.Unmarshal(%v) err(%v)", msg, err)
return
}
log.Info("labour add (%+v)", que)
if err = s.createBFSImg(c, que); err != nil {
log.Error("createBFSImg(%v) err(%v)", que, err)
return
}
que.State = model.HadCreateImg
s.dao.AddQs(c, que)
return
}
// ModifyLabourQuestion nodify labour question.
func (s *Service) ModifyLabourQuestion(c context.Context, msg *model.MsgCanal) (err error) {
var (
newq = &model.LabourQs{}
oldq = &model.LabourQs{}
)
if err = json.Unmarshal(msg.New, newq); err != nil {
log.Error("newlqs json.Unmarshal(%v) err(%v)", msg, err)
return
}
if err = json.Unmarshal(msg.Old, oldq); err != nil {
log.Error("oldlqs json.Unmarshal(%v) err(%v)", msg, err)
return
}
log.Info("labour modify (%+v)(%+v)", newq, oldq)
if newq.Status == oldq.Status && newq.Ans == oldq.Ans && newq.Isdel == oldq.Isdel {
log.Error("ModifyLabourQuestion no change(%v, %v)", newq, oldq)
return
}
s.dao.UpdateQs(c, newq)
return
}
// UploadQueImg uplaod que img.
func (s *Service) UploadQueImg(c context.Context, que *model.LabourQs) (err error) {
if err = s.createBFSImg(c, que); err != nil {
log.Error("createBFSImg(%v) err(%v)", que, err)
return
}
que.State = model.HadCreateImg
s.dao.UpdateState(c, que)
return
}

View File

@@ -0,0 +1,161 @@
package service
import (
"context"
"encoding/json"
"sync"
"time"
"go-common/app/job/main/answer/conf"
"go-common/app/job/main/answer/dao"
"go-common/app/job/main/answer/model"
"go-common/library/log"
"go-common/library/queue/databus"
)
const (
_insertAction = "insert"
_updateAction = "update"
_labourTable = "blocked_labour_question"
)
// Service service def.
type Service struct {
c *conf.Config
dao *dao.Dao
labourDatabus *databus.Databus
accountFormal *databus.Databus
waiter sync.WaitGroup
uploadInterval time.Duration
closed bool
}
// New create a instance of Service and return.
func New(c *conf.Config) (s *Service) {
s = &Service{
c: c,
dao: dao.New(c),
uploadInterval: time.Duration(c.Properties.UploadInterval),
}
if c.Databus.Labour != nil {
s.labourDatabus = databus.New(c.Databus.Labour)
s.waiter.Add(1)
go s.labourproc()
}
if c.Databus.Account != nil {
s.accountFormal = databus.New(c.Databus.Account)
go s.formalproc()
}
s.waiter.Add(1)
go s.loadextarqueproc()
return s
}
func (s *Service) labourproc() {
defer s.waiter.Done()
var (
err error
msg *databus.Message
msgChan = s.labourDatabus.Messages()
ok bool
)
for {
msg, ok = <-msgChan
if !ok {
log.Info("labour msgChan closed")
}
if s.closed {
return
}
if err = msg.Commit(); err != nil {
log.Error("msg.Commit err(%v)", err)
}
v := &model.MsgCanal{}
if err = json.Unmarshal([]byte(msg.Value), v); err != nil {
log.Error("json.Unmarshal(%v) err(%v)", v, err)
continue
}
if v.Table == _labourTable {
switch v.Action {
case _insertAction:
s.AddLabourQuestion(context.Background(), v)
case _updateAction:
s.ModifyLabourQuestion(context.Background(), v)
}
}
}
}
func (s *Service) formalproc() {
var (
ok bool
err error
msg *databus.Message
msgChan = s.accountFormal.Messages()
)
for {
msg, ok = <-msgChan
if !ok {
log.Info("account formal msgChan closed")
}
if s.closed {
return
}
v := &model.Formal{}
if err = json.Unmarshal([]byte(msg.Value), v); err != nil {
log.Error("json.Unmarshal(%v) err(%v)", v, err)
continue
}
for retries := 0; retries < s.c.Properties.MaxRetries; retries++ {
if err = s.dao.BeFormal(context.Background(), v.Mid, v.IP); err != nil {
sleep := s.c.Backoff.Backoff(retries)
log.Error("s.dao.BeFormal(%+v) sleep(%d) err(%+v)", v, sleep, err)
time.Sleep(sleep * time.Second)
continue
}
break
}
if err = msg.Commit(); err != nil {
log.Error("msg.Commit err(%v)", err)
}
}
}
// Close all resource.
func (s *Service) Close() (err error) {
defer s.waiter.Wait()
s.closed = true
s.dao.Close()
if err = s.labourDatabus.Close(); err != nil {
log.Error("s.labourDatabus.Close() error(%v)", err)
return
}
return
}
// Ping check dao health.
func (s *Service) Ping(c context.Context) (err error) {
return s.dao.Ping(c)
}
func (s *Service) loadextarqueproc() {
defer s.waiter.Done()
for {
time.Sleep(s.uploadInterval)
if s.closed {
return
}
res, err := s.dao.QidsExtraByState(context.Background(), model.LimitSize)
if err != nil {
log.Error("s.dao.QidsExtraByState() error(%v)", err)
continue
}
if len(res) == 0 {
continue
}
for _, q := range res {
s.UploadQueImg(context.Background(), q)
}
}
}

View File

@@ -0,0 +1,81 @@
package service
import (
"context"
"flag"
"fmt"
"os"
"testing"
"go-common/app/job/main/answer/conf"
"go-common/app/job/main/answer/model"
. "github.com/smartystreets/goconvey/convey"
)
var (
s *Service
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "")
flag.Set("conf_appid", "")
flag.Set("conf_token", "")
flag.Set("tree_id", "")
flag.Set("conf_version", "server-1")
flag.Set("deploy_env", "dev")
flag.Set("conf_env", "10")
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/answer-job-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
s = New(conf.Conf)
os.Exit(m.Run())
}
func TestUpdateBfs(t *testing.T) {
Convey("create img", t, func(s *Service) {
err := s.createBFSImg(context.TODO(), &model.LabourQs{
Question: "测试附加题3",
ID: 3,
})
fmt.Println("err:", err)
So(err, ShouldBeNil)
})
}
func TestPing(t *testing.T) {
Convey("Test_Ping", t, func(s *Service) {
err := s.Ping(context.TODO())
So(err, ShouldBeNil)
})
}
// go test -test.v -test.run TestAddQue
func TestCreateBFSImg(t *testing.T) {
Convey("TestAddQue add question data", t, func(s *Service) {
for i := 90; i < 100; i++ {
que := &model.LabourQs{
Question: fmt.Sprintf("测试d=====( ̄▽ ̄*)b厉害 %d", i),
Ans: int8(i%2 + 1),
AvID: int64(i),
Status: int8(i%2 + 1),
Source: int8(1),
State: model.HadCreateImg,
ID: int64(i),
}
err := s.createBFSImg(context.TODO(), que)
So(err, ShouldBeNil)
err = s.dao.AddQs(context.TODO(), que)
So(err, ShouldBeNil)
}
})
}