Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

issue_watch.go 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright 2017 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.
  4. package models
  5. import (
  6. "code.gitea.io/gitea/models/db"
  7. user_model "code.gitea.io/gitea/models/user"
  8. "code.gitea.io/gitea/modules/timeutil"
  9. )
  10. // IssueWatch is connection request for receiving issue notification.
  11. type IssueWatch struct {
  12. ID int64 `xorm:"pk autoincr"`
  13. UserID int64 `xorm:"UNIQUE(watch) NOT NULL"`
  14. IssueID int64 `xorm:"UNIQUE(watch) NOT NULL"`
  15. IsWatching bool `xorm:"NOT NULL"`
  16. CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"`
  17. UpdatedUnix timeutil.TimeStamp `xorm:"updated NOT NULL"`
  18. }
  19. func init() {
  20. db.RegisterModel(new(IssueWatch))
  21. }
  22. // IssueWatchList contains IssueWatch
  23. type IssueWatchList []*IssueWatch
  24. // CreateOrUpdateIssueWatch set watching for a user and issue
  25. func CreateOrUpdateIssueWatch(userID, issueID int64, isWatching bool) error {
  26. iw, exists, err := getIssueWatch(db.GetEngine(db.DefaultContext), userID, issueID)
  27. if err != nil {
  28. return err
  29. }
  30. if !exists {
  31. iw = &IssueWatch{
  32. UserID: userID,
  33. IssueID: issueID,
  34. IsWatching: isWatching,
  35. }
  36. if _, err := db.GetEngine(db.DefaultContext).Insert(iw); err != nil {
  37. return err
  38. }
  39. } else {
  40. iw.IsWatching = isWatching
  41. if _, err := db.GetEngine(db.DefaultContext).ID(iw.ID).Cols("is_watching", "updated_unix").Update(iw); err != nil {
  42. return err
  43. }
  44. }
  45. return nil
  46. }
  47. // GetIssueWatch returns all IssueWatch objects from db by user and issue
  48. // the current Web-UI need iw object for watchers AND explicit non-watchers
  49. func GetIssueWatch(userID, issueID int64) (iw *IssueWatch, exists bool, err error) {
  50. return getIssueWatch(db.GetEngine(db.DefaultContext), userID, issueID)
  51. }
  52. // Return watcher AND explicit non-watcher if entry in db exist
  53. func getIssueWatch(e db.Engine, userID, issueID int64) (iw *IssueWatch, exists bool, err error) {
  54. iw = new(IssueWatch)
  55. exists, err = e.
  56. Where("user_id = ?", userID).
  57. And("issue_id = ?", issueID).
  58. Get(iw)
  59. return
  60. }
  61. // CheckIssueWatch check if an user is watching an issue
  62. // it takes participants and repo watch into account
  63. func CheckIssueWatch(user *user_model.User, issue *Issue) (bool, error) {
  64. iw, exist, err := getIssueWatch(db.GetEngine(db.DefaultContext), user.ID, issue.ID)
  65. if err != nil {
  66. return false, err
  67. }
  68. if exist {
  69. return iw.IsWatching, nil
  70. }
  71. w, err := getWatch(db.GetEngine(db.DefaultContext), user.ID, issue.RepoID)
  72. if err != nil {
  73. return false, err
  74. }
  75. return isWatchMode(w.Mode) || IsUserParticipantsOfIssue(user, issue), nil
  76. }
  77. // GetIssueWatchersIDs returns IDs of subscribers or explicit unsubscribers to a given issue id
  78. // but avoids joining with `user` for performance reasons
  79. // User permissions must be verified elsewhere if required
  80. func GetIssueWatchersIDs(issueID int64, watching bool) ([]int64, error) {
  81. return getIssueWatchersIDs(db.GetEngine(db.DefaultContext), issueID, watching)
  82. }
  83. func getIssueWatchersIDs(e db.Engine, issueID int64, watching bool) ([]int64, error) {
  84. ids := make([]int64, 0, 64)
  85. return ids, e.Table("issue_watch").
  86. Where("issue_id=?", issueID).
  87. And("is_watching = ?", watching).
  88. Select("user_id").
  89. Find(&ids)
  90. }
  91. // GetIssueWatchers returns watchers/unwatchers of a given issue
  92. func GetIssueWatchers(issueID int64, listOptions db.ListOptions) (IssueWatchList, error) {
  93. return getIssueWatchers(db.GetEngine(db.DefaultContext), issueID, listOptions)
  94. }
  95. func getIssueWatchers(e db.Engine, issueID int64, listOptions db.ListOptions) (IssueWatchList, error) {
  96. sess := e.
  97. Where("`issue_watch`.issue_id = ?", issueID).
  98. And("`issue_watch`.is_watching = ?", true).
  99. And("`user`.is_active = ?", true).
  100. And("`user`.prohibit_login = ?", false).
  101. Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id")
  102. if listOptions.Page != 0 {
  103. sess = db.SetSessionPagination(sess, &listOptions)
  104. watches := make([]*IssueWatch, 0, listOptions.PageSize)
  105. return watches, sess.Find(&watches)
  106. }
  107. watches := make([]*IssueWatch, 0, 8)
  108. return watches, sess.Find(&watches)
  109. }
  110. func removeIssueWatchersByRepoID(e db.Engine, userID, repoID int64) error {
  111. _, err := e.
  112. Join("INNER", "issue", "`issue`.id = `issue_watch`.issue_id AND `issue`.repo_id = ?", repoID).
  113. Where("`issue_watch`.user_id = ?", userID).
  114. Delete(new(IssueWatch))
  115. return err
  116. }