Ejemplo n.º 1
0
    '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)

Ejemplo n.º 2
0
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()