From e286b1f0aed3846d20f0fee3b447316d9c747e35 Mon Sep 17 00:00:00 2001 From: Thomas Huffert Date: Tue, 5 Mar 2024 19:18:09 +0100 Subject: [PATCH] allow overwriting part names --- inventree_part_import/cli.py | 14 ++++++++++---- inventree_part_import/part_importer.py | 13 ++++++++----- inventree_part_import/suppliers/base.py | 3 ++- .../suppliers/supplier_digikey.py | 3 ++- inventree_part_import/suppliers/supplier_lcsc.py | 1 + inventree_part_import/suppliers/supplier_mouser.py | 1 + .../suppliers/supplier_reichelt.py | 1 + inventree_part_import/suppliers/supplier_tme.py | 1 + 8 files changed, 26 insertions(+), 11 deletions(-) diff --git a/inventree_part_import/cli.py b/inventree_part_import/cli.py index 807bc9f..61c55c5 100644 --- a/inventree_part_import/cli.py +++ b/inventree_part_import/cli.py @@ -57,6 +57,11 @@ def wrapper(*args, **kwargs): @click.option("-d", "--dry", is_flag=True, help="Run without modifying InvenTree database.") @click.option("-c", "--config-dir", help="Override path to config directory.") @click.option("-v", "--verbose", is_flag=True, help="Enable verbose output for debugging.") +@click.option("--overwrite-part-name", help=( + "Override name of the part related to the search results. " + "If multiple search terms are given, all resulting manufacturer/supplier parts " + "will point to the same part." +)) @click.option("--show-config-dir", is_flag=True, help="Show path to config directory and exit.") @click.option("--configure", type=AvailableSuppliersChoices, help="Configure supplier.") @click.option("--update", metavar="CATEGORY", help="Update all parts from InvenTree CATEGORY.") @@ -74,6 +79,7 @@ def inventree_part_import( dry=False, config_dir=False, verbose=False, + overwrite_part_name=None, show_config_dir=False, configure=None, update=None, @@ -203,9 +209,9 @@ def inventree_part_import( try: for index, part in enumerate(parts): last_import_result = ( - importer.import_part(part.name, part, supplier, only_supplier) + importer.import_part(part.name, part, supplier, only_supplier, overwrite_part_name) if isinstance(part, Part) else - importer.import_part(part, None, supplier, only_supplier) + importer.import_part(part, None, supplier, only_supplier, overwrite_part_name) ) print() match last_import_result: @@ -227,9 +233,9 @@ def inventree_part_import( importer.interactive = True for part in parts2: import_result = ( - importer.import_part(part.name, part, supplier, only_supplier) + importer.import_part(part.name, part, supplier, only_supplier, overwrite_part_name) if isinstance(part, Part) else - importer.import_part(part, None, supplier, only_supplier) + importer.import_part(part, None, supplier, only_supplier, overwrite_part_name) ) match import_result: case ImportResult.ERROR | ImportResult.FAILURE: diff --git a/inventree_part_import/part_importer.py b/inventree_part_import/part_importer.py index 5e41997..0cb762a 100644 --- a/inventree_part_import/part_importer.py +++ b/inventree_part_import/part_importer.py @@ -51,7 +51,8 @@ def import_part( search_term, existing_part: Part = None, supplier_id=None, - only_supplier=False + only_supplier=False, + overwrite_part_name=None ): info(f"searching for {search_term} ...", end="\n") import_result = ImportResult.SUCCESS @@ -68,6 +69,8 @@ def import_part( if len(results) == 1: api_part = results[0] + if overwrite_part_name is not None: + api_part.name = overwrite_part_name elif self.interactive: prompt(f"found multiple parts at {supplier.name}, select which one to import") results = results[:get_config()["max_results"]] @@ -167,7 +170,7 @@ def import_supplier_part(self, supplier: Company, api_part: ApiPart, part: Part if update_part: if not api_part.finalize(): return ImportResult.FAILURE - update_object_data(part, api_part.get_part_data(), f"part {api_part.MPN}") + update_object_data(part, api_part.get_part_data(), f"part {api_part.name}") if not part.image and api_part.image_url: upload_image(part, api_part.image_url) @@ -217,8 +220,8 @@ def create_manufacturer_part( part: Part = None, ) -> tuple[ManufacturerPart, Part]: part_data = api_part.get_part_data() - if part or (part := get_part(self.api, api_part.MPN)): - update_object_data(part, part_data, f"part {api_part.MPN}") + if part or (part := get_part(self.api, api_part.name)): + update_object_data(part, part_data, f"part {api_part.name}") else: for subcategory in reversed(api_part.category_path): if category := self.category_map.get(subcategory.lower()): @@ -236,7 +239,7 @@ def create_manufacturer_part( category.add_alias(api_part.category_path[-1]) self.category_map[api_part.category_path[-1].lower()] = category - info(f"creating part {api_part.MPN} in '{category.part_category.pathstring}' ...") + info(f"creating part {api_part.name} in '{category.part_category.pathstring}' ...") part = Part.create(self.api, {"category": category.part_category.pk, **part_data}) manufacturer = create_manufacturer(self.api, api_part.manufacturer) diff --git a/inventree_part_import/suppliers/base.py b/inventree_part_import/suppliers/base.py index cbc07ad..7ec92a3 100644 --- a/inventree_part_import/suppliers/base.py +++ b/inventree_part_import/suppliers/base.py @@ -8,6 +8,7 @@ @dataclass class ApiPart: + name: str description: str image_url: str datasheet_url: str @@ -35,7 +36,7 @@ def finalize_hook(self): def get_part_data(self): return { - "name": self.MPN, + "name": self.name, "description": self.description, "link": self.manufacturer_link[:200], "active": True, diff --git a/inventree_part_import/suppliers/supplier_digikey.py b/inventree_part_import/suppliers/supplier_digikey.py index 41dee16..3e1d1d7 100644 --- a/inventree_part_import/suppliers/supplier_digikey.py +++ b/inventree_part_import/suppliers/supplier_digikey.py @@ -96,6 +96,7 @@ def get_api_part(self, digikey_part): } return ApiPart( + name=digikey_part.manufacturer_part_number, description=digikey_part.product_description, image_url=digikey_part.primary_photo, datasheet_url=digikey_part.primary_datasheet, @@ -109,5 +110,5 @@ def get_api_part(self, digikey_part): category_path=category_path, parameters=parameters, price_breaks=price_breaks, - currency=self.currency, + currency=self.currency ) diff --git a/inventree_part_import/suppliers/supplier_lcsc.py b/inventree_part_import/suppliers/supplier_lcsc.py index eed5c6a..60ebdb1 100644 --- a/inventree_part_import/suppliers/supplier_lcsc.py +++ b/inventree_part_import/suppliers/supplier_lcsc.py @@ -113,6 +113,7 @@ def get_api_part(self, lcsc_part): currency = self.currency return ApiPart( + name=lcsc_part.get("productModel", ""), description=REMOVE_HTML_TAGS.sub("", description), image_url=image_url, datasheet_url=lcsc_part.get("pdfUrl"), diff --git a/inventree_part_import/suppliers/supplier_mouser.py b/inventree_part_import/suppliers/supplier_mouser.py index 52fd0b8..4e79f0d 100644 --- a/inventree_part_import/suppliers/supplier_mouser.py +++ b/inventree_part_import/suppliers/supplier_mouser.py @@ -72,6 +72,7 @@ def get_api_part(self, mouser_part): quantity_available = 0 api_part = ApiPart( + name=mouser_part.get("ManufacturerPartNumber", ""), description=REMOVE_HTML_TAGS.sub("", mouser_part.get("Description", "")), image_url=mouser_part.get("ImagePath"), datasheet_url=mouser_part.get("DataSheetUrl"), diff --git a/inventree_part_import/suppliers/supplier_reichelt.py b/inventree_part_import/suppliers/supplier_reichelt.py index ae8daa3..b74a5d8 100644 --- a/inventree_part_import/suppliers/supplier_reichelt.py +++ b/inventree_part_import/suppliers/supplier_reichelt.py @@ -129,6 +129,7 @@ def get_api_part(self, soup, sku, link): currency = meta["content"] return ApiPart( + name=mpn, description=description, image_url=image_url, datasheet_url=datasheet_url, diff --git a/inventree_part_import/suppliers/supplier_tme.py b/inventree_part_import/suppliers/supplier_tme.py index ecc1738..492f81f 100644 --- a/inventree_part_import/suppliers/supplier_tme.py +++ b/inventree_part_import/suppliers/supplier_tme.py @@ -75,6 +75,7 @@ def get_api_part(self, tme_part, tme_stock): } api_part = ApiPart( + name=tme_part.get("OriginalSymbol", ""), description=tme_part.get("Description", ""), image_url=fix_tme_url(tme_part.get("Photo")), datasheet_url=None,