You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

task.go 4.3 kB

3 years ago
2 years ago
3 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
2 years ago
2 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
2 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
2 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package task
  2. import (
  3. "code.gitea.io/gitea/models"
  4. "code.gitea.io/gitea/modules/log"
  5. "code.gitea.io/gitea/services/reward"
  6. "code.gitea.io/gitea/services/reward/limiter"
  7. "fmt"
  8. "strconv"
  9. "strings"
  10. )
  11. func Accomplish(action models.Action) {
  12. defer func() {
  13. if err := recover(); err != nil {
  14. combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2))
  15. log.Error("PANIC:%v", combinedErr)
  16. }
  17. }()
  18. taskType := models.GetTaskTypeFromAction(action.OpType)
  19. if taskType == "" {
  20. log.Info("Accomplish finished.taskType is not exist.action.ID=%d", action.ID)
  21. return
  22. }
  23. actions := make([]models.Action, 0)
  24. actions = append(actions, action)
  25. switch taskType {
  26. //only creating public repo can be rewarded
  27. case models.TaskCreatePublicRepo:
  28. if action.Repo.IsPrivate {
  29. return
  30. }
  31. //only creating public image can be rewarded
  32. case models.TaskCreateImage:
  33. if action.IsPrivate {
  34. return
  35. }
  36. case models.TaskBindWechat:
  37. n, err := models.CountWechatBindLog(action.Content, models.WECHAT_BIND)
  38. if err != nil {
  39. log.Error("CountWechatBindLog error when accomplish task,err=%v", err)
  40. return
  41. }
  42. //if wechatOpenId has been bound before,the action can not get reward
  43. if n > 1 && models.IsWechatOpenIdRewarded(action.Content) {
  44. log.Debug("the wechat account has been bound before,wechatOpenId = %s", action.Content)
  45. return
  46. }
  47. case models.TaskDatasetRecommended:
  48. datasetIdStr := strings.Split(action.Content, "|")[0]
  49. datasetId, _ := strconv.ParseInt(datasetIdStr, 10, 64)
  50. users, err := models.GetAllDatasetContributorByDatasetId(datasetId)
  51. if err != nil {
  52. return
  53. }
  54. for _, user := range users {
  55. if user.ID == action.ActUserID {
  56. continue
  57. }
  58. actions = append(actions, models.Action{
  59. ID: action.ID,
  60. OpType: models.ActionDatasetRecommended,
  61. ActUserID: action.ActUserID,
  62. UserID: user.ID,
  63. RepoID: action.RepoID,
  64. Content: action.Content,
  65. })
  66. }
  67. }
  68. batchAccomplish(taskType, actions...)
  69. }
  70. func batchAccomplish(taskType models.TaskType, actions ...models.Action) {
  71. for _, act := range actions {
  72. go accomplish(act, taskType)
  73. }
  74. }
  75. func accomplish(action models.Action, taskType models.TaskType) error {
  76. defer func() {
  77. if err := recover(); err != nil {
  78. combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2))
  79. log.Error("PANIC:%v", combinedErr)
  80. }
  81. }()
  82. log.Info("accomplish start. actionId=%d userId= %d", action.ID, action.UserID)
  83. userId := action.UserID
  84. if !isUserAvailable(userId) {
  85. return nil
  86. }
  87. //get task config
  88. config, err := GetTaskConfig(string(taskType))
  89. if err != nil {
  90. log.Error("GetTaskConfig error,%v", err)
  91. return err
  92. }
  93. if config == nil {
  94. log.Info("task config not exist,userId=%d taskType=%s", userId, taskType)
  95. return nil
  96. }
  97. //is limited?
  98. if isLimited(userId, config, models.JustReject) {
  99. log.Info("task accomplish maximum times are reached,userId=%d taskType=%s", userId, taskType)
  100. return nil
  101. }
  102. //add log
  103. _, err = models.InsertTaskAccomplishLog(&models.TaskAccomplishLog{
  104. ConfigId: config.ID,
  105. TaskCode: config.TaskCode,
  106. UserId: userId,
  107. ActionId: action.ID,
  108. })
  109. if err != nil {
  110. log.Error("InsertTaskAccomplishLog error,%v", err)
  111. return err
  112. }
  113. //reward
  114. reward.Operate(&models.RewardOperateContext{
  115. SourceType: models.SourceTypeAccomplishTask,
  116. SourceId: fmt.Sprint(action.ID),
  117. SourceTemplateId: string(taskType),
  118. Title: config.Title,
  119. Reward: models.Reward{
  120. Amount: config.AwardAmount,
  121. Type: models.GetRewardTypeInstance(config.AwardType),
  122. },
  123. TargetUserId: userId,
  124. RequestId: fmt.Sprintf("%d_%d", action.ID, userId),
  125. OperateType: models.OperateTypeIncrease,
  126. RejectPolicy: models.FillUp,
  127. })
  128. log.Debug("accomplish success,action=%v", action)
  129. return nil
  130. }
  131. func isLimited(userId int64, config *models.TaskConfig, rejectPolicy models.LimiterRejectPolicy) bool {
  132. if _, err := limiter.CheckLimit(config.TaskCode, models.LimitTypeTask, userId, 1, rejectPolicy); err != nil {
  133. log.Error(" isLimited CheckLimit error. %v", err)
  134. return true
  135. }
  136. return false
  137. }
  138. func isUserAvailable(userId int64) bool {
  139. if userId < 1 {
  140. return false
  141. }
  142. user, err := models.GetUserByID(userId)
  143. if err != nil || user == nil {
  144. return false
  145. }
  146. if user.IsOrganization() {
  147. return false
  148. }
  149. return true
  150. }