Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# Store the field dict under the key made from the
# concatenation of the library and part names.
libparts[str(p['lib']) + SEPRTR + str(p['part'])] = fields
# Also have to store the fields under any part aliases.
try:
for alias in p.find('aliases').find_all('alias'):
libparts[str(p['lib']) + SEPRTR + str(alias.string)] = fields
except AttributeError:
pass # No aliases for this part.
# Find the components used in the schematic and elaborate
# them with global values from the libraries and local values
# from the schematic.
logger.log(DEBUG_OVERVIEW, 'Getting components...')
components = {}
for c in root.find('components').find_all('comp'):
# Find the library used for this component.
libsource = c.find('libsource')
if libsource:
# Create the key to look up the part in the libparts dict.
#libpart = str(libsource['lib'] + SEPRTR + libsource['part'])
libpart = str(libsource['lib']) + SEPRTR + str(libsource['part'])
else:
libpart = '???'
logger.log(DEBUG_OVERVIEW, 'Fottprint library not assigned to {}'.format(''))#TODO
# Initialize the fields from the global values in the libparts dict entry.
# (These will get overwritten by any local values down below.)
# (Use an empty dict if no part exists in the library.)
Group common parts looking in the existent files that could be merged
by the use of `fields_merge`. First group all designed parts without
look the manufacture/distributors codes, after see if any will be
propagated (designed part with out information and same values,
footprint and so on that other that have manufacture part, receive
this code).
Count the quantities of each part designed using the 'manf#_qty'
field, this is important to merge subparts of different parts and
parts of different BOMs (in the mode of multifiles).
@param components Part components in a `list()` of `dict()`, format given by the EDA modules.
@param fields_merge Data fields of the `dict()` variable to be merged and ignored to make the identical components group (before be scraped in the distributors web site).
@return `list()` of `dict()`
'''
logger.log(DEBUG_OVERVIEW, '# Grouping parts...')
# All codes to scrape, do not include code field name of distributors
# that will not be scraped. This definition is used to create and check
# the identical groups or subsplit the seemingly identical parts.
FIELDS_MANFCAT = ([d + '#' for d in distributor_dict] + ['manf#'])
# Calculated all the fields that never have to be used to create the hash keys.
# These include all the manufacture company and codes, distributors codes
# recognized by the installed modules and, quantity and sub quantity of the part.
FIELDS_NOT_HASH = (['manf#_qty', 'manf'] + FIELDS_MANFCAT + [d + '#_qty' for d in distributor_dict])
# Check if was asked to merge some not allowed fields (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_NOT_HASH:
if c in fields_merge:
def remove_dnp_parts(components, variant):
'''@brief Remove the DNP parts or not assigned to the current variant.
Remove components that are assigned to a variant that is not the current variant,
or which are "do not populate" (DNP). (Any component that does not have a variant
is assigned the current variant so it will not be removed unless it is also DNP.)
@param components Part components in a `list()` of `dict()`, format given by the EDA modules.
@return `list()` of `dict()`.
'''
logger.log(DEBUG_OVERVIEW, '# Removing do not populate parts...')
accepted_components = {}
for ref, fields in components.items():
# Remove DNPs.
dnp = fields.get('local:dnp', fields.get('dnp', 0))
try:
dnp = float(dnp)
except ValueError:
pass # The field value must have been a string.
if dnp:
continue
# Get part variant. Prioritize local variants over global ones.
variants = fields.get('local:variant', fields.get('variant', None))
# Remove parts that are not assigned to the current variant.
# 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()
return refs, fields
# Read-in the schematic XML file to get a tree and get its root.
logger.log(DEBUG_OVERVIEW, '# Getting from XML \'{}\' Altium BoM...'.format(
os.path.basename(in_file)) )
file_h = open(in_file)
root = BeautifulSoup(file_h, 'lxml')
file_h.close()
# Get the header of the XML file of Altium, so KiCost is able to to
# to get all the informations in the file.
logger.log(DEBUG_OVERVIEW, 'Getting the XML table header...')
header = [ extract_field(entry, 'name') for entry in root.find('columns').find_all('column') ]
logger.log(DEBUG_OVERVIEW, 'Getting components...')
accepted_components = {}
for row in root.find('rows').find_all('row'):
# Get the values for the fields in each library part (if any).
refs, fields = extract_fields_row(row, variant, header)
for i in range(len(refs)):
ref = refs[i]
ref = re.sub('\+$', 'p', ref) # Finishing "+".
ref = re.sub(PART_REF_REGEX_NOT_ALLOWED, '', ref) # Generic special characters not allowed. To work around #ISSUE #89.
ref = re.sub('\-+', '-', ref) # Double "-".
ref = re.sub('^\-', '', ref) # Starting "-".
ref = re.sub('\-$', 'n', ref) # Finishing "-".
if not re.search('\d$', ref):