From 6e8405c143c684e77047c01339c189b50fac70b5 Mon Sep 17 00:00:00 2001 From: Guusggg Date: Sun, 24 Oct 2021 19:29:34 +0200 Subject: [PATCH 01/13] Removed redundant variables --- python/InvenTreeLink/functions.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/python/InvenTreeLink/functions.py b/python/InvenTreeLink/functions.py index 4bdd1a9..dd99eda 100644 --- a/python/InvenTreeLink/functions.py +++ b/python/InvenTreeLink/functions.py @@ -118,7 +118,7 @@ def load_config(ui: adsk.core.UserInterface): "next couple of input boxes.\n" ) - def ask_user(line, context, default=""): + def ask_user(line, default=""): (value, cancelled) = ui.inputBox( line, TITLE, @@ -131,7 +131,6 @@ def ask_user(line, context, default=""): address = ask_user( "Please enter the server address of the InvenTree instance.", - "Instance address" ) if address is None: @@ -139,8 +138,7 @@ def ask_user(line, context, default=""): return False token = ask_user( - "Please enter the user token:", - "Authentication token", + "Please enter the user token:" ) if token is None: @@ -148,8 +146,7 @@ def ask_user(line, context, default=""): return False part_category = ask_user( - "Please enter the part category's name were you would like the Part's to show up.", - "Part Category", + "Please enter the part category's name were you would like the Part's to show up.", "plugin-test" ) From b3ae6c9e8794fb8187d6b776e1eb0de2a0534204 Mon Sep 17 00:00:00 2001 From: Guusggg Date: Fri, 5 Nov 2021 15:29:06 +0100 Subject: [PATCH 02/13] Cleaned up generated conf.ini --- python/InvenTreeLink/functions.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/python/InvenTreeLink/functions.py b/python/InvenTreeLink/functions.py index dd99eda..04f1842 100644 --- a/python/InvenTreeLink/functions.py +++ b/python/InvenTreeLink/functions.py @@ -154,15 +154,15 @@ def ask_user(line, default=""): ui.messageBox("Invalid part category", TITLE) return False - config_text = ( - "[SERVER]\n" - "current = default\n" - "\n" - "[default]\n" - f"{config.CFG_ADDRESS} = {address}\n" - f"{config.CFG_TOKEN} = {token}\n" - f"{config.CFG_PART_CATEGORY} = {part_category}\n" - ) + config_text = '\n'.join(( + "[SERVER]", + "current = default", + "", + "[default]", + f"{config.CFG_ADDRESS} = {address}", + f"{config.CFG_TOKEN} = {token}", + f"{config.CFG_PART_CATEGORY} = {part_category}", + )) with open(config_path, "w") as f: f.write(config_text) From 7b7d85c122d523435b0bd0db0f7d9a43a52f4e3c Mon Sep 17 00:00:00 2001 From: Guusggg Date: Fri, 5 Nov 2021 15:47:19 +0100 Subject: [PATCH 03/13] Added ImportPartCommand --- python/InvenTreeLink/InvenTreeLink.py | 26 +++++++++++++++---- .../commands/ImportPartCommand.py | 23 ++++++++++++++++ python/InvenTreeLink/config.py | 7 ++++- 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 python/InvenTreeLink/commands/ImportPartCommand.py diff --git a/python/InvenTreeLink/InvenTreeLink.py b/python/InvenTreeLink/InvenTreeLink.py index 7a1ce0d..a5eafeb 100644 --- a/python/InvenTreeLink/InvenTreeLink.py +++ b/python/InvenTreeLink/InvenTreeLink.py @@ -17,6 +17,7 @@ from .commands.SendBomCommand import SendBomCommand from .commands.SendBomOnlineCommand import SendBomOnlineCommand from .commands.SendStepCommand import SendStepCommand + from .commands.ImportPartCommand import ImportPartCommand # Commands my_addin.add_command( @@ -26,7 +27,7 @@ 'cmd_description': 'Show the InvenTree part-details for the selected part', 'cmd_id': config.DEF_SEND_PART, 'workspace': 'FusionSolidEnvironment', - 'toolbar_panel_id': 'Commands', + 'toolbar_panel_id': config.ToolbarPanelID.COMMANDS, 'cmd_resources': config.DEF_SEND_PART, 'command_visible': True, 'command_promoted': False, @@ -40,7 +41,7 @@ 'cmd_description': 'Generates a STEP file and attaches it to a part', 'cmd_id': config.DEF_SEND_STEP, 'workspace': 'FusionSolidEnvironment', - 'toolbar_panel_id': 'Commands', + 'toolbar_panel_id': config.ToolbarPanelID.COMMANDS, 'cmd_resources': config.DEF_SEND_BOM, 'command_visible': True, 'command_promoted': False, @@ -56,7 +57,7 @@ 'cmd_description': 'Show the BOM overview palette', 'cmd_id': config.DEF_SHOW_PALETTE, 'workspace': 'FusionSolidEnvironment', - 'toolbar_panel_id': config.APP_PANEL, + 'toolbar_panel_id': config.ToolbarPanelID.INVENTREE_LINK, 'cmd_resources': 'ShowPalette', 'command_visible': True, 'command_promoted': True, @@ -80,7 +81,7 @@ 'cmd_description': 'Load the BOM for the assembly in the current file', 'cmd_id': config.DEF_SEND_BOM, 'workspace': 'FusionSolidEnvironment', - 'toolbar_panel_id': config.APP_PANEL, + 'toolbar_panel_id': config.ToolbarPanelID.INVENTREE_LINK, 'cmd_resources': config.DEF_SEND_BOM, 'command_visible': True, 'command_promoted': False, @@ -95,7 +96,22 @@ 'cmd_description': 'Fetch the InvenTree information for all BOM-parts', 'cmd_id': config.DEF_SEND_ONLINE_STATE, 'workspace': 'FusionSolidEnvironment', - 'toolbar_panel_id': config.APP_PANEL, + 'toolbar_panel_id': config.ToolbarPanelID.INVENTREE_LINK, + 'cmd_resources': config.DEF_SEND_ONLINE_STATE, + 'command_visible': True, + 'command_promoted': False, + 'palette_id': config.ITEM_PALETTE, + } + ) + + my_addin.add_command( + 'Import', + ImportPartCommand, + { + 'cmd_description': 'Import a Part as STL', + 'cmd_id': config.DEF_IMPORT_PART, + 'workspace': 'FusionSolidEnvironment', + 'toolbar_panel_id': config.ToolbarPanelID.PARTS, 'cmd_resources': config.DEF_SEND_ONLINE_STATE, 'command_visible': True, 'command_promoted': False, diff --git a/python/InvenTreeLink/commands/ImportPartCommand.py b/python/InvenTreeLink/commands/ImportPartCommand.py new file mode 100644 index 0000000..da6bcca --- /dev/null +++ b/python/InvenTreeLink/commands/ImportPartCommand.py @@ -0,0 +1,23 @@ +import adsk.core +import adsk.fusion +import adsk.cam + +import os +from datetime import datetime + +from ..apper import apper +from .. import functions +from .. import helpers +from .. import config + + +class ImportPartCommand(apper.Fusion360CommandBase): + + @apper.lib_import(config.lib_path) + def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): + try: + ao = apper.AppObjects() + + except Exception as _e: + config.app_tracking.capture_exception(_e) + raise _e diff --git a/python/InvenTreeLink/config.py b/python/InvenTreeLink/config.py index c70eb76..97e64bc 100644 --- a/python/InvenTreeLink/config.py +++ b/python/InvenTreeLink/config.py @@ -13,13 +13,13 @@ # Magic numbers ITEM_PALETTE = 'InvenTreePalette' -APP_PANEL = 'InvenTreeLink' DEF_SHOW_PALETTE = "ShowPalette" DEF_SEND_BOM = "SendBom" DEF_SEND_ONLINE_STATE = "SendOnlineState" DEF_SEND_PART = "SendPart" DEF_SEND_STEP = "SendStep" +DEF_IMPORT_PART = "ImportPart" CFG_ADDRESS = 'address' CFG_TOKEN = 'token' @@ -31,3 +31,8 @@ INV_API = None # API-connection CONFIG = {} # Config section REF_CACHE = {} # saves refs for reduced loading + +class ToolbarPanelID: + COMMANDS = "Commands" + INVENTREE_LINK = "Inventree Link" + PARTS = "Parts" \ No newline at end of file From b0fbb3097d1baa0e5cbda364b887e48d9da07766 Mon Sep 17 00:00:00 2001 From: Guusggg Date: Fri, 5 Nov 2021 16:33:51 +0100 Subject: [PATCH 04/13] Little refactor to make it more clear --- python/InvenTreeLink/InvenTreeLink.py | 8 +++---- ...endBomCommand.py => GenerateBomCommand.py} | 8 +++---- ...eCommand.py => LoadInventreeBomCommand.py} | 22 +++++++++++++------ python/InvenTreeLink/functions.py | 18 +++++++++------ 4 files changed, 34 insertions(+), 22 deletions(-) rename python/InvenTreeLink/commands/{SendBomCommand.py => GenerateBomCommand.py} (88%) rename python/InvenTreeLink/commands/{SendBomOnlineCommand.py => LoadInventreeBomCommand.py} (57%) diff --git a/python/InvenTreeLink/InvenTreeLink.py b/python/InvenTreeLink/InvenTreeLink.py index a5eafeb..46cb9c2 100644 --- a/python/InvenTreeLink/InvenTreeLink.py +++ b/python/InvenTreeLink/InvenTreeLink.py @@ -14,8 +14,8 @@ from .commands.ShowPartCommand import ShowPartCommand from .commands.BOMOverviewCommand import BomOverviewPaletteShowCommand - from .commands.SendBomCommand import SendBomCommand - from .commands.SendBomOnlineCommand import SendBomOnlineCommand + from .commands.GenerateBomCommand import GenerateBomCommand + from .commands.LoadInventreeBomCommand import LoadInventreeBomCommand from .commands.SendStepCommand import SendStepCommand from .commands.ImportPartCommand import ImportPartCommand @@ -76,7 +76,7 @@ # Commands that need the palette my_addin.add_command( 'Load BOM for assembly', - SendBomCommand, + GenerateBomCommand, { 'cmd_description': 'Load the BOM for the assembly in the current file', 'cmd_id': config.DEF_SEND_BOM, @@ -91,7 +91,7 @@ my_addin.add_command( 'Get InvenTree Information', - SendBomOnlineCommand, + LoadInventreeBomCommand, { 'cmd_description': 'Fetch the InvenTree information for all BOM-parts', 'cmd_id': config.DEF_SEND_ONLINE_STATE, diff --git a/python/InvenTreeLink/commands/SendBomCommand.py b/python/InvenTreeLink/commands/GenerateBomCommand.py similarity index 88% rename from python/InvenTreeLink/commands/SendBomCommand.py rename to python/InvenTreeLink/commands/GenerateBomCommand.py index 359d277..7e5ec3b 100644 --- a/python/InvenTreeLink/commands/SendBomCommand.py +++ b/python/InvenTreeLink/commands/GenerateBomCommand.py @@ -9,8 +9,8 @@ from .. import config from .. import functions - -class SendBomCommand(apper.Fusion360CommandBase): +# Loads the Bill of Materials from the current Fusion360 design. +class GenerateBomCommand(apper.Fusion360CommandBase): def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): try: # Get Reference to Palette @@ -32,8 +32,8 @@ def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.Comma palette.sendInfoToHTML( config.DEF_SEND_BOM, - '

{nbr} parts found in {time}

{table}'.format( - nbr=len(config.BOM), + '

{count} parts found in {time}

{table}'.format( + count=len(config.BOM), table=table_c, time=datetime.now() - start ) diff --git a/python/InvenTreeLink/commands/SendBomOnlineCommand.py b/python/InvenTreeLink/commands/LoadInventreeBomCommand.py similarity index 57% rename from python/InvenTreeLink/commands/SendBomOnlineCommand.py rename to python/InvenTreeLink/commands/LoadInventreeBomCommand.py index 45de1bb..759bfaa 100644 --- a/python/InvenTreeLink/commands/SendBomOnlineCommand.py +++ b/python/InvenTreeLink/commands/LoadInventreeBomCommand.py @@ -6,8 +6,8 @@ from .. import config from .. import functions - -class SendBomOnlineCommand(apper.Fusion360CommandBase): +# Loads the Bill of Materials that Inventree has of this Part. +class LoadInventreeBomCommand(apper.Fusion360CommandBase): def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): try: # Get Reference to Palette @@ -22,14 +22,22 @@ def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.Comma ) # Work with it - inv_status = functions.inventree_get_part([a['id'] for a in config.BOM]) - for a in config.BOM: - a['status'] = inv_status[a['id']] + bom_parts = functions.inventree_get_part([item['id'] for item in config.BOM]) + for item in config.BOM: + part = bom_parts[item['id']] + + if part is not False: + item['status'] = " Synced " + else: + item['status'] = "Not synced" body = ''.join( - ['%s%s%s' % (a['name'], a['instances'], a['status']) for a in config.BOM] + [ + f" {item['name']} {item['instances']} {item['status']} " + for item in config.BOM + ] ) - table = '
{body}
NameCountIs InvenTree
'.format(body=body) + table = '
{body}
NameCountStatus
'.format(body=body) palette.sendInfoToHTML( config.DEF_SEND_BOM, diff --git a/python/InvenTreeLink/functions.py b/python/InvenTreeLink/functions.py index 04f1842..1e174cc 100644 --- a/python/InvenTreeLink/functions.py +++ b/python/InvenTreeLink/functions.py @@ -278,15 +278,17 @@ def extract_bom(): bom = [] for occ in occs: comp = occ.component - jj = 0 - for bomI in bom: - if bomI['component'] == comp: + already_exists = False + + # Go through the BOM for items previously added + for item in bom: + if item['component'] == comp: # Increment the instance count of the existing row. - bomI['instances'] += 1 + item['instances'] += 1 + already_exists = True break - jj += 1 - if jj == len(bom): + if already_exists is False: # Gather any BOM worthy values from the component volume = 0 bodies = comp.bRepBodies @@ -311,18 +313,20 @@ def component_info(comp, parent='#', comp_set=False): """ returns a node element """ node = { 'name': comp.name, - 'nbr': comp.partNumber, + 'IPN': comp.partNumber, 'id': comp.id, 'revision-id': comp.revisionId, 'instances': 1, 'parent': parent, } + if comp_set: node['component'] = comp else: node['state'] = {'opened': True, 'checkbox_disabled': False} node["type"] = "4-root_component" node["text"] = comp.name + return node From b330a301b97458400f5ee5919773143b32a3382f Mon Sep 17 00:00:00 2001 From: Guusggg Date: Fri, 5 Nov 2021 17:35:20 +0100 Subject: [PATCH 05/13] Removed refreshing from online data to avoid confusion --- python/InvenTreeLink/InvenTreeLink.py | 20 +-- .../commands/BOMOverviewCommand.py | 3 + .../commands/GenerateBomCommand.py | 65 +++++-- ...SendStepCommand.py => ImportStlCommand.py} | 6 +- .../commands/LoadInventreeBomCommand.py | 48 ----- .../commands/palette_html/palette.html | 166 ++++++++++-------- python/InvenTreeLink/config.py | 2 - python/InvenTreeLink/functions.py | 10 +- 8 files changed, 164 insertions(+), 156 deletions(-) rename python/InvenTreeLink/commands/{SendStepCommand.py => ImportStlCommand.py} (92%) delete mode 100644 python/InvenTreeLink/commands/LoadInventreeBomCommand.py diff --git a/python/InvenTreeLink/InvenTreeLink.py b/python/InvenTreeLink/InvenTreeLink.py index 46cb9c2..cd4915b 100644 --- a/python/InvenTreeLink/InvenTreeLink.py +++ b/python/InvenTreeLink/InvenTreeLink.py @@ -15,8 +15,7 @@ from .commands.ShowPartCommand import ShowPartCommand from .commands.BOMOverviewCommand import BomOverviewPaletteShowCommand from .commands.GenerateBomCommand import GenerateBomCommand - from .commands.LoadInventreeBomCommand import LoadInventreeBomCommand - from .commands.SendStepCommand import SendStepCommand + from .commands.ImportStlCommand import ImportStlCommand from .commands.ImportPartCommand import ImportPartCommand # Commands @@ -36,7 +35,7 @@ my_addin.add_command( 'Upload STEP to attachments', - SendStepCommand, + ImportStlCommand, { 'cmd_description': 'Generates a STEP file and attaches it to a part', 'cmd_id': config.DEF_SEND_STEP, @@ -89,21 +88,6 @@ } ) - my_addin.add_command( - 'Get InvenTree Information', - LoadInventreeBomCommand, - { - 'cmd_description': 'Fetch the InvenTree information for all BOM-parts', - 'cmd_id': config.DEF_SEND_ONLINE_STATE, - 'workspace': 'FusionSolidEnvironment', - 'toolbar_panel_id': config.ToolbarPanelID.INVENTREE_LINK, - 'cmd_resources': config.DEF_SEND_ONLINE_STATE, - 'command_visible': True, - 'command_promoted': False, - 'palette_id': config.ITEM_PALETTE, - } - ) - my_addin.add_command( 'Import', ImportPartCommand, diff --git a/python/InvenTreeLink/commands/BOMOverviewCommand.py b/python/InvenTreeLink/commands/BOMOverviewCommand.py index e7b3947..34fe258 100644 --- a/python/InvenTreeLink/commands/BOMOverviewCommand.py +++ b/python/InvenTreeLink/commands/BOMOverviewCommand.py @@ -46,6 +46,9 @@ def on_html_event(self, html_args: adsk.core.HTMLEventArgs): selections.add(entitiesByToken) # TODO selection not working helpers.get_cmd(ao, config.DEF_SEND_PART).execute() + elif html_args.action == 'UploadBom': + ao.ui.messageBox("Uploading bom") + # TODO investigate ghost answers # else: # raise NotImplementedError('unknown message received from HTML') diff --git a/python/InvenTreeLink/commands/GenerateBomCommand.py b/python/InvenTreeLink/commands/GenerateBomCommand.py index 7e5ec3b..072eb66 100644 --- a/python/InvenTreeLink/commands/GenerateBomCommand.py +++ b/python/InvenTreeLink/commands/GenerateBomCommand.py @@ -13,6 +13,15 @@ class GenerateBomCommand(apper.Fusion360CommandBase): def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): try: + ao = apper.AppObjects() + design = ao.product + + if not design: + ao.ui.messageBox('No active design', 'Extract BOM') + return + + root = design.rootComponent + # Get Reference to Palette ao = apper.AppObjects() palette = ao.ui.palettes.itemById(config.ITEM_PALETTE) @@ -25,22 +34,58 @@ def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.Comma ) start = datetime.now() - config.BOM = functions.extract_bom() - config.BOM_HIR = functions.make_component_tree() - body = ''.join(['%s%s' % (a['name'], a['instances']) for a in config.BOM]) - table_c = '
{body}
NameCount
'.format(body=body) + + bom = functions.extract_bom() + unsynced_parts = [item for item in bom if item['synced'] is False] + + component_tree = functions.make_component_tree() + + element_synced = " Synced " + element_not_synced = " Not synced " + + header = ''.join(( + f"

{root.name}

" + )) + + body = ''.join([ + ''.join(( + "" + f"{item['name']}" + f"{item['instances']}" + f"{element_synced if item['synced'] else element_not_synced}" + "" + )) + for item in bom + ]) + + table_c = ''.join([ + "
", + "", + "", + "", + "", + "", + "", + "", + f"{body}
Name Count Synced
", + ]) + + complete = ''.join(( + header, + f"

{len(bom)} parts found in {datetime.now() - start}

" + f"{table_c}" + "" + "" + )) palette.sendInfoToHTML( config.DEF_SEND_BOM, - '

{count} parts found in {time}

{table}'.format( - count=len(config.BOM), - table=table_c, - time=datetime.now() - start - ) + complete ) + palette.sendInfoToHTML( 'SendTree', - json.dumps(config.BOM_HIR) + json.dumps(component_tree) ) except Exception as _e: config.app_tracking.capture_exception(_e) diff --git a/python/InvenTreeLink/commands/SendStepCommand.py b/python/InvenTreeLink/commands/ImportStlCommand.py similarity index 92% rename from python/InvenTreeLink/commands/SendStepCommand.py rename to python/InvenTreeLink/commands/ImportStlCommand.py index ebe1067..58e6f28 100644 --- a/python/InvenTreeLink/commands/SendStepCommand.py +++ b/python/InvenTreeLink/commands/ImportStlCommand.py @@ -11,7 +11,7 @@ from .. import config -class SendStepCommand(apper.Fusion360CommandBase): +class ImportStlCommand(apper.Fusion360CommandBase): @apper.lib_import(config.lib_path) def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): @@ -20,8 +20,6 @@ def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.Comma try: ao = apper.AppObjects() - ao.ui.messageBox("STEP FILE") - if ao.ui.activeSelections.count == 1: occ = adsk.fusion.Occurrence.cast(ao.ui.activeSelections[0].entity) @@ -35,8 +33,6 @@ def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.Comma self._write_step(temp_path, occ.component) - ao.ui.messageBox("File at {}, size: {}".format(temp_path, os.path.getsize(temp_path))) - part = functions.inventree_get_part(occ.component.id) if part is False: diff --git a/python/InvenTreeLink/commands/LoadInventreeBomCommand.py b/python/InvenTreeLink/commands/LoadInventreeBomCommand.py deleted file mode 100644 index 759bfaa..0000000 --- a/python/InvenTreeLink/commands/LoadInventreeBomCommand.py +++ /dev/null @@ -1,48 +0,0 @@ -import adsk.core -import adsk.fusion -import adsk.cam - -from ..apper import apper -from .. import config -from .. import functions - -# Loads the Bill of Materials that Inventree has of this Part. -class LoadInventreeBomCommand(apper.Fusion360CommandBase): - def on_execute(self, command: adsk.core.Command, command_inputs: adsk.core.CommandInputs, args, input_values): - try: - # Get Reference to Palette - ao = apper.AppObjects() - palette = ao.ui.palettes.itemById(config.ITEM_PALETTE) - - # Send message to the HTML Page - if palette: - palette.sendInfoToHTML( - config.DEF_SEND_BOM, - '


Loading...
' - ) - - # Work with it - bom_parts = functions.inventree_get_part([item['id'] for item in config.BOM]) - for item in config.BOM: - part = bom_parts[item['id']] - - if part is not False: - item['status'] = " Synced " - else: - item['status'] = "Not synced" - - body = ''.join( - [ - f" {item['name']} {item['instances']} {item['status']} " - for item in config.BOM - ] - ) - table = '
{body}
NameCountStatus
'.format(body=body) - - palette.sendInfoToHTML( - config.DEF_SEND_BOM, - '{table}'.format(table=table) - ) - except Exception as _e: - config.app_tracking.capture_exception(_e) - raise _e diff --git a/python/InvenTreeLink/commands/palette_html/palette.html b/python/InvenTreeLink/commands/palette_html/palette.html index 54453a2..2547636 100644 --- a/python/InvenTreeLink/commands/palette_html/palette.html +++ b/python/InvenTreeLink/commands/palette_html/palette.html @@ -1,83 +1,103 @@ - - - - - + + + - - - - - -
-
-
-
-

InvenTreeBom more Information -

-
-
-
-

Check the github for more information

-
+ + + + + + + + + +
+
+
+
+

InvenTreeBom more Information +

+
+
+
+

Check the github for more + information

+
-