Skip to content

Commit 9f5fd2e

Browse files
authored
Merge pull request #81 from drscholly/fix/better_screens
Fix copy_screens
2 parents 1ffe0ad + 0d5c3bd commit 9f5fd2e

File tree

3 files changed

+44
-111
lines changed

3 files changed

+44
-111
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ jobs:
1818
python-version: ["3.9"]
1919
runs-on: ubuntu-latest
2020
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
2123
- name: Initialize CodeQL
2224
uses: github/codeql-action/init@v3
23-
- uses: actions/checkout@v4
2425
- name: Setup Python ${{ matrix.python-version }}
2526
uses: actions/setup-python@v5
2627
with:

toolbox/api/datagalaxy_api_screens.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,15 @@ def list_screens(self) -> list:
2323

2424
return body_json
2525

26-
def update_screen(self, screen) -> object:
26+
def update_screen(self, data_type: str, entity_type: str, categories: list) -> dict:
2727
headers = {'Authorization': f"Bearer {self.token}"}
28-
dataType = screen['dataType'].lower()
29-
type = screen['type'].lower()
30-
categories = screen['categories']
28+
data_type = data_type.lower()
29+
entity_type = entity_type.lower()
3130
if self.workspace is None:
32-
response = self.http_client.put(f"{self.url}/attributes/screens/{dataType}/{type}", json=categories, headers=headers)
31+
response = self.http_client.put(f"{self.url}/attributes/screens/{data_type}/{entity_type}", json=categories, headers=headers)
3332
else:
3433
params = {'versionId': self.workspace['versionId']}
35-
response = self.http_client.put(f"{self.url}/attributes/screens/{dataType}/{type}", json=categories, headers=headers, params=params)
34+
response = self.http_client.put(f"{self.url}/attributes/screens/{data_type}/{entity_type}", json=categories, headers=headers, params=params)
3635
code = response.status_code
3736
body_json = response.json()
3837
if code != 200:

toolbox/commands/copy_screens.py

Lines changed: 37 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
from typing import Optional
33

44
from toolbox.api.datagalaxy_api_screens import DataGalaxyApiScreen
5-
from toolbox.api.datagalaxy_api_workspaces import DataGalaxyApiWorkspace
65
from toolbox.api.http_client import HttpClient
6+
from toolbox.commands.utils import config_workspace
77

88

