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.3KB

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