From 52d6767a712a3a4d49c4be1071e3288c49c4d556 Mon Sep 17 00:00:00 2001 From: Fernando Rios Date: Fri, 5 Sep 2025 15:32:55 -0400 Subject: [PATCH 1/7] Fetch folder structure from page proof of concept --- .gitignore | 2 ++ playwright/get_article_folder_structure.py | 37 ++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 playwright/get_article_folder_structure.py diff --git a/.gitignore b/.gitignore index 8b6f0c9..b799a68 100644 --- a/.gitignore +++ b/.gitignore @@ -142,3 +142,5 @@ dmypy.json #Other .DS_Store + +playwright/.auth diff --git a/playwright/get_article_folder_structure.py b/playwright/get_article_folder_structure.py new file mode 100644 index 0000000..ee14cad --- /dev/null +++ b/playwright/get_article_folder_structure.py @@ -0,0 +1,37 @@ +import json +from playwright.sync_api import Playwright, sync_playwright, expect + + +def run(p: Playwright) -> None: + browser = playwright.chromium.launch(headless=True, channel='chromium') + context = browser.new_context() + page = context.new_page() + page.goto("https://arizona.figshare.com/articles/dataset/Optical_Phenotyping_Using_Label-Free_Microscopy_and_Deep_Learning/28664747/1") + + itemdatastr = '' + for script in page.locator('//script').all(): + if script.inner_text().startswith(';(function() { window.__APOLLO_STATE__ = '): + itemdatastr = script.inner_text() + itemdatastr = itemdatastr.replace(';(function() { window.__APOLLO_STATE__ = ', '').replace('; }());', '') + break + + itemdata = json.loads(itemdatastr) + + # find the key that contains the folder structure. + filtered_keys = [key for key in itemdata.keys() if key.startswith('ItemVersion:')] + if len(filtered_keys) != 1: + raise Exception('More than one ItemVersion key found in item data structure on page ' + page.url) + itemversiondata = itemdata[filtered_keys[0]] + if not 'folderStructure' in itemversiondata.keys(): + raise Exception('folderStructure not found in item version data structure on page ' + page.url) + folderstructure = itemversiondata['folderStructure'] + print(folderstructure) + + # --------------------- + context.close() + browser.close() + + +if __name__ == "__main__": + with sync_playwright() as playwright: + run(playwright) \ No newline at end of file From d325d248688e0163e0abb90e19911b5a4b01ff97 Mon Sep 17 00:00:00 2001 From: Fernando Rios Date: Sun, 7 Sep 2025 14:11:50 -0400 Subject: [PATCH 2/7] Use os.path functions instead of string concat in process_articles --- figshare/Article.py | 20 ++++++++++---------- figshare/Utils.py | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/figshare/Article.py b/figshare/Article.py index 378e1a7..5bbdd8e 100644 --- a/figshare/Article.py +++ b/figshare/Article.py @@ -524,18 +524,18 @@ def __download_files(self, files, version_data, folder_name): if (len(files) > 0): version_no = format_version(version_data["version"]) - article_folder = folder_name + "/" + version_no + article_folder = os.path.join(folder_name, version_no) file_no = 0 for file in files: if (file['is_link_only'] is False): - article_files_folder = article_folder + "/DATA" + article_files_folder = os.path.join(article_folder, "DATA") ingest_staging_storage = self.ingest_staging_storage - article_folder_path = ingest_staging_storage + article_files_folder + article_folder_path = os.path.join(ingest_staging_storage, article_files_folder) article_files_path_exists = os.path.exists(article_folder_path) if (article_files_path_exists is False): os.makedirs(article_folder_path, exist_ok=True) - file_name_with_path = article_folder_path + "/" + str(file['id']) + "_" + file['name'] + file_name_with_path = os.path.join(article_folder_path, str(file['id']) + "_" + file['name']) self.logs.write_log_in_file("info", f"Downloading file {file['id']} for article {version_data['id']} - " + f"version {version_data['version']}", True) @@ -733,10 +733,10 @@ def check_required_space(self, required_space): """ def __check_file_hash(self, files, version_data, folder_path): version_no = format_version(version_data["version"]) - article_version_folder = folder_path + "/" + version_no - article_files_folder = article_version_folder + "/DATA" + article_version_folder = os.path.join(folder_path, version_no) + article_files_folder = os.path.join(article_version_folder, "DATA") ingest_staging_storage = self.ingest_staging_storage - article_folder_path = ingest_staging_storage + article_files_folder + article_folder_path = os.path.join(ingest_staging_storage, article_files_folder) # check if preservation dir is reachable self.check_access_of_directories(ingest_staging_storage, "preservation") @@ -750,7 +750,7 @@ def __check_file_hash(self, files, version_data, folder_path): if (len(get_files) > 0): self.logs.write_log_in_file('info', "Comparing Figshare file hashes against existing local files.", True) for file in files: - file_path = article_folder_path + "/" + str(file['id']) + "_" + file['name'] + file_path = os.path.join(article_folder_path, str(file['id']) + "_" + file['name']) file_exists = os.path.exists(file_path) compare_hash = file['supplied_md5'] if (compare_hash == ""): @@ -1116,7 +1116,7 @@ def process_articles(self, articles): if (self.matched_curation_folder_list): curation_folder_size = 0 for folder in self.matched_curation_folder_list: - path = curation_storage_location + folder + path = os.path.join(curation_storage_location, folder) curation_folder_size += self.get_file_size_of_given_path(path, "UAL_RDM") elif len(self.matched_curation_folder_list) == 0 and len(article_data) != 0: curation_folder_size = 0 @@ -1175,7 +1175,7 @@ def process_articles(self, articles): self.logs.write_log_in_file("info", "Pre-processing script finished successfully.", True) # check main folder exists in preservation storage. ingest_staging_storage = self.ingest_staging_storage - check_dir = ingest_staging_storage + folder_name + check_dir = os.path.join(ingest_staging_storage, folder_name) check_files = True copy_files = True self.logs.write_log_in_file("info", f"Checking if {check_dir} exists.", True) diff --git a/figshare/Utils.py b/figshare/Utils.py index c9b9e28..e59b956 100644 --- a/figshare/Utils.py +++ b/figshare/Utils.py @@ -414,7 +414,7 @@ def check_local_path(article_id: int, version_no: Any, path="") -> list: if path == "": config = configparser.ConfigParser() - config.read('bagger/config/default.toml') + config.read(os.path.join('bagger', 'config', 'default.toml')) default_config = config['Defaults'] path = default_config['archival_staging_storage'] @@ -603,9 +603,9 @@ def get_article_id_and_version_from_path(path: str) -> tuple: version_no = '' article_id = '' if path: - path_elements = path.split('/') - version_no = path_elements[-2] - article_id = path_elements[-3].split('_')[-1] + path_elements = os.path.split(os.path.split(path)[0]) + version_no = path_elements[1] + article_id = os.path.split(path_elements[0])[1].split('_')[-1] return article_id, version_no From f8d9bfbe32e825756a3da390931cb453228fc157 Mon Sep 17 00:00:00 2001 From: Fernando Rios Date: Tue, 9 Sep 2025 13:53:24 -0400 Subject: [PATCH 3/7] Move playwright test to tests folder --- .../get_article_folder_structure.py | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) rename {playwright => tests}/get_article_folder_structure.py (50%) diff --git a/playwright/get_article_folder_structure.py b/tests/get_article_folder_structure.py similarity index 50% rename from playwright/get_article_folder_structure.py rename to tests/get_article_folder_structure.py index ee14cad..98416b9 100644 --- a/playwright/get_article_folder_structure.py +++ b/tests/get_article_folder_structure.py @@ -1,12 +1,12 @@ import json -from playwright.sync_api import Playwright, sync_playwright, expect +from playwright.sync_api import Playwright, sync_playwright def run(p: Playwright) -> None: - browser = playwright.chromium.launch(headless=True, channel='chromium') + browser = p.chromium.launch(headless=True, channel='chromium') context = browser.new_context() page = context.new_page() - page.goto("https://arizona.figshare.com/articles/dataset/Optical_Phenotyping_Using_Label-Free_Microscopy_and_Deep_Learning/28664747/1") + page.goto("https://arizona.figshare.com/articles/dataset/Supplementary_Information_for_The_Journey_of_Sediment-Rich_M_langes_in_Subduction_Zones_Table_S1_to_S12/27989354/1") itemdatastr = '' for script in page.locator('//script').all(): @@ -16,17 +16,19 @@ def run(p: Playwright) -> None: break itemdata = json.loads(itemdatastr) - + print(itemdatastr) + # find the key that contains the folder structure. filtered_keys = [key for key in itemdata.keys() if key.startswith('ItemVersion:')] - if len(filtered_keys) != 1: - raise Exception('More than one ItemVersion key found in item data structure on page ' + page.url) - itemversiondata = itemdata[filtered_keys[0]] - if not 'folderStructure' in itemversiondata.keys(): - raise Exception('folderStructure not found in item version data structure on page ' + page.url) - folderstructure = itemversiondata['folderStructure'] - print(folderstructure) - + for key in filtered_keys: + itemversiondata = itemdata[key] + if 'folderStructure' in itemversiondata.keys(): + folderstructure = itemversiondata['folderStructure'] + else: + folderstructure = {} + print(f'Item Version {key.split(':')[-1].replace('}', '')}\n---------') + print(folderstructure) + # --------------------- context.close() browser.close() @@ -34,4 +36,4 @@ def run(p: Playwright) -> None: if __name__ == "__main__": with sync_playwright() as playwright: - run(playwright) \ No newline at end of file + run(playwright) From 6096de9e75f671ad9169e826c40f8c24c3bd1eba Mon Sep 17 00:00:00 2001 From: Fernando Rios Date: Tue, 9 Sep 2025 14:05:16 -0400 Subject: [PATCH 4/7] create folder structure for downloaded files Folder structure is retrieved during initial fetch for public, non-embargoed items. Embargoed files will download with no folder structure --- figshare/Article.py | 26 ++++++++++++++++++--- figshare/Utils.py | 55 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/figshare/Article.py b/figshare/Article.py index 5bbdd8e..f30a463 100644 --- a/figshare/Article.py +++ b/figshare/Article.py @@ -10,7 +10,7 @@ from figshare.Integration import Integration from figshare.Utils import standardize_api_result, sorter_api_result, get_preserved_version_hash_and_size, metadata_to_hash, check_local_path from figshare.Utils import compare_hash, check_wasabi, calculate_payload_size, get_article_id_and_version_from_path, stringify_metadata -from figshare.Utils import format_version, get_folder_name_in_local_storage, upload_to_remote +from figshare.Utils import format_version, get_folder_name_in_local_storage, upload_to_remote, get_article_folder_structure from slugify import slugify from requests.adapters import HTTPAdapter, Retry @@ -300,10 +300,18 @@ def __get_article_metadata_by_version(self, version, article_id): private_version_no = private_data['private_version_no'] file_len = private_data['file_len'] version_data['files'] = files + version_data['folders'] = {} # Folders can't be retrieved for embargoed data w/o logging into figshare else: file_len = len(version_data['files']) files = version_data['files'] + try: + version_data['folders'] = get_article_folder_structure(version_data['url_public_html'], version_data['version']) + except Exception as e: + self.logs.write_log_in_file("error", str(e), True) + if self.system_config['continue-on-error'] == "False": + self.logs.write_log_in_file("info", "Aborting execution.", True, True) + version_md5 = '' version_data_for_hashing = metadata_to_hash(version_data) version_data_for_hashing = standardize_api_result(version_data_for_hashing) @@ -535,7 +543,14 @@ def __download_files(self, files, version_data, folder_name): if (article_files_path_exists is False): os.makedirs(article_folder_path, exist_ok=True) - file_name_with_path = os.path.join(article_folder_path, str(file['id']) + "_" + file['name']) + folder_for_file = '' + # if an item version has no folders, folders dict will be empty + if len(version_data['folders'].keys()) > 0 and str(file['id']) in version_data['folders'].keys(): + folder_for_file = version_data['folders'][str(file['id'])] + filepath = os.path.join(article_folder_path, folder_for_file) + if not os.path.exists(filepath): + os.makedirs(filepath, exist_ok=True) + file_name_with_path = os.path.join(filepath, str(file['id']) + "_" + file['name']) self.logs.write_log_in_file("info", f"Downloading file {file['id']} for article {version_data['id']} - " + f"version {version_data['version']}", True) @@ -750,7 +765,12 @@ def __check_file_hash(self, files, version_data, folder_path): if (len(get_files) > 0): self.logs.write_log_in_file('info', "Comparing Figshare file hashes against existing local files.", True) for file in files: - file_path = os.path.join(article_folder_path, str(file['id']) + "_" + file['name']) + # if an item version has no folders, folders dict will be empty + if len(version_data['folders'].keys()) > 0 and str(file['id']) in version_data['folders'].keys(): + folder_for_file = version_data['folders'][str(file['id'])] + else: + folder_for_file = '' + file_path = os.path.join(article_folder_path, folder_for_file, str(file['id']) + "_" + file['name']) file_exists = os.path.exists(file_path) compare_hash = file['supplied_md5'] if (compare_hash == ""): diff --git a/figshare/Utils.py b/figshare/Utils.py index e59b956..3688637 100644 --- a/figshare/Utils.py +++ b/figshare/Utils.py @@ -7,6 +7,7 @@ import tempfile from bagger.wasabi import Wasabi import configparser +from playwright.sync_api import Playwright, sync_playwright def standardize_api_result(api_result) -> dict: @@ -655,3 +656,57 @@ def stringify_metadata(metadata: Any) -> str: metadata_str += str(metadata) return metadata_str + + +def get_article_folder_structure(article_url: str, article_version: str) -> dict: + """ + Returns the folder structure for the files in the given item + + :param article_url: URL of the article to retrieve the list of files from + :type: str + + :return: A dictionary containing the information. The keys are file ids, the values are the file paths + :rtype: dict + """ + with sync_playwright() as playwright: + return __get_folders(playwright, article_url, article_version) + + +def __get_folders(p: Playwright, url, version) -> dict: + browser = p.chromium.launch(headless=True, channel='chromium') + context = browser.new_context() + page = context.new_page() + page.goto(url) + + itemdatastr = '' + for script in page.locator('//script').all(): + if script.inner_text().startswith(';(function() { window.__APOLLO_STATE__ = '): + itemdatastr = script.inner_text() + itemdatastr = itemdatastr.replace(';(function() { window.__APOLLO_STATE__ = ', '').replace('; }());', '') + break + + itemdata = json.loads(itemdatastr) + + # find the key that contains the folder structure. + filtered_keys = [key for key in itemdata.keys() if key.startswith('ItemVersion:')] + version_found = False + for key in filtered_keys: + itemversiondata = itemdata[key] + itemversiondata_version = key.split(':')[-1].replace('}', '') + if itemversiondata_version == str(version): + version_found = True + + # the folderStructure won't be present in items with no folders + if 'folderStructure' in itemversiondata.keys(): + folderstructure = itemversiondata['folderStructure'] + else: + folderstructure = {} + break + + context.close() + browser.close() + + if not version_found: + raise Exception(f'Version {version} not found in ItemVersion data structure on page ' + page.url) + + return folderstructure \ No newline at end of file From 03d7736f5fb4c8449ea19cb61af59d9dc7e01a48 Mon Sep 17 00:00:00 2001 From: Fernando Rios Date: Tue, 9 Sep 2025 14:08:42 -0400 Subject: [PATCH 5/7] lint --- figshare/Article.py | 2 +- figshare/Utils.py | 2 +- tests/get_article_folder_structure.py | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/figshare/Article.py b/figshare/Article.py index f30a463..37321fe 100644 --- a/figshare/Article.py +++ b/figshare/Article.py @@ -300,7 +300,7 @@ def __get_article_metadata_by_version(self, version, article_id): private_version_no = private_data['private_version_no'] file_len = private_data['file_len'] version_data['files'] = files - version_data['folders'] = {} # Folders can't be retrieved for embargoed data w/o logging into figshare + version_data['folders'] = {} # Folders can't be retrieved for embargoed data w/o logging into figshare else: file_len = len(version_data['files']) files = version_data['files'] diff --git a/figshare/Utils.py b/figshare/Utils.py index 3688637..4fcff18 100644 --- a/figshare/Utils.py +++ b/figshare/Utils.py @@ -709,4 +709,4 @@ def __get_folders(p: Playwright, url, version) -> dict: if not version_found: raise Exception(f'Version {version} not found in ItemVersion data structure on page ' + page.url) - return folderstructure \ No newline at end of file + return folderstructure diff --git a/tests/get_article_folder_structure.py b/tests/get_article_folder_structure.py index 98416b9..6c750c6 100644 --- a/tests/get_article_folder_structure.py +++ b/tests/get_article_folder_structure.py @@ -6,7 +6,10 @@ def run(p: Playwright) -> None: browser = p.chromium.launch(headless=True, channel='chromium') context = browser.new_context() page = context.new_page() - page.goto("https://arizona.figshare.com/articles/dataset/Supplementary_Information_for_The_Journey_of_Sediment-Rich_M_langes_in_Subduction_Zones_Table_S1_to_S12/27989354/1") + page.goto( + "https://arizona.figshare.com/articles/dataset/" + + "Supplementary_Information_for_The_Journey_of_Sediment-Rich_M_langes_in_Subduction_Zones_Table_S1_to_S12/27989354/1" + ) itemdatastr = '' for script in page.locator('//script').all(): From b0bfda542bb7e5332254f2d522e5836acf34403a Mon Sep 17 00:00:00 2001 From: HafeezOJ <32125238+HafeezOJ@users.noreply.github.com> Date: Tue, 7 Jul 2026 12:05:38 -0700 Subject: [PATCH 6/7] Get folder structure from version data --- figshare/Article.py | 18 +++++---------- figshare/Utils.py | 55 --------------------------------------------- 2 files changed, 5 insertions(+), 68 deletions(-) diff --git a/figshare/Article.py b/figshare/Article.py index 37321fe..b2407df 100644 --- a/figshare/Article.py +++ b/figshare/Article.py @@ -10,7 +10,7 @@ from figshare.Integration import Integration from figshare.Utils import standardize_api_result, sorter_api_result, get_preserved_version_hash_and_size, metadata_to_hash, check_local_path from figshare.Utils import compare_hash, check_wasabi, calculate_payload_size, get_article_id_and_version_from_path, stringify_metadata -from figshare.Utils import format_version, get_folder_name_in_local_storage, upload_to_remote, get_article_folder_structure +from figshare.Utils import format_version, get_folder_name_in_local_storage, upload_to_remote from slugify import slugify from requests.adapters import HTTPAdapter, Retry @@ -300,18 +300,10 @@ def __get_article_metadata_by_version(self, version, article_id): private_version_no = private_data['private_version_no'] file_len = private_data['file_len'] version_data['files'] = files - version_data['folders'] = {} # Folders can't be retrieved for embargoed data w/o logging into figshare else: file_len = len(version_data['files']) files = version_data['files'] - try: - version_data['folders'] = get_article_folder_structure(version_data['url_public_html'], version_data['version']) - except Exception as e: - self.logs.write_log_in_file("error", str(e), True) - if self.system_config['continue-on-error'] == "False": - self.logs.write_log_in_file("info", "Aborting execution.", True, True) - version_md5 = '' version_data_for_hashing = metadata_to_hash(version_data) version_data_for_hashing = standardize_api_result(version_data_for_hashing) @@ -545,8 +537,8 @@ def __download_files(self, files, version_data, folder_name): folder_for_file = '' # if an item version has no folders, folders dict will be empty - if len(version_data['folders'].keys()) > 0 and str(file['id']) in version_data['folders'].keys(): - folder_for_file = version_data['folders'][str(file['id'])] + if len(version_data['folder_structure'].keys()) > 0 and str(file['id']) in version_data['folder_structure'].keys(): + folder_for_file = version_data['folder_structure'][str(file['id'])] filepath = os.path.join(article_folder_path, folder_for_file) if not os.path.exists(filepath): os.makedirs(filepath, exist_ok=True) @@ -766,8 +758,8 @@ def __check_file_hash(self, files, version_data, folder_path): self.logs.write_log_in_file('info', "Comparing Figshare file hashes against existing local files.", True) for file in files: # if an item version has no folders, folders dict will be empty - if len(version_data['folders'].keys()) > 0 and str(file['id']) in version_data['folders'].keys(): - folder_for_file = version_data['folders'][str(file['id'])] + if len(version_data['folder_structure'].keys()) > 0 and str(file['id']) in version_data['folder_structure'].keys(): + folder_for_file = version_data['folder_structure'][str(file['id'])] else: folder_for_file = '' file_path = os.path.join(article_folder_path, folder_for_file, str(file['id']) + "_" + file['name']) diff --git a/figshare/Utils.py b/figshare/Utils.py index 4fcff18..e59b956 100644 --- a/figshare/Utils.py +++ b/figshare/Utils.py @@ -7,7 +7,6 @@ import tempfile from bagger.wasabi import Wasabi import configparser -from playwright.sync_api import Playwright, sync_playwright def standardize_api_result(api_result) -> dict: @@ -656,57 +655,3 @@ def stringify_metadata(metadata: Any) -> str: metadata_str += str(metadata) return metadata_str - - -def get_article_folder_structure(article_url: str, article_version: str) -> dict: - """ - Returns the folder structure for the files in the given item - - :param article_url: URL of the article to retrieve the list of files from - :type: str - - :return: A dictionary containing the information. The keys are file ids, the values are the file paths - :rtype: dict - """ - with sync_playwright() as playwright: - return __get_folders(playwright, article_url, article_version) - - -def __get_folders(p: Playwright, url, version) -> dict: - browser = p.chromium.launch(headless=True, channel='chromium') - context = browser.new_context() - page = context.new_page() - page.goto(url) - - itemdatastr = '' - for script in page.locator('//script').all(): - if script.inner_text().startswith(';(function() { window.__APOLLO_STATE__ = '): - itemdatastr = script.inner_text() - itemdatastr = itemdatastr.replace(';(function() { window.__APOLLO_STATE__ = ', '').replace('; }());', '') - break - - itemdata = json.loads(itemdatastr) - - # find the key that contains the folder structure. - filtered_keys = [key for key in itemdata.keys() if key.startswith('ItemVersion:')] - version_found = False - for key in filtered_keys: - itemversiondata = itemdata[key] - itemversiondata_version = key.split(':')[-1].replace('}', '') - if itemversiondata_version == str(version): - version_found = True - - # the folderStructure won't be present in items with no folders - if 'folderStructure' in itemversiondata.keys(): - folderstructure = itemversiondata['folderStructure'] - else: - folderstructure = {} - break - - context.close() - browser.close() - - if not version_found: - raise Exception(f'Version {version} not found in ItemVersion data structure on page ' + page.url) - - return folderstructure From c15203d9f55ff71e35d1a382e4318bef4b7c4b4e Mon Sep 17 00:00:00 2001 From: HafeezOJ <32125238+HafeezOJ@users.noreply.github.com> Date: Tue, 7 Jul 2026 12:37:46 -0700 Subject: [PATCH 7/7] Update .gitignore --- tests/get_article_folder_structure.py | 42 --------------------------- 1 file changed, 42 deletions(-) delete mode 100644 tests/get_article_folder_structure.py diff --git a/tests/get_article_folder_structure.py b/tests/get_article_folder_structure.py deleted file mode 100644 index 6c750c6..0000000 --- a/tests/get_article_folder_structure.py +++ /dev/null @@ -1,42 +0,0 @@ -import json -from playwright.sync_api import Playwright, sync_playwright - - -def run(p: Playwright) -> None: - browser = p.chromium.launch(headless=True, channel='chromium') - context = browser.new_context() - page = context.new_page() - page.goto( - "https://arizona.figshare.com/articles/dataset/" - + "Supplementary_Information_for_The_Journey_of_Sediment-Rich_M_langes_in_Subduction_Zones_Table_S1_to_S12/27989354/1" - ) - - itemdatastr = '' - for script in page.locator('//script').all(): - if script.inner_text().startswith(';(function() { window.__APOLLO_STATE__ = '): - itemdatastr = script.inner_text() - itemdatastr = itemdatastr.replace(';(function() { window.__APOLLO_STATE__ = ', '').replace('; }());', '') - break - - itemdata = json.loads(itemdatastr) - print(itemdatastr) - - # find the key that contains the folder structure. - filtered_keys = [key for key in itemdata.keys() if key.startswith('ItemVersion:')] - for key in filtered_keys: - itemversiondata = itemdata[key] - if 'folderStructure' in itemversiondata.keys(): - folderstructure = itemversiondata['folderStructure'] - else: - folderstructure = {} - print(f'Item Version {key.split(':')[-1].replace('}', '')}\n---------') - print(folderstructure) - - # --------------------- - context.close() - browser.close() - - -if __name__ == "__main__": - with sync_playwright() as playwright: - run(playwright)