99
def copy_screens(url_source: str,
@@ -20,138 +20,71 @@ def copy_screens(url_source: str,
2020
url_target = url_source
2121

2222
if workspace_source_name is None:
23-
logging.info("copy_screens - No source workspace name given : copying the clientspace's screens")
23+
# Source clientspace
24+
logging.info("copy_screens - No source workspace name given, will copy screens at the clientspace level")
2425
source_workspace = None
2526
else:
26-
logging.info("copy_screens - Source workspace name given : copying the workspace's screens")
27-
workspaces_api_on_source_env = DataGalaxyApiWorkspace(
27+
# Source workspace
28+
logging.info("copy_screens - Source workspace name given, will copy screens at the workspace level")
29+
source_workspace = config_workspace(
30+
mode="source",
2831
url=url_source,
2932
token=token_source,
33+
workspace_name=workspace_source_name,
34+
version_name=None,
3035
http_client=http_client
3136
)
32-
source_workspace = workspaces_api_on_source_env.get_workspace(workspace_source_name)
33-
if source_workspace is None:
34-
raise Exception(f'workspace {workspace_source_name} does not exist')
37+
if not source_workspace:
38+
return 1
3539

3640
if workspace_target_name is None:
37-
logging.info("copy_screens - No target workspace name given : writing on clientspace's screens")
41+
logging.info("copy_screens - No target workspace name given, will edit screens at the clientspace level")
3842
target_workspace = None
3943
else:
40-
logging.info("copy_screens - Target workspace name given : writing on workspace's screens")
41-
workspaces_api_on_target_env = DataGalaxyApiWorkspace(
44+
logging.info("copy_screens - Target workspace name given, will edit screens at the workspace level")
45+
target_workspace = config_workspace(
46+
mode="target",
4247
url=url_target,
4348
token=token_target,
49+
workspace_name=workspace_target_name,
50+
version_name=None,
4451
http_client=http_client
4552
)
46-
target_workspace = workspaces_api_on_target_env.get_workspace(workspace_target_name)
47-
if target_workspace is None:
48-
raise Exception(f'workspace {workspace_target_name} does not exist')
53+
if not target_workspace:
54+
return 1
4955

5056
source_screens_api = DataGalaxyApiScreen(url=url_source, token=token_source, workspace=source_workspace, http_client=http_client)
5157
target_screens_api = DataGalaxyApiScreen(url=url_target, token=token_target, workspace=target_workspace, http_client=http_client)
5258

5359
source_screens = source_screens_api.list_screens()
54-
target_screens = target_screens_api.list_screens()
60+
# target_screens = target_screens_api.list_screens()
5561

5662
if len(source_screens) == 0:
5763
raise Exception('Unexpected error: source has no screen')
5864

59-
if len(target_screens) == 0:
60-
raise Exception('Unexpected error: target has no screen')
61-
62-
if len(source_screens) != len(target_screens):
63-
raise Exception('Unexpected error: source and target do not have the same number of screens')
64-
6565
for source_screen in source_screens:
66-
flag_to_copy = False
67-
type = source_screen['type']
68-
# Unsupported types (API issues somehow)
69-
if type in ["OpenDataSet", "SubStructure", "UsageComponent", "FreeDiagram", "PhysicalDiagram"]:
70-
logging.info(f'copy_screens - {type} is currently not supported by the API, aborting this screen')
66+
data_type = source_screen.get('dataType') # example: "property"
67+
entity_type = source_screen.get('type') # example: "dimension"
68+
if data_type is None or entity_type is None:
7169
continue
72-
target_screen = None
73-
# We find the corresponding screen in the target space
74-
for item in target_screens:
75-
if item['type'] == type:
76-
target_screen = item
77-
break
78-
# The screen has to exist in the target space
79-
if target_screen is None:
80-
raise Exception('Unexpected error: screen not found on target space')
81-
source_categories = source_screen['categories']
82-
target_categories = target_screen['categories']
83-
# If the number of categories is different, an update request must be sent
84-
if len(source_categories) != len(target_categories):
85-
logging.info(f'copy_screens - Must sent PUT request for {type} because not the same number of categories')
86-
flag_to_copy = True
87-
else:
88-
categories_comparison = list(zip(source_categories, target_categories))
89-
for category_comparison in categories_comparison:
90-
source_category = category_comparison[0]
91-
target_category = category_comparison[1]
92-
# If the categories contains differences, an update request must be sent
93-
equal = check_are_categories_equal(source_category, target_category)
94-
if equal is False:
95-
logging.info(f'copy_screens - Must sent PUT request for {type} because categories are different')
96-
flag_to_copy = True
97-
# If the attributes of the category contains differences, an update request must be sent
98-
equal = check_are_attributes_equal(source_category['attributes'], target_category['attributes'])
99-
if equal is False:
100-
logging.info(f'copy_screens - Must sent PUT request for {type} because attributes are different')
101-
flag_to_copy = True
102-
# Replacing attributes by attribute names for the (potential) update request and deleting id property for custom attributes
103-
for index, element in enumerate(source_categories):
104-
source_categories[index]['attributes'] = [attribute['name'] for attribute in element['attributes'] if 'name' in attribute]
105-
if 'isSystem' not in element or element['isSystem'] is False:
106-
del source_categories[index]['id']
107-
source_screen['categories'] = source_categories
108-
109-
if flag_to_copy is True:
110-
logging.info(f'copy_screens - Sending PUT request for {type}')
111-
target_screens_api.update_screen(source_screen)
70+
new_categories = []
71+
for category in source_screen['categories']:
72+
new_category = {
73+
'name': category['name'],
74+
'isHidden': category['isHidden'],
75+
'attributes': [attribute['name'] for attribute in category['attributes'] if 'name' in attribute]
76+
}
77+
if 'isSystem' in category and category['isSystem'] is True:
78+
new_category['id'] = category['id']
79+
new_categories.append(new_category)
80+
if entity_type == "OpenDataSet":
81+
# temporary to avoid an API error
82+
continue
83+
target_screens_api.update_screen(data_type=data_type, entity_type=entity_type, categories=new_categories)
11284

11385
return 0
11486

11587

116-
def check_are_categories_equal(source_category, target_category) -> bool:
117-
if 'isSystem' not in source_category or source_category['isSystem'] is False:
118-
# Custom category
119-
logging.info(f'check_are_categories_equal - Custom category detected : {source_category["name"]}')
120-
return False
121-
else:
122-
# DG standard category
123-
if source_category['id'] != target_category['id']:
124-
logging.info(f'check_are_categories_equal - Different id : {source_category["id"]} / {target_category["id"]}')
125-
return False
126-
if source_category['name'] != target_category['name']:
127-
logging.info(f'check_are_categories_equal - Different name : {source_category["name"]} / {target_category["name"]}')
128-
return False
129-
if source_category['isHidden'] != target_category['isHidden']:
130-
logging.info(f'check_are_categories_equal - Different isHidden : {source_category["isHidden"]} / {target_category["isHidden"]}')
131-
return False
132-
return True
133-
134-
135-
def check_are_attributes_equal(source_attributes, target_attributes) -> bool:
136-
if len(source_attributes) != len(target_attributes):
137-
logging.info(f'check_are_attributes_equal - Not the same number of attributes : source {len(source_attributes)} / target {len(target_attributes)}')
138-
return False
139-
attributes_comparison = list(zip(source_attributes, target_attributes))
140-
for attribute_comparison in attributes_comparison:
141-
source_attribute = attribute_comparison[0]
142-
target_attribute = attribute_comparison[1]
143-
if source_attribute['isCustom'] is True:
144-
# Custom attribute
145-
logging.info(f'check_are_attributes_equal - Custom attribute detected ({source_attribute["name"]}), need to update')
146-
return False
147-
else:
148-
# DG standard attribute
149-
if source_attribute['name'] != target_attribute['name']:
150-
logging.info(f'check_are_attributes_equal - Different name : {source_attribute["name"]} / {target_attribute["name"]}')
151-
return False
152-
return True
153-
154-
15588
def copy_screens_parse(subparsers):
15689
# create the parser for the "copy-screens" command
15790
copy_screens_parse = subparsers.add_parser('copy-screens', help='copy-screens help')

0 commit comments

Comments
 (0)