'Mechanicals', 'Power Management', 'Resistors', 'RF', 'Transistors', ] # Enable tests on extra methods ENABLE_TEST_METHODS = True ### # Enable test mode settings.enable_test_mode() # Enable InvenTree settings.set_inventree_enable_flag(True, save=True) # Enable KiCad settings.set_kicad_enable_flag(True, save=True) # Create user configuration files settings.create_user_config_files() # Set path to test libraries test_library_path = os.path.join(settings.PROJECT_DIR, 'tests', 'TEST.lib') symbol_libraries_test_path = os.path.join(settings.PROJECT_DIR, 'tests', 'files', 'SYMBOLS') footprint_libraries_test_path = os.path.join(settings.PROJECT_DIR, 'tests', 'files', 'FOOTPRINTS', '') # Disable API logging disable_digikey_api_logger() if not test_digikey_api_connect(): cprint('[INFO]\tFailed to get Digi-Key API token, aborting.') sys.exit(-1)
def main(): ''' Main GUI window ''' # Create user configuration files if not settings.create_user_config_files(): cprint('\n[ERROR]\tSome Ki-nTree configuration files seem to be missing') return CREATE_CUSTOM = False # Select PySimpleGUI theme # sg.theme_previewer() # Show all sg.theme('DarkTeal10') # Main Menu menu_def = [ ['Settings', [ 'Digi-Key', 'KiCad', 'InvenTree', ], ], [ 'More', [ # 'Synchronize', 'Custom Part', ], ], ] # Main Window layout = [ [sg.Menu(menu_def,)], [ sg.Text('Enter Part Number:'), sg.InputText(key='part_number'), ], [ sg.Checkbox('Add to KiCad', enable_events=True, default=settings.ENABLE_KICAD, key='enable_kicad'), sg.Checkbox('Add to InvenTree', enable_events=True, default=settings.ENABLE_INVENTREE, key='enable_inventree'), ], [ sg.Button('CREATE', size=(59,1)), ], ] # Create the Window window = sg.Window(f'Ki-nTree [{settings.version}]', layout, location=(500, 500) ) # Event Loop to process 'events' and get the 'values' of the inputs while True: if CREATE_CUSTOM: event = 'CREATE_CUSTOM' else: event, values = window.read() if event == sg.WIN_CLOSED: # if user closes window or clicks cancel break if event == 'Digi-Key': search_api_settings_window() elif event == 'InvenTree': inventree_settings_window() elif event == 'KiCad': kicad_settings_window() elif 'enable' in event: settings.set_inventree_enable_flag(values['enable_inventree'], save=True) settings.set_kicad_enable_flag(values['enable_kicad'], save=True) elif event == 'Custom Part': custom_part_info = add_custom_part(part_data={}) if custom_part_info: CREATE_CUSTOM = True else: # Adding part information to InvenTree categories = [None, None] symbol = None template = None footprint = None new_part = False part_pk = 0 part_info = {} part_data = {} progressbar = False if CREATE_CUSTOM: if custom_part_info['name'] and custom_part_info['description']: part_info = custom_part_info cprint('\n[MAIN]\tCustom Part', silent=settings.SILENT) else: if values['part_number']: # New part separation new_search = '-' * 20 cprint(f'\n{new_search}', silent=settings.SILENT) # Load KiCad settings settings.load_kicad_settings() # Load InvenTree settings settings.load_inventree_settings() # SnapEDA test # snapeda_window(values['part_number']) # Digi-Key Search part_info = inventree_interface.digikey_search(values['part_number']) if not part_info: # Missing Part Information if CREATE_CUSTOM: sg.popup_ok(f'Missing "Name" and "Description"', title='Incomplete Custom Part Data', location=(500, 500)) else: sg.popup_ok(f'Failed to fetch part information\n' 'Make sure:\n- Digi-Key API settings are correct ("Settings > Digi-Key")' '\n- Part number is valid', title='Digi-Key API Search', location=(500, 500)) else: if settings.ENABLE_INVENTREE: cprint('\n[MAIN]\tConnecting to Inventree server', silent=settings.SILENT) inventree_connect = inventree_interface.connect_to_server() if part_info and not inventree_connect: sg.popup_ok(f'Failed to access InvenTree server\nMake sure your username and password are correct', title='InvenTree Server Error', location=(500, 500)) # Reset part info part_info = {} # User Categories if part_info and (settings.ENABLE_INVENTREE or settings.ENABLE_KICAD): if settings.ENABLE_INVENTREE: cprint('\n[MAIN]\tCreating part in Inventree', silent=settings.SILENT) categories = inventree_interface.get_categories(part_info=part_info, supplier_only=False) # If categories do not exist: request user to fill in categories if not categories[0]: categories = user_defined_categories(extend=settings.ENABLE_INVENTREE) if categories[0]: cprint(f'[INFO]\tCategory: "{categories[0]}"', silent=settings.SILENT) if categories[1]: cprint(f'[INFO]\tSubcategory: "{categories[1]}"', silent=settings.SILENT) elif categories[0] and not categories[1]: categories = user_defined_categories(category=categories[0], extend=settings.ENABLE_INVENTREE) if categories[1]: cprint(f'[INFO]\tUpdated Category: "{categories[0]}"', silent=settings.SILENT) cprint(f'[INFO]\tSubcategory: "{categories[1]}"', silent=settings.SILENT) else: # Ask user to re-confirm categories (pre-filled) categories = user_defined_categories(category=categories[0], subcategory=categories[1], extend=settings.ENABLE_INVENTREE) cprint(f'[INFO]\tUser Category: "{categories[0]}"', silent=settings.SILENT) cprint(f'[INFO]\tUser Subcategory: "{categories[1]}"', silent=settings.SILENT) # User Part Info if not (categories[0] and categories[1]): part_info = {} else: if CREATE_CUSTOM: # Translate custom part data part_info = inventree_interface.translate_form_to_digikey(part_info=part_info, categories=categories, custom=True) else: # Add to supplier categories configuration file category_dict = { categories[0]: { categories[1]: part_info['subcategory'] } } if not config_interface.add_supplier_category(category_dict, settings.CONFIG_DIGIKEY_CATEGORIES): config_file = settings.CONFIG_DIGIKEY_CATEGORIES.split(os.sep)[-1] cprint(f'[INFO]\tWarning: Failed to add new supplier category to {config_file} file', silent=settings.SILENT) cprint(f'[DBUG]\tcategory_dict = {category_dict}', silent=settings.SILENT) # Confirm part data with user form_data = add_custom_part(inventree_interface.translate_digikey_to_inventree(part_info=part_info, categories=categories, skip_params=True)) if form_data: # Translate to part info format user_part_info = inventree_interface.translate_form_to_digikey(part_info=form_data, categories=categories, custom=False) # Merge original part_info with user_part_info part_info = {**part_info, **user_part_info} else: # User did not proceed part_info = {} # Set KiCad user libraries and symbol/footprint if part_info and settings.ENABLE_KICAD: # Request user to select symbol and footprint libraries symbol, template, footprint = user_defined_symbol_template_footprint(categories, values['part_number']) # cprint(f'{symbol=}\t{template=}\t{footprint=}', silent=settings.HIDE_DEBUG) if not symbol and not footprint: part_info = {} if part_info: # Create progress bar window progressbar = progress.create_progress_bar_window() # InvenTree if (symbol and footprint) or settings.ENABLE_INVENTREE: # Create part in InvenTree if settings.ENABLE_INVENTREE: new_part, part_pk, part_data = inventree_interface.inventree_create(part_info=part_info, categories=categories, kicad=settings.ENABLE_KICAD, symbol=symbol, footprint=footprint, show_progress=progressbar) if not part_data: cprint(f'[INFO]\tError: Could not add part to InvenTree', silent=settings.SILENT) else: if not categories[0]: pseudo_categories = [symbol, None] part_data = inventree_interface.translate_digikey_to_inventree(part_info=part_info, categories=pseudo_categories) else: part_data = inventree_interface.translate_digikey_to_inventree(part_info=part_info, categories=categories) part_data['parameters']['Symbol'] = symbol part_data['parameters']['Footprint'] = footprint if not part_data: cprint(f'[INFO]\tError: Could not format part data', silent=settings.SILENT) if part_data: if not settings.ENABLE_INVENTREE: # Replace IPN with part name if InvenTree is not used (no part number) if CREATE_CUSTOM: try: manufacturer = part_data['manufacturer'].keys()[0] part_data['IPN'] = part_data['manufacturer'][manufacturer][0] except: part_data['IPN'] = part_data['name'] else: part_data['IPN'] = values['part_number'] if part_data['datasheet']: part_data['inventree_url'] = part_data['datasheet'] kicad_success = False # KiCad if settings.ENABLE_KICAD: # Reload paths settings.load_kicad_settings() symbol_libraries_paths = config_interface.load_libraries_paths(settings.CONFIG_KICAD_CATEGORY_MAP, settings.KICAD_SYMBOLS_PATH) symbol_templates_paths = config_interface.load_templates_paths(settings.CONFIG_KICAD_CATEGORY_MAP, settings.KICAD_TEMPLATES_PATH) # Adding part symbol to KiCAD cprint(f'\n[MAIN]\tAdding part to KiCad', silent=settings.SILENT) if not symbol: kicad_error = 'Incorrect symbol choice' cprint(f'[INFO]\tError: {kicad_error}', silent=settings.SILENT) elif not template: kicad_error = 'Incorrect template choice' cprint(f'[INFO]\tError: {kicad_error}', silent=settings.SILENT) elif not footprint: kicad_error = 'Incorrect footprint choice' cprint(f'[INFO]\tError: {kicad_error}', silent=settings.SILENT) else: try: library_path = symbol_libraries_paths[categories[0]][symbol] except: library_path = symbol_libraries_paths[symbol][symbol] if template == 'None': cprint(f'[INFO]\tWarning: Missing template, using default', silent=settings.SILENT) template_path = settings.KICAD_TEMPLATES_PATH + 'default.lib' else: try: template_path = symbol_templates_paths[categories[0]][template] except: template_path = symbol_templates_paths[symbol][template] try: library_directory = os.path.dirname(library_path) except: library_directory = None cprint(f'[INFO]\tError: Failed to map library file', silent=settings.SILENT) if library_directory: if settings.AUTO_GENERATE_LIB: create_library(library_directory, symbol, settings.symbol_template_lib) try: kicad_success, kicad_new_part = kicad_interface.inventree_to_kicad(part_data=part_data, library_path=library_path, template_path=template_path, show_progress=progressbar) except: cprint(f'[INFO]\tError: Failed to add part to KiCad (incomplete InvenTree data)', silent=settings.SILENT) # Final result message result_message = '' # Result pop-up window if settings.ENABLE_INVENTREE: if not new_part: if part_pk: result_message = 'Part already in InvenTree database' else: result_message = 'Error while adding part to InvenTree (check output)' else: result_message = 'Part added to InvenTree database' if settings.ENABLE_KICAD and settings.ENABLE_INVENTREE: result_message += '\n' if settings.ENABLE_KICAD: if not kicad_success: result_message += 'Error while adding part in KiCad (check output)' try: result_message += f'\nINFO: {kicad_error}' except: pass else: if kicad_new_part: result_message += 'Part added to KiCad library' else: result_message += 'Part already in KiCad library' else: if settings.ENABLE_INVENTREE: if not categories[0] or categories[1]: result_message = 'Part categories were not set properly' if settings.ENABLE_INVENTREE or settings.ENABLE_KICAD: if not part_data: result_message = 'Part data not found - Check part number' if not part_pk: result_message = 'Unexpected error - Contact developper' # Update progress bar to complete and close window if progressbar: progress.update_progress_bar_window(progress.MAX_PROGRESS) progress.close_progress_bar_window() if symbol and result_message: sg.popup_ok(result_message, title='Results', location=(500, 500)) if part_data.get('inventree_url', None): # Auto-Open Browser Window cprint(f'\n[MAIN]\tOpening URL {part_data["inventree_url"]} in browser', silent=settings.SILENT) try: webbrowser.open(part_data['inventree_url'], new=2) except TypeError: cprint(f'[INFO]\tError: Failed to open URL', silent=settings.SILENT) # Reset create custom flag CREATE_CUSTOM = False window.close()