bilibili-backup/app/service/main/reply-feed/server/http/http.go
2019-04-22 02:59:20 +00:00

254 lines
5.7 KiB
Go

package http
import (
"encoding/json"
"net/http"
"strconv"
"strings"
"go-common/app/service/main/reply-feed/conf"
"go-common/app/service/main/reply-feed/model"
"go-common/app/service/main/reply-feed/service"
"go-common/library/ecode"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/net/http/blademaster/middleware/verify"
)
var (
svc *service.Service
vfy *verify.Verify
)
// Init init
func Init(c *conf.Config, s *service.Service) {
svc = s
vfy = verify.New(c.Verify)
engine := bm.DefaultServer(c.BM)
router(engine)
if err := engine.Start(); err != nil {
log.Error("engine.Start error(%v)", err)
panic(err)
}
}
func router(e *bm.Engine) {
e.Ping(ping)
e.Register(register)
g := e.Group("/x/reply-feed")
{
g.POST("/strategy/new", newEGroup)
g.POST("/strategy/edit", editEgroup)
g.POST("/strategy/state", modifyState)
g.POST("/strategy/resize", resizeSlots)
g.POST("/strategy/reset", resetEgroup)
g.GET("/strategy/list", listEGroup)
g.GET("/statistics/list", statistics)
}
}
func ping(c *bm.Context) {
if err := svc.Ping(c); err != nil {
log.Error("ping error(%v)", err)
c.AbortWithStatus(http.StatusServiceUnavailable)
}
}
func register(c *bm.Context) {
c.JSON(map[string]interface{}{}, nil)
}
func validate(algorithm string, weight string) (err error) {
switch algorithm {
case model.WilsonLHRRAlgorithm:
w := &model.WilsonLHRRWeight{}
if err = json.Unmarshal([]byte(weight), &w); err != nil {
return
}
return w.Validate()
case model.WilsonLHRRFluidAlgorithm:
w := &model.WilsonLHRRFluidWeight{}
if err = json.Unmarshal([]byte(weight), &w); err != nil {
return
}
return w.Validate()
case model.OriginAlgorithm, model.LikeDescAlgorithm:
return
default:
log.Error("unknown algorithm accepted (%s)", algorithm)
err = ecode.RequestErr
}
if err != nil {
return
}
return
}
func listEGroup(c *bm.Context) {
stats, err := svc.SlotStatsManager(c)
if err != nil {
c.JSON(nil, err)
return
}
c.JSON(stats, nil)
}
func newEGroup(c *bm.Context) {
v := new(struct {
Name string `form:"name" validate:"required"`
Percent int `form:"percent" validate:"required"`
Algorithm string `form:"algorithm" validate:"required"`
Weight string `form:"weight" validate:"required"`
})
var (
err error
)
if err = c.Bind(v); err != nil {
return
}
if err = validate(v.Algorithm, v.Weight); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(nil, svc.NewEGroup(c, v.Name, v.Algorithm, v.Weight, v.Percent))
}
func editEgroup(c *bm.Context) {
v := new(struct {
Name string `form:"name" validate:"required"`
Algorithm string `form:"algorithm" validate:"required"`
Weight string `form:"weight" validate:"required"`
Slots []int64 `form:"slots,split" validate:"required"`
})
var (
err error
)
if err = c.Bind(v); err != nil {
return
}
if err = validate(v.Algorithm, v.Weight); err != nil {
c.JSON(nil, ecode.RequestErr)
return
}
c.JSON(nil, svc.EditSlotsStat(c, v.Name, v.Algorithm, v.Weight, v.Slots))
}
func modifyState(c *bm.Context) {
v := new(struct {
Name string `form:"name" validate:"required"`
State int `form:"state"`
})
var (
err error
)
if err = c.Bind(v); err != nil {
return
}
c.JSON(nil, svc.ModifyState(c, v.Name, v.State))
}
func resizeSlots(c *bm.Context) {
v := new(struct {
Name string `form:"name" validate:"required"`
Percent int `form:"percent" validate:"required"`
})
var (
err error
)
if err = c.Bind(v); err != nil {
return
}
c.JSON(nil, svc.ResizeSlots(c, v.Name, v.Percent))
}
func resetEgroup(c *bm.Context) {
v := new(struct {
Name string `form:"name" validate:"required"`
})
var (
err error
)
if err = c.Bind(v); err != nil {
return
}
c.JSON(nil, svc.ResetEGroup(c, v.Name))
}
func statistics(c *bm.Context) {
v := new(model.SSReq)
if err := c.Bind(v); err != nil {
return
}
if v.Hour {
res := new(model.SSHourRes)
data, err := svc.StatisticsByHour(c, v)
if err != nil {
c.JSON(nil, err)
return
}
xAxisMap := make(map[string]struct{})
res.Series = make(map[string][]*model.StatisticsStat)
for legend, m := range data {
res.Legend = append(res.Legend, legend)
for xAxis := range m {
xAxisMap[xAxis] = struct{}{}
}
}
for k := range xAxisMap {
res.XAxis = append(res.XAxis, k)
}
for _, legend := range res.Legend {
if hourStatistics, ok := data[legend]; ok {
for _, hour := range res.XAxis {
if stat, exists := hourStatistics[hour]; exists {
res.Series[legend] = append(res.Series[legend], stat)
} else {
t := strings.Split(hour, "-")
if len(t) < 2 {
c.Abort()
return
}
date, _ := strconv.Atoi(t[0])
hour, _ := strconv.Atoi(t[1])
res.Series[legend] = append(res.Series[legend], &model.StatisticsStat{Date: date, Hour: hour})
}
}
}
}
res.Sort()
c.JSON(res, nil)
return
}
res := new(model.SSDateRes)
data, err := svc.StatisticsByDate(c, v)
if err != nil {
c.JSON(nil, err)
return
}
xAxisMap := make(map[int]struct{})
res.Series = make(map[string][]*model.StatisticsStat)
for legend, m := range data {
res.Legend = append(res.Legend, legend)
for xAxis := range m {
xAxisMap[xAxis] = struct{}{}
}
}
for k := range xAxisMap {
res.XAxis = append(res.XAxis, k)
}
for _, legend := range res.Legend {
if dateStatistics, ok := data[legend]; ok {
for _, date := range res.XAxis {
if stat, exists := dateStatistics[date]; exists {
res.Series[legend] = append(res.Series[legend], stat)
} else {
res.Series[legend] = append(res.Series[legend], &model.StatisticsStat{Date: date})
}
}
}
}
res.Sort()
c.JSON(res, nil)
}