How to use the kicost.global_vars.logger.log function in kicost

To help you get started, we’ve selected a few kicost examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github xesscorp / KiCost / kicost / edas / tools.py View on Github external
#   One manf# number (and one cat# for each distributor):
    #       All parts have the same manf#. Don't split this group.
    #   Two manf# numbers (or cat# distributor code), but one is `None`:
    #       Some of the parts have no manf# or distributor# but are otherwise
    #       identical to the other parts in the group. Don't split this group.
    #       Instead, propagate the non-None manf# to all the parts.
    #   Two manf# (or two cat# distributor code), neither is `None`:
    #       All parts have non-`None` manf# and distributor# numbers. Split
    #       the group into two smaller groups of parts all having the same
    #       manf# and distributor#.
    #   Three or more manf# (or distributor#):
    #       Split this group into smaller groups, each one with parts having
    #       the same manf# and distributor#, even if it's `None`. It's
    #       impossible to determine which manf# the `None` parts should be
    #       assigned to, so leave their manf# as `None`.
    logger.log(DEBUG_OVERVIEW, 'Checking the seemingly identical parts group...')
    new_component_groups = [] # Copy new component groups into this.
    for g, grp in list(component_groups.items()):
        num_manfcat_codes = {f:len(grp.manfcat_codes[f]) for f in FIELDS_MANFCAT}
        if all([num_manfcat_codes[f]==1 or (num_manfcat_codes[f]==2 and None in grp.manfcat_codes[f]) for f in FIELDS_MANFCAT]):
            new_component_groups.append(grp)
            continue  # CASE ONE and TWO:
                      # Single manf# and distributor catalogue. Or a seemingly
                      # identical group with just one valid manf# or cat# code,
                      # the other one is `None`.Don't split this group. `None`
                      # will be replaced with the propagated manufacture /
                      # distributor catalogue code.
        elif all([(num_manfcat_codes[f]==1 and grp.manfcat_codes[f]==None) for f in FIELDS_MANFCAT]):
            new_component_groups.append(grp)
            continue  # CASE THREE:
                      # One manf# or cat# that is `None`. Don't split this
                      # group. These parts are not intended to be purchased.
github xesscorp / KiCost / kicost / edas / eda_altium.py View on Github external
# 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):
github xesscorp / KiCost / kicost / edas / eda_kicad.py View on Github external
logger.log(DEBUG_OVERVIEW, 'Getting authorship data...')
    title = root.find('title_block')
    def title_find_all(data, field):
        '''Helper function for finding title info, especially if it is absent.'''
        try:
            return data.find_all(field)[0].string
        except (AttributeError, IndexError):
            return None
    prj_info = dict()
    prj_info['title'] = title_find_all(title, 'title') or os.path.basename( in_file )
    prj_info['company'] = title_find_all(title, 'company')
    prj_info['date'] = title_find_all(root, 'date') or (datetime.strptime(time.ctime(os.path.getmtime(in_file)), '%a %b %d %H:%M:%S %Y').strftime("%Y-%m-%d %H:%M:%S") + ' (file)')

    # Make a dictionary from the fields in the parts library so these field
    # values can be instantiated into the individual components in the schematic.
    logger.log(DEBUG_OVERVIEW, 'Getting parts library...')
    libparts = {}
    if root.find('libparts'):
        for p in root.find('libparts').find_all('libpart'):

            # Get the values for the fields in each library part (if any).
            fields = extract_fields(p, variant)

            # 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:
github xesscorp / KiCost / kicost / edas / tools.py View on Github external
# 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:
             raise ValueError('Manufacturer/distributor codes and manufacture company "{}" can\'t be ignored to create the components groups.'.format(c))
    FIELDS_NOT_HASH = FIELDS_NOT_HASH + fields_merge # Not use the fields do merge to create the hash.

    # 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_NOT_HASH 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:
