<commit_before>
import sys

if sys.version_info.major >= 3:
    import configparser as ConfigParser
else:
    import ConfigParser
import os
from columns import ColumnList

class BomPref:
    
    SECTION_IGNORE = "IGNORE_COLUMNS"
    SECTION_GENERAL = "BOM_OPTIONS"
    SECTION_ALIASES = "COMPONENT_ALIASES"
    SECTION_GROUPING_FIELDS = "GROUP_FIELDS"
    SECTION_REGEXCLUDES = "REGEX_EXCLUDE"
    SECTION_REGINCLUDES = "REGEX_INCLUDE"
    
    OPT_PCB_CONFIG = "pcb_configuration"
    OPT_NUMBER_ROWS = "number_rows"
    OPT_GROUP_CONN = "group_connectors"
    OPT_USE_REGEX = "test_regex"
    OPT_MERGE_BLANK = "merge_blank_fields"
    OPT_IGNORE_DNF = "ignore_dnf"
    OPT_BACKUP = "make_backup"

    OPT_CONFIG_FIELD = "fit_field"
    
    def __init__(self):
        self.ignore = [
            ColumnList.COL_PART_LIB,
            ColumnList.COL_FP_LIB,
            ] #list of headings to ignore in BoM generation
        self.ignoreDNF = True #ignore rows for do-not-fit parts
        self.numberRows = True #add row-numbers to BoM output
        self.groupConnectors = True #group connectors and ignore component value
        self.useRegex = True #Test various columns with regex
        self.boards = 1
        self.mergeBlankFields = True #blanks fields will be merged when possible
        self.hideHeaders = False
        self.verbose = False #by default, is not verbose
        self.configField = "Config" #default field used for part fitting config
        self.pcbConfig = "default"
        self.backup = "%O.tmp"
            
        #default fields used to group components
        self.groups = [
            ColumnList.COL_PART,
            ColumnList.COL_PART_LIB,
            ColumnList.COL_VALUE,
            ColumnList.COL_FP,
            ColumnList.COL_FP_LIB,
            #user can add custom grouping columns in bom.ini
            ]
            
        self.regIncludes = [] #none by default
        
        self.regExcludes = [
            [ColumnList.COL_REFERENCE,'^TP[0-9]*'],
            [ColumnList.COL_REFERENCE,'^FID'],
            [ColumnList.COL_PART,'mount.*hole'],
            [ColumnList.COL_PART,'solder.*bridge'],
            [ColumnList.COL_PART,'test.*point'],
            [ColumnList.COL_FP,'test.*point'],
            [ColumnList.COL_FP,'mount.*hole'],
            [ColumnList.COL_FP,'fiducial'],
        ]
            
        #default component groupings
        self.aliases = [
            ["c", "c_small", "cap", "capacitor"],
            ["r", "r_small", "res", "resistor"],
            ["sw", "switch"],
            ["l", "l_small", "inductor"],
            ["zener","zenersmall"],
            ["d","diode","d_small"]
            ]
        
    #check an option within the SECTION_GENERAL group
    def checkOption(self, parser, opt, default=False):
        if parser.has_option(self.SECTION_GENERAL, opt):
            return parser.get(self.SECTION_GENERAL, opt).lower() in ["1","true","yes"]
        else:
            return default
            
    #read KiBOM preferences from file
    def Read(self, file, verbose=False):
        file = os.path.abspath(file)
        if not os.path.exists(file) or not os.path.isfile(file):
            print("{f} is not a valid file!".format(f=file))
            return
            
        with open(file, 'rb') as configfile:
            cf = ConfigParser.RawConfigParser(allow_no_value = True)
            cf.optionxform=str
            
            cf.read(file)
            
            #read general options
            if self.SECTION_GENERAL in cf.sections():
                self.ignoreDNF =  self.checkOption(cf, self.OPT_IGNORE_DNF, default=True)
                self.numberRows = self.checkOption(cf, self.OPT_NUMBER_ROWS, default=True)
                self.groupConnectors = self.checkOption(cf, self.OPT_GROUP_CONN, default=True)
                self.useRegex = self.checkOption(cf, self.OPT_USE_REGEX, default=True)
                self.mergeBlankFields = self.checkOption(cf, self.OPT_MERGE_BLANK, default = True)
                
            if cf.has_option(self.SECTION_GENERAL, self.OPT_CONFIG_FIELD):
                self.configField = cf.get(self.SECTION_GENERAL, self.OPT_CONFIG_FIELD)

            if cf.has_option(self.SECTION_GENERAL, self.OPT_BACKUP):
                self.backup = cf.get(self.SECTION_GENERAL, self.OPT_BACKUP)
       
            #read out grouping colums
            if self.SECTION_GROUPING_FIELDS in cf.sections():
                self.groups = [i for i in cf.options(self.SECTION_GROUPING_FIELDS)]
       
            #read out ignored-rows
            if self.SECTION_IGNORE in cf.sections():
                self.ignore = [i for i in cf.options(self.SECTION_IGNORE)]
            
            #read out component aliases
            if self.SECTION_ALIASES in cf.sections():
                self.aliases = [a.split("\t") for a in cf.options(self.SECTION_ALIASES)]
                
            if self.SECTION_REGEXCLUDES in cf.sections():
                self.regExcludes = []
                for pair in cf.options(self.SECTION_REGEXCLUDES):
                    if len(pair.split("\t")) == 2:
                        self.regExcludes.append(pair.split("\t"))
                
            if self.SECTION_REGINCLUDES in cf.sections():
                self.regIncludes = []
                for pair in cf.options(self.SECTION_REGINCLUDES):
                    if len(pair.split("\t")) == 2:
                        self.regIncludes.append(pair.split("\t"))
            
    #add an option to the SECTION_GENRAL group
    def addOption(self, parser, opt, value, comment=None):
        if comment:
            if not comment.startswith(";"):<commit_msg>made creation of backup file configurable<commit_after>
