Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def subpartqty_split(components):
'''@brief Split the components with subparts in different components.
Take each part and the all manufacture/distributors combination
possibility to split in subpart the components part that have
more than one manufacture/distributors code.
For each designator...
For designator with a "single subpart" check with the quantity
is more than one.
@param components Part components in a `list()` of `dict()`, format given by the EDA modules.
@return Same as the input.
'''
logger.log(DEBUG_OVERVIEW, 'Splitting subparts in the manufacture / distributors codes...')
FIELDS_MANF = [d+'#' for d in distributor_dict]
FIELDS_MANF.append('manf#')
split_components = {}
for part_ref, part in components.items():
try:
# Divide the subparts in different parts keeping the other fields
# (reference, description, ...).
# First search for the used fields to manufacture/distributor numbers
# and how many subparts are in them. Use the loop also to extract the
# manufacture/distributor codes in list. Use the maximum of them.
founded_fields = []
subparts_qty = 0
subparts_manf_code = dict()
for field_code in FIELDS_MANF:
if field_code in part:
subparts_qty_field = len( subpart_list(part[field_code]) )
# Extract each information, by the the header given, for each
# row part, spliting it in a list.
value = extract_field(row, hdr.lower())
value = re.split(ALTIUM_PART_SEPRTR, value)
if hdr.lower() in ign_fields:
continue
elif not SEPRTR in hdr.lower():
for i in range(qty):
if len(value)==qty:
v = value[i]
else:
v = value[0] # Footprint is just one for group.
# Do not create empty fields. This is useful
# when used more than one `manf#` alias in one designator.
if v and v!=ALTIUM_NONE:
fields[i][field_name_translations.get(hdr.lower(),hdr.lower())] = v.strip()
else:
# Now look for fields that start with 'kicost' and possibly
# another dot-separated variant field and store their values.
# Anything else is in a non-kicost namespace.
key_re = 'kicost(\.{})?:(?P.*)'.format(variant)
mtch = re.match(key_re, name, flags=re.IGNORECASE)
if mtch:
# The field name is anything that came after the leading
# 'kicost' and variant field.
name = mtch.group('name')
name = field_name_translations.get(name, name)
# If the field name isn't for a manufacturer's part
# number or a distributors catalog number, then add
# it to 'local' if it doesn't start with a distributor
# name and colon.
if name not in ('manf#', 'manf') and name[:-1] not in distributor_dict:
def extract_fields_row(row, variant, header):
'''Extract XML fields from the part in a library or schematic.'''
# First get the references and the quantities of elements in each rwo group.
header_translated = [field_name_translations.get(hdr.lower(),hdr.lower()) for hdr in header]
hdr_refs = [i for i, x in enumerate(header_translated) if x == "refs"]
if not hdr_refs:
raise ValueError('Not founded the part designators/references in the BOM.\nTry to generate the file again at Altium.')
else:
hdr_refs = hdr_refs[0]
refs = re.split(ALTIUM_PART_SEPRTR, extract_field(row, header[hdr_refs].lower()) )
if sys.version_info >= (3,0):
header_valid = header.copy()
else:
header_valid = copy.copy(header)
header_valid.remove(header[hdr_refs])
try:
hdr_qty = [i for i, x in enumerate(header_translated) if x == "qty"][0]
qty = int( extract_field(row, header[hdr_qty].lower()) )
header_valid.remove(header[hdr_qty])
if qty!=len(refs):
# These include all the manufacture company and codes, distributors codes
# recognized by the insalled modules and, quantity and sub quantity of the part.
FIELDS_MANF = (['manf#', 'manf#_qty', 'manf'] + [d + '#' for d in distributor_dict] + [d + '#_qty' for d in distributor_dict])
# Check if was asked to merge some not allowed fiels (as `manf`, `manf# ...
# other ones as `desc` and even `value` and `footprint`may be merged due
# the different typed (1uF and 1u) or footprint library names to the same one.
fields_merge = list( [field_name_translations.get(f.lower(),f.lower()) for f in fields_merge] )
for c in FIELDS_MANF:
if c in fields_merge:
exit('Manufactutor/distributor codes and manufacture company "{}" can\'t be ignored to create the components groups.'.format(c))
# Now partition the parts into groups of like components.
# First, get groups of identical components but ignore any manufacturer's
# part numbers that may be assigned. Just collect those in a list for each group.
logger.log(DEBUG_OVERVIEW, 'Getting groups of identical components...')
component_groups = {}
for ref, fields in list(components.items()): # part references and field values.
# Take the field keys and values of each part and create a hash.
# Use the hash as the key to a dictionary that stores lists of
# part references that have identical field values. The important fields
# are the reference prefix ('R', 'C', etc.), value, and footprint.
# Don't use the manufacturer's part number when calculating the hash!
# Also, don't use any fields with SEPRTR in the label because that indicates
# a field used by a specific tool (including kicost).
hash_fields = {k: fields[k] for k in fields if k not in FIELDS_MANF+fields_merge and SEPRTR not in k}
h = hash(tuple(sorted(hash_fields.items())))
# Now add the hashed component to the group with the matching hash
# or create a new group if the hash hasn't been seen before.
try:
def subpartqty_split(components):
'''@brief Split the components with subparts in different components.
Take each part and the all manufacture/distributors combination
possibility to split in subpart the components part that have
more than one manufacture/distributors code.
For each designator...
For designator with a "single subpart" check with the quantity
is more than one.
@param components Part components in a `list()` of `dict()`, format given by the EDA modules.
@return Same as the input.
'''
logger.log(DEBUG_OVERVIEW, 'Spliting subparts in the manufacture / distributors codes...')
FIELDS_MANF = [d+'#' for d in distributor_dict]
FIELDS_MANF.append('manf#')
splitted_components = {}
for part_ref, part in components.items():
try:
# Divide the subparts in diferent parts keeping the other fields
# (reference, description, ...).
# First search for the used filed to manufacture/distributor numbers
# and how many subparts are in them. Use the loop also to extract the
# manufacture/distributor codes in list.
founded_fields = []
subparts_qty = 0
subparts_manf_code = dict()
for field_code in FIELDS_MANF:
def groups_sort(new_component_groups):
'''@brief Order the groups in a alphabetical way.
Put the components groups in the spreadsheet rows in a spefic order
using the reference string of the components. The order is defined
by BOM_ORDER.
@param components Part components in a `list()` of `dict()`, format given by the EDA modules.
@return Same as input.
'''
logger.log(DEBUG_OVERVIEW, 'Sorting the groups for better visualization...')
ref_identifiers = re.split('(?0:
# If found more than one group with the reference, use the 'manf#'
def updateEDAselection(self):
''' @brief Update the EDA selection in the listBox based on the comboBox actual text.'''
fileNames = re.split(SEP_FILES, self.m_comboBox_files.GetValue())
if len(fileNames)==1:
eda_module = file_eda_match(fileNames[0])
if eda_module:
self.m_listBox_edatool.SetSelection(self.m_listBox_edatool.FindString(eda_dict[eda_module]['label']))
elif len(fileNames)>1:
# Check if all the EDA are the same. For different ones,
# the guide is not able now to deal, need improvement
# on `self.m_listBox_edatool`.
eda_module = file_eda_match(fileNames[0])
for fName in fileNames[1:]:
if file_eda_match(fName) != eda_module:
return
if eda_module:
self.m_listBox_edatool.SetSelection(self.m_listBox_edatool.FindString(eda_dict[eda_module]['label']))
def updateEDAselection(self):
''' @brief Update the EDA selection in the listBox based on the comboBox actual text.'''
fileNames = re.split(SEP_FILES, self.m_comboBox_files.GetValue())
if len(fileNames)==1:
eda_module = file_eda_match(fileNames[0])
if eda_module:
self.m_listBox_edatool.SetSelection(self.m_listBox_edatool.FindString(eda_dict[eda_module]['label']))
elif len(fileNames)>1:
# Check if all the EDA are the same. For different ones,
# the guide is not able now to deal, need improvement
# on `self.m_listBox_edatool`.
eda_module = file_eda_match(fileNames[0])
for fName in fileNames[1:]:
if file_eda_match(fName) != eda_module:
return
if eda_module:
self.m_listBox_edatool.SetSelection(self.m_listBox_edatool.FindString(eda_dict[eda_module]['label']))
def updateEDAselection(self):
''' @brief Update the EDA selection in the listBox based on the comboBox actual text.'''
fileNames = re.split(SEP_FILES, self.m_comboBox_files.GetValue())
if len(fileNames)==1:
eda_module = file_eda_match(fileNames[0])
if eda_module:
self.m_listBox_edatool.SetSelection(self.m_listBox_edatool.FindString(eda_dict[eda_module]['label']))
elif len(fileNames)>1:
# Check if all the EDA are the same. For different ones,
# the guide is not able now to deal, need improvement
# on `self.m_listBox_edatool`.
eda_module = file_eda_match(fileNames[0])
for fName in fileNames[1:]:
if file_eda_match(fName) != eda_module:
return
if eda_module:
self.m_listBox_edatool.SetSelection(self.m_listBox_edatool.FindString(eda_dict[eda_module]['label']))
@return Same as input.
'''
logger.log(DEBUG_OVERVIEW, 'Sorting the groups for better visualization...')
ref_identifiers = re.split('(?0:
# If found more than one group with the reference, use the 'manf#'
# as second order criteria.
if len(component_groups_ref_match)>1:
try:
for item in component_groups_ref_match:
component_groups_order_old.remove(item)
except ValueError:
pass
# Examine 'manf#' and refs to get the order.
# Order by refs that have 'manf#' codes, that ones that don't have stay at the end of the group.
group_manf_list = [new_component_groups[h].fields.get('manf#') for h in component_groups_ref_match]
group_refs_list = [new_component_groups[h].refs for h in component_groups_ref_match]
sorted_groups = sorted(range(len(group_refs_list)), key=lambda k:(group_manf_list[k] is None, group_refs_list[k]))
logger.log(DEBUG_OBSESSIVE, '{} > order: {}'.format( group_manf_list, sorted_groups) )
component_groups_ref_match = [component_groups_ref_match[i] for i in sorted_groups]