github xesscorp / KiCost / kicost / edas / tools.py View on Github external
continue # If not manf/distributor code pass to next.
            # Divide the `manf` manufacture name.
            try:
                subparts_manf = subpart_list(part['manf'])
                if len(subparts_manf)!=subparts_qty:
                    if len(subparts_manf)==1:
                        # If just one `manf`assumes that is for all.
                        subparts_manf = [subparts_manf[0]]*subparts_qty
                    else:
                        # Exception `manf` and `manf#` length doesn't match, fill with '' at the end.
                        subparts_manf.extend(['']*(subparts_qty-len(subparts_manf)))
            except KeyError:
                subparts_manf = ['']*subparts_qty
                pass

            logger.log(DEBUG_DETAILED, '{} >> {}'.format(part_ref, founded_fields) )

            # Second, if more than one subpart, split the sub parts as
            # new components with the same description, footprint, and
            # so on... Get the subpart.
            if subparts_qty>1:
                # Remove the actual part from the list.
                part_actual = part
                part_actual_value = part_actual['value']
                subpart_part = ''
                subpart_qty = ''
                # Add the split subparts.
                for subparts_index in range(subparts_qty):
                    # Create a sub component based on the main component with
                    # the subparts. Modify the designator and the part. Create
                    # a sub quantity field.
                    subpart_actual = part_actual.copy()
github xesscorp / KiCost / kicost / edas / eda_kicad.py View on Github external
# Empty value also propagated to force deleting default value
                            fields[name] = value
                        logger.log(DEBUG_OBSESSIVE, 'Field {}={}'.format(name,value))
        except AttributeError:
            pass  # No fields found for this part.
        return fields

    # Read-in the schematic XML file to get a tree and get its root.
    logger.log(DEBUG_OVERVIEW, '# Getting from XML \'{}\' KiCad BoM...'.format(
                                    os.path.basename(in_file)) )
    file_h = open(in_file)
    root = BeautifulSoup(file_h, 'lxml')
    file_h.close()

    # Get the general information of the project BoM XML file.
    logger.log(DEBUG_OVERVIEW, 'Getting authorship data...')
    title = root.find('title_block')
    def title_find_all(data, field):
        '''Helper function for finding title info, especially if it is absent.'''
        try:
            return data.find_all(field)[0].string
        except (AttributeError, IndexError):
            return None
    prj_info = dict()
    prj_info['title'] = title_find_all(title, 'title') or os.path.basename( in_file )
    prj_info['company'] = title_find_all(title, 'company')
    prj_info['date'] = title_find_all(root, 'date') or (datetime.strptime(time.ctime(os.path.getmtime(in_file)), '%a %b %d %H:%M:%S %Y').strftime("%Y-%m-%d %H:%M:%S") + ' (file)')

    # Make a dictionary from the fields in the parts library so these field
    # values can be instantiated into the individual components in the schematic.
    logger.log(DEBUG_OVERVIEW, 'Getting parts library...')
    libparts = {}
github xesscorp / KiCost / kicost / edas / tools.py View on Github external
logger.log(DEBUG_OBSESSIVE, 'Identifier: {} in {}.'.format(ref_identifier, component_groups_ref_match) )
        if len(component_groups_ref_match)>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]
                component_groups_order_new += component_groups_ref_match
            else:
                try:
                    component_groups_order_old.remove(component_groups_ref_match[0])
                except ValueError:
                    pass
                component_groups_order_new += component_groups_ref_match
    # The new order is the found refs first and at the last the not referenced in BOM_ORDER.
    component_groups_order_new += component_groups_order_old # Add the missing references groups.
    new_component_groups = [new_component_groups[i] for i in component_groups_order_new]
    return new_component_groups
github xesscorp / KiCost / kicost / edas / eda_kicad.py View on Github external
# 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', 'desc', 'value', 'comment', 'S1PN', 'S1MN', 'S1PL', 'S2PN', 'S2MN', 'S2PL') and name[:-1] not in distributor_dict:
                        dist_mtch = re.match('([^:]+):',name)
                        if dist_mtch and dist_mtch.group(1) not in distributor_dict:
                            # 'name' is a distibutore (preceded & followed with ':'
                            logger.log(DEBUG_OBSESSIVE, 'Assigning local: for name "{}" dist "{}" ... '.format(name,dist_mtch.group(1)) )
                            # Original code supposes that name is a distributor
                            if SEPRTR not in name: # This field has no distributor.
                                name = 'local:' + name # Assign it to a local distributor.
                        value = str(f.string)
                        if value or v is not None:
                            # Empty value also propagated to force deleting default value
                            fields[name] = value
                        logger.log(DEBUG_OBSESSIVE, 'Field {}={}'.format(name,value))
        except AttributeError:
            pass  # No fields found for this part.
        return fields