From beb4c1fa304a331f64a771a767d6d675bde7b715 Mon Sep 17 00:00:00 2001 From: T0jan Date: Wed, 29 May 2024 15:21:53 +0200 Subject: [PATCH 1/6] fix iissues with pdf filenames --- kintree/database/inventree_api.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kintree/database/inventree_api.py b/kintree/database/inventree_api.py index 35eab299..4e3a712e 100644 --- a/kintree/database/inventree_api.py +++ b/kintree/database/inventree_api.py @@ -467,10 +467,7 @@ def upload_part_datasheet(datasheet_url: str, part_id: int) -> str: global inventree_api # Get attachment full path - datasheet_name = f'{os.path.basename(datasheet_url)}' - # inventree needs .pdf at the end of filename to recognize a PDF - if not datasheet_name.lower().endswith('.pdf'): - datasheet_name += '.pdf' + datasheet_name = f'{str(part_id)}.pdf' datasheet_location = settings.search_datasheets + datasheet_name # Download image (multiple attempts) From d5cc193e01abbb342d4354562c142ff1bb458c11 Mon Sep 17 00:00:00 2001 From: T0jan Date: Wed, 29 May 2024 17:26:57 +0200 Subject: [PATCH 2/6] first try to tackle the (TI) redirects --- kintree/database/inventree_api.py | 10 ++++++++-- run_tests.py | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/kintree/database/inventree_api.py b/kintree/database/inventree_api.py index 4e3a712e..92732f43 100644 --- a/kintree/database/inventree_api.py +++ b/kintree/database/inventree_api.py @@ -467,10 +467,16 @@ def upload_part_datasheet(datasheet_url: str, part_id: int) -> str: global inventree_api # Get attachment full path - datasheet_name = f'{str(part_id)}.pdf' + datasheet_name = f'{part_id}_datasheet.pdf' datasheet_location = settings.search_datasheets + datasheet_name - # Download image (multiple attempts) + # some distributors/manufacturers implement + # redirects which don't allow direct downloads + if 'gotoUrl' in datasheet_url and 'www.ti.com' in datasheet_url: + mpn = datasheet_url.split('%2F')[-1] + datasheet_url = f'https://www.ti.com/lit/ds/symlink/{mpn}.pdf' + + # Download datasheet (multiple attempts) if not download_with_retry(datasheet_url, datasheet_location, filetype='PDF', diff --git a/run_tests.py b/run_tests.py index f36139cf..45703d9e 100644 --- a/run_tests.py +++ b/run_tests.py @@ -271,7 +271,7 @@ def check_result(status: str, new_part: bool) -> bool: cprint(f'[DBUG]\tpart_pk = {part_pk}') # Disable datasheet download/upload after first part (to speed up testing) - settings.DATASHEET_UPLOAD = False + # settings.DATASHEET_UPLOAD = False if ENABLE_TEST_METHODS: methods = [ From c94f9e504132cbcf3473a4c309259648b32a5428 Mon Sep 17 00:00:00 2001 From: T0jan <22519396+T0jan@users.noreply.github.com> Date: Wed, 19 Jun 2024 12:55:51 +0200 Subject: [PATCH 3/6] activate datasheet upload for unit testing --- tests/files/inventree_dev.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/files/inventree_dev.yaml b/tests/files/inventree_dev.yaml index fcdff3d8..e01bfb2b 100644 --- a/tests/files/inventree_dev.yaml +++ b/tests/files/inventree_dev.yaml @@ -1,8 +1,8 @@ -DATASHEET_UPLOAD: false +DATASHEET_UPLOAD: true ENABLE: true ENABLE_PROXY: false PASSWORD: !!binary | WVdSdGFXND0= SERVER_ADDRESS: http://127.0.0.1:8000/ USERNAME: admin -PROXIES: null \ No newline at end of file +PROXIES: null From 6aa403a8d02af56074f414724080d625babf660c Mon Sep 17 00:00:00 2001 From: T0jan Date: Mon, 24 Jun 2024 14:20:13 +0200 Subject: [PATCH 4/6] move datasheet redirect handling to tools.py --- kintree/common/tools.py | 6 ++++++ kintree/database/inventree_api.py | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kintree/common/tools.py b/kintree/common/tools.py index bfa8f24b..96f600ea 100644 --- a/kintree/common/tools.py +++ b/kintree/common/tools.py @@ -80,6 +80,12 @@ def download(url, filetype='API data', fileoutput='', timeout=3, enable_headers= opener.addheaders = list(headers.items()) urllib.request.install_opener(opener) try: + if filetype == 'PDF': + # some distributors/manufacturers implement + # redirects which don't allow direct downloads + if 'gotoUrl' in url and 'www.ti.com' in url: + mpn = url.split('%2F')[-1] + url = f'https://www.ti.com/lit/ds/symlink/{mpn}.pdf' if filetype == 'Image' or filetype == 'PDF': # Enable use of requests library for downloading files (some URLs do NOT work with urllib) if requests_lib: diff --git a/kintree/database/inventree_api.py b/kintree/database/inventree_api.py index 92732f43..114ea4cb 100644 --- a/kintree/database/inventree_api.py +++ b/kintree/database/inventree_api.py @@ -470,12 +470,6 @@ def upload_part_datasheet(datasheet_url: str, part_id: int) -> str: datasheet_name = f'{part_id}_datasheet.pdf' datasheet_location = settings.search_datasheets + datasheet_name - # some distributors/manufacturers implement - # redirects which don't allow direct downloads - if 'gotoUrl' in datasheet_url and 'www.ti.com' in datasheet_url: - mpn = datasheet_url.split('%2F')[-1] - datasheet_url = f'https://www.ti.com/lit/ds/symlink/{mpn}.pdf' - # Download datasheet (multiple attempts) if not download_with_retry(datasheet_url, datasheet_location, From 49e07ae769dad850c7657a38b67fd8c1ff686bd9 Mon Sep 17 00:00:00 2001 From: T0jan <22519396+T0jan@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:56:10 +0200 Subject: [PATCH 5/6] Replace special characters with unicode in parameters.yaml --- kintree/config/inventree/parameters.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kintree/config/inventree/parameters.yaml b/kintree/config/inventree/parameters.yaml index 20f3d455..82e5a89c 100644 --- a/kintree/config/inventree/parameters.yaml +++ b/kintree/config/inventree/parameters.yaml @@ -7,8 +7,8 @@ Breakdown Voltage: V Capacitance: nF Clamping Voltage: V Collector Gate Voltage: V -DC Resistance: mΩ -ESR: mΩ +DC Resistance: "m\u03A9" +ESR: "m\u03A9" Footprint: null Forward Voltage: V Frequency: Hz @@ -39,7 +39,7 @@ Package Type: null Pitch: mm Polarity: null Quiescent Current: A -RDS On Resistance: Ω +RDS On Resistance: "\u03A9" RDS On Voltage: V Rated Current: A Rated Power: W From 688f5d7bfae3088d1af9781efc2e8f62f4a9f306 Mon Sep 17 00:00:00 2001 From: eeintech Date: Fri, 28 Jun 2024 12:40:33 -0400 Subject: [PATCH 6/6] Further improvements to datasheet local download and upload to InvenTree --- kintree/__init__.py | 4 ++-- kintree/database/inventree_api.py | 31 ++++++++++++++----------- kintree/database/inventree_interface.py | 29 +++++++++++++++-------- kintree/gui/views/main.py | 26 +++++++++++++-------- 4 files changed, 55 insertions(+), 35 deletions(-) diff --git a/kintree/__init__.py b/kintree/__init__.py index c1f723c9..337aaf91 100644 --- a/kintree/__init__.py +++ b/kintree/__init__.py @@ -4,8 +4,8 @@ # VERSION INFORMATION version_info = { 'MAJOR_REVISION': 1, - 'MINOR_REVISION': 0, - 'RELEASE_STATUS': '0dev', + 'MINOR_REVISION': 1, + 'RELEASE_STATUS': '99dev', } __version__ = '.'.join([str(v) for v in version_info.values()]) diff --git a/kintree/database/inventree_api.py b/kintree/database/inventree_api.py index 114ea4cb..2641c5f6 100644 --- a/kintree/database/inventree_api.py +++ b/kintree/database/inventree_api.py @@ -462,27 +462,32 @@ def upload_part_image(image_url: str, part_id: int) -> bool: return False -def upload_part_datasheet(datasheet_url: str, part_id: int) -> str: +def upload_part_datasheet(datasheet_url: str, part_ipn: int, part_pk: int) -> str: ''' Upload InvenTree part attachment''' global inventree_api - # Get attachment full path - datasheet_name = f'{part_id}_datasheet.pdf' - datasheet_location = settings.search_datasheets + datasheet_name - - # Download datasheet (multiple attempts) - if not download_with_retry(datasheet_url, - datasheet_location, - filetype='PDF', - timeout=10): - return '' + datasheet_name = f'{part_ipn}.pdf' + # Get datasheet path based on user settings for local storage + if settings.DATASHEET_SAVE_ENABLED: + datasheet_location = os.path.join(settings.DATASHEET_SAVE_PATH, datasheet_name) + else: + datasheet_location = os.path.join(settings.search_datasheets, datasheet_name) + + if not os.path.isfile(datasheet_location): + # Download datasheet (multiple attempts) + if not download_with_retry( + datasheet_url, + datasheet_location, + filetype='PDF', + timeout=10 + ): + return '' # Upload Datasheet to InvenTree - part = Part(inventree_api, part_id) + part = Part(inventree_api, part_pk) if part: try: attachment = part.uploadAttachment(attachment=datasheet_location) - os.remove(datasheet_location) return f'{inventree_api.base_url.strip("/")}{attachment["attachment"]}' except Exception: return '' diff --git a/kintree/database/inventree_interface.py b/kintree/database/inventree_interface.py index 418555e0..8d97d8d2 100644 --- a/kintree/database/inventree_interface.py +++ b/kintree/database/inventree_interface.py @@ -646,14 +646,17 @@ def inventree_create(part_info: dict, stock=None, kicad=False, symbol=None, foot image_result = inventree_api.upload_part_image(inventree_part['image'], part_pk) if not image_result: cprint('[TREE]\tWarning: Failed to upload part image', silent=settings.SILENT) - if inventree_part['datasheet'] and settings.DATASHEET_UPLOAD: - # Upload datasheet - datasheet_link = inventree_api.upload_part_datasheet(inventree_part['datasheet'], part_pk) - if not datasheet_link: - cprint('[TREE]\tWarning: Failed to upload part datasheet', silent=settings.SILENT) - # TODO: this is messing up with the datasheet download to local folder - # else: - # inventree_part['datasheet'] = datasheet_link + if inventree_part['datasheet'] and settings.DATASHEET_UPLOAD: + # Upload datasheet + datasheet_link = inventree_api.upload_part_datasheet( + datasheet_url=inventree_part['datasheet'], + part_ipn=inventree_part['IPN'], + part_pk=part_pk, + ) + if not datasheet_link: + cprint('[TREE]\tWarning: Failed to upload part datasheet', silent=settings.SILENT) + else: + cprint('[TREE]\tSuccess: Uploaded part datasheet', silent=settings.SILENT) if kicad: try: @@ -843,8 +846,14 @@ def inventree_create_alternate(part_info: dict, part_id='', part_ipn='', show_pr if settings.DATASHEET_UPLOAD and not attachment: if datasheet: part_info['datasheet'] = inventree_api.upload_part_datasheet( - part_id=part_pk, - datasheet_url=datasheet) + datasheet_url=datasheet, + part_ipn=part_ipn, + part_pk=part_id, + ) + if not part_info['datasheet']: + cprint('[TREE]\tWarning: Failed to upload part datasheet', silent=settings.SILENT) + else: + cprint('[TREE]\tSuccess: Uploaded part datasheet', silent=settings.SILENT) # if an attachment is present, set it as the datasheet field if attachment: part_info['datasheet'] = f'{inventree_api.inventree_api.base_url.strip("/")}{attachment[0]["attachment"]}' diff --git a/kintree/gui/views/main.py b/kintree/gui/views/main.py index 808ef35b..b8375bf2 100644 --- a/kintree/gui/views/main.py +++ b/kintree/gui/views/main.py @@ -1546,17 +1546,23 @@ def create_part(self, e=None): return self.process_cancel() # Final operations - # Download datasheet + # Download a local version of the part datasheet if settings.DATASHEET_SAVE_ENABLED: - datasheet_url = part_info.get('datasheet', None) - if datasheet_url: - filename = os.path.join( - settings.DATASHEET_SAVE_PATH, - f'{part_info.get("IPN", "datasheet")}.pdf', - ) - cprint('\n[MAIN]\tDownloading Datasheet') - if download_with_retry(datasheet_url, filename, filetype='PDF', timeout=10): - cprint(f'[INFO]\tSuccess: Datasheet saved to {filename}') + filename = os.path.join( + settings.DATASHEET_SAVE_PATH, + f'{part_info.get("IPN", "datasheet")}.pdf', + ) + if settings.DATASHEET_UPLOAD and os.path.isfile(filename): + # Datasheet was already downloaded + cprint('\n[MAIN]\tDatasheet') + cprint(f'[INFO]\tSuccess: Datasheet file exists ({filename})') + else: + # Datasheet needs to be downloaded + datasheet_url = part_info.get('datasheet', None) + if datasheet_url: + cprint('\n[MAIN]\tDownloading Datasheet') + if download_with_retry(datasheet_url, filename, filetype='PDF', timeout=10): + cprint(f'[INFO]\tSuccess: Datasheet saved to {filename}') # Open browser if settings.ENABLE_INVENTREE: if part_info.get('inventree_url', None):