]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1437384 - phabbugz_feed.pl in PhabBugz extension should be extended to also query...
authordklawren <dklawren@users.noreply.github.com>
Wed, 28 Feb 2018 15:00:05 +0000 (10:00 -0500)
committerGitHub <noreply@github.com>
Wed, 28 Feb 2018 15:00:05 +0000 (10:00 -0500)
extensions/PhabBugz/bin/update_project_members.pl
extensions/PhabBugz/lib/Feed.pm
extensions/PhabBugz/lib/Revision.pm

index a0449a915343d61b1a749d801f3342a20353d290..2a305da3d3cf0f6c0aed632915b6f3b78abf0469 100755 (executable)
@@ -65,10 +65,10 @@ foreach my $group (@$sync_groups) {
         });
     }
 
-    my @group_members = get_group_members($group);
-
-    $project->set_members(\@group_members);
-    $project->update();
+    if (my @group_members = get_group_members($group)) {
+        $project->set_members(\@group_members);
+        $project->update();
+    }
 }
 
 sub get_group_members {
index f91d108ecdc6fb6d13339763f677f7a14327cf58..c7d6d0a29faece328eda10f8a2b5072bac1fa1b7 100644 (file)
@@ -14,11 +14,13 @@ use List::MoreUtils qw(any);
 use Moo;
 
 use Bugzilla::Constants;
+use Bugzilla::Search;
 use Bugzilla::Util qw(diff_arrays);
 
 use Bugzilla::Extension::PhabBugz::Constants;
 use Bugzilla::Extension::PhabBugz::Policy;
 use Bugzilla::Extension::PhabBugz::Revision;
+use Bugzilla::Extension::PhabBugz::User;
 use Bugzilla::Extension::PhabBugz::Util qw(
     add_security_sync_comments
     create_private_revision_policy
@@ -61,22 +63,18 @@ sub feed_query {
         return;
     }
 
+    # PROCESS NEW FEED TRANSACTIONS
+
     $self->logger->info("FEED: Fetching new transactions");
 
-    my $last_id = $dbh->selectrow_array("
-        SELECT value FROM phabbugz WHERE name = 'feed_last_id'");
-    $last_id ||= 0;
-    $self->logger->debug("QUERY LAST_ID: $last_id");
+    my $story_last_id = $self->get_last_id('feed');
 
     # Check for new transctions (stories)
-    my $transactions = $self->feed_transactions($last_id);
-    if (!@$transactions) {
-        $self->logger->info("FEED: No new transactions");
-        return;
-    }
+    my $new_stories = $self->new_stories($story_last_id);
+    $self->logger->info("FEED: No new stories") unless @$new_stories;
 
     # Process each story
-    foreach my $story_data (@$transactions) {
+    foreach my $story_data (@$new_stories) {
         my $story_id    = $story_data->{id};
         my $story_phid  = $story_data->{phid};
         my $author_phid = $story_data->{authorPHID};
@@ -92,7 +90,7 @@ sub feed_query {
         # Only interested in changes to revisions for now.
         if ($object_phid !~ /^PHID-DREV/) {
             $self->logger->debug("SKIPPING: Not a revision change");
-            $self->save_feed_last_id($story_id);
+            $self->save_last_id($story_id, 'feed');
             next;
         }
 
@@ -102,22 +100,40 @@ sub feed_query {
             my $user = Bugzilla::User->new({ id => $phab_users->[0]->{id}, cache => 1 });
             if ($user->login eq PHAB_AUTOMATION_USER) {
                 $self->logger->debug("SKIPPING: Change made by phabricator user");
-                $self->save_feed_last_id($story_id);
+                $self->save_last_id($story_id, 'feed');
                 next;
             }
         }
 
         $self->process_revision_change($object_phid, $story_text);
-        $self->save_feed_last_id($story_id);
+        $self->save_last_id($story_id, 'feed');
     }
-}
 
-sub save_feed_last_id {
-    my ($self, $story_id) = @_;
-    # Store the largest last key so we can start from there in the next session
-    $self->logger->debug("UPDATING FEED_LAST_ID: $story_id");
-    Bugzilla->dbh->do("REPLACE INTO phabbugz (name, value) VALUES ('feed_last_id', ?)",
-                      undef, $story_id);
+    # PROCESS NEW USERS
+
+    $self->logger->info("FEED: Fetching new users");
+
+    my $user_last_id = $self->get_last_id('user');
+
+    # Check for new users
+    my $new_users = $self->new_users($user_last_id);
+    $self->logger->info("FEED: No new users") unless @$new_users;
+
+    # Process each new user
+    foreach my $user_data (@$new_users) {
+        my $user_id       = $user_data->{id};
+        my $user_login    = $user_data->{fields}{username};
+        my $user_realname = $user_data->{fields}{realName};
+        my $object_phid   = $user_data->{phid};
+
+        $self->logger->debug("USER ID: $user_id");
+        $self->logger->debug("USER LOGIN: $user_login");
+        $self->logger->debug("USER REALNAME: $user_realname");
+        $self->logger->debug("OBJECT PHID: $object_phid");
+
+        $self->process_new_user($user_data);
+        $self->save_last_id($user_id, 'user');
+    }
 }
 
 sub process_revision_change {
@@ -154,10 +170,7 @@ sub process_revision_change {
 
     # Pre setup before making changes
     my $old_user = set_phab_user();
-
-    my $is_shadow_db = Bugzilla->is_shadow_db;
-    Bugzilla->switch_to_main_db if $is_shadow_db;
-
+    my $is_shadow_db = Bugzilla->is_shadow_db;                                                                                                                                                                      Bugzilla->switch_to_main_db if $is_shadow_db;
     my $dbh = Bugzilla->dbh;
     $dbh->bz_start_transaction;
 
@@ -347,21 +360,154 @@ sub process_revision_change {
 
     Bugzilla->set_user($old_user);
 
-    $self->logger->info("SUCCESS");
+    $self->logger->info('SUCCESS: Revision D' . $revision->id . ' processed');
 }
 
-sub feed_transactions {
-    my ($self, $after) = @_;
+sub process_new_user {
+    my ( $self, $user_data ) = @_;
+
+    # Load the user data into a proper object
+    my $phab_user = Bugzilla::Extension::PhabBugz::User->new($user_data);
+
+    if (!$phab_user->bugzilla_id) {
+        $self->logger->debug("SKIPPING: No bugzilla id associated with user");
+        return;
+    }
+
+    my $bug_user  = $phab_user->bugzilla_user;
+
+    # Pre setup before querying DB
+    my $old_user = set_phab_user();
+
+    Bugzilla->switch_to_shadow_db();
+
+    my $params = {
+        f3  => 'OP',
+        j3  => 'OR',
+
+        # User must be either reporter, assignee, qa_contact
+        # or on the cc list of the bug
+        f4  => 'cc',
+        o4  => 'equals',
+        v4  => $bug_user->login,
+
+        f5  => 'assigned_to',
+        o5  => 'equals',
+        v5  => $bug_user->login,
+
+        f6  => 'qa_contact',
+        o6  => 'equals',
+        v6  => $bug_user->login,
+
+        f7  => 'reporter',
+        o7  => 'equals',
+        v7  => $bug_user->login,
+
+        f9  => 'CP',
+
+        # The bug needs to be private
+        f10 => 'bug_group',
+        o10 => 'isnotempty',
+
+        # And the bug must have one or more attachments
+        # that are connected to revisions
+        f11 => 'attachments.filename',
+        o11 => 'regexp',
+        v11 => '^phabricator-D[[:digit:]]+-url[[.period.]]txt$',
+    };
+
+    my $search = Bugzilla::Search->new( fields => [ 'bug_id' ],
+                                        params => $params,
+                                        order  => [ 'bug_id' ] );
+    my $data = $search->data;
+
+    # the first value of each row should be the bug id
+    my @bug_ids = map { shift @$_ } @$data;
+
+    foreach my $bug_id (@bug_ids) {
+        $self->logger->debug("Processing bug $bug_id");
+
+        my $bug = Bugzilla::Bug->new({ id => $bug_id, cache => 1 });
+
+        my @attachments =
+            grep { is_attachment_phab_revision($_) } @{ $bug->attachments() };
+
+        foreach my $attachment (@attachments) {
+            my ($revision_id) = ($attachment->filename =~ PHAB_ATTACHMENT_PATTERN);
+            $self->logger->debug("Processing revision D$revision_id");
+
+            my $revision = Bugzilla::Extension::PhabBugz::Revision->new_from_query(
+                { ids => [ int($revision_id) ] });
+
+            $revision->add_subscriber($phab_user->phid);
+            $revision->update();
+
+            $self->logger->debug("Revision $revision_id updated");
+        }
+    }
+
+    Bugzilla->set_user($old_user);
+
+    $self->logger->info('SUCCESS: User ' . $phab_user->id . ' processed');
+}
+
+##################
+# Helper Methods #
+##################
+
+sub new_stories {
+    my ( $self, $after ) = @_;
     my $data = { view => 'text' };
     $data->{after} = $after if $after;
-    my $result = request('feed.query_id', $data);
-    unless (ref $result->{result}{data} eq 'ARRAY'
-            && @{ $result->{result}{data} })
+    my $result = request( 'feed.query_id', $data );
+    unless ( ref $result->{result}{data} eq 'ARRAY'
+        && @{ $result->{result}{data} } )
     {
         return [];
     }
+
     # Guarantee that the data is in ascending ID order
     return [ sort { $a->{id} <=> $b->{id} } @{ $result->{result}{data} } ];
 }
 
+sub new_users {
+    my ( $self, $after ) = @_;
+    my $data = {
+        order       => [ "id" ],
+        attachments => {
+            'external-accounts' => 1
+        }
+    };
+    $data->{before} = $after if $after;
+    my $result = request( 'user.search', $data );
+    unless ( ref $result->{result}{data} eq 'ARRAY'
+        && @{ $result->{result}{data} } )
+    {
+        return [];
+    }
+
+    # Guarantee that the data is in ascending ID order
+    return [ sort { $a->{id} <=> $b->{id} } @{ $result->{result}{data} } ];
+}
+
+sub get_last_id {
+    my ( $self, $type ) = @_;
+    my $type_full = $type . "_last_id";
+    my $last_id   = Bugzilla->dbh->selectrow_array( "
+        SELECT value FROM phabbugz WHERE name = ?", undef, $type_full );
+    $last_id ||= 0;
+    $self->logger->debug( "QUERY " . uc($type_full) . ": $last_id" );
+    return $last_id;
+}
+
+sub save_last_id {
+    my ( $self, $last_id, $type ) = @_;
+
+    # Store the largest last key so we can start from there in the next session
+    my $type_full = $type . "_last_id";
+    $self->logger->debug( "UPDATING " . uc($type_full) . ": $last_id" );
+    Bugzilla->dbh->do( "REPLACE INTO phabbugz (name, value) VALUES (?, ?)",
+        undef, $type_full, $last_id );
+}
+
 1;
index 144232ccb35bb580a798dfa93072ce8337fb602b..a897acf313e8dd8dd2f156bc575363a6a0840a7f 100644 (file)
@@ -9,6 +9,7 @@ package Bugzilla::Extension::PhabBugz::Revision;
 
 use 5.10.1;
 use Moo;
+use Scalar::Util qw(blessed);
 use Types::Standard -all;
 use Type::Utils;