2018-02-21 13:55:34 +03:00
// Copyright 2018 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2018-02-21 13:55:34 +03:00
2022-08-25 05:31:57 +03:00
package activities
2018-02-21 13:55:34 +03:00
2021-09-19 14:49:59 +03:00
import (
2022-05-20 17:08:52 +03:00
"context"
2021-09-19 14:49:59 +03:00
"fmt"
2024-03-12 07:57:19 +03:00
"strconv"
2021-09-19 14:49:59 +03:00
"code.gitea.io/gitea/models/db"
2024-03-12 07:57:19 +03:00
issues_model "code.gitea.io/gitea/models/issues"
2021-12-10 04:27:50 +03:00
repo_model "code.gitea.io/gitea/models/repo"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2022-03-31 12:20:39 +03:00
"code.gitea.io/gitea/modules/container"
2024-03-12 07:57:19 +03:00
"code.gitea.io/gitea/modules/util"
"xorm.io/builder"
2021-09-19 14:49:59 +03:00
)
2018-02-21 13:55:34 +03:00
// ActionList defines a list of actions
type ActionList [ ] * Action
func ( actions ActionList ) getUserIDs ( ) [ ] int64 {
2024-04-09 15:27:30 +03:00
return container . FilterSlice ( actions , func ( action * Action ) ( int64 , bool ) {
return action . ActUserID , true
} )
2018-02-21 13:55:34 +03:00
}
2024-03-12 07:57:19 +03:00
func ( actions ActionList ) LoadActUsers ( ctx context . Context ) ( map [ int64 ] * user_model . User , error ) {
2018-02-21 13:55:34 +03:00
if len ( actions ) == 0 {
return nil , nil
}
userIDs := actions . getUserIDs ( )
2021-11-24 12:49:20 +03:00
userMaps := make ( map [ int64 ] * user_model . User , len ( userIDs ) )
2022-05-20 17:08:52 +03:00
err := db . GetEngine ( ctx ) .
2018-02-21 13:55:34 +03:00
In ( "id" , userIDs ) .
Find ( & userMaps )
if err != nil {
2022-10-24 22:29:17 +03:00
return nil , fmt . Errorf ( "find user: %w" , err )
2018-02-21 13:55:34 +03:00
}
for _ , action := range actions {
action . ActUser = userMaps [ action . ActUserID ]
}
2022-03-13 19:40:47 +03:00
return userMaps , nil
2018-02-21 13:55:34 +03:00
}
func ( actions ActionList ) getRepoIDs ( ) [ ] int64 {
2024-04-09 15:27:30 +03:00
return container . FilterSlice ( actions , func ( action * Action ) ( int64 , bool ) {
return action . RepoID , true
} )
2018-02-21 13:55:34 +03:00
}
2024-03-12 07:57:19 +03:00
func ( actions ActionList ) LoadRepositories ( ctx context . Context ) error {
2018-02-21 13:55:34 +03:00
if len ( actions ) == 0 {
2022-03-13 19:40:47 +03:00
return nil
2018-02-21 13:55:34 +03:00
}
repoIDs := actions . getRepoIDs ( )
2021-12-10 04:27:50 +03:00
repoMaps := make ( map [ int64 ] * repo_model . Repository , len ( repoIDs ) )
2022-05-20 17:08:52 +03:00
err := db . GetEngine ( ctx ) . In ( "id" , repoIDs ) . Find ( & repoMaps )
2018-02-21 13:55:34 +03:00
if err != nil {
2022-10-24 22:29:17 +03:00
return fmt . Errorf ( "find repository: %w" , err )
2018-02-21 13:55:34 +03:00
}
for _ , action := range actions {
action . Repo = repoMaps [ action . RepoID ]
}
2024-03-12 07:57:19 +03:00
repos := repo_model . RepositoryList ( util . ValuesOfMap ( repoMaps ) )
return repos . LoadUnits ( ctx )
2018-02-21 13:55:34 +03:00
}
2022-05-20 17:08:52 +03:00
func ( actions ActionList ) loadRepoOwner ( ctx context . Context , userMap map [ int64 ] * user_model . User ) ( err error ) {
2022-03-13 19:40:47 +03:00
if userMap == nil {
userMap = make ( map [ int64 ] * user_model . User )
2018-02-21 13:55:34 +03:00
}
2024-04-09 15:27:30 +03:00
missingUserIDs := container . FilterSlice ( actions , func ( action * Action ) ( int64 , bool ) {
2022-05-05 18:39:26 +03:00
if action . Repo == nil {
2024-04-09 15:27:30 +03:00
return 0 , false
2024-03-12 07:57:19 +03:00
}
2024-04-09 15:27:30 +03:00
_ , alreadyLoaded := userMap [ action . Repo . OwnerID ]
return action . Repo . OwnerID , ! alreadyLoaded
} )
2024-04-17 04:25:03 +03:00
if len ( missingUserIDs ) == 0 {
return nil
}
2024-03-12 07:57:19 +03:00
if err := db . GetEngine ( ctx ) .
2024-04-09 15:27:30 +03:00
In ( "id" , missingUserIDs ) .
2024-03-12 07:57:19 +03:00
Find ( & userMap ) ; err != nil {
return fmt . Errorf ( "find user: %w" , err )
}
for _ , action := range actions {
if action . Repo != nil {
action . Repo . Owner = userMap [ action . Repo . OwnerID ]
2022-03-13 19:40:47 +03:00
}
2018-02-21 13:55:34 +03:00
}
return nil
}
2024-03-12 07:57:19 +03:00
// LoadAttributes loads all attributes
func ( actions ActionList ) LoadAttributes ( ctx context . Context ) error {
// the load sequence cannot be changed because of the dependencies
userMap , err := actions . LoadActUsers ( ctx )
2022-03-13 19:40:47 +03:00
if err != nil {
return err
}
2024-03-12 07:57:19 +03:00
if err := actions . LoadRepositories ( ctx ) ; err != nil {
return err
}
if err := actions . loadRepoOwner ( ctx , userMap ) ; err != nil {
return err
}
if err := actions . LoadIssues ( ctx ) ; err != nil {
2022-03-13 19:40:47 +03:00
return err
}
2024-03-12 07:57:19 +03:00
return actions . LoadComments ( ctx )
}
func ( actions ActionList ) LoadComments ( ctx context . Context ) error {
if len ( actions ) == 0 {
return nil
}
commentIDs := make ( [ ] int64 , 0 , len ( actions ) )
for _ , action := range actions {
if action . CommentID > 0 {
commentIDs = append ( commentIDs , action . CommentID )
}
}
2024-04-17 04:25:03 +03:00
if len ( commentIDs ) == 0 {
return nil
}
2022-03-13 19:40:47 +03:00
2024-03-12 07:57:19 +03:00
commentsMap := make ( map [ int64 ] * issues_model . Comment , len ( commentIDs ) )
if err := db . GetEngine ( ctx ) . In ( "id" , commentIDs ) . Find ( & commentsMap ) ; err != nil {
return fmt . Errorf ( "find comment: %w" , err )
}
for _ , action := range actions {
if action . CommentID > 0 {
action . Comment = commentsMap [ action . CommentID ]
if action . Comment != nil {
action . Comment . Issue = action . Issue
}
}
}
return nil
}
func ( actions ActionList ) LoadIssues ( ctx context . Context ) error {
if len ( actions ) == 0 {
return nil
}
conditions := builder . NewCond ( )
issueNum := 0
for _ , action := range actions {
if action . IsIssueEvent ( ) {
infos := action . GetIssueInfos ( )
if len ( infos ) == 0 {
continue
}
index , _ := strconv . ParseInt ( infos [ 0 ] , 10 , 64 )
if index > 0 {
conditions = conditions . Or ( builder . Eq {
"repo_id" : action . RepoID ,
"`index`" : index ,
} )
issueNum ++
}
}
}
if ! conditions . IsValid ( ) {
return nil
}
issuesMap := make ( map [ string ] * issues_model . Issue , issueNum )
issues := make ( [ ] * issues_model . Issue , 0 , issueNum )
if err := db . GetEngine ( ctx ) . Where ( conditions ) . Find ( & issues ) ; err != nil {
return fmt . Errorf ( "find issue: %w" , err )
}
for _ , issue := range issues {
issuesMap [ fmt . Sprintf ( "%d-%d" , issue . RepoID , issue . Index ) ] = issue
}
for _ , action := range actions {
if ! action . IsIssueEvent ( ) {
continue
}
if index := action . getIssueIndex ( ) ; index > 0 {
if issue , ok := issuesMap [ fmt . Sprintf ( "%d-%d" , action . RepoID , index ) ] ; ok {
action . Issue = issue
action . Issue . Repo = action . Repo
}
}
}
return nil
2018-02-21 13:55:34 +03:00
}