@@ -16,6 +16,7 @@ import (
16
16
17
17
"code.gitea.io/gitea/models/db"
18
18
repo_model "code.gitea.io/gitea/models/repo"
19
+ "code.gitea.io/gitea/models/unit"
19
20
user_model "code.gitea.io/gitea/models/user"
20
21
"code.gitea.io/gitea/modules/base"
21
22
"code.gitea.io/gitea/modules/git"
@@ -414,3 +415,127 @@ func DeleteOldActions(olderThan time.Duration) (err error) {
414
415
_ , err = db .GetEngine (db .DefaultContext ).Where ("created_unix < ?" , time .Now ().Add (- olderThan ).Unix ()).Delete (& Action {})
415
416
return
416
417
}
418
+
419
+ func notifyWatchers (ctx context.Context , actions ... * Action ) error {
420
+ var watchers []* repo_model.Watch
421
+ var repo * repo_model.Repository
422
+ var err error
423
+ var permCode []bool
424
+ var permIssue []bool
425
+ var permPR []bool
426
+
427
+ e := db .GetEngine (ctx )
428
+
429
+ for _ , act := range actions {
430
+ repoChanged := repo == nil || repo .ID != act .RepoID
431
+
432
+ if repoChanged {
433
+ // Add feeds for user self and all watchers.
434
+ watchers , err = repo_model .GetWatchers (ctx , act .RepoID )
435
+ if err != nil {
436
+ return fmt .Errorf ("get watchers: %v" , err )
437
+ }
438
+ }
439
+
440
+ // Add feed for actioner.
441
+ act .UserID = act .ActUserID
442
+ if _ , err = e .Insert (act ); err != nil {
443
+ return fmt .Errorf ("insert new actioner: %v" , err )
444
+ }
445
+
446
+ if repoChanged {
447
+ act .loadRepo ()
448
+ repo = act .Repo
449
+
450
+ // check repo owner exist.
451
+ if err := act .Repo .GetOwner (ctx ); err != nil {
452
+ return fmt .Errorf ("can't get repo owner: %v" , err )
453
+ }
454
+ } else if act .Repo == nil {
455
+ act .Repo = repo
456
+ }
457
+
458
+ // Add feed for organization
459
+ if act .Repo .Owner .IsOrganization () && act .ActUserID != act .Repo .Owner .ID {
460
+ act .ID = 0
461
+ act .UserID = act .Repo .Owner .ID
462
+ if _ , err = e .InsertOne (act ); err != nil {
463
+ return fmt .Errorf ("insert new actioner: %v" , err )
464
+ }
465
+ }
466
+
467
+ if repoChanged {
468
+ permCode = make ([]bool , len (watchers ))
469
+ permIssue = make ([]bool , len (watchers ))
470
+ permPR = make ([]bool , len (watchers ))
471
+ for i , watcher := range watchers {
472
+ user , err := user_model .GetUserByIDEngine (e , watcher .UserID )
473
+ if err != nil {
474
+ permCode [i ] = false
475
+ permIssue [i ] = false
476
+ permPR [i ] = false
477
+ continue
478
+ }
479
+ perm , err := getUserRepoPermission (ctx , repo , user )
480
+ if err != nil {
481
+ permCode [i ] = false
482
+ permIssue [i ] = false
483
+ permPR [i ] = false
484
+ continue
485
+ }
486
+ permCode [i ] = perm .CanRead (unit .TypeCode )
487
+ permIssue [i ] = perm .CanRead (unit .TypeIssues )
488
+ permPR [i ] = perm .CanRead (unit .TypePullRequests )
489
+ }
490
+ }
491
+
492
+ for i , watcher := range watchers {
493
+ if act .ActUserID == watcher .UserID {
494
+ continue
495
+ }
496
+ act .ID = 0
497
+ act .UserID = watcher .UserID
498
+ act .Repo .Units = nil
499
+
500
+ switch act .OpType {
501
+ case ActionCommitRepo , ActionPushTag , ActionDeleteTag , ActionPublishRelease , ActionDeleteBranch :
502
+ if ! permCode [i ] {
503
+ continue
504
+ }
505
+ case ActionCreateIssue , ActionCommentIssue , ActionCloseIssue , ActionReopenIssue :
506
+ if ! permIssue [i ] {
507
+ continue
508
+ }
509
+ case ActionCreatePullRequest , ActionCommentPull , ActionMergePullRequest , ActionClosePullRequest , ActionReopenPullRequest :
510
+ if ! permPR [i ] {
511
+ continue
512
+ }
513
+ }
514
+
515
+ if _ , err = e .InsertOne (act ); err != nil {
516
+ return fmt .Errorf ("insert new action: %v" , err )
517
+ }
518
+ }
519
+ }
520
+ return nil
521
+ }
522
+
523
+ // NotifyWatchers creates batch of actions for every watcher.
524
+ func NotifyWatchers (actions ... * Action ) error {
525
+ return notifyWatchers (db .DefaultContext , actions ... )
526
+ }
527
+
528
+ // NotifyWatchersActions creates batch of actions for every watcher.
529
+ func NotifyWatchersActions (acts []* Action ) error {
530
+ ctx , committer , err := db .TxContext ()
531
+ if err != nil {
532
+ return err
533
+ }
534
+ defer committer .Close ()
535
+ for _ , act := range acts {
536
+ if err := notifyWatchers (ctx , act ); err != nil {
537
+ return err
538
+ }
539
+ }
540
+ return committer .Commit ()
541
+ }
0 commit comments