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

user_heatmap.go 2.4KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. // Copyright 2018 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package activities
  4. import (
  5. "code.gitea.io/gitea/models/db"
  6. "code.gitea.io/gitea/models/organization"
  7. user_model "code.gitea.io/gitea/models/user"
  8. "code.gitea.io/gitea/modules/setting"
  9. "code.gitea.io/gitea/modules/timeutil"
  10. )
  11. // UserHeatmapData represents the data needed to create a heatmap
  12. type UserHeatmapData struct {
  13. Timestamp timeutil.TimeStamp `json:"timestamp"`
  14. Contributions int64 `json:"contributions"`
  15. }
  16. // GetUserHeatmapDataByUser returns an array of UserHeatmapData
  17. func GetUserHeatmapDataByUser(user, doer *user_model.User) ([]*UserHeatmapData, error) {
  18. return getUserHeatmapData(user, nil, doer)
  19. }
  20. // GetUserHeatmapDataByUserTeam returns an array of UserHeatmapData
  21. func GetUserHeatmapDataByUserTeam(user *user_model.User, team *organization.Team, doer *user_model.User) ([]*UserHeatmapData, error) {
  22. return getUserHeatmapData(user, team, doer)
  23. }
  24. func getUserHeatmapData(user *user_model.User, team *organization.Team, doer *user_model.User) ([]*UserHeatmapData, error) {
  25. hdata := make([]*UserHeatmapData, 0)
  26. if !ActivityReadable(user, doer) {
  27. return hdata, nil
  28. }
  29. // Group by 15 minute intervals which will allow the client to accurately shift the timestamp to their timezone.
  30. // The interval is based on the fact that there are timezones such as UTC +5:30 and UTC +12:45.
  31. groupBy := "created_unix / 900 * 900"
  32. groupByName := "timestamp" // We need this extra case because mssql doesn't allow grouping by alias
  33. switch {
  34. case setting.Database.UseMySQL:
  35. groupBy = "created_unix DIV 900 * 900"
  36. case setting.Database.UseMSSQL:
  37. groupByName = groupBy
  38. }
  39. cond, err := activityQueryCondition(GetFeedsOptions{
  40. RequestedUser: user,
  41. RequestedTeam: team,
  42. Actor: doer,
  43. IncludePrivate: true, // don't filter by private, as we already filter by repo access
  44. IncludeDeleted: true,
  45. // * Heatmaps for individual users only include actions that the user themself did.
  46. // * For organizations actions by all users that were made in owned
  47. // repositories are counted.
  48. OnlyPerformedBy: !user.IsOrganization(),
  49. })
  50. if err != nil {
  51. return nil, err
  52. }
  53. return hdata, db.GetEngine(db.DefaultContext).
  54. Select(groupBy+" AS timestamp, count(user_id) as contributions").
  55. Table("action").
  56. Where(cond).
  57. And("created_unix > ?", timeutil.TimeStampNow()-31536000).
  58. GroupBy(groupByName).
  59. OrderBy("timestamp").
  60. Find(&hdata)
  61. }