import sys

if sys.version_info.major >= 3:
    import configparser as ConfigParser
else:
    import ConfigParser
import os
from columns import ColumnList

class BomPref:
    
    SECTION_IGNORE = "IGNORE_COLUMNS"
    SECTION_GENERAL = "BOM_OPTIONS"
    SECTION_ALIASES = "COMPONENT_ALIASES"
    SECTION_GROUPING_FIELDS = "GROUP_FIELDS"
    SECTION_REGEXCLUDES = "REGEX_EXCLUDE"
    SECTION_REGINCLUDES = "REGEX_INCLUDE"
    
    OPT_PCB_CONFIG = "pcb_configuration"
    OPT_NUMBER_ROWS = "number_rows"
    OPT_GROUP_CONN = "group_connectors"
    OPT_USE_REGEX = "test_regex"
    OPT_MERGE_BLANK = "merge_blank_fields"
    OPT_IGNORE_DNF = "ignore_dnf"
    OPT_BACKUP = "make_backup"

    OPT_CONFIG_FIELD = "fit_field"
    
    def __init__(self):
        self.ignore = [
            ColumnList.COL_PART_LIB,
            ColumnList.COL_FP_LIB,
            ] #list of headings to ignore in BoM generation
        self.ignoreDNF = True #ignore rows for do-not-fit parts
        self.numberRows = True #add row-numbers to BoM output
        self.groupConnectors = True #group connectors and ignore component value
        self.useRegex = True #Test various columns with regex
        self.boards = 1
        self.mergeBlankFields = True #blanks fields will be merged when possible
        self.hideHeaders = False
        self.verbose = False #by default, is not verbose
        self.configField = "Config" #default field used for part fitting config
        self.pcbConfig = "default"
        self.backup = "%O.tmp"
            
        #default fields used to group components
        self.groups = [
            ColumnList.COL_PART,
            ColumnList.COL_PART_LIB,
            ColumnList.COL_VALUE,
            ColumnList.COL_FP,
            ColumnList.COL_FP_LIB,
            #user can add custom grouping columns in bom.ini
            ]
            
        self.regIncludes = [] #none by default
        
        self.regExcludes = [
            [ColumnList.COL_REFERENCE,'^TP[0-9]*'],
            [ColumnList.COL_REFERENCE,'^FID'],
            [ColumnList.COL_PART,'mount.*hole'],
            [ColumnList.COL_PART,'solder.*bridge'],
            [ColumnList.COL_PART,'test.*point'],
            [ColumnList.COL_FP,'test.*point'],
            [ColumnList.COL_FP,'mount.*hole'],
            [ColumnList.COL_FP,'fiducial'],
        ]
            
        #default component groupings
        self.aliases = [
            ["c", "c_small", "cap", "capacitor"],
            ["r", "r_small", "res", "resistor"],
            ["sw", "switch"],
            ["l", "l_small", "inductor"],
            ["zener","zenersmall"],
            ["d","diode","d_small"]
            ]
        
    #check an option within the SECTION_GENERAL group
    def checkOption(self, parser, opt, default=False):
        if parser.has_option(self.SECTION_GENERAL, opt):
            return parser.get(self.SECTION_GENERAL, opt).lower() in ["1","true","yes"]
        else:
            return default
            
    #read KiBOM preferences from file
    def Read(self, file, verbose=False):
        file = os.path.abspath(file)
        if not os.path.exists(file) or not os.path.isfile(file):
            print("{f} is not a valid file!".format(f=file))
            return
            
        with open(file, 'rb') as configfile:
            cf = ConfigParser.RawConfigParser(allow_no_value = True)
            cf.optionxform=str
            
            cf.read(file)
            
            #read general options
            if self.SECTION_GENERAL in cf.sections():
                self.ignoreDNF =  self.checkOption(cf, self.OPT_IGNORE_DNF, default=True)
                self.numberRows = self.checkOption(cf, self.OPT_NUMBER_ROWS, default=True)
                self.groupConnectors = self.checkOption(cf, self.OPT_GROUP_CONN, default=True)
                self.useRegex = self.checkOption(cf, self.OPT_USE_REGEX, default=True)
                self.mergeBlankFields = self.checkOption(cf, self.OPT_MERGE_BLANK, default = True)
                
            if cf.has_option(self.SECTION_GENERAL, self.OPT_CONFIG_FIELD):
                self.configField = cf.get(self.SECTION_GENERAL, self.OPT_CONFIG_FIELD)

            if cf.has_option(self.SECTION_GENERAL, self.OPT_BACKUP):
                self.backup = cf.get(self.SECTION_GENERAL, self.OPT_BACKUP)
            else:
                self.backup = False
       
            #read out grouping colums
            if self.SECTION_GROUPING_FIELDS in cf.sections():
                self.groups = [i for i in cf.options(self.SECTION_GROUPING_FIELDS)]
       
            #read out ignored-rows
            if self.SECTION_IGNORE in cf.sections():
                self.ignore = [i for i in cf.options(self.SECTION_IGNORE)]
            
            #read out component aliases
            if self.SECTION_ALIASES in cf.sections():
                self.aliases = [a.split("\t") for a in cf.options(self.SECTION_ALIASES)]
                
            if self.SECTION_REGEXCLUDES in cf.sections():
                self.regExcludes = []
                for pair in cf.options(self.SECTION_REGEXCLUDES):
                    if len(pair.split("\t")) == 2:
                        self.regExcludes.append(pair.split("\t"))
                
            if self.SECTION_REGINCLUDES in cf.sections():
                self.regIncludes = []
                for pair in cf.options(self.SECTION_REGINCLUDES):
                    if len(pair.split("\t")) == 2:
                        self.regIncludes.append(pair.split("\t"))
            
    #add an option to the SECTION_GENRAL group
    def addOption(self, parser, opt, value, comment=None):
        if comment:
            if not comment.startswith(";"):
{'fraction_non_alphanumeric': 0.0997908314450061, 'fraction_numerical': 0.001220149904131079, 'mean_word_length': 1.9674166020170676, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3264581', 'n_tokens_mistral': 3491, 'n_tokens_neox': 3377, 'n_words': 723}