Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/tracker/issueimport.py b/tracker/issueimport.py
index bd54db9..042d0c7 100644
--- a/tracker/issueimport.py
+++ b/tracker/issueimport.py
@@ -1,7 +1,6 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file or at
-# https://developers.google.com/open-source/licenses/bsd
+# Copyright 2016 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
 
 """Servlet to import a file of issues in JSON format.
 """
@@ -11,20 +10,14 @@
 
 import collections
 import json
-import logging
-import time
-
-import ezt
 
 from features import filterrules_helpers
-from framework import flaskservlet
 from framework import framework_helpers
 from framework import jsonfeed
 from framework import permissions
 from framework import servlet
-from framework import urls
-from proto import tracker_pb2
-
+from mrproto import tracker_pb2
+from tracker import tracker_bizobj
 
 ParserState = collections.namedtuple(
     'ParserState',
@@ -36,7 +29,7 @@
   """IssueImport loads a file of issues in JSON format."""
 
   _PAGE_TEMPLATE = 'tracker/issue-import-page.ezt'
-  _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_ISSUES
+  _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_ISSUES
 
   def AssertBasePermission(self, mr):
     """Make sure that the logged in user has permission to view this page."""
@@ -180,8 +173,9 @@
       issue.owner_id = user_id_dict[issue_json['owner']]
     if issue_json.get('closed'):
       issue.closed_timestamp = issue_json['closed']
+    config = self.services.config.GetProjectConfig(cnxn, project_id)
     comments = [self._ParseComment(
-                    project_id, user_id_dict, comment_json, event_log)
+                    project_id, user_id_dict, comment_json, event_log, config)
                 for comment_json in issue_json.get('comments', [])]
 
     starrers = [user_id_dict[starrer] for starrer in issue_json['starrers']]
@@ -209,7 +203,8 @@
 
     return field
 
-  def _ParseComment(self, project_id, user_id_dict, comment_json, event_log):
+  def _ParseComment(
+      self, project_id, user_id_dict, comment_json, event_log, config):
     comment = tracker_pb2.IssueComment(
         # Note: issue_id is filled in after the issue is saved.
         project_id=project_id,
@@ -219,7 +214,7 @@
 
     for amendment in comment_json['amendments']:
       comment.amendments.append(
-          self._ParseAmendment(amendment, user_id_dict, event_log))
+          self._ParseAmendment(amendment, user_id_dict, event_log, config))
 
     for attachment in comment_json['attachments']:
       comment.attachments.append(
@@ -230,7 +225,7 @@
 
     return comment
 
-  def _ParseAmendment(self, amendment_json, user_id_dict, _event_log):
+  def _ParseAmendment(self, amendment_json, user_id_dict, _event_log, config):
     amendment = tracker_pb2.Amendment(
         field=tracker_pb2.FieldID(amendment_json['field']))
 
@@ -244,7 +239,16 @@
     if 'removed_users' in amendment_json:
       amendment.removed_user_ids.extend(
           [user_id_dict[email] for email in amendment_json['removed_users']])
-
+    if 'added_components' in amendment_json:
+      for comp in amendment_json['added_components']:
+        comp_def = tracker_bizobj.FindComponentDef(comp, config)
+        if comp_def:
+          amendment.added_component_ids.extend(comp_def.component_id)
+    if 'removed_components' in amendment_json:
+      for comp in amendment_json['removed_components']:
+        comp_def = tracker_bizobj.FindComponentDef(comp, config)
+        if comp_def:
+          amendment.removed_component_ids.extend(comp_def.component_id)
     return amendment
 
   def _ParseAttachment(self, attachment_json, _event_log):
@@ -305,11 +309,11 @@
     self.services.issue.SetUsedLocalID(cnxn, project_id)
     event_log.append('Finished import')
 
-  # def GetIssueImport(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def GetIssueImport(self, **kwargs):
+    return self.handler(**kwargs)
 
-  # def PostIssueImport(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def PostIssueImport(self, **kwargs):
+    return self.handler(**kwargs)
 
 
 class JSONImportError(Exception):