I've recently introduced my ideas and first, second, third, and fourth version of the script for finding duplicate screens in Jira.
Here's the fifth version, which not only compares the screens but also the screen schemes.
Unfortunately, there’s no REST API method to get information about screen schemes for DC, so this part only works for cloud. If two screen schemes have the same or duplicate screens for all four issue operations (default, create, edit, view), they are considered as duplicate.
For example, if we have the first screen scheme defined like this:
default: Screen A
create: Screen B
and the second screen scheme defined like this:
default: Screen A*
create: Screen B,
if screen A and screen A* are considered as duplicate, the screen schemes are also considered as duplicate.
import time
import requests
import hashlib
import argparse
def get_screen_schemes():
start_at = 0
max_results = 100
screen_schemes = []
while True:
try:
time.sleep(0.25)
print(f"Getting screen schemes, start_at = {start_at}, max_results = {max_results}")
params = {"startAt": start_at, "maxResults": max_results}
headers = {"Accept": "application/json"}
response = requests.get(f"{base_url}/rest/api/2/screenscheme",
headers=headers,
params=params,
auth=(user, password))
response.raise_for_status()
response_data = response.json()
screen_schemes.extend(response_data['values'])
if start_at + max_results >= response_data['total']:
break
start_at += max_results
except requests.exceptions.RequestException as e:
print(f"Failed to get screen schemes. ({e})")
exit(255)
return screen_schemes
def get_screens():
start_at = 0
max_results = 100
screens = []
while True:
try:
time.sleep(0.25)
print(f"Getting screens, start_at = {start_at}, max_results = {max_results}")
params = {"startAt": start_at, "maxResults": max_results}
headers = {"Accept": "application/json"}
response = requests.get(f"{base_url}/rest/api/2/screens",
headers=headers,
params=params,
auth=(user, password))
response.raise_for_status()
response_data = response.json()
# DC response
if 'screens' in response_data:
screens.extend(response_data['screens'])
# Cloud response
if 'values' in response_data:
screens.extend(response_data['values'])
if start_at + max_results >= response_data['total']:
break
start_at += max_results
except requests.exceptions.RequestException as e:
print(f"Failed to get screens. ({e})")
exit(255)
return screens
def get_tabs(screen_id):
tabs = []
try:
time.sleep(0.25)
print(f"Getting tabs for screen id {screen_id}")
headers = {"Accept": "application/json"}
response = requests.get(f"{base_url}/rest/api/2/screens/{screen_id}/tabs",
headers=headers,
auth=(user, password))
response.raise_for_status()
tabs = response.json()
except requests.exceptions.RequestException as e:
print(f"Failed to get tabs for screen id {screen_id}. ({e})")
return tabs
def get_fields(screen_id, tab_id):
fields = []
try:
time.sleep(0.25)
print(f"Getting fields for screen id {screen_id} and tab id {tab_id}")
headers = {"Accept": "application/json"}
response = requests.get(f"{base_url}/rest/api/2/screens/{screen_id}/tabs/{tab_id}/fields",
headers=headers,
auth=(user, password))
response.raise_for_status()
fields = response.json()
except requests.exceptions.RequestException as e:
print(f"Failed to get fields for screen id {screen_id} and tab id {tab_id}. ({e})")
return fields
def get_items_list_md5(list_to_encode):
return hashlib.md5(str(list_to_encode).encode()).hexdigest()
def get_screen_scheme_title(screen_scheme_id, screen_scheme_name):
return str(screen_scheme_id) + ": " + screen_scheme_name
def get_screen_title(screen_id, screen_name):
return str(screen_id) + ": " + screen_name
def get_tab_title(screen_id, screen_name, tab_id, tab_name):
return str(screen_id) + ": " + screen_name + ", " + str(tab_id) + ": " + tab_name
def export_screen_schemes_groups(screen_schemes_groups):
print(f"Exporting screen schemes groups")
export_items_groups("screen_schemes.txt", screen_schemes_groups)
def export_screens_groups(screens_groups):
print(f"Exporting screens groups")
export_items_groups("screens.txt", screens_groups)
def export_tabs_groups(tabs_groups):
print(f"Exporting tabs groups")
export_items_groups("tabs.txt", tabs_groups)
def export_items_groups(filename, items_groups):
with open(filename, 'a') as f:
f.truncate(0)
for item_group_key in items_groups:
f.write(str(item_group_key) + "\n")
for item_group_item in items_groups[item_group_key]:
f.write(str(item_group_item) + "\n")
f.write("\n\n")
f.close()
def execute():
screens_identifiers = {}
tabs_groups = {}
screens_groups = {}
screens = get_screens()
for screen in screens:
screen_items_list = []
tabs = get_tabs(screen["id"])
for tab in tabs:
tab_items_list = []
fields = get_fields(screen["id"], tab["id"])
for field in fields:
tab_items_list.append(field["id"])
screen_items_list.append(field["id"])
tab_items_list.sort()
tab_identifier = get_items_list_md5(tab_items_list)
tab_title = get_tab_title(screen["id"], screen["name"], tab["id"], tab["name"])
if tab_identifier in tabs_groups.keys():
tabs_groups[tab_identifier].append(tab_title)
else:
tabs_groups[tab_identifier] = [tab_title]
screen_items_list.sort()
screen_identifier = get_items_list_md5(screen_items_list)
screen_title = get_screen_title(screen["id"], screen["name"])
if screen_identifier in screens_groups.keys():
screens_groups[screen_identifier].append(screen_title)
else:
screens_groups[screen_identifier] = [screen_title]
screens_identifiers[screen["id"]] = screen_identifier
export_tabs_groups(tabs_groups)
export_screens_groups(screens_groups)
screen_schemes_groups = {}
screen_schemes = get_screen_schemes()
for screen_scheme in screen_schemes:
screen_scheme_items_list = [screens_identifiers[screen_scheme["screens"]['default']],
screens_identifiers[screen_scheme["screens"][
'create' if 'create' in screen_scheme["screens"] else 'default'
]],
screens_identifiers[screen_scheme["screens"][
'edit' if 'edit' in screen_scheme["screens"] else 'default'
]],
screens_identifiers[screen_scheme["screens"][
'view' if 'view' in screen_scheme["screens"] else 'default'
]]]
screen_scheme_identifier = get_items_list_md5(screen_scheme_items_list)
screen_scheme_title = get_screen_scheme_title(screen_scheme["id"], screen_scheme["name"])
if screen_scheme_identifier in screen_schemes_groups.keys():
screen_schemes_groups[screen_scheme_identifier].append(screen_scheme_title)
else:
screen_schemes_groups[screen_scheme_identifier] = [screen_scheme_title]
export_screen_schemes_groups(screen_schemes_groups)
parser = argparse.ArgumentParser()
parser.add_argument('--url', nargs='?', required=True,
help='https://my.testjira.com (DC) or https://mytestjira.atlassian.net (Cloud)')
parser.add_argument('--user', nargs='?', required=True,
help='username (DC) or e-mail (cloud)')
parser.add_argument('--password', nargs='?', required=True, metavar='password',
help='Password (DC) or token (cloud)')
args = parser.parse_args()
base_url = args.url
user = args.user
password = args.password
execute()
I would like to look more into issue type screen schemes, whether there is a possibility to compare them too.
Hana Kučerová
Atlassian Consultant
BiQ Group
Prague, Czech Republic
511 accepted answers
0 comments