print access errors separately

When user invoking 'my_activity.py' does not have an account on one or
more of the servers the utility queries, access errors are reported
interleaving with access progress report printouts, this creates a
messy looking output.

With this patch access error messages are accumulated in a set and
then, if there are any, get printed out separately.

TEST=verified that error messages are printed neatly after servers
     queries finished running:

  > my_activity.py -u xxxyyzz
  Loading data.................................

  Access Errors:
  Looking up 'pdfium-review.googlesource.com': Bad Request: User xxxyyzz not found
  Looking up 'android-review.googlesource.com': Bad Request: User xxxyyzz not found
  Looking up 'chrome-internal-review.googlesource.com': Bad Request: User xxxyyzz not found
  Looking up 'chromium-review.googlesource.com': Bad Request: User xxxyyzz not found

Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Change-Id: Ie9f41110becb67936f49095ff36a8eeaa7a4f114
Reviewed-on: https://chromium-review.googlesource.com/1058722
Reviewed-by: Aaron Gable <agable@chromium.org>
diff --git a/my_activity.py b/my_activity.py
index 17f4a13..15dc3ca 100755
--- a/my_activity.py
+++ b/my_activity.py
@@ -196,6 +196,7 @@
     self.referenced_issues = []
     self.check_cookies()
     self.google_code_auth_token = None
+    self.access_errors = set()
 
   def show_progress(self, how='.'):
     if sys.stdout.isatty():
@@ -351,8 +352,7 @@
       ret.append(r)
     return ret
 
-  @staticmethod
-  def gerrit_changes_over_rest(instance, filters):
+  def gerrit_changes_over_rest(self, instance, filters):
     # Convert the "key:value" filter to a list of (key, value) pairs.
     req = list(f.split(':', 1) for f in filters)
     try:
@@ -362,7 +362,9 @@
           o_params=['MESSAGES', 'LABELS', 'DETAILED_ACCOUNTS',
                     'CURRENT_REVISION', 'CURRENT_COMMIT']))
     except gerrit_util.GerritError, e:
-      logging.error('Looking up %r: %s', instance['url'], e)
+      error_message = 'Looking up %r: %s' % (instance['url'], e)
+      if error_message not in self.access_errors:
+        self.access_errors.add(error_message)
       return []
 
   def gerrit_search(self, instance, owner=None, reviewer=None):
@@ -669,6 +671,10 @@
       for change in self.changes:
           self.print_change(change)
 
+  def print_access_errors(self):
+    if self.access_errors:
+      print ('\nAccess Errors:\n%s' % ''.join(self.access_errors))
+
   def get_reviews(self):
     num_instances = len(rietveld_instances) + len(gerrit_instances)
     with contextlib.closing(ThreadPool(num_instances)) as pool:
@@ -1024,6 +1030,8 @@
 
   my_activity.show_progress('\n')
 
+  my_activity.print_access_errors()
+
   output_file = None
   try:
     if options.output: