berserker.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. package dao
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/md5"
  6. "encoding/hex"
  7. "fmt"
  8. "net/url"
  9. "sort"
  10. "strings"
  11. "time"
  12. "go-common/app/job/openplatform/open-market/model"
  13. "go-common/library/conf/env"
  14. "go-common/library/log"
  15. xhttp "net/http"
  16. pkgerr "github.com/pkg/errors"
  17. )
  18. const (
  19. _userAgent = "User-Agent"
  20. _queryJSON = `{"select":[{"name":"item_id"},{"name":"pv"},{"name":"uv"},{"name":"days_before"}],"where":{"item_id":{"in":[%d]}},"page":{"limit":30,"skip":0}}`
  21. )
  22. var (
  23. signParams = []string{"appKey", "timestamp", "version"}
  24. )
  25. // QueryPUVCount get puv info from berserker
  26. func (d *Dao) QueryPUVCount(c context.Context, itemID int32) (pv map[int32]int64, uv map[int32]int64, err error) {
  27. pv = make(map[int32]int64)
  28. uv = make(map[int32]int64)
  29. v := make(url.Values, 8)
  30. v.Set("appKey", d.c.Berserker.Appkey)
  31. v.Set("signMethod", "md5")
  32. v.Set("timestamp", time.Now().Format("2006-01-02 15:04:05"))
  33. v.Set("version", "1.0")
  34. query := fmt.Sprintf(_queryJSON, itemID)
  35. v.Set("query", query)
  36. var res struct {
  37. Code int `json:"code"`
  38. Result []model.PUVResult `json:"result"`
  39. }
  40. if err = d.doHTTPRequest(c, d.c.Berserker.URL, "", v, &res); err != nil {
  41. log.Error(d.c.Berserker.URL+"?"+v.Encode(), err)
  42. return
  43. }
  44. if res.Code == 200 && len(res.Result) > 0 {
  45. for _, v := range res.Result {
  46. pv[v.DaysBefore] = v.PV
  47. uv[v.DaysBefore] = v.UV
  48. }
  49. return
  50. }
  51. return
  52. }
  53. // doHttpRequest make a http request for data platform api
  54. func (d *Dao) doHTTPRequest(c context.Context, uri, ip string, params url.Values, res interface{}) (err error) {
  55. enc, err := d.sign(params)
  56. if err != nil {
  57. err = pkgerr.Wrapf(err, "uri:%s,params:%v", uri, params)
  58. return
  59. }
  60. if enc != "" {
  61. uri = uri + "?" + enc
  62. }
  63. req, err := xhttp.NewRequest(xhttp.MethodGet, uri, nil)
  64. if err != nil {
  65. err = pkgerr.Wrapf(err, "method:%s,uri:%s", xhttp.MethodGet, uri)
  66. return
  67. }
  68. req.Header.Set(_userAgent, "changxuanran@bilibili.com "+env.AppID)
  69. if err != nil {
  70. return
  71. }
  72. return d.client.Do(c, req, res)
  73. }
  74. // Sign calc appkey and appsecret sign.
  75. func (d *Dao) sign(params url.Values) (query string, err error) {
  76. tmp := params.Encode()
  77. signTmp := d.encode(params)
  78. if strings.IndexByte(tmp, '+') > -1 {
  79. tmp = strings.Replace(tmp, "+", "%20", -1)
  80. }
  81. var b bytes.Buffer
  82. b.WriteString(d.c.Berserker.Secret)
  83. b.WriteString(signTmp)
  84. b.WriteString(d.c.Berserker.Secret)
  85. mh := md5.Sum(b.Bytes())
  86. // query
  87. var qb bytes.Buffer
  88. qb.WriteString(tmp)
  89. qb.WriteString("&sign=")
  90. qb.WriteString(strings.ToUpper(hex.EncodeToString(mh[:])))
  91. query = qb.String()
  92. return
  93. }
  94. // Encode encodes the values into ``URL encoded'' form
  95. // ("bar=baz&foo=quux") sorted by key.
  96. func (d *Dao) encode(v url.Values) string {
  97. if v == nil {
  98. return ""
  99. }
  100. var buf bytes.Buffer
  101. keys := make([]string, 0, len(v))
  102. for k := range v {
  103. keys = append(keys, k)
  104. }
  105. sort.Strings(keys)
  106. for _, k := range keys {
  107. found := false
  108. for _, p := range signParams {
  109. if p == k {
  110. found = true
  111. break
  112. }
  113. }
  114. if !found {
  115. continue
  116. }
  117. vs := v[k]
  118. prefix := k
  119. for _, v := range vs {
  120. buf.WriteString(prefix)
  121. buf.WriteString(v)
  122. }
  123. }
  124. return buf.String()
  125. }
  126. //func (d *Dao) reverse(s string) string {
  127. // n := len(s)
  128. // runes := make([]rune, n)
  129. // for _, rune := range s {
  130. // n--
  131. // runes[n] = rune
  132. // }
  133. // return string(runes[n:])
  134. //}