img.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package service
  2. import (
  3. "bufio"
  4. "bytes"
  5. "context"
  6. "crypto/hmac"
  7. "crypto/md5"
  8. "crypto/sha1"
  9. "encoding/base64"
  10. "encoding/hex"
  11. "fmt"
  12. "image/jpeg"
  13. "net/http"
  14. "strconv"
  15. "time"
  16. "go-common/library/log"
  17. "go-common/library/text/translate/chinese"
  18. "github.com/golang/freetype"
  19. )
  20. var (
  21. allOrders [][]int
  22. x = []int{0, 1, 2, 3}
  23. bname = "member"
  24. accessKey = "3d34b1ea1dbbb0ca"
  25. secretKey = "d4caa344f3b115e302033b05dd0aa4"
  26. _template = "%s\n%s\n%s\n%d\n"
  27. fileFormat = "v3_%s_A-%s_B-%s_C-%s_D-%s_%s"
  28. bfsURL = "http://bfs.bilibili.co/bfs/%s/%s"
  29. platform = map[string]bool{"H5": true, "PC": false}
  30. language = []string{"zh-CN", "zh-TW"}
  31. )
  32. // generate 全排列组合算法 4*3*2*1 种情况
  33. func (s *Service) generate(c context.Context, a []int, begin int, end int) {
  34. if begin == end {
  35. allOrders = append(allOrders, []int{a[0], a[1], a[2], a[3]})
  36. return
  37. }
  38. for i := begin; i <= end; i++ {
  39. a[begin], a[i] = a[i], a[begin]
  40. s.generate(c, a, begin+1, end)
  41. a[begin], a[i] = a[i], a[begin]
  42. }
  43. return
  44. }
  45. // GenerateImage .
  46. func (s *Service) GenerateImage(c context.Context) {
  47. // 把有效id放redis
  48. ids, _ := s.dao.IDsByState(c)
  49. s.CreateBFSImg(c, ids)
  50. }
  51. // CreateBFSImg .
  52. func (s *Service) CreateBFSImg(c context.Context, ids []int64) {
  53. for _, qid := range ids {
  54. log.Error("qid_%d", qid)
  55. que, err := s.dao.QueByID(c, qid)
  56. log.Error("que:%+v", que)
  57. if err != nil {
  58. log.Error("get question(%d), err(%v)", qid, err)
  59. }
  60. for _, langv := range language {
  61. if langv == "zh-TW" {
  62. que.Question = chinese.Convert(c, que.Question)
  63. que.Ans[0] = chinese.Convert(c, que.Ans[0])
  64. que.Ans[1] = chinese.Convert(c, que.Ans[1])
  65. que.Ans[2] = chinese.Convert(c, que.Ans[2])
  66. que.Ans[3] = chinese.Convert(c, que.Ans[3])
  67. }
  68. for plat, platv := range platform {
  69. for _, order := range allOrders {
  70. log.Error("allOrders(len:%d) %s_%s_%s_%s_%s_%s, %+v", len(allOrders), strconv.FormatInt(qid, 10), que.Ans[order[0]], que.Ans[order[1]], que.Ans[order[2]], que.Ans[order[3]], plat, que)
  71. quec := s.dao.QueConf(platv)
  72. imgh := s.dao.Height(quec, que.Question, len(que.Ans))
  73. r := s.dao.Board(imgh)
  74. imgc := s.dao.Context(r, s.c.Answer.FontFilePath)
  75. pt := freetype.Pt(0, int(quec.Fontsize))
  76. s.dao.DrawQue(imgc, que.Question, quec, &pt)
  77. as := [4]string{que.Ans[order[0]], que.Ans[order[1]], que.Ans[order[2]], que.Ans[order[3]]}
  78. s.dao.DrawAns(imgc, quec, as, &pt)
  79. buf := new(bytes.Buffer)
  80. jpeg.Encode(buf, r, nil)
  81. bufReader := bufio.NewReader(buf)
  82. ts := time.Now().Unix()
  83. tm := time.Unix(ts, 0)
  84. m := md5.New()
  85. m.Write([]byte(fmt.Sprintf(fileFormat, strconv.FormatInt(qid, 10), que.Ans[order[0]], que.Ans[order[1]], que.Ans[order[2]], que.Ans[order[3]], plat)))
  86. fname := hex.EncodeToString(m.Sum(nil)) + ".jpg"
  87. if s.c.Answer.Debug {
  88. fname = fmt.Sprintf("debug_%s", fname)
  89. }
  90. //imgName = append(imgName, fname)
  91. client := &http.Client{}
  92. content := fmt.Sprintf(_template, "PUT", bname, fname, ts)
  93. mac := hmac.New(sha1.New, []byte(secretKey))
  94. mac.Write([]byte(content))
  95. sign := base64.StdEncoding.EncodeToString(mac.Sum(nil))
  96. req, _ := http.NewRequest(http.MethodPut, fmt.Sprintf(bfsURL, bname, fname), bufReader)
  97. req.Host = "bfs.bilibili.co"
  98. req.Header.Add("Date", tm.Format("2006-01-02 03:04:05"))
  99. req.Header.Add("Authorization", accessKey+":"+sign+":"+strconv.FormatInt(ts, 10))
  100. req.Header.Set("Content-Type", "image/jpeg")
  101. resp, _ := client.Do(req)
  102. //defer resp.Body.Close()
  103. if err != nil {
  104. log.Error("qid %s bfs upload failed error(%s)", strconv.FormatInt(qid, 10), err)
  105. //return
  106. }
  107. log.Info("upload img(%d), %s, %+v", qid, fname, resp)
  108. time.Sleep(time.Millisecond * 50)
  109. }
  110. }
  111. }
  112. }
  113. }