How to detect duplicate screens in Jira - part 4

I've recently introduced my ideas and first, second and third version of the script for finding duplicate screens in Jira.

Here's the fourth version, which not only compares the tabs but also the screens.

Each field can be added to a specific screen only once, and it is always located on one of the tabs. Since there is currently no method to get the position of the tab on the screen using the REST API, the options for comparing the screens are quite limited. So we get identifiers for all fields on the screen, sort them, and the sorted list of the identifiers gives us unique identifier of the screen. If two screens have the same set of fields, they are considered as duplicate (no matter on which tab the fields are). This comparison concept is consistent with that used for the tabs; thus, the parameter sort has been removed from the script. The sorting of field identifiers is now performed automatically in both cases - tabs and screens.

Python Script

import time
import requests
import hashlib
import argparse


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_list_md5(list_to_encode):
return hashlib.md5(str(list_to_encode).encode()).hexdigest()


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_tabs_groups(tabs_groups):
export_items_groups("tabs.txt", tabs_groups)


def export_screens_groups(screens_groups):
export_items_groups("screens.txt", screens_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():
tabs_groups = {}
screens_groups = {}

screens = get_screens()
for screen in screens:
screen_fields_list = []
tabs = get_tabs(screen["id"])
for tab in tabs:
tab_fields_list = []
fields = get_fields(screen["id"], tab["id"])
for field in fields:
tab_fields_list.append(field["id"])
screen_fields_list.append(field["id"])

tab_fields_list.sort()
tab_identifier = get_list_md5(tab_fields_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_fields_list.sort()
screen_identifier = get_list_md5(screen_fields_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]

export_tabs_groups(tabs_groups)
export_screens_groups(screens_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()

What's next?

I would like to look more into screen schemes, whether there is a possibility to compare them too.

0 comments

Comment

Log in or Sign up to comment
TAGS
AUG Leaders

Atlassian Community Events