Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pivotal importer fixes #176

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion taiga/importers/management/commands/import_from_jira.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def add_arguments(self, parser):
parser.add_argument('--project-type', dest="project_type", type=str,
help='Project type in jira: project or board')
parser.add_argument('--template', dest='template', default="scrum",
help='template to use: scrum or scrum (default scrum)')
help='template to use: scrum or kanban (default scrum)')
parser.add_argument('--ask-for-users', dest='ask_for_users', const=True,
action="store_const", default=False,
help='Import closed data')
Expand Down
22 changes: 5 additions & 17 deletions taiga/importers/management/commands/import_from_pivotal.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ def add_arguments(self, parser):
parser.add_argument('--project-id', dest="project_id", type=str,
help='Project ID or full name (ex: taigaio/taiga-back)')
parser.add_argument('--template', dest='template', default="scrum",
help='template to use: scrum or scrum (default scrum)')
parser.add_argument('--ask-for-users', dest='ask_for_users', const=True,
help='template to use: scrum or kanban (default scrum)')
parser.add_argument('--map-users', dest='map_users', const=True,
action="store_const", default=False,
help='Import closed data')
help='Map usernames from Pivotal to Taiga. You can create users in Taiga in advance via /admin/users/user')
parser.add_argument('--closed-data', dest='closed_data', const=True,
action="store_const", default=False,
help='Import closed data')
Expand Down Expand Up @@ -50,25 +50,13 @@ def handle(self, *args, **options):
project_id = input("Project id: ")

users_bindings = {}
if options.get('ask_for_users', None):
print("Add the username or email for next pivotal users:")
if options.get('map_users', None):
for user in importer.list_users(project_id):
try:
users_bindings[user['id']] = User.objects.get(Q(email=user['person'].get('email', "not-valid")))
break
users_bindings[user['person']['id']] = User.objects.get(Q(email=user['person'].get('email', "not-valid")))
except User.DoesNotExist:
pass

while True:
username_or_email = input("{}: ".format(user['person']['name']))
if username_or_email == "":
break
try:
users_bindings[user['id']] = User.objects.get(Q(username=username_or_email) | Q(email=username_or_email))
break
except User.DoesNotExist:
print("ERROR: Invalid username or email")

options = {
"template": options.get('template'),
"import_closed_data": options.get("closed_data", False),
Expand Down
75 changes: 69 additions & 6 deletions taiga/importers/pivotal/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,28 @@ def _import_project_data(self, project_id, options):
UserStoryCustomAttribute.objects.create(
name="Type",
description="Story type",
type="text",
type="dropdown",
order=2,
project=project
project=project,
extra=[
"feature",
"bug",
"chore",
"release"
]
)
UserStoryCustomAttribute.objects.create(
name="Priority",
description="Priority",
type="dropdown",
order=3,
project=project,
extra=[
"Critical",
"High",
"Medium",
"Low"
]
)
for user in options.get('users_bindings', {}).values():
if user != self._user:
Expand Down Expand Up @@ -298,6 +317,7 @@ def _import_user_stories_data(self, project_data, project, options):
epics = {e['label']['id']: e for e in project_data['epics']}
due_date_field = project.userstorycustomattributes.get(name="Due date")
story_type_field = project.userstorycustomattributes.get(name="Type")
story_priority_field = project.userstorycustomattributes.get(name="Priority")
story_milestone_binding = {}
for iteration in project_data['iterations']:
for story in iteration['stories']:
Expand All @@ -318,6 +338,7 @@ def _import_user_stories_data(self, project_data, project, options):
"description",
"estimate",
"story_type",
"story_priority",
"current_state",
"deadline",
"requested_by_id",
Expand All @@ -337,8 +358,13 @@ def _import_user_stories_data(self, project_data, project, options):
tags.append(label['name'])

assigned_to = None
assigned_users = []
if len(story['owner_ids']) > 0:
assigned_to = users_bindings.get(story['owner_ids'][0], None)
for assignee in story['owner_ids']:
bound_user = users_bindings.get(assignee, None)
if bound_user:
assigned_users.append(bound_user.id)

owner = users_bindings.get(story['requested_by_id'], self._user)

Expand All @@ -361,6 +387,9 @@ def _import_user_stories_data(self, project_data, project, options):
milestone=story_milestone_binding.get(story['id'], None)
)

if assigned_users:
us.assigned_users.set(assigned_users)

points = Points.objects.get(project=project, value=story.get('estimate', None))
RolePoints.objects.filter(user_story=us, role__slug="main").update(points_id=points.id)

Expand All @@ -374,12 +403,23 @@ def _import_user_stories_data(self, project_data, project, options):
if watcher_user:
us.add_watcher(watcher_user)

custom_attributes_values = {}
if story.get('deadline', None):
us.custom_attributes_values.attributes_values = {due_date_field.id: story['deadline']}
us.custom_attributes_values.save()
custom_attributes_values[due_date_field.id] = story['deadline']
if story.get('story_type', None):
us.custom_attributes_values.attributes_values = {story_type_field.id: story['story_type']}
us.custom_attributes_values.save()
custom_attributes_values[story_type_field.id] = story['story_type']
if story.get('story_priority', None):
if story['story_priority'] == "p0":
priority = "Critical"
if story['story_priority'] == "p1":
priority = "High"
if story['story_priority'] == "p2":
priority = "Medium"
if story['story_priority'] == "p3":
priority = "Low"
custom_attributes_values[story_priority_field.id] = priority
us.custom_attributes_values.attributes_values = custom_attributes_values
us.custom_attributes_values.save()

UserStory.objects.filter(id=us.id).update(
ref=story['id'],
Expand Down Expand Up @@ -477,6 +517,11 @@ def _import_comments(self, project_data, obj, story, options):
users_bindings = options.get('users_bindings', {})

for comment in story['comments']:
if not comment.get('person', False):
print(f"Person element is missing in comment {comment['id']} of story {story['id']}, will treat as unknown")
comment['person'] = {}
comment['person']['id'] = '0'
comment['person']['name'] = 'unknown'
if 'text' in comment:
snapshot = take_snapshot(
obj,
Expand Down Expand Up @@ -566,6 +611,7 @@ def _transform_activity_data(self, obj, activity, options):
users_bindings = options.get('users_bindings', {})
due_date_field = obj.project.userstorycustomattributes.get(name="Due date")
story_type_field = obj.project.userstorycustomattributes.get(name="Type")
story_priority_field = obj.project.userstorycustomattributes.get(name="Priority")

user = {"pk": None, "name": activity.get('performed_by', {}).get('name', None)}
taiga_user = users_bindings.get(activity.get('performed_by', {}).get('id', None), None)
Expand Down Expand Up @@ -661,6 +707,23 @@ def _transform_activity_data(self, obj, activity, options):
"id": story_type_field.id
})

if 'story_priority' in change['new_values']:
if "custom_attributes" not in result['change_old']:
result['change_old']["custom_attributes"] = []
if "custom_attributes" not in result['change_new']:
result['change_new']["custom_attributes"] = []

result['change_old']["custom_attributes"].append({
"name": "Priority",
"value": change['original_values']['story_priority'],
"id": story_priority_field.id
})
result['change_new']["custom_attributes"].append({
"name": "Priority",
"value": change['new_values']['story_priority'],
"id": story_priority_field.id
})

if 'deadline' in change['new_values']:
if "custom_attributes" not in result['change_old']:
result['change_old']["custom_attributes"] = []
Expand Down