user.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package libamuse
  2. import (
  3. "notabug.org/apiote/amuse/accounts"
  4. "notabug.org/apiote/amuse/db"
  5. "notabug.org/apiote/amuse/network"
  6. "crypto/sha256"
  7. "encoding/base64"
  8. "errors"
  9. "net/http"
  10. "notabug.org/apiote/gott"
  11. )
  12. type Avatar struct {
  13. Data []byte
  14. Mimetype string
  15. Etag string
  16. }
  17. func getUser(args ...interface{}) (interface{}, error) {
  18. request := args[0].(*RequestData)
  19. result := args[1].(*Result)
  20. user, err := db.GetUser(request.id)
  21. result.result = user
  22. return gott.Tuple(args), err
  23. }
  24. func getAvatar(args ...interface{}) (interface{}, error) {
  25. result := args[1].(*Result)
  26. small := args[2].(bool)
  27. user := result.result.(*db.User)
  28. if small {
  29. if string(user.AvatarSmall) == "" {
  30. return gott.Tuple(args), errors.New("No avatar")
  31. } else {
  32. result.result = user.AvatarSmall
  33. }
  34. } else {
  35. if string(user.Avatar) == "" {
  36. return gott.Tuple(args), errors.New("No avatar")
  37. } else {
  38. result.result = user.Avatar
  39. }
  40. }
  41. result.result2 = "image/webp"
  42. return gott.Tuple(args), nil
  43. }
  44. func checkEtag(args ...interface{}) (interface{}, error) {
  45. request := args[0].(*RequestData)
  46. result := args[1].(*Result)
  47. h := sha256.New()
  48. _, err := h.Write([]byte(result.page))
  49. if err != nil {
  50. return gott.Tuple(args), err
  51. }
  52. etag := base64.StdEncoding.EncodeToString(h.Sum(nil))
  53. if etag == request.etag {
  54. result.result = []byte{}
  55. }
  56. result.page = etag
  57. return gott.Tuple(args), nil
  58. }
  59. func createPlaceholderRequest(args ...interface{}) (interface{}, error) {
  60. request := args[0].(*network.Request)
  61. result := args[1].(*network.Result)
  62. small := args[2].(bool)
  63. result.Client = &http.Client{}
  64. size := "512"
  65. if small {
  66. size = "40"
  67. }
  68. httpRequest, err := http.NewRequest("GET", "https://api.adorable.io/avatars/"+size+"/"+request.Id+".png", nil)
  69. result.Request = httpRequest
  70. return gott.Tuple(args), err
  71. }
  72. func unmarshalPlaceholder(args ...interface{}) interface{} {
  73. result := args[1].(*network.Result)
  74. result.Result = result.Body
  75. return gott.Tuple(args)
  76. }
  77. func recovery(args ...interface{}) (interface{}, error) {
  78. err := args[3].(error)
  79. switch err.Error() {
  80. case "No avatar":
  81. return getPlaceholder(args...)
  82. default:
  83. return gott.Tuple(args), err
  84. }
  85. }
  86. func getPlaceholder(args ...interface{}) (interface{}, error) {
  87. request := args[0].(*RequestData)
  88. result := args[1].(*Result)
  89. small := args[2].(bool)
  90. r, err := gott.
  91. NewResult(gott.Tuple{&network.Request{Id: request.id, Etag: request.etag}, &network.Result{}, small}).
  92. Bind(createPlaceholderRequest).
  93. Map(network.AddHeaders).
  94. Bind(network.DoRequest).
  95. Bind(network.HandleRequestError).
  96. Bind(network.ReadResponse).
  97. Map(unmarshalPlaceholder).
  98. // todo get etag
  99. Finish()
  100. if err != nil {
  101. return gott.Tuple(args), err
  102. }
  103. result.result = r.(gott.Tuple)[1].(*network.Result).Result.([]byte)
  104. result.result2 = "image/png"
  105. return gott.Tuple(args), nil
  106. }
  107. func ShowUserAvatar(username, etagReq string, auth accounts.Authentication, small bool) (Avatar, error) {
  108. auth.Necessary = true
  109. avatar := Avatar{}
  110. r, err := gott.
  111. NewResult(gott.Tuple{&RequestData{id: username, etag: etagReq, auth: auth, username: username}, &Result{}, small}).
  112. Bind(verifyToken).
  113. Bind(verifyUser).
  114. Bind(getUser).
  115. Bind(getAvatar).
  116. Bind(checkEtag).
  117. Recover(recovery).
  118. Finish()
  119. if err != nil {
  120. return avatar, err
  121. }
  122. r = r.(gott.Tuple)[1]
  123. avatar.Data = r.(*Result).result.([]byte)
  124. avatar.Mimetype = r.(*Result).result2.(string)
  125. avatar.Etag = r.(*Result).page
  126. return avatar, nil
  